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 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------ evaluate.h | 21 +++++++++++++++++---- 2 files changed, 72 insertions(+), 10 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 "< nil] pushnum, // [ -> this.num] pushstr, // [ -> this.str] pushscope, // [ -> this.scope] + newscope, // [ -> {}] pop, // [x -> ] swap, // [x,y -> y,x] add, // [x,y -> x+y] @@ -84,7 +91,7 @@ class Assembly{ create, // [value -> ] Creates binding this.name in the top scope store, // [value -> ] Stores in the first scope to contain a this.name binding load, // [ -> value] Retrieves from the first scope to contain a this.name binding - enter, // [scope -> ] Pushes the given scope on the scope stack + enter, // [scope -> scope] Copies the given scope to the scope stack leave, // [ -> ] Pops from the scope stack call, // [scope,arg,...,arg -> scope] Pops this.nargs arguments and replaces for names from scope.scopeDef.args }; @@ -92,7 +99,7 @@ class Assembly{ Type type; double num; string str; - ScopeDef *scope; + ScopeDef *scope=nullptr; string name; int nargs; @@ -101,6 +108,12 @@ class Assembly{ Instruction(Type type,const string &str); // pushstr, create, store, load Instruction(Type type,ScopeDef *scope); // pushscope Instruction(Type type,int nargs); // call + Instruction(const Instruction &other); + Instruction(Instruction &&other); + ~Instruction(); + + Instruction& operator=(const Instruction &other) = delete; + Instruction& operator=(Instruction &&other) = delete; }; vector listing; -- cgit v1.2.3-54-g00ecf