int Mission::checkIntExpr(missionNode *node,int mode){ int res=0; if(node->tag==DTAG_VAR_EXPR){ res=doIntVar(node,mode); } else if(node->tag==DTAG_FMATH){ res=doIMath(node,mode); } else if(node->tag==DTAG_CONST){ varInst *vi=doConst(node,mode); if(vi && vi->type==VAR_INT){ res=vi->int_val; } else{ fatalError(node,mode,"expected a float const, got a different one"); assert(0); } deleteVarInst(vi); } else if(node->tag==DTAG_CALL){ varInst *vi=doCall(node,mode); if(vi->type==VAR_INT){ res=vi->int_val; } else if(vi->type==VAR_ANY && mode==SCRIPT_PARSE){ res=vi->int_val; } else{ fatalError(node,mode,"expected a int call, got a different one"); assert(0); } deleteVarInst(vi); } else if(node->tag==DTAG_EXEC){ varInst *vi=doExec(node,mode); if(vi==NULL){ fatalError(node,mode,"doExec returned NULL"); assert(0); } else if(node->script.vartype==VAR_INT){ res=vi->int_val; } else{ fatalError(node,mode,"expected a int exec, got a different one"); assert(0); } deleteVarInst(vi); } else{ fatalError(node,mode,"no such int expression tag"); assert(0); } return res; }
int Mission::doIMath(missionNode *node,int mode){ // debug(0,node,mode,"deprecated Imath"); varInst *math_vi=doMath(node,mode); if(math_vi->type!=VAR_INT){ fatalError(node,mode,"fmath expected int"); assert(0); } int res=math_vi->int_val; deleteVarInst(math_vi); return res; #if 0 // if(mode==SCRIPT_PARSE){ string mathname=node->attr_value("math"); int len=node->subnodes.size(); if(len<2){ fatalError(node,mode,"imath needs at least 2 arguments"); assert(0); } int res=checkIntExpr((missionNode *)node->subnodes[0],mode); char buffer[200]; sprintf(buffer,"imath: 1st expr returns %d",res); debug(4,node,mode,buffer); for(int i=1;i<len;i++){ int res2=checkIntExpr((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 imath expression"); assert(0); } } } if(mode==SCRIPT_RUN){ return res; } return 0; #endif }
void Mission::doModule( missionNode *node, int mode ) { if (mode == SCRIPT_PARSE) { string name = node->attr_value( "name" ); if (parsemode == PARSE_DECL) { if ( name.empty() ) { fatalError( node, mode, "you have to give a module name" ); assert( 0 ); } if (runtime.modules[name] != NULL) { fatalError( node, mode, "there can only be one module with name "+name ); assert( 0 ); } if (name == "director") director = node; node->script.name = name; varInstMap *cvmap = new varInstMap; node->script.classvars.push_back( cvmap ); node->script.classinst_counter = 0; debug( 10, node, mode, "created classinst 0" ); runtime.modules[name] = node; //add this module to the list of known modules } scope_stack.push_back( node ); current_module = node; debug( 5, node, mode, "added module "+name+" to list of known modules" ); } if (mode == SCRIPT_RUN) { //SCRIPT_RUN runtime.cur_thread->module_stack.push_back( node ); runtime.cur_thread->classid_stack.push_back( 0 ); } vector< easyDomNode* >::const_iterator siter; for (siter = node->subnodes.begin(); siter != node->subnodes.end(); siter++) { missionNode *snode = (missionNode*) *siter; if (snode->tag == DTAG_SCRIPT) { varInst *vi = doScript( snode, mode ); deleteVarInst( vi ); } else if (snode->tag == DTAG_DEFVAR) { doDefVar( snode, mode ); } else if (snode->tag == DTAG_GLOBALS) { doGlobals( snode, mode ); } else if (snode->tag == DTAG_IMPORT) { doImport( snode, mode ); } else { fatalError( snode, mode, "unkown node type for module subnodes" ); assert( 0 ); } } if (mode == SCRIPT_PARSE) { scope_stack.pop_back(); } else { runtime.cur_thread->module_stack.pop_back(); runtime.cur_thread->classid_stack.pop_back(); } }
void Mission::removeContextStack() { contextStack *cstack = runtime.cur_thread->exec_stack.back(); runtime.cur_thread->exec_stack.pop_back(); if (cstack->return_value != NULL) deleteVarInst( cstack->return_value, true ); delete cstack; }
void Mission::deleteVarMap( varInstMap *vmap ) { vsUMap< string, varInst* >::const_iterator iter; for (iter = vmap->begin(); iter != vmap->end(); iter++) { varInst *vi = (*iter).second; if (vi == NULL) debug( 12, NULL, 0, "NULLVAR "+(*iter).first+"\n" ); else deleteVarInst( vi, true ); } }
void Mission::removeContext() { contextStack *stack = runtime.cur_thread->exec_stack.back(); int lastelem = stack->contexts.size()-1; scriptContext *old = stack->contexts[lastelem]; stack->contexts.pop_back(); #if 0 vsUMap< string, varInst* >::const_iterator iter; for (iter = old->varinsts->begin(); iter != old->varinsts->end(); iter++) { varInst *vi = (*iter).second; deleteVarInst( vi ); } #endif deleteVarMap( old->varinsts ); delete old->varinsts; delete old; }
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; }
bool Mission::doTest(missionNode *node,int mode){ if(mode==SCRIPT_PARSE){ string teststr=node->attr_value("test"); if(teststr.empty()){ fatalError(node,mode,"you have to give test an argument what to test"); assert(0); } if(teststr=="gt"){ node->script.tester=TEST_GT; } else if(teststr=="lt"){ node->script.tester=TEST_LT; } else if(teststr=="eq"){ node->script.tester=TEST_EQ; } else if(teststr=="ne"){ node->script.tester=TEST_NE; } else if(teststr=="ge"){ node->script.tester=TEST_GE; } else if(teststr=="le"){ node->script.tester=TEST_LE; } #if 0 else if(teststr=="between"){ node->script.tester=TEST_BETWEEN; } #endif else { fatalError(node,mode,"unknown test argument for test"); assert(0); } vector<easyDomNode *>::const_iterator siter; #if 0 int i=0; for(siter= node->subnodes.begin() ; siter!=node->subnodes.end() && i<2; siter++){ missionNode *snode=(missionNode *)*siter; (node->script.test_arg)[i]=snode; } if(i<2){ fatalError(node,mode,"a test-expr needs exact two subnodes"); assert(0); } #endif int len=node->subnodes.size(); if(len!=2){ fatalError(node,mode,"a test-expr needs exact two subnodes"); assert(0); } node->script.test_arg[0]=(missionNode *)node->subnodes[0]; node->script.test_arg[1]=(missionNode *)node->subnodes[1]; } // end of parse varInst * arg1_vi=checkExpression(node->script.test_arg[0],mode); varInst * arg2_vi=checkExpression(node->script.test_arg[1],mode); bool res=false; if(arg1_vi->type!=arg2_vi->type){ fatalError(node,mode,"test is getting not the same types"); assert(0); } if(mode==SCRIPT_RUN){ if(arg1_vi->type==VAR_FLOAT){ double arg1=arg1_vi->float_val; double arg2=arg2_vi->float_val; switch(node->script.tester){ case TEST_GT: res=(arg1>arg2); break; case TEST_LT: res=(arg1<arg2); break; case TEST_EQ: res=(arg1==arg2); break; case TEST_NE: res=(arg1!=arg2); break; case TEST_GE: res=(arg1>=arg2); break; case TEST_LE: res=(arg1<=arg2); break; default: fatalError(node,mode,"no valid tester"); assert(0); } } else if(arg1_vi->type==VAR_INT){ int arg1=arg1_vi->int_val; int arg2=arg2_vi->int_val; switch(node->script.tester){ case TEST_GT: res=(arg1>arg2); break; case TEST_LT: res=(arg1<arg2); break; case TEST_EQ: res=(arg1==arg2); break; case TEST_NE: res=(arg1!=arg2); break; case TEST_GE: res=(arg1>=arg2); break; case TEST_LE: res=(arg1<=arg2); break; default: fatalError(node,mode,"no valid tester"); assert(0); } } else{ fatalError(node,mode,"no such type allowed for test"); assert(0); } }// SCRIPT_RUN deleteVarInst(arg1_vi); deleteVarInst(arg2_vi); return res; }
bool Mission::checkBoolExpr(missionNode *node,int mode){ bool ok; // no difference between parse/run if(node->tag==DTAG_AND_EXPR){ ok=doAndOr(node,mode); } else if(node->tag==DTAG_OR_EXPR){ ok=doAndOr(node,mode); } else if(node->tag==DTAG_NOT_EXPR){ ok=doNot(node,mode); } else if(node->tag==DTAG_TEST_EXPR){ ok=doTest(node,mode); } else if(node->tag==DTAG_VAR_EXPR){ ok=doBooleanVar(node,mode); } else if(node->tag==DTAG_CONST){ varInst *vi=doConst(node,mode); if(vi->type==VAR_BOOL){ ok=vi->bool_val; } else{ fatalError(node,mode,"expected a bool const, got a different one"); assert(0); } deleteVarInst(vi); } else if(node->tag==DTAG_CALL){ varInst *vi=doCall(node,mode); if(vi->type==VAR_BOOL){ ok=vi->bool_val; } else if(vi->type==VAR_ANY && mode==SCRIPT_PARSE){ ok=vi->bool_val; } else{ fatalError(node,mode,"expected a bool call, got a different one"); assert(0); } deleteVarInst(vi); } else if(node->tag==DTAG_EXEC){ varInst *vi=doExec(node,mode); if(vi==NULL){ fatalError(node,mode,"doExec returned NULL"); assert(0); // parsing? } else if(node->script.vartype==VAR_BOOL){ ok=vi->bool_val; } else{ fatalError(node,mode,"expected a bool exec, got a different one"); assert(0); } deleteVarInst(vi); } else{ fatalError(node,mode,"no such boolean expression tag"); assert(0); } return ok; }
varInst * Mission::doMath(missionNode *node,int mode){ // if(mode==SCRIPT_PARSE){ string mathname=node->attr_value("math"); int len=node->subnodes.size(); if(len<2){ fatalError(node,mode,"math needs at least 2 arguments"); assert(0); } varInst *res_vi=newVarInst(VI_TEMP); varInst* res1_vi=checkExpression((missionNode *)node->subnodes[0],mode); if(res1_vi->type!=VAR_INT && res1_vi->type!=VAR_FLOAT && res1_vi->type!=VAR_ANY){ printf("res1_vi=%d\n",res1_vi->type); fatalError(node,mode,"only int or float expr allowed for math"); assert(0); } res_vi->type=res1_vi->type; assignVariable(res_vi,res1_vi); if(res_vi->type==VAR_ANY){ res_vi->type=VAR_FLOAT; } deleteVarInst(res1_vi); // char buffer[200]; //sprintf(buffer,"fmath: 1st expr returns %f",res); //debug(4,node,mode,buffer); for(int i=1;i<len;i++){ varInst * res2_vi=checkExpression((missionNode *)node->subnodes[i],mode); var_type res2_type=res2_vi->type; if(res2_type==VAR_INT && res_vi->type==VAR_FLOAT){ res2_type=VAR_FLOAT; if(mode==SCRIPT_RUN){ float res2=(float)res2_vi->int_val; float res=floatMath(mathname,res_vi->float_val,res2); res_vi->float_val=res; } } else if(res2_type==VAR_FLOAT && res_vi->type==VAR_INT){ res_vi->type=VAR_FLOAT; if(mode==SCRIPT_RUN){ res_vi->float_val=(float)res_vi->int_val; float res2=res2_vi->float_val; float res=floatMath(mathname,res_vi->float_val,res2); res_vi->float_val=res; } } else{ if(res_vi->type!=res2_type){ fatalError(node,mode,"can't do math on such types"); assert(0); } if(mode==SCRIPT_RUN){ if(res_vi->type==VAR_INT){ int res=intMath(mathname,res_vi->int_val,res2_vi->int_val); res_vi->int_val=res; } else if(res_vi->type==VAR_FLOAT){ float res=floatMath(mathname,res_vi->float_val,res2_vi->float_val); res_vi->float_val=res; } else{ if(res_vi->type!=res2_type){ fatalError(node,mode,"can't do math on such types"); assert(0); } } } // of SCRIPT_RUN } // else deleteVarInst(res2_vi); } // for arguments return res_vi; }
varInst *Mission::call_omap(missionNode *node,int mode){ //varInst *viret=new varInst; varInst *viret=NULL; if(mode==SCRIPT_PARSE){ string cmd=node->attr_value("name"); node->script.method_id=module_omap_map[cmd]; } callback_module_omap_type method_id=(callback_module_omap_type) node->script.method_id; if(method_id==CMT_OMAP_new){ viret=call_omap_new(node,mode); return viret; } else{ varInst *ovi=getObjectArg(node,mode); omap_t *my_object=getOMapObject(node,mode,ovi); if(method_id==CMT_OMAP_delete){ if(mode==SCRIPT_RUN){ omap_t::iterator iter; for(iter=my_object->begin();iter!=my_object->end();iter++){ string varname=(*iter).first ; varInst *vi=(*iter).second; deleteVarInst(vi,true); } my_object->clear(); delete my_object; } viret=newVarInst(VI_TEMP); viret->type=VAR_VOID; } else if(method_id==CMT_OMAP_set){ missionNode *snode=getArgument(node,mode,2); //varInst *vi=doVariable(snode,mode); // should be getObjExpr varInst *var_vi=checkExpression(snode,mode); // should be getObjExpr string name=getStringArgument(node,mode,1); debug(3,node,mode,"omap set"); if(mode==SCRIPT_RUN){ varInst *push_vi=newVarInst(VI_IN_OBJECT); push_vi->type=var_vi->type; assignVariable(push_vi,var_vi); (*my_object)[name]=push_vi; //printf("setting [%s] type %d\n",name.c_str(),push_vi->type); } deleteVarInst(var_vi); viret=newVarInst(VI_TEMP); viret->type=VAR_VOID; //return viret; } else if(method_id==CMT_OMAP_get){ debug(3,node,mode,"omap.get"); string name=getStringArgument(node,mode,1); viret=newVarInst(VI_TEMP); viret->type=VAR_ANY; if(mode==SCRIPT_RUN){ varInst *back_vi=(*my_object)[name]; assignVariable(viret,back_vi); // printf("viret type=%d back_vi type=%d\n",viret->type,back_vi->type); if(back_vi->type>10){ assert(0); } deleteVarInst(back_vi); // this won't delete it } } else if(method_id==CMT_OMAP_toxml){ if(node->subnodes.size()!=1){ fatalError(node,mode,"olist.toxml needs no arguments"); assert(0); } debug(3,node,mode,"omap.toxml"); if(mode==SCRIPT_RUN){ //call_olist_toxml(node,mode,ovi); } viret =newVarInst(VI_TEMP); viret->type=VAR_VOID; } else if(method_id==CMT_OMAP_size){ if(node->subnodes.size()!=1){ fatalError(node,mode,"olist.size needs one arguments"); assert(0); } debug(3,node,mode,"omap.size"); viret=newVarInst(VI_TEMP); if(mode==SCRIPT_RUN){ int len=my_object->size(); viret->int_val=len; } viret->type=VAR_INT; //return viret; } else{ fatalError(node,mode,"unknown command "+node->script.name+" for callback omap"); assert(0); } deleteVarInst(ovi); return viret; } // else (objects) return NULL; // never reach }