Wed, 18 Mar 2015 17:43:45 +0200
* static variables
--- a/Source/Scripting/Builtin.cpp Wed Mar 18 13:28:16 2015 +0200 +++ b/Source/Scripting/Builtin.cpp Wed Mar 18 17:43:45 2015 +0200 @@ -39,6 +39,28 @@ } return String::To<bool>(str); } + + void static2(std::string name, Data value) { + auto &vm=VirtualMachine::Get(); + + auto &scope=vm.CurrentScopeInstance().GetScope(); + auto var=scope.GetVariable(name); + + // if static variable is being redefined, it will not be reassigned + if(var) + return; + + //if this variable is already defined, throw error + if(vm.CurrentScopeInstance().GetLocalVariable(name)) { + throw AmbiguousSymbolException(name, SymbolType::Variable, "Variable is already declared non-static"); + } + + scope.SetVariable(name, value); + } + + void static1(std::string name) { + static2(name, Data::Invalid()); + } } @@ -385,6 +407,24 @@ }), MappedMethods(), KeywordTag ), + new MappedFunction("static", + "Creates a static variable", + nullptr, nullptr, + ParameterList { + new Parameter( + "Variable", + "This is the variable to be declared", + String, VariableTag + ), + new Parameter( + "Value", + "This is the variable to be declared", + Variant, OptionalTag + ) + }, + MappedFunctions(static2, static1), MappedMethods(), + KeywordTag + ), new MappedFunction("unset", "Unsets a given variable", nullptr, nullptr,
--- a/Source/Scripting/Compilers/AST.cpp Wed Mar 18 13:28:16 2015 +0200 +++ b/Source/Scripting/Compilers/AST.cpp Wed Mar 18 17:43:45 2015 +0200 @@ -372,6 +372,8 @@ //Assignment operation if(tree->Type==ASTNode::Assignment) { + ASSERT(tree->Leaves.GetCount()==2, "Assignment requires two parameters"); + Instruction inst; inst.Type=InstructionType::Assignment; @@ -597,6 +599,7 @@ } else if(String::ToLower(tree->Text)=="const") { ASSERT(tree->Leaves.GetSize()==1, "const keyword requires a single parameter"); + ASSERT(tree->Leaves[0].Leaves.GetSize()==2, "Assignment requires two parameters"); ASSERT(tree->Leaves[0].Leaves[0].Type==ASTNode::Identifier || tree->Leaves[0].Leaves[0].Type==ASTNode::Variable, "const can only be applied to simple variables" @@ -614,6 +617,26 @@ return true; } + else if(String::ToLower(tree->Text)=="static") { + ASSERT(tree->Leaves.GetSize()==1, "static keyword requires a single parameter"); + ASSERT(tree->Leaves[0].Leaves.GetSize()==2, "Assignment requires two parameters"); + ASSERT(tree->Leaves[0].Leaves[0].Type==ASTNode::Identifier || + tree->Leaves[0].Leaves[0].Type==ASTNode::Variable, + "static can only be applied to simple variables" + ); + + Instruction inst; + inst.Type=InstructionType::FunctionCall; + inst.Name.SetStringLiteral("static"); + inst.Store=0; + Value v; + v.SetVariable(tree->Leaves[0].Leaves[0].Text); + inst.Parameters.push_back(v); + inst.Parameters.push_back(compilevalue(tree->Leaves[0].Leaves[1], list, tempind)); + list.push_back(inst); + + return true; + } else if(String::ToLower(tree->Text)=="end") { if(scopes.size()==0) { throw FlowException("`End` without a keyword scope");
--- a/Source/Scripting/Compilers/PD.cpp Wed Mar 18 13:28:16 2015 +0200 +++ b/Source/Scripting/Compilers/PD.cpp Wed Mar 18 17:43:45 2015 +0200 @@ -692,7 +692,7 @@ } static const std::set<std::string, String::CaseInsensitiveLess> internalkeywords={ - "if", "for", "elseif", "else", "while", "continue", "break", "end" + "if", "for", "elseif", "else", "while", "continue", "break", "end", "static" }; ASTNode *parse(const std::string &input) { @@ -763,11 +763,12 @@ auto expr=parseexpression(input, index); root->Leaves.Push(expr); } - else if(String::ToLower(token.repr)=="const") { //this is actually an assignment - assignment(nullptr, "const"); + else if(String::ToLower(token.repr)=="const" || String::ToLower(token.repr)=="static") { //this is actually an assignment + auto name=String::ToLower(token.repr); + assignment(nullptr, name); auto proot=root; root=new ASTNode(ASTNode::Keyword); - root->Text="const", + root->Text=name; root->Leaves.Push(proot); } else {
--- a/Source/Scripting/Scope.h Wed Mar 18 13:28:16 2015 +0200 +++ b/Source/Scripting/Scope.h Wed Mar 18 17:43:45 2015 +0200 @@ -217,6 +217,14 @@ return name; } + Variable *GetLocalVariable(const std::string &name) { + auto varit=variables.find(name); + if( varit !=variables.end() ) + return &varit->second; + else + return nullptr; + } + Variable *GetVariable(const std::string &name) { auto varit=variables.find(name); if( varit !=variables.end() )
--- a/Source/Scripting/VirtualMachine.h Wed Mar 18 13:28:16 2015 +0200 +++ b/Source/Scripting/VirtualMachine.h Wed Mar 18 17:43:45 2015 +0200 @@ -170,7 +170,7 @@ } /// Returns the current exection scope - const ScopeInstance &CurrentScopeInstance() const { + ScopeInstance &CurrentScopeInstance() const { return scopeinstances.Last().Current(); }