diff options
author | tomsmeding <hallo@tomsmeding.nl> | 2015-09-06 22:18:30 +0200 |
---|---|---|
committer | tomsmeding <hallo@tomsmeding.nl> | 2015-09-06 22:18:30 +0200 |
commit | b50d606bdd0fbda3451e9fcb07e8096fa5bee55b (patch) | |
tree | b323b11157acdd52c6a7ba61b3036e82b0a57381 /functions.cpp | |
parent | 61dc84ab5ae95b3fa6bbbdcadf880f8ec64a925f (diff) |
Add scopes!
Diffstat (limited to 'functions.cpp')
-rw-r--r-- | functions.cpp | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/functions.cpp b/functions.cpp index 4795c93..9655e5a 100644 --- a/functions.cpp +++ b/functions.cpp @@ -1,7 +1,9 @@ #include <iostream> #include <fstream> #include <unordered_map> +#include <unordered_set> #include <vector> +#include <stack> #include <string> #include <functional> #include <unistd.h> @@ -16,6 +18,8 @@ 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; + //please extern this shit with const! unordered_map<string,function<void(vector<Stackitem>&,unordered_map<string,Stackitem>&)>> builtins={ {"+",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){ @@ -207,6 +211,18 @@ unordered_map<string,function<void(vector<Stackitem>&,unordered_map<string,Stack BUILTIN_GUARD_STACKSIZE("store",2) Stackitem name=move(S.back()); S.pop_back(); if(!name.isstr)throw string("Second argument to 'store' not a string"); + auto it=variables.find(name.strval); + bool exists=it!=variables.end(); + //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()); + 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) + Stackitem name=move(S.back()); S.pop_back(); + if(!name.isstr)throw string("Second argument to 'store' not a string"); variables[name.strval]=move(S.back()); S.pop_back(); }}, @@ -224,6 +240,20 @@ unordered_map<string,function<void(vector<Stackitem>&,unordered_map<string,Stack S.push_back(move(variables[name.strval])); variables[name.strval].intval=0; }}, + {"enterscope",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){ + //cerr<<"scope enter"<<endl; + scopestack.emplace(); + }}, + {"leavescope",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){ + 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<<' '; + } + //cerr<<endl; + scopestack.pop(); + }}, //positive n: roll OFF top to bottom; negative n: roll off bottom ONTO top {"roll",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){ BUILTIN_GUARD_STACKSIZE("roll",1) |