summaryrefslogtreecommitdiff
path: root/evaluate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'evaluate.cpp')
-rw-r--r--evaluate.cpp61
1 files changed, 55 insertions, 6 deletions
diff --git a/evaluate.cpp b/evaluate.cpp
index 550fc49..e808b95 100644
--- a/evaluate.cpp
+++ b/evaluate.cpp
@@ -26,6 +26,21 @@ Value::Value(const string &strval)
:type(Type::string),strval(strval){}
Value::Value(ScopeVal *scopeval)
:type(Type::scope),scopeval(scopeval){}
+Value::Value(const Value &other):type(other.type),numval(other.numval),strval(other.strval){
+ if(other.scopeval){
+ scopeval=new ScopeVal(*other.scopeval);
+ }
+}
+Value::Value(Value &&other):type(other.type),numval(other.numval),
+ strval(other.strval),scopeval(other.scopeval){
+ if(other.scopeval){
+ other.type=Type::nil;
+ other.scopeval=nullptr;
+ }
+}
+Value::~Value(){
+ if(scopeval)delete scopeval;
+}
ScopeVal::ScopeVal(const ScopeDef &scopeDef)
@@ -109,6 +124,23 @@ Assembly::Instruction::Instruction(Type type,int nargs):type(type),nargs(nargs){
throw runtime_error("Instruction(type,nargs) called with invalid type "+to_string((int)type));
}
}
+Assembly::Instruction::Instruction(const Instruction &other)
+ :type(other.type),num(other.num),str(other.str),name(other.name),nargs(other.nargs){
+ if(other.scope){
+ scope=new ScopeDef(*other.scope);
+ }
+}
+Assembly::Instruction::Instruction(Instruction &&other)
+ :type(other.type),num(other.num),str(other.str),
+ scope(other.scope),name(other.name),nargs(other.nargs){
+ if(other.scope){
+ other.type=Type::pushnil;
+ other.scope=nullptr;
+ }
+}
+Assembly::Instruction::~Instruction(){
+ if(scope)delete scope;
+}
void Assembly::codegen(const StatementList &stl){
for(const Statement &stmt : stl){
@@ -169,10 +201,12 @@ void Assembly::codegen(const Expression &expr){
listing.emplace_back(Instruction::Type::call,(int)expr.args.size());
}
if(expr.type==Expression::Type::dive){
- listing.emplace_back(Instruction::Type::enter);
assert(expr.scope.type==ScopeDef::Type::direct);
+ listing.emplace_back(Instruction::Type::enter);
+ listing.emplace_back(Instruction::Type::pop);
codegen(expr.scope.body);
listing.emplace_back(Instruction::Type::leave);
+ listing.emplace_back(Instruction::Type::pushnil);
}
break;
@@ -185,7 +219,21 @@ void Assembly::codegen(const Expression &expr){
break;
case Expression::Type::scope:
- listing.emplace_back(Instruction::Type::pushscope,new ScopeDef(expr.scope));
+ // listing.emplace_back(Instruction::Type::pushscope,new ScopeDef(expr.scope));
+ switch(expr.scope.type){
+ case ScopeDef::Type::direct:
+ assert(expr.scope.args.size()==0);
+ listing.emplace_back(Instruction::Type::newscope);
+ listing.emplace_back(Instruction::Type::enter);
+ codegen(expr.scope.body);
+ listing.emplace_back(Instruction::Type::leave);
+ break;
+
+ case ScopeDef::Type::lazy:
+ case ScopeDef::Type::function:
+ listing.emplace_back(Instruction::Type::pushscope,new ScopeDef(expr.scope));
+ break;
+ }
break;
}
}
@@ -200,8 +248,9 @@ ostream& operator<<(ostream &os,const Assembly &as){
switch(ins.type){
case Assembly::Instruction::Type::pushnil: os<<"pushnil\n"; break;
case Assembly::Instruction::Type::pushnum: os<<"pushnum "<<ins.num<<"\n"; break;
- case Assembly::Instruction::Type::pushstr: os<<"pushstr "<<ins.str<<"\n"; break;
+ case Assembly::Instruction::Type::pushstr: os<<"pushstr \""<<ins.str<<"\"\n"; break;
case Assembly::Instruction::Type::pushscope: os<<"pushscope "<<*ins.scope<<"\n"; break;
+ case Assembly::Instruction::Type::newscope: os<<"newscope\n"; break;
case Assembly::Instruction::Type::pop: os<<"pop\n"; break;
case Assembly::Instruction::Type::swap: os<<"swap\n"; break;
case Assembly::Instruction::Type::add: os<<"add\n"; break;
@@ -209,9 +258,9 @@ ostream& operator<<(ostream &os,const Assembly &as){
case Assembly::Instruction::Type::mul: os<<"mul\n"; break;
case Assembly::Instruction::Type::div: os<<"div\n"; break;
case Assembly::Instruction::Type::mod: os<<"mod\n"; break;
- case Assembly::Instruction::Type::create: os<<"create "<<ins.name<<"\n"; break;
- case Assembly::Instruction::Type::store: os<<"store "<<ins.name<<"\n"; break;
- case Assembly::Instruction::Type::load: os<<"load "<<ins.name<<"\n"; break;
+ case Assembly::Instruction::Type::create: os<<"create \""<<ins.name<<"\"\n"; break;
+ case Assembly::Instruction::Type::store: os<<"store \""<<ins.name<<"\"\n"; break;
+ case Assembly::Instruction::Type::load: os<<"load \""<<ins.name<<"\"\n"; break;
case Assembly::Instruction::Type::enter: os<<"enter\n"; break;
case Assembly::Instruction::Type::leave: os<<"leave\n"; break;
case Assembly::Instruction::Type::call: os<<"call "<<ins.nargs<<"\n"; break;