X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibspiderscript.so_src%2Fast_to_bytecode.c;h=58cc5f822609c6b90aa0b8b78ec8c464db882db2;hb=f9c581641afeb556188e84428febd4011e61edc2;hp=6b7e038ac1508417589071cad0c5ffd56d12ecc6;hpb=d5540392ca476276630775b5bfd6e4b4b198239e;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/libspiderscript.so_src/ast_to_bytecode.c b/Usermode/Libraries/libspiderscript.so_src/ast_to_bytecode.c index 6b7e038a..58cc5f82 100644 --- a/Usermode/Libraries/libspiderscript.so_src/ast_to_bytecode.c +++ b/Usermode/Libraries/libspiderscript.so_src/ast_to_bytecode.c @@ -79,11 +79,19 @@ tBC_Function *Bytecode_ConvertFunction(tScript_Function *Fcn) return NULL; } + Bytecode_AppendConstInt(ret, 0); // TODO: NULL + Bytecode_AppendReturn(ret); Fcn->BCFcn = ret; return ret; } +// Indepotent operation +#define CHECK_IF_NEEDED(b_warn) do { if(!bKeepValue) {\ + if(b_warn)AST_RuntimeMessage(Node, "Bytecode", "Operation without saving");\ + Bytecode_AppendDelete(Block->Handle);\ +} } while(0) + /** * \brief Convert a node into bytecode * \param Block Execution context @@ -94,11 +102,13 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue) tAST_Node *node; int ret = 0; int i, op = 0; + int bAddedValue = 1; // Used to tell if the value needs to be deleted switch(Node->Type) { // No Operation case NODETYPE_NOP: + bAddedValue = 0; break; // Code block @@ -126,8 +136,6 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue) AST_RuntimeError(Node, "LVALUE of assignment is not a variable"); return -1; } - ret = AST_ConvertNode(Block, Node->Assign.Value, 1); - if(ret) return ret; // Perform assignment operation if( Node->Assign.Operation != NODETYPE_NOP ) @@ -135,6 +143,8 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue) ret = BC_Variable_GetValue(Block, Node->Assign.Dest); if(ret) return ret; + ret = AST_ConvertNode(Block, Node->Assign.Value, 1); + if(ret) return ret; switch(Node->Assign.Operation) { // General Binary Operations @@ -157,6 +167,11 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue) printf("assign, op = %i\n", op); Bytecode_AppendBinOp(Block->Handle, op); } + else + { + ret = AST_ConvertNode(Block, Node->Assign.Value, 1); + if(ret) return ret; + } if( bKeepValue ) Bytecode_AppendDuplicate(Block->Handle); @@ -167,14 +182,20 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue) // Post increment/decrement case NODETYPE_POSTINC: case NODETYPE_POSTDEC: - Bytecode_AppendConstInt(Block->Handle, 1); - // TODO: Support assigning to object attributes if( Node->UniOp.Value->Type != NODETYPE_VARIABLE ) { AST_RuntimeError(Node, "LVALUE of assignment is not a variable"); return -1; } + // Save original value if requested + if(bKeepValue) { + ret = BC_Variable_GetValue(Block, Node->UniOp.Value); + if(ret) return ret; + } + + Bytecode_AppendConstInt(Block->Handle, 1); + ret = BC_Variable_GetValue(Block, Node->UniOp.Value); if(ret) return ret; @@ -184,8 +205,10 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue) Bytecode_AppendBinOp(Block->Handle, BC_OP_ADD); if(ret) return ret; + ret = BC_Variable_SetValue(Block, Node->UniOp.Value); if(ret) return ret; + // Doesn't push unless needed break; // Function Call @@ -193,6 +216,13 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue) case NODETYPE_FUNCTIONCALL: case NODETYPE_CREATEOBJECT: { int nargs = 0; + + // Put the object earlier on the stack to the arguments (for exec) + if( Node->Type == NODETYPE_METHODCALL ) { + ret = AST_ConvertNode(Block, Node->FunctionCall.Object, 1); + if(ret) return ret; + } + for(node = Node->FunctionCall.FirstArg; node; node = node->NextSibling) { ret = AST_ConvertNode(Block, node, 1); @@ -204,8 +234,6 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue) if( Node->Type == NODETYPE_METHODCALL ) { // TODO: Sanity check stack top - ret = AST_ConvertNode(Block, Node->FunctionCall.Object, 1); - if(ret) return ret; Bytecode_AppendMethodCall(Block->Handle, Node->FunctionCall.Name, nargs); } else @@ -236,6 +264,8 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue) Bytecode_AppendFunctionCall(Block->Handle, manglename, nargs); } } + CHECK_IF_NEEDED(0); // Don't warn + // TODO: Implement warn_unused_ret } break; // Conditional @@ -373,11 +403,14 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue) Block->CurNamespaceStack[i] = Node->Scope.Name; ret = AST_ConvertNode(Block, Node->Scope.Element, 2); Block->CurNamespaceStack[i] = NULL; + CHECK_IF_NEEDED(0); // No warning? + // TODO: Will this collide with _CALLFUNCTION etc? break; // Variable case NODETYPE_VARIABLE: ret = BC_Variable_GetValue( Block, Node ); + CHECK_IF_NEEDED(1); break; // Element of an Object @@ -386,6 +419,7 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue) if(ret) return ret; Bytecode_AppendElement(Block->Handle, Node->Scope.Name); + CHECK_IF_NEEDED(1); break; // Cast a value to another @@ -393,6 +427,7 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue) ret = AST_ConvertNode(Block, Node->Cast.Value, 1); if(ret) return ret; Bytecode_AppendCast(Block->Handle, Node->Cast.DataType); + CHECK_IF_NEEDED(1); break; // Index into an array @@ -403,6 +438,7 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue) if(ret) return ret; Bytecode_AppendIndex(Block->Handle); + CHECK_IF_NEEDED(1); break; // TODO: Implement runtime constants @@ -415,12 +451,15 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue) // Constant Values case NODETYPE_STRING: Bytecode_AppendConstString(Block->Handle, Node->Constant.String.Data, Node->Constant.String.Length); + CHECK_IF_NEEDED(1); break; case NODETYPE_INTEGER: Bytecode_AppendConstInt(Block->Handle, Node->Constant.Integer); + CHECK_IF_NEEDED(1); break; case NODETYPE_REAL: Bytecode_AppendConstReal(Block->Handle, Node->Constant.Real); + CHECK_IF_NEEDED(1); break; // --- Operations --- @@ -434,6 +473,7 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue) ret = AST_ConvertNode(Block, Node->UniOp.Value, 1); if(ret) return ret; Bytecode_AppendUniOp(Block->Handle, op); + CHECK_IF_NEEDED(1); break; // Logic @@ -464,12 +504,13 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue) if(ret) return ret; Bytecode_AppendBinOp(Block->Handle, op); + CHECK_IF_NEEDED(1); break; - //default: - // ret = NULL; - // AST_RuntimeError(Node, "BUG - SpiderScript AST_ConvertNode Unimplemented %i", Node->Type); - // break; + default: + ret = -1; + AST_RuntimeError(Node, "BUG - SpiderScript AST_ConvertNode Unimplemented %i", Node->Type); + break; } #if TRACE_NODE_RETURNS