diff options
| author | tomsmeding <hallo@tomsmeding.nl> | 2015-09-08 19:14:27 +0200 | 
|---|---|---|
| committer | tomsmeding <hallo@tomsmeding.nl> | 2015-09-08 19:36:44 +0200 | 
| commit | 03deaf70dde4181373c2c3c44e8bbb0ba6718b41 (patch) | |
| tree | b76dca62c332de266da236139eb0f91ff6b5b349 | |
| parent | b50d606bdd0fbda3451e9fcb07e8096fa5bee55b (diff) | |
make scopes ACTUALLY WORK nicely
| -rw-r--r-- | functions.cpp | 40 | 
1 files changed, 29 insertions, 11 deletions
diff --git a/functions.cpp b/functions.cpp index 9655e5a..8bd4053 100644 --- a/functions.cpp +++ b/functions.cpp @@ -1,11 +1,12 @@  #include <iostream>  #include <fstream>  #include <unordered_map> -#include <unordered_set> +// #include <unordered_set>  #include <vector>  #include <stack>  #include <string>  #include <functional> +#include <cmath>  #include <unistd.h>  #include <fcntl.h> @@ -18,7 +19,10 @@ extern char **g_argv;  #define BUILTIN_GUARD_STACKSIZE(nm,sz) {if(S.size()<(sz))throw string("Builtin '" nm "' needs " #sz " stack item")+(sz==1?"":"s");} -stack<unordered_set<string>> scopestack; +stack<unordered_map<string,pair<Stackitem,bool>>> scopestack; +//Each stack frame contains the variables local to the stack frame. The bool is +//whether it was already present in the previous frame, and the Stackitem +//is the value held by the previous frame, if any.  //please extern this shit with const!  unordered_map<string,function<void(vector<Stackitem>&,unordered_map<string,Stackitem>&)>> builtins={ @@ -213,11 +217,17 @@ unordered_map<string,function<void(vector<Stackitem>&,unordered_map<string,Stack  		if(!name.isstr)throw string("Second argument to 'store' not a string");  		auto it=variables.find(name.strval);  		bool exists=it!=variables.end(); +		if(scopestack.size()&&scopestack.top().find(name.strval)==scopestack.top().end()){ +			if(exists) +				scopestack.top()[name.strval]={move(variables[name.strval]),true}; +			else +				scopestack.top()[name.strval]={Stackitem(),false}; +		}  		//insert_or_assign is C++17 sadly -		/*if(exists)variables.insert(it,make_pair(name.strval,move(S.back()))); -		else*/ variables[name.strval]=move(S.back()); +		/*if(exists)variables.insert_or_assign(it,make_pair(name.strval,move(S.back()))); +		else variables[name.strval]=move(S.back());*/ +		variables[name.strval]=move(S.back());  		S.pop_back(); -		if(scopestack.size()&&!exists)scopestack.top().insert(name.strval);  	}},  	{"gstore",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){  		BUILTIN_GUARD_STACKSIZE("gstore",2) @@ -241,17 +251,19 @@ unordered_map<string,function<void(vector<Stackitem>&,unordered_map<string,Stack  		variables[name.strval].intval=0;  	}},  	{"enterscope",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){ -		//cerr<<"scope enter"<<endl; +		BUILTIN_GUARD_STACKSIZE("enterscope",0)  		scopestack.emplace();  	}},  	{"leavescope",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){ +		BUILTIN_GUARD_STACKSIZE("leavescope",0)  		if(scopestack.size()<1)throw string("Scope stack empty while requesting scope leave"); -		//cerr<<"scope leave: "; -		for(const string &varname : scopestack.top()){ -			variables.erase(varname); -			//cerr<<varname<<' '; +		for(const pair<string,pair<Stackitem,bool>> &var : scopestack.top()){ +			if(var.second.second){ +				variables[var.first]=move(var.second.first); +			} else { +				variables.erase(var.first); +			}  		} -		//cerr<<endl;  		scopestack.pop();  	}},  	//positive n: roll OFF top to bottom; negative n: roll off bottom ONTO top @@ -323,6 +335,12 @@ unordered_map<string,function<void(vector<Stackitem>&,unordered_map<string,Stack  		S.back().intval=(int)S.back().strval[0];  		S.back().strval="";  	}}, +	{"sleep",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){ +		BUILTIN_GUARD_STACKSIZE("sleep",1) +		if(S.back().isstr)throw string("Argument to 'sleep' not a number"); +		usleep(S.back().intval); +		S.pop_back(); +	}},  	{"stackdump",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){  		BUILTIN_GUARD_STACKSIZE("stackdump",0)  		cerr<<"STACKDUMP: ";  | 
