diff options
Diffstat (limited to 'runtime.cpp')
-rw-r--r-- | runtime.cpp | 68 |
1 files changed, 57 insertions, 11 deletions
diff --git a/runtime.cpp b/runtime.cpp index 98ae245..19108cd 100644 --- a/runtime.cpp +++ b/runtime.cpp @@ -1,10 +1,12 @@ #include <iostream> +#include <sstream> #include <vector> #include <string> #include <unordered_map> #include <unordered_set> #include <functional> #include <cstring> +#include <cassert> #include "runtime.h" @@ -15,23 +17,67 @@ inline bool isextword(char c){return isword(c)||isdigit(c);} inline bool isoperator(char c){return (bool)strchr("+-*/%&|~^!=><{}",c);} -Stackitem::Stackitem(void):isstr(false),intval(0){} -Stackitem::Stackitem(int _i):isstr(false),intval(_i){} -Stackitem::Stackitem(const string &_s):isstr(true),strval(_s),intval(0){} -Stackitem::Stackitem(const Stackitem&)=default; -Stackitem::Stackitem(Stackitem &&other):isstr(other.isstr),strval(move(other.strval)),intval(other.intval){ - other.isstr=false; +Stackitem::Stackitem(void){} + +Stackitem::Stackitem(int _i):type(SIT_INT),intval(_i){} +Stackitem::Stackitem(const string &_s):type(SIT_STR),strval(_s){} +Stackitem::Stackitem(const vector<Stackitem> &_a):type(SIT_ARR),arrval(_a){} + +Stackitem::Stackitem(const Stackitem &other)=default; +Stackitem::Stackitem(Stackitem &&other):type(other.type),strval(move(other.strval)),intval(other.intval),arrval(move(other.arrval)){ + other.type=SIT_INT; +} + +Stackitem& Stackitem::operator=(const Stackitem &other){ + type=other.type; + strval=other.strval; + intval=other.intval; + arrval=other.arrval; + return *this; } -Stackitem& Stackitem::operator=(const Stackitem&)=default; Stackitem& Stackitem::operator=(Stackitem &&other){ - isstr=other.isstr; + type=other.type; strval=move(other.strval); intval=other.intval; - other.isstr=false; + arrval=move(other.arrval); + other.type=SIT_INT; return *this; } -Stackitem::operator bool(void) const{return (isstr&&strval.size())||(!isstr&&intval);} -bool Stackitem::operator==(const Stackitem &other) const{return isstr==other.isstr&&(isstr?strval==other.strval:intval==other.intval);} + +Stackitem::operator bool(void) const{ + return (type==SIT_INT&&intval)|| + (type==SIT_STR&&strval.size())|| + (type==SIT_ARR&&arrval.size()); +} + +bool Stackitem::operator==(const Stackitem &other) const{ + if(type!=other.type)return false; + if(type==SIT_INT)return intval==other.intval; + if(type==SIT_STR)return strval==other.strval; + assert(type==SIT_ARR); + auto sz=arrval.size(); + if(sz!=other.arrval.size())return false; + for(int i=0;i<sz;i++)if(arrval[i]!=other.arrval[i])return false; + return true; +} +bool Stackitem::operator!=(const Stackitem &other) const{ + return !(*this==other); +} + +string to_string(const Stackitem &si){ + if(si.type==SIT_ARR){ + stringstream ss; + ss<<'['; + const auto sz=si.arrval.size(); + for(unsigned int i=0;i<sz;i++){ + if(i!=0)ss<<','; + ss<<to_string(si.arrval[i]); + } + ss<<']'; + return ss.str(); + } else if(si.type==SIT_STR)return si.strval; + else return to_string(si.intval); +} extern const unordered_map<string,function<void(vector<Stackitem>&,unordered_map<string,Stackitem>&)>> builtins; |