From 164a8d297429d58d216b9fa44e0cb42db5d23e2c Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Sat, 11 Feb 2017 22:54:35 +0100 Subject: Handle functions better in 'compilation' --- evaluate.cpp | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) (limited to 'evaluate.cpp') diff --git a/evaluate.cpp b/evaluate.cpp index e808b95..bc02a8f 100644 --- a/evaluate.cpp +++ b/evaluate.cpp @@ -26,6 +26,11 @@ Value::Value(const string &strval) :type(Type::string),strval(strval){} Value::Value(ScopeVal *scopeval) :type(Type::scope),scopeval(scopeval){} +Value::Value(Type type,Assembly *asmval):type(type),asmval(asmval){ + if(type!=Type::lazy&&type!=Type::function){ + throw runtime_error("Value(type,asmval) called with invalid type "+to_string((int)type)); + } +} Value::Value(const Value &other):type(other.type),numval(other.numval),strval(other.strval){ if(other.scopeval){ scopeval=new ScopeVal(*other.scopeval); @@ -124,11 +129,19 @@ 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(Type type,Assembly *asmval):type(type),asmval(asmval){ + if(type!=Type::pushfunc){ + throw runtime_error("Instruction(type,asmval) 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); } + if(other.asmval){ + asmval=new Assembly(*other.asmval); + } } Assembly::Instruction::Instruction(Instruction &&other) :type(other.type),num(other.num),str(other.str), @@ -137,6 +150,10 @@ Assembly::Instruction::Instruction(Instruction &&other) other.type=Type::pushnil; other.scope=nullptr; } + if(other.asmval){ + other.type=Type::pushnil; + other.asmval=nullptr; + } } Assembly::Instruction::~Instruction(){ if(scope)delete scope; @@ -203,10 +220,8 @@ void Assembly::codegen(const Expression &expr){ if(expr.type==Expression::Type::dive){ 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; @@ -219,7 +234,6 @@ void Assembly::codegen(const Expression &expr){ break; case Expression::Type::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); @@ -230,11 +244,16 @@ void Assembly::codegen(const Expression &expr){ break; case ScopeDef::Type::lazy: + throw runtime_error("Lazy scopes not implemented"); + case ScopeDef::Type::function: - listing.emplace_back(Instruction::Type::pushscope,new ScopeDef(expr.scope)); + listing.emplace_back(Instruction::Type::pushfunc,new Assembly(expr.scope)); break; } break; + + case Expression::Type::cond: + throw runtime_error("Conditions not implemented"); } } @@ -242,14 +261,25 @@ Assembly::Assembly(const StatementList &stl){ codegen(stl); } +Assembly::Assembly(const ScopeDef &scopeDef){ + for(int i=scopeDef.args.size()-1;i>=0;i--){ + listing.emplace_back(Instruction::Type::create,scopeDef.args[i]); + } + codegen(scopeDef.body); +} + ostream& operator<<(ostream &os,const Assembly &as){ + static int depth=0; + depth++; for(const Assembly::Instruction &ins : as.listing){ + os<