summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortomsmeding <tom.smeding@gmail.com>2017-02-11 21:01:18 +0100
committertomsmeding <tom.smeding@gmail.com>2017-02-11 21:01:29 +0100
commit15d1419c0d97d63a70271c451fdeef1e69ad7d96 (patch)
treefd594d41989e36f575c942e626cc929a57c9f976
parentca45da0925cabc3bbf0d22d5d23ccb9a25d8e228 (diff)
Evaluate direct scopes, and fix bugs
-rw-r--r--evaluate.cpp61
-rw-r--r--evaluate.h21
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 "<<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;
diff --git a/evaluate.h b/evaluate.h
index 50166cd..e2dc241 100644
--- a/evaluate.h
+++ b/evaluate.h
@@ -36,12 +36,18 @@ public:
Type type;
double numval;
string strval;
- ScopeVal *scopeval;
+ ScopeVal *scopeval=nullptr;
Value();
Value(double numval);
Value(const string &strval);
Value(ScopeVal *scopeval);
+ Value(const Value &other);
+ Value(Value &&other);
+ ~Value();
+
+ Value& operator=(const Value &other) = delete;
+ Value& operator=(Value &&other) = delete;
};
class ScopeVal{
@@ -69,11 +75,12 @@ namespace A {
class Assembly{
class Instruction{
public:
- enum class Type{ // Effect on the value stack is given
+ enum class Type{
pushnil, // [ -> 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<Instruction> listing;