double Mission::doFMath(missionNode *node,int mode){ //debug(0,node,mode,"deprecated Fmath"); varInst *math_vi=doMath(node,mode); if(math_vi->type!=VAR_FLOAT){ fatalError(node,mode,"fmath expected float"); assert(0); } double ret=math_vi->float_val; deleteVarInst(math_vi); return ret; // if(mode==SCRIPT_PARSE){ string mathname=node->attr_value("math"); int len=node->subnodes.size(); if(len<2){ fatalError(node,mode,"fmath needs at least 2 arguments"); assert(0); } double res=checkFloatExpr((missionNode *)node->subnodes[0],mode); char buffer[200]; sprintf(buffer,"fmath: 1st expr returns %f",res); debug(4,node,mode,buffer); for(int i=1;i<len;i++){ double res2=checkFloatExpr((missionNode *)node->subnodes[i],mode); if(mode==SCRIPT_RUN){ if(mathname=="+"){ res=res+res2; } else if(mathname=="-"){ res=res-res2; } else if(mathname=="*"){ res=res*res2; } else if(mathname=="/"){ res=res/res2; } else{ fatalError(node,mode,"no such fmath expression"); assert(0); } } } if(mode==SCRIPT_RUN){ return res; } return 0.0; }
void Mission::doReturn( missionNode *node, int mode ) { trace( node, mode ); if (mode == SCRIPT_PARSE) { missionNode *script = current_script; node->script.exec_node = script; } int len = node->subnodes.size(); varInst *vi = newVarInst( VI_LOCAL ); missionNode *script = node->script.exec_node; if (script->script.vartype == VAR_VOID) { if (len != 0) { fatalError( node, mode, "script returning void, but return statement with node" ); assert( 0 ); } } else { //return something non-void if (len != 1) { fatalError( node, mode, "return statement needs only one subnode" ); assert( 0 ); } missionNode *expr = (missionNode*) node->subnodes[0]; if (script->script.vartype == VAR_BOOL) { bool res = checkBoolExpr( expr, mode ); vi->bool_val = res; } else if (script->script.vartype == VAR_FLOAT) { double res = checkFloatExpr( expr, mode ); vi->float_val = res; } else if (script->script.vartype == VAR_INT) { int res = checkIntExpr( expr, mode ); vi->int_val = res; } else if (script->script.vartype == VAR_OBJECT) { varInst *vi2 = checkObjectExpr( expr, mode ); vi->type = VAR_OBJECT; assignVariable( vi, vi2 ); } else { fatalError( node, mode, "unkown variable type" ); assert( 0 ); } } if (mode == SCRIPT_RUN) { contextStack *cstack = runtime.cur_thread->exec_stack.back(); vi->type = script->script.vartype; cstack->return_value = vi; } }
varInst* Mission::doExec( missionNode *node, int mode ) { trace( node, mode ); if (mode == SCRIPT_PARSE) { string name = node->attr_value( "name" ); if ( name.empty() ) { fatalError( node, mode, "you have to give name to exec" ); assert( 0 ); } node->script.name = name; string use_modstr = node->attr_value( "module" ); missionNode *module = NULL; missionNode *script = NULL; if ( !use_modstr.empty() ) { module = runtime.modules[use_modstr]; } else { module = current_module; } if (module == NULL) { fatalError( node, mode, "module "+use_modstr+" not found" ); assert( 0 ); } script = module->script.scripts[name]; if (script == NULL) { fatalError( node, mode, "script "+name+" not found in module "+use_modstr ); assert( 0 ); } node->script.exec_node = script; node->script.vartype = script->script.vartype; node->script.module_node = module; } missionNode *arg_node = node->script.exec_node->script.argument_node; int nr_arguments; if (arg_node == NULL) nr_arguments = 0; else nr_arguments = arg_node->script.nr_arguments; int nr_exec_args = node->subnodes.size(); if (nr_arguments != nr_exec_args) { char buffer[200]; sprintf( buffer, "wrong nr of arguments in doExec=%d doScript=%d", nr_exec_args, nr_arguments ); fatalError( node, mode, buffer ); assert( 0 ); } varInstMap *varmap = NULL; if (nr_arguments > 0) { varmap = new varInstMap; for (int i = 0; i < nr_arguments; i++) { missionNode *defnode = (missionNode*) arg_node->subnodes[i]; missionNode *callnode = (missionNode*) node->subnodes[i]; varInst *vi = newVarInst( VI_LOCAL ); vi->type = defnode->script.vartype; if (defnode->script.vartype == VAR_FLOAT) { debug( 4, node, mode, "doExec checking floatExpr" ); double res = checkFloatExpr( callnode, mode ); vi->float_val = res; } else if (defnode->script.vartype == VAR_INT) { debug( 4, node, mode, "doExec checking intExpr" ); int res = checkIntExpr( callnode, mode ); vi->int_val = res; } else if (defnode->script.vartype == VAR_BOOL) { debug( 4, node, mode, "doExec checking boolExpr" ); bool ok = checkBoolExpr( callnode, mode ); vi->bool_val = ok; } else if (defnode->script.vartype == VAR_OBJECT) { debug( 3, node, mode, "doExec checking objectExpr" ); varInst *ovi = checkObjectExpr( callnode, mode ); vi->type = VAR_OBJECT; if (mode == SCRIPT_RUN) assignVariable( vi, ovi ); deleteVarInst( ovi ); } else { fatalError( node, mode, "unsupported vartype in doExec" ); assert( 0 ); } (*varmap)[defnode->script.name] = vi; } } if (mode == SCRIPT_RUN) { //SCRIPT_RUN debug( 4, node, mode, "executing "+node->script.name ); missionNode *module = node->script.module_node; missionNode *old_module = runtime.cur_thread->module_stack.back(); unsigned int classid = 0; if (old_module == module) classid = runtime.cur_thread->classid_stack.back(); runtime.cur_thread->module_stack.push_back( module ); runtime.cur_thread->classid_stack.push_back( classid ); varInst *vi = doScript( node->script.exec_node, mode, varmap ); runtime.cur_thread->module_stack.pop_back(); runtime.cur_thread->classid_stack.pop_back(); if (varmap) { deleteVarMap( varmap ); delete varmap; } return vi; } //SCRIPT_PARSE varInst *vi = newVarInst( VI_TEMP ); vi->type = node->script.exec_node->script.vartype; return vi; }