]> git.mxchange.org Git - simgear.git/blobdiff - simgear/nasal/lib.c
Removal of PLIB/SG from SimGear
[simgear.git] / simgear / nasal / lib.c
index 8763d0ddb93d5c41182210cb1ae3e0785a89754a..11c8e434ac3b0aadae09f6f0b2d5afd81bfb3bdd 100644 (file)
@@ -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; i<sd; i++) {
-                naVec_append(errv, naGetSourceFile(subc, i));
-                naVec_append(errv, naNum(naGetLine(subc, i)));
-            }
+    if(!naGetError(subc)) {
+        naFreeContext(subc);
+        return result;
+    }
+
+    // Error handling. Note that we don't free the subcontext after an
+    // error, in case the user re-throws the same error or calls
+    // naContinue()
+    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; i<sd; i++) {
+            naVec_append(errv, naGetSourceFile(subc, i));
+            naVec_append(errv, naNum(naGetLine(subc, i)));
         }
     }
-    return result;
+    return naNil();
 }
 
 static naRef f_die(naContext c, naRef me, int argc, naRef* args)
@@ -419,8 +426,8 @@ static naRef f_find(naContext c, naRef me, int argc, naRef* args)
     int start = 0;
     if(argc < 2 || !IS_STR(args[0]) || !IS_STR(args[1])) ARGERR();
     if(argc > 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 }
 };