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;
}