* static variables gscript

Wed, 18 Mar 2015 17:43:45 +0200

author
cemkalyoncu
date
Wed, 18 Mar 2015 17:43:45 +0200
branch
gscript
changeset 657
76625b8556e6
parent 656
022acd8cb2f9
child 659
eabcfe8fc8e7

* static variables

Source/Scripting/Builtin.cpp file | annotate | diff | comparison | revisions
Source/Scripting/Compilers/AST.cpp file | annotate | diff | comparison | revisions
Source/Scripting/Compilers/PD.cpp file | annotate | diff | comparison | revisions
Source/Scripting/Scope.h file | annotate | diff | comparison | revisions
Source/Scripting/VirtualMachine.h file | annotate | diff | comparison | revisions
--- 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();
 			}
 

mercurial