From 142854d3d191817784fd15d9d51ba3742b9ce26c Mon Sep 17 00:00:00 2001 From: andy Date: Mon, 18 Apr 2005 19:49:13 +0000 Subject: [PATCH] Upgrade to Nasal 1.0 test candidate --- src/Scripting/NasalSys.cxx | 54 +++++++++++++------------- src/Scripting/NasalSys.hxx | 2 +- src/Scripting/nasal-props.cxx | 73 +++++++++++++++++------------------ 3 files changed, 64 insertions(+), 65 deletions(-) diff --git a/src/Scripting/NasalSys.cxx b/src/Scripting/NasalSys.cxx index 1a894415b..6163a30b9 100644 --- a/src/Scripting/NasalSys.cxx +++ b/src/Scripting/NasalSys.cxx @@ -116,11 +116,11 @@ void FGNasalSys::hashset(naRef hash, const char* key, naRef val) // is the utility function that walks the property tree. // Future enhancement: support integer arguments to specify array // elements. -static SGPropertyNode* findnode(naContext c, naRef vec, int len) +static SGPropertyNode* findnode(naContext c, naRef* vec, int len) { SGPropertyNode* p = globals->get_props(); for(int i=0; igetNode(naStr_data(a)); if(p == 0) return 0; @@ -131,9 +131,9 @@ static SGPropertyNode* findnode(naContext c, naRef vec, int len) // getprop() extension function. Concatenates its string arguments as // property names and returns the value of the specified property. Or // nil if it doesn't exist. -static naRef f_getprop(naContext c, naRef args) +static naRef f_getprop(naContext c, naRef me, int argc, naRef* args) { - const SGPropertyNode* p = findnode(c, args, naVec_size(args)); + const SGPropertyNode* p = findnode(c, args, argc); if(!p) return naNil(); switch(p->getType()) { @@ -159,16 +159,15 @@ static naRef f_getprop(naContext c, naRef args) // setprop() extension function. Concatenates its string arguments as // property names and sets the value of the specified property to the // final argument. -static naRef f_setprop(naContext c, naRef args) +static naRef f_setprop(naContext c, naRef me, int argc, naRef* args) { #define BUFLEN 1024 - int argc = naVec_size(args); char buf[BUFLEN + 1]; buf[BUFLEN] = 0; char* p = buf; int buflen = BUFLEN; for(int i=0; iget_props(); - naRef val = naVec_get(args, argc-1); + naRef val = args[argc-1]; if(naIsString(val)) props->setStringValue(buf, naStr_data(val)); else props->setDoubleValue(buf, naNumValue(val).num); return naNil(); @@ -190,7 +189,7 @@ static naRef f_setprop(naContext c, naRef args) // print() extension function. Concatenates and prints its arguments // to the FlightGear log. Uses the highest log level (SG_ALERT), to // make sure it appears. Is there better way to do this? -static naRef f_print(naContext c, naRef args) +static naRef f_print(naContext c, naRef me, int argc, naRef* args) { #define BUFLEN 1024 char buf[BUFLEN + 1]; @@ -198,9 +197,9 @@ static naRef f_print(naContext c, naRef args) buf[0] = 0; // Zero-length in case there are no arguments char* p = buf; int buflen = BUFLEN; - int n = naVec_size(args); + int n = argc; for(int i=0; iget_commands()->execute(naStr_data(cmd), *node); return naNil(); @@ -228,16 +227,16 @@ static naRef f_fgcommand(naContext c, naRef args) // settimer(func, dt, simtime) extension function. Falls through to // FGNasalSys::setTimer(). See there for docs. -static naRef f_settimer(naContext c, naRef args) +static naRef f_settimer(naContext c, naRef me, int argc, naRef* args) { FGNasalSys* nasal = (FGNasalSys*)globals->get_subsystem("nasal"); - nasal->setTimer(args); + nasal->setTimer(argc, args); return naNil(); } // Returns a ghost handle to the argument to the currently executing // command -static naRef f_cmdarg(naContext c, naRef args) +static naRef f_cmdarg(naContext c, naRef me, int argc, naRef* args) { FGNasalSys* nasal = (FGNasalSys*)globals->get_subsystem("nasal"); return nasal->cmdArgGhost(); @@ -247,15 +246,15 @@ static naRef f_cmdarg(naContext c, naRef args) // ghost (SGPropertyNode_ptr*) or a string (global property path) to // interpolate. The second argument is a vector of pairs of // value/delta numbers. -static naRef f_interpolate(naContext c, naRef args) +static naRef f_interpolate(naContext c, naRef me, int argc, naRef* args) { SGPropertyNode* node; - naRef prop = naVec_get(args, 0); + naRef prop = argc > 0 ? args[0] : naNil(); if(naIsString(prop)) node = fgGetNode(naStr_data(prop), true); else if(naIsGhost(prop)) node = *(SGPropertyNode_ptr*)naGhost_ptr(prop); else return naNil(); - naRef curve = naVec_get(args, 1); + naRef curve = argc > 1 ? args[1] : naNil(); if(!naIsVector(curve)) return naNil(); int nPoints = naVec_size(curve) / 2; double* values = new double[nPoints]; @@ -271,7 +270,10 @@ static naRef f_interpolate(naContext c, naRef args) return naNil(); } -static naRef f_rand(naContext c, naRef args) +// This is a better RNG than the one in the default Nasal distribution +// (which is based on the C library rand() implementation). It will +// override. +static naRef f_rand(naContext c, naRef me, int argc, naRef* args) { return naNum(sg_random()); } @@ -502,17 +504,17 @@ bool FGNasalSys::handleCommand(const SGPropertyNode* arg) // "saved" somehow lest they be inadvertently cleaned. In this case, // they are inserted into a globals.__gcsave hash and removed on // expiration. -void FGNasalSys::setTimer(naRef args) +void FGNasalSys::setTimer(int argc, naRef* args) { // Extract the handler, delta, and simtime arguments: - naRef handler = naVec_get(args, 0); + naRef handler = argc > 0 ? args[0] : naNil(); if(!(naIsCode(handler) || naIsCCode(handler) || naIsFunc(handler))) return; - naRef delta = naNumValue(naVec_get(args, 1)); + naRef delta = argc > 1 ? args[1] : naNil(); if(naIsNil(delta)) return; - bool simtime = naTrue(naVec_get(args, 2)) ? true : false; + bool simtime = (argc > 2 && naTrue(args[2])) ? true : false; // Generate and register a C++ timer handler NasalTimer* t = new NasalTimer; diff --git a/src/Scripting/NasalSys.hxx b/src/Scripting/NasalSys.hxx index 8e584f9eb..01404a064 100644 --- a/src/Scripting/NasalSys.hxx +++ b/src/Scripting/NasalSys.hxx @@ -30,7 +30,7 @@ public: FGNasalScript* parseScript(const char* src, const char* name=0); // Implementation of the settimer extension function - void setTimer(naRef args); + void setTimer(int argc, naRef* args); // Returns a ghost wrapper for the current _cmdArg naRef cmdArgGhost(); diff --git a/src/Scripting/nasal-props.cxx b/src/Scripting/nasal-props.cxx index 81d58fc33..2e530c9bd 100644 --- a/src/Scripting/nasal-props.cxx +++ b/src/Scripting/nasal-props.cxx @@ -44,17 +44,14 @@ naRef FGNasalSys::propNodeGhost(SGPropertyNode* handle) // array. This allows the Nasal handlers to do things like: // Node.getChild = func { _getChild(me.ghost, arg) } // -#define NODEARG() \ - naRef ghost = naVec_get(args, 0); \ - SGPropertyNode_ptr* node = (SGPropertyNode_ptr*)naGhost_ptr(ghost); \ - if(!node || naGhost_type(ghost) != &PropNodeGhostType) \ - return naNil(); \ - if(naVec_size(args) > 1) { \ - args = naVec_get(args, 1); \ - if(!naIsVector(args)) return naNil(); \ - } else { args = naNil(); } - -static naRef f_getType(naContext c, naRef args) +#define NODEARG() \ + if(argc < 2 || !naIsGhost(args[0]) || \ + naGhost_type(args[0]) != &PropNodeGhostType) \ + naRuntimeError(c, "bad argument to props function"); \ + SGPropertyNode_ptr* node = (SGPropertyNode_ptr*)naGhost_ptr(args[0]); \ + naRef argv = args[1] + +static naRef f_getType(naContext c, naRef me, int argc, naRef* args) { NODEARG(); char* t = "unknown"; @@ -72,19 +69,19 @@ static naRef f_getType(naContext c, naRef args) return NASTR(t); } -static naRef f_getName(naContext c, naRef args) +static naRef f_getName(naContext c, naRef me, int argc, naRef* args) { NODEARG(); return NASTR((*node)->getName()); } -static naRef f_getIndex(naContext c, naRef args) +static naRef f_getIndex(naContext c, naRef me, int argc, naRef* args) { NODEARG(); return naNum((*node)->getIndex()); } -static naRef f_getValue(naContext c, naRef args) +static naRef f_getValue(naContext c, naRef me, int argc, naRef* args) { NODEARG(); switch((*node)->getType()) { @@ -99,23 +96,23 @@ static naRef f_getValue(naContext c, naRef args) return naNil(); } -static naRef f_setValue(naContext c, naRef args) +static naRef f_setValue(naContext c, naRef me, int argc, naRef* args) { NODEARG(); - naRef val = naVec_get(args, 0); + naRef val = naVec_get(argv, 0); if(naIsString(val)) (*node)->setStringValue(naStr_data(val)); else (*node)->setDoubleValue(naNumValue(val).num); return naNil(); } -static naRef f_setIntValue(naContext c, naRef args) +static naRef f_setIntValue(naContext c, naRef me, int argc, naRef* args) { NODEARG(); // Original code: - // int iv = (int)naNumValue(naVec_get(args, 0)).num; + // int iv = (int)naNumValue(naVec_get(argv, 0)).num; // Junk to pacify the gcc-2.95.3 optimizer: - naRef tmp0 = naVec_get(args, 0); + naRef tmp0 = naVec_get(argv, 0); naRef tmp1 = naNumValue(tmp0); double tmp2 = tmp1.num; int iv = (int)tmp2; @@ -124,22 +121,22 @@ static naRef f_setIntValue(naContext c, naRef args) return naNil(); } -static naRef f_setBoolValue(naContext c, naRef args) +static naRef f_setBoolValue(naContext c, naRef me, int argc, naRef* args) { NODEARG(); - naRef val = naVec_get(args, 0); + naRef val = naVec_get(argv, 0); (*node)->setBoolValue(naTrue(val) ? true : false); return naNil(); } -static naRef f_setDoubleValue(naContext c, naRef args) +static naRef f_setDoubleValue(naContext c, naRef me, int argc, naRef* args) { NODEARG(); - (*node)->setDoubleValue(naNumValue(naVec_get(args, 0)).num); + (*node)->setDoubleValue(naNumValue(naVec_get(argv, 0)).num); return naNil(); } -static naRef f_getParent(naContext c, naRef args) +static naRef f_getParent(naContext c, naRef me, int argc, naRef* args) { NODEARG(); SGPropertyNode* n = (*node)->getParent(); @@ -147,12 +144,12 @@ static naRef f_getParent(naContext c, naRef args) return propNodeGhostCreate(c, n); } -static naRef f_getChild(naContext c, naRef args) +static naRef f_getChild(naContext c, naRef me, int argc, naRef* args) { NODEARG(); - naRef child = naVec_get(args, 0); + naRef child = naVec_get(argv, 0); if(!naIsString(child)) return naNil(); - naRef idx = naNumValue(naVec_get(args, 1)); + naRef idx = naNumValue(naVec_get(argv, 1)); SGPropertyNode* n; if(naIsNil(idx) || !naIsNum(idx)) { n = (*node)->getChild(naStr_data(child)); @@ -163,17 +160,17 @@ static naRef f_getChild(naContext c, naRef args) return propNodeGhostCreate(c, n); } -static naRef f_getChildren(naContext c, naRef args) +static naRef f_getChildren(naContext c, naRef me, int argc, naRef* args) { NODEARG(); naRef result = naNewVector(c); - if(naIsNil(args) || naVec_size(args) == 0) { + if(naIsNil(argv) || naVec_size(argv) == 0) { // Get all children for(int i=0; i<(*node)->nChildren(); i++) naVec_append(result, propNodeGhostCreate(c, (*node)->getChild(i))); } else { // Get all children of a specified name - naRef name = naVec_get(args, 0); + naRef name = naVec_get(argv, 0); if(!naIsString(name)) return naNil(); vector children = (*node)->getChildren(naStr_data(name)); @@ -183,32 +180,32 @@ static naRef f_getChildren(naContext c, naRef args) return result; } -static naRef f_removeChild(naContext c, naRef args) +static naRef f_removeChild(naContext c, naRef me, int argc, naRef* args) { NODEARG(); - naRef child = naVec_get(args, 0); - naRef index = naVec_get(args, 1); + naRef child = naVec_get(argv, 0); + naRef index = naVec_get(argv, 1); if(!naIsString(child) || !naIsNum(index)) return naNil(); (*node)->removeChild(naStr_data(child), (int)index.num); return naNil(); } -static naRef f_getNode(naContext c, naRef args) +static naRef f_getNode(naContext c, naRef me, int argc, naRef* args) { NODEARG(); - naRef path = naVec_get(args, 0); - bool create = naTrue(naVec_get(args, 1)); + naRef path = naVec_get(argv, 0); + bool create = naTrue(naVec_get(argv, 1)); if(!naIsString(path)) return naNil(); SGPropertyNode* n = (*node)->getNode(naStr_data(path), create); return propNodeGhostCreate(c, n); } -static naRef f_new(naContext c, naRef args) +static naRef f_new(naContext c, naRef me, int argc, naRef* args) { return propNodeGhostCreate(c, new SGPropertyNode()); } -static naRef f_globals(naContext c, naRef args) +static naRef f_globals(naContext c, naRef me, int argc, naRef* args) { return propNodeGhostCreate(c, globals->get_props()); } -- 2.39.5