summaryrefslogtreecommitdiff
path: root/runtime.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'runtime.cpp')
-rw-r--r--runtime.cpp68
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;