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 +++++++++++++++++++++++++++++++++++---- evaluate.h | 10 ++++++++++ test.squig | 17 ++++++++++++++++- 3 files changed, 61 insertions(+), 5 deletions(-) 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< this.num] pushstr, // [ -> this.str] pushscope, // [ -> this.scope] + pushfunc, // [ -> Value(function,this.asmval)] newscope, // [ -> {}] pop, // [x -> ] swap, // [x,y -> y,x] @@ -102,12 +108,14 @@ class Assembly{ ScopeDef *scope=nullptr; string name; int nargs; + Assembly *asmval=nullptr; Instruction(Type type); Instruction(Type type,double num); // pushnum Instruction(Type type,const string &str); // pushstr, create, store, load Instruction(Type type,ScopeDef *scope); // pushscope Instruction(Type type,int nargs); // call + Instruction(Type type,Assembly *asmval); // pushfunc Instruction(const Instruction &other); Instruction(Instruction &&other); ~Instruction(); @@ -122,6 +130,8 @@ class Assembly{ void codegen(const Statement &stmt); void codegen(const Expression &expr); + Assembly(const ScopeDef &scopeDef); + public: Assembly(const StatementList &stl); diff --git a/test.squig b/test.squig index 1e83fb2..c45cdb2 100644 --- a/test.squig +++ b/test.squig @@ -1 +1,16 @@ -a := 1 +v := "first v value" + +f := ??{ + puts("function") + x := v +} + +f { + puts(x) +} + +v = "second v value" + +f { + puts(x) +} -- cgit v1.2.3-54-g00ecf