From b50d606bdd0fbda3451e9fcb07e8096fa5bee55b Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Sun, 6 Sep 2015 22:18:30 +0200 Subject: Add scopes! --- bf.prn | 2 +- functions.cpp | 30 ++++++++++++++++++++++++++++++ runtime.cpp | 2 ++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/bf.prn b/bf.prn index acaa6c1..19d1368 100644 --- a/bf.prn +++ b/bf.prn @@ -80,7 +80,7 @@ dup 0 > while c ">" = if -1 roll end c "<" = if 1 roll end c "]" = if - i "loopend" depth 1 - + store + i "loopend" depth 1 - + gstore len "i" store # == break end c "[" = if diff --git a/functions.cpp b/functions.cpp index 4795c93..9655e5a 100644 --- a/functions.cpp +++ b/functions.cpp @@ -1,7 +1,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -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> scopestack; + //please extern this shit with const! unordered_map&,unordered_map&)>> builtins={ {"+",[](vector &S,unordered_map &variables){ @@ -207,6 +211,18 @@ unordered_map&,unordered_map &S,unordered_map &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&,unordered_map &S,unordered_map &variables){ + //cerr<<"scope enter"< &S,unordered_map &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< &S,unordered_map &variables){ BUILTIN_GUARD_STACKSIZE("roll",1) diff --git a/runtime.cpp b/runtime.cpp index 63e0b52..3cf607d 100644 --- a/runtime.cpp +++ b/runtime.cpp @@ -129,7 +129,9 @@ void runpasseval(const vector &T, } else { auto it=functions.find(word); if(it!=functions.end()){ + builtins.find("enterscope")->second(S,variables); runpasseval(it->second.first,S,functions,variables,it->second.second); + builtins.find("leavescope")->second(S,variables); } else { if(word=="while"){ if(S.size()<1)throw string("Keyword 'while' needs 1 stack item"); -- cgit v1.2.3-70-g09d2