bool Mission::doAndOr(missionNode *node,int mode){
  bool ok;

  // no difference between parse/run

  if(node->tag==DTAG_AND_EXPR){
    ok=true;
  }
  else if(node->tag==DTAG_OR_EXPR){
    ok=false;
  }

  vector<easyDomNode *>::const_iterator siter;
  
  int i=0;
  for(siter= node->subnodes.begin() ; siter!=node->subnodes.end() ; siter++,i++){
    missionNode *snode=(missionNode *)*siter;
    bool res=checkBoolExpr(snode,mode);

    if(node->tag==DTAG_AND_EXPR){
      ok=ok && res;
    }
    else if(node->tag==DTAG_OR_EXPR){
      ok=ok || res;
    }

  }

  if(mode==SCRIPT_PARSE){
    if(i<2){
      warning("less than two arguments for and/or");
    }
  }
  return ok;
}
varInst *Mission::checkExpression(missionNode *node,int mode){

  varInst *ret=NULL;
  debug(3,node,mode,"checking expression");
  //  printRuntime();

  switch(node->tag){
  case DTAG_AND_EXPR:
  case DTAG_OR_EXPR:
  case DTAG_NOT_EXPR:
  case DTAG_TEST_EXPR:
    {
    bool res=checkBoolExpr(node,mode);
    ret=newVarInst(VI_TEMP);
    ret->type=VAR_BOOL;
    ret->bool_val=res;
    return ret;
    }
    break;
  case DTAG_CONST:
    {
    ret=doConst(node,mode);
    return ret;
    }
    break;
  case DTAG_VAR_EXPR:
    {
    ret=doVariable(node,mode);
    return ret;
    }
    break;
  case DTAG_FMATH:
    {
    ret=doMath(node,mode);
    return ret;
    }
    break;
  case DTAG_CALL:
    {
    ret=doCall(node,mode);
    return ret;
    }
    break;
  case DTAG_EXEC:
    {
    ret=doExec(node,mode);
    return ret;
    }
    break;
  default:
    fatalError(node,mode,"no such expression");
    assert(0);
    break;
  }
  return ret;
}
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;
    }
}
bool Mission::doNot(missionNode *node,int mode){
  bool ok;

  // no difference between parse/run

  missionNode *snode=(missionNode *)node->subnodes[0];
  
  if(snode){
    ok=checkBoolExpr(snode,mode);

    return !ok;
  }
  else{
    fatalError(node,mode,"no subnode in not");
    assert(0);
    return false; // we'll never get here
  }
}
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;
}