From 14ec4b8342ee1abc268d13f6c5c33f982c16f41e Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Wed, 19 Aug 2015 14:19:01 +0200 Subject: 2nd and 3rd pass, lots o builtins, keywords --- postrun.cpp | 184 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----- test.prn | 19 ++++++- 2 files changed, 186 insertions(+), 17 deletions(-) diff --git a/postrun.cpp b/postrun.cpp index 17d72ca..7d2a08d 100644 --- a/postrun.cpp +++ b/postrun.cpp @@ -7,6 +7,7 @@ #include #include #include +#include using namespace std; @@ -28,7 +29,7 @@ vector tokenise(istream &stream){ token+=c; } else { if(token.size())tokens.push_back(move(token)); - else if(isoperator(c))tokens.push_back(string(1,c)); + if(isoperator(c))tokens.push_back(string(1,c)); else if(c=='"'||c=='\''){ stringmode=c; while(true){ @@ -86,16 +87,22 @@ struct Stackitem{ bool isstr; string strval; int intval; + + Stackitem(void):isstr(false),intval(0){} + Stackitem(int _i):isstr(false),intval(_i){} + Stackitem(const string &_s):isstr(true),strval(_s),intval(0){} + operator bool(void){return (isstr&&strval.size())||(!isstr&&intval);} + bool operator==(const Stackitem &other){return isstr==other.isstr&&(isstr?strval==other.strval:intval==other.intval);} }; const unordered_map&,unordered_map&)>> builtins={ {"+",[](stack &S,unordered_map &variables){ if(S.size()<2)throw string("Builtin '+' needs 2 stack items"); - Stackitem a,b,c; + Stackitem a,b; b=S.top(); S.pop(); a=S.top(); S.pop(); if(!a.isstr&&!b.isstr){ - S.push({false,"",a.intval+b.intval}); + S.emplace(a.intval+b.intval); return; } if(!a.isstr){ @@ -106,15 +113,81 @@ const unordered_map&,unordered_map &S,unordered_map &variables){ if(S.size()<2)throw string("Builtin '-' needs 2 stack items"); - Stackitem a,b,c; + Stackitem a,b; b=S.top(); S.pop(); a=S.top(); S.pop(); if(a.isstr||b.isstr)throw string("Builtin '-' cannot accept a string argument"); - S.push({false,"",a.intval-b.intval}); + S.emplace(a.intval-b.intval); + }}, + {"*",[](stack &S,unordered_map &variables){ + if(S.size()<2)throw string("Builtin '*' needs 2 stack items"); + Stackitem a,b; + b=S.top(); S.pop(); + a=S.top(); S.pop(); + if(a.isstr||b.isstr)throw string("Builtin '*' cannot accept a string argument"); + S.emplace(a.intval*b.intval); + }}, + {"/",[](stack &S,unordered_map &variables){ + if(S.size()<2)throw string("Builtin '/' needs 2 stack items"); + Stackitem a,b; + b=S.top(); S.pop(); + a=S.top(); S.pop(); + if(a.isstr||b.isstr)throw string("Builtin '/' cannot accept a string argument"); + S.emplace(a.intval/b.intval); + }}, + {"%",[](stack &S,unordered_map &variables){ + if(S.size()<2)throw string("Builtin '%' needs 2 stack items"); + Stackitem a,b; + b=S.top(); S.pop(); + a=S.top(); S.pop(); + if(a.isstr||b.isstr)throw string("Builtin '%' cannot accept a string argument"); + S.emplace(a.intval%b.intval); + }}, + {"^",[](stack &S,unordered_map &variables){ + if(S.size()<2)throw string("Builtin '^' needs 2 stack items"); + Stackitem a,b; + b=S.top(); S.pop(); + a=S.top(); S.pop(); + if(a.isstr||b.isstr)throw string("Builtin '^' cannot accept a string argument"); + S.emplace((int)pow(a.intval,b.intval)); + }}, + {"!",[](stack &S,unordered_map &variables){ + if(S.size()<1)throw string("Builtin '!' needs 1 stack item"); + Stackitem v; + v=S.top(); S.pop(); + if(v.isstr)S.emplace(!v.strval.size()); + else S.emplace(!v.intval); + }}, + {"=",[](stack &S,unordered_map &variables){ + if(S.size()<2)throw string("Builtin '=' needs 2 stack items"); + Stackitem a,b; + b=S.top(); S.pop(); + a=S.top(); S.pop(); + S.emplace(a==b); + }}, + {"<",[](stack &S,unordered_map &variables){ + if(S.size()<2)throw string("Builtin '<' needs 2 stack items"); + Stackitem a,b; + b=S.top(); S.pop(); + a=S.top(); S.pop(); + if(a.isstr&&b.isstr)S.emplace(a.strval",[](stack &S,unordered_map &variables){ + if(S.size()<2)throw string("Builtin '>' needs 2 stack items"); + Stackitem a,b; + b=S.top(); S.pop(); + a=S.top(); S.pop(); + if(a.isstr&&b.isstr)S.emplace(a.strval>b.strval); + else if(!a.isstr&&!b.isstr)S.emplace(a.intval>b.intval); + else if(a.isstr)S.emplace(a.strval>to_string(b.intval)); + else S.emplace(to_string(a.intval)>b.strval); }}, {"print",[](stack &S,unordered_map &variables){ if(S.size()<1)throw string("Builtin 'print' needs 1 stack item"); @@ -122,21 +195,33 @@ const unordered_map&,unordered_map &S,unordered_map &variables){ + cout< &S,unordered_map &variables){ + if(S.size()<1)throw string("Builtin 'dup' needs 1 stack item"); + S.push(S.top()); + }}, + {"pop",[](stack &S,unordered_map &variables){ + if(S.size()<1)throw string("Builtin 'pop' needs 1 stack item"); + S.pop(); + }}, }; -void runpass2(const vector &T, +void runpasseval(const vector &T, stack &S, const unordered_map> &functions, - unordered_map &variables){ + unordered_map &variables, + const unordered_map &jumpmap){ unsigned int cursor; for(cursor=0;cursor'< &T, } else { auto it=functions.find(word); if(it!=functions.end()){ - runpass2(it->second,S,functions,variables); + runpasseval(it->second,S,functions,variables,jumpmap); } else { + if(word=="while"){ + if(S.size()<1)throw string("Keyword 'while' needs 1 stack item"); + Stackitem v=S.top(); S.pop(); + if(!v){ + cursor=jumpmap.find(cursor)->second-1; //jump to corresponding end + } + continue; + } else if(word=="if"){ + if(S.size()<1)throw string("Keyword 'if' needs 1 stack item"); + Stackitem v=S.top(); S.pop(); + if(!v){ + cursor=jumpmap.find(cursor)->second-1; //jump to corresponding else/end + } + continue; + } else if(word=="else"||word=="end"){ + cursor=jumpmap.find(cursor)->second-1; + continue; + } + auto it=builtins.find(word); if(it==builtins.end())throw "Unknown variable or function '"+word+"'"; it->second(S,variables); @@ -158,6 +262,7 @@ void runpass2(const vector &T, void run(vector T){ unordered_map> functions; unordered_map variables; + unordered_map jumpmap; stack S; unsigned int cursor=0; //first pass, handle functions and includes @@ -192,8 +297,59 @@ void run(vector T){ } } - //second pass, evaluate file - runpass2(T,S,functions,variables); + //second pass, index flow control keywords and translate '?' + vector flowindexes; + for(cursor=0;cursor if + "2>1!" print lf +else + "logic?" print lf +end + +0 if + "yup!" print lf +end +"done." print lf -- cgit v1.2.3-54-g00ecf