X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fnasal%2Flib.c;h=11c8e434ac3b0aadae09f6f0b2d5afd81bfb3bdd;hb=2a2e2716bdfbecb3494ab935171ed6224a178470;hp=8763d0ddb93d5c41182210cb1ae3e0785a89754a;hpb=dcb3da9f2811253710cd4afae9fa332455257aed;p=simgear.git diff --git a/simgear/nasal/lib.c b/simgear/nasal/lib.c index 8763d0dd..11c8e434 100644 --- a/simgear/nasal/lib.c +++ b/simgear/nasal/lib.c @@ -214,6 +214,10 @@ static naRef f_compile(naContext c, naRef me, int argc, naRef* args) // that it can be reset if we get a die()/naRethrowError() situation // later. Right now, the IP on the stack trace is the line of the // die() call, when it should be this one... +// +// FIXME: don't use naCall at all here, we don't need it. Fix up the +// context stack to tail call the function directly. There's no need +// for f_call() to live on the C stack at all. static naRef f_call(naContext c, naRef me, int argc, naRef* args) { naContext subc; @@ -224,32 +228,35 @@ static naRef f_call(naContext c, naRef me, int argc, naRef* args) callns = argc > 3 ? args[3] : naNil(); // ditto if(!IS_HASH(callme)) callme = naNil(); if(!IS_HASH(callns)) callns = naNil(); - if(!IS_FUNC(args[0]) || (!IS_NIL(callargs) && !IS_VEC(callargs))) + if(argc==0 || !IS_FUNC(args[0]) || (!IS_NIL(callargs) && !IS_VEC(callargs))) ARGERR(); - // Note that we don't free the subcontext, in case the user - // re-throws the same error. That happens at the next OP_RETURN - // or naSubContext(). subc = naSubContext(c); vr = IS_NIL(callargs) ? 0 : PTR(callargs).vec->rec; result = naCall(subc, args[0], vr ? vr->size : 0, vr ? vr->array : 0, callme, callns); - if(naGetError(subc)) { - if(argc <= 2 || !IS_VEC(args[argc-1])) { - naRethrowError(subc); - } else { - int i, sd; - naRef errv = args[argc-1]; - if(!IS_NIL(subc->dieArg)) naVec_append(errv, subc->dieArg); - else naVec_append(errv, NEWCSTR(subc, naGetError(subc))); - sd = naStackDepth(subc); - for(i=0; idieArg)) naVec_append(errv, subc->dieArg); + else naVec_append(errv, NEWCSTR(subc, naGetError(subc))); + sd = naStackDepth(subc); + for(i=0; i 2) start = (int)(naNumValue(args[2]).num); - return naNum(find(PTR(args[0]).str->data, PTR(args[0]).str->len, - PTR(args[1]).str->data, PTR(args[1]).str->len, + return naNum(find((void*)naStr_data(args[0]), naStr_len(args[0]), + (void*)naStr_data(args[1]), naStr_len(args[1]), start)); } @@ -514,6 +521,7 @@ static naRef f_sort(naContext c, naRef me, int argc, naRef* args) if(argc != 2 || !naIsVector(args[0]) || !naIsFunc(args[1])) naRuntimeError(c, "bad/missing argument to sort()"); sd.subc = naSubContext(c); + if(!PTR(args[0]).vec->rec) return naNewVector(c); sd.elems = PTR(args[0]).vec->rec->array; sd.n = PTR(args[0]).vec->rec->size; sd.fn = args[1]; @@ -533,6 +541,25 @@ static naRef f_sort(naContext c, naRef me, int argc, naRef* args) return out; } +static naRef f_id(naContext c, naRef me, int argc, naRef* args) +{ + char *t = "unk", buf[64]; + if(argc != 1 || !IS_REF(args[0])) + naRuntimeError(c, "bad/missing argument to id()"); + if (IS_STR(args[0])) t = "str"; + else if(IS_VEC(args[0])) t = "vec"; + else if(IS_HASH(args[0])) t = "hash"; + else if(IS_CODE(args[0])) t = "code"; + else if(IS_FUNC(args[0])) t = "func"; + else if(IS_CCODE(args[0])) t = "ccode"; + else if(IS_GHOST(args[0])) { + naGhostType *gt = PTR(args[0]).ghost->gtype; + t = gt->name ? (char*)gt->name : "ghost"; + } + sprintf(buf, "%s:%p", (char*)t, (void*)PTR(args[0]).obj); + return NEWCSTR(c, buf); +} + static naCFuncItem funcs[] = { { "size", f_size }, { "keys", f_keys }, @@ -561,6 +588,7 @@ static naCFuncItem funcs[] = { { "rand", f_rand }, { "bind", f_bind }, { "sort", f_sort }, + { "id", f_id }, { 0 } };