X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibspiderscript.so_src%2Fexec_ast.c;h=53558386e4822ea60c62ade946baf6070be8b6a6;hb=c967d91a4794ec9c0ec7dab438c033f4c0b49952;hp=22469798d124b28d5e5ed19f0f52af14bb256435;hpb=be6e3ccd05add9ad319a121661c20cb4769f58d7;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/libspiderscript.so_src/exec_ast.c b/Usermode/Libraries/libspiderscript.so_src/exec_ast.c index 22469798..53558386 100644 --- a/Usermode/Libraries/libspiderscript.so_src/exec_ast.c +++ b/Usermode/Libraries/libspiderscript.so_src/exec_ast.c @@ -508,7 +508,8 @@ tSpiderValue *SpiderScript_ExecuteFunction(tSpiderScript *Script, // Not found? if(!bFound) { - fprintf(stderr, "Undefined reference to function '%s'\n", Function); + fprintf(stderr, "Undefined reference to function '%s' (ns='%s')\n", + Function, Namespace->Name); return ERRPTR; } @@ -650,6 +651,9 @@ tSpiderValue *SpiderScript_CreateObject(tSpiderScript *Script, { class = NULL; // Just to allow the below code to be neat + //if( !Namespace ) + // Namespace = &Script->Variant->RootNamespace; + // Second: Scan current namespace if( !class && Namespace ) { @@ -745,10 +749,13 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node) blockInfo.RetVal = NULL; blockInfo.BaseNamespace = Block->BaseNamespace; blockInfo.CurNamespace = NULL; + blockInfo.BreakTarget = NULL; blockInfo.Ident = giNextBlockIdent ++; ret = NULL; // Loop over all nodes, or until the return value is set - for(node = Node->Block.FirstChild; node && !blockInfo.RetVal; node = node->NextSibling ) + for(node = Node->Block.FirstChild; + node && !blockInfo.RetVal && !blockInfo.BreakTarget; + node = node->NextSibling ) { ret = AST_ExecuteNode(&blockInfo, node); if(ret == ERRPTR) break; // Error check @@ -767,6 +774,12 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node) // Set parent's return value if needed if( blockInfo.RetVal ) Block->RetVal = blockInfo.RetVal; + if( blockInfo.BreakTarget ) { + Block->BreakTarget = blockInfo.BreakTarget; + Block->BreakType = blockInfo.BreakType; + } + + // TODO: Unset break if break type deontes a block break } break; @@ -843,6 +856,7 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node) case NODETYPE_CREATEOBJECT: // Logical block (used to allocate `params`) { + tSpiderNamespace *ns = Block->CurNamespace; tSpiderValue *params[Node->FunctionCall.NumArgs]; i = 0; for(node = Node->FunctionCall.FirstArg; node; node = node->NextSibling) @@ -856,14 +870,13 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node) i ++; } - if( !Block->CurNamespace ) - Block->CurNamespace = Block->BaseNamespace; + if( !ns ) ns = Block->BaseNamespace; // Call the function if( Node->Type == NODETYPE_CREATEOBJECT ) { ret = SpiderScript_CreateObject(Block->Script, - Block->CurNamespace, + ns, Node->FunctionCall.Name, Node->FunctionCall.NumArgs, params ); @@ -887,7 +900,7 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node) else { ret = SpiderScript_ExecuteFunction(Block->Script, - Block->CurNamespace, Node->FunctionCall.Name, + ns, Node->FunctionCall.Name, Node->FunctionCall.NumArgs, params ); } @@ -918,38 +931,59 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node) // Loop case NODETYPE_LOOP: + // Initialise ret = AST_ExecuteNode(Block, Node->For.Init); if(ret == ERRPTR) break; - if( Node->For.bCheckAfter ) + + // Check initial condition + if( !Node->For.bCheckAfter ) { - do { - Object_Dereference(ret); - ret = AST_ExecuteNode(Block, Node->For.Code); - if(ret == ERRPTR) return ERRPTR; - Object_Dereference(ret); - ret = AST_ExecuteNode(Block, Node->For.Increment); - if(ret == ERRPTR) return ERRPTR; + Object_Dereference(ret); + + ret = AST_ExecuteNode(Block, Node->For.Condition); + if(ret == ERRPTR) return ERRPTR; + if(!SpiderScript_IsValueTrue(ret)) { Object_Dereference(ret); - ret = AST_ExecuteNode(Block, Node->For.Condition); - if(ret == ERRPTR) return ERRPTR; - } while( SpiderScript_IsValueTrue(ret) ); + ret = NULL; + break; + } } - else + + // Perform loop + for( ;; ) { Object_Dereference(ret); - ret = AST_ExecuteNode(Block, Node->For.Condition); + + // Code + ret = AST_ExecuteNode(Block, Node->For.Code); if(ret == ERRPTR) return ERRPTR; - while( SpiderScript_IsValueTrue(ret) ) { - Object_Dereference(ret); - ret = AST_ExecuteNode(Block, Node->For.Code); - if(ret == ERRPTR) return ERRPTR; - Object_Dereference(ret); - ret = AST_ExecuteNode(Block, Node->For.Increment); - if(ret == ERRPTR) return ERRPTR; - Object_Dereference(ret); - ret = AST_ExecuteNode(Block, Node->For.Condition); - if(ret == ERRPTR) return ERRPTR; + Object_Dereference(ret); + + if(Block->BreakTarget) + { + if( Block->BreakTarget[0] == '\0' || strcmp(Block->BreakTarget, Node->For.Tag) == 0 ) + { + // Ours + free((void*)Block->BreakTarget); Block->BreakTarget = NULL; + if( Block->BreakType == NODETYPE_CONTINUE ) { + // Continue, just keep going + } + else + break; + } + else + break; // Break out of this loop } + + // Increment + ret = AST_ExecuteNode(Block, Node->For.Increment); + if(ret == ERRPTR) return ERRPTR; + Object_Dereference(ret); + + // Check condition + ret = AST_ExecuteNode(Block, Node->For.Condition); + if(ret == ERRPTR) return ERRPTR; + if(!SpiderScript_IsValueTrue(ret)) break; } Object_Dereference(ret); ret = NULL; @@ -963,6 +997,12 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node) ret = NULL; // the `return` statement does not return a value break; + case NODETYPE_BREAK: + case NODETYPE_CONTINUE: + Block->BreakTarget = strdup(Node->Variable.Name); + Block->BreakType = Node->Type; + break; + // Define a variable case NODETYPE_DEFVAR: if( Node->DefVar.InitialValue ) { @@ -1303,6 +1343,10 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node) // break; } _return: + // Reset namespace when no longer needed + if( Node->Type != NODETYPE_SCOPE ) + Block->CurNamespace = NULL; + #if TRACE_NODE_RETURNS if(ret && ret != ERRPTR) { AST_RuntimeError(Node, "Ret type of %p %i is %i", Node, Node->Type, ret->Type); @@ -1593,7 +1637,9 @@ tAST_Variable *Variable_Lookup(tAST_BlockState *Block, tAST_Node *VarNode, int C */ int Variable_SetValue(tAST_BlockState *Block, tAST_Node *VarNode, tSpiderValue *Value) { - tAST_Variable *var = Variable_Lookup(Block, VarNode, Value->Type); + tAST_Variable *var; + + var = Variable_Lookup(Block, VarNode, (Value ? Value->Type : SS_DATATYPE_UNDEF)); if( !var ) return -1;