From 15d1419c0d97d63a70271c451fdeef1e69ad7d96 Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Sat, 11 Feb 2017 21:01:18 +0100 Subject: Evaluate direct scopes, and fix bugs --- evaluate.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 6 deletions(-) (limited to 'evaluate.cpp') 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 "<