summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortomsmeding <tom.smeding@gmail.com>2017-02-09 22:20:56 +0100
committertomsmeding <tom.smeding@gmail.com>2017-02-09 22:20:56 +0100
commit269f28df980f34895c3c7181140963b4a86a1afc (patch)
tree883e0365462e7d33f9a772f2ebba327d2e6dd483
parent6c56e7209fc82888cb7a8c85c38ff5c3479cefbb (diff)
Split the Scope types, and generic ref/unref
-rw-r--r--ast.cpp18
-rw-r--r--ast.h16
-rw-r--r--evaluate.cpp45
-rw-r--r--evaluate.h20
-rw-r--r--parser.cpp22
5 files changed, 69 insertions, 52 deletions
diff --git a/ast.cpp b/ast.cpp
index d903ad5..b57b5ef 100644
--- a/ast.cpp
+++ b/ast.cpp
@@ -44,10 +44,10 @@ ostream& operator<<(ostream &os,Site site){
}
-Scope::Scope():type(Type::direct){}
-Scope::Scope(Type type,const StatementList &body,const vector<Expression> &args)
+ScopeDef::ScopeDef():type(Type::direct){}
+ScopeDef::ScopeDef(Type type,const StatementList &body,const vector<Expression> &args)
:type(type),body(body),args(args){}
-/*Scope::Scope(Type type,const StatementList &body,const vector<Name> &nameargs)
+/*ScopeDef::ScopeDef(Type type,const StatementList &body,const vector<Name> &nameargs)
:type(type),body(body){
for(const Name &n : nameargs){
args.emplace_back(Expression::Type::call,n,vector<Expression>());
@@ -58,11 +58,11 @@ string indent(int amount){
return string(amount,'\t');
}
-ostream& operator<<(ostream &os,const Scope &scope){
+ostream& operator<<(ostream &os,const ScopeDef &scope){
switch(scope.type){
- case Scope::Type::direct: break;
- case Scope::Type::lazy: os<<'?'; break;
- case Scope::Type::function: os<<"??"; break;
+ case ScopeDef::Type::direct: break;
+ case ScopeDef::Type::lazy: os<<'?'; break;
+ case ScopeDef::Type::function: os<<"??"; break;
}
if(scope.args.size()!=0){
os<<'(';
@@ -98,7 +98,7 @@ Expression::Expression(Type type,const Name &name,const Expression &arg)
throw runtime_error("Expression(type,name,arg) called with invalid type "+to_string(type));
}
}
-Expression::Expression(Type type,const Name &name,const vector<Expression> &args,const Scope &scope)
+Expression::Expression(Type type,const Name &name,const vector<Expression> &args,const ScopeDef &scope)
:type(type),name(name),args(args),scope(scope){
if(type!=Type::dive){
throw runtime_error("Expression(type,name,args,scope) called with invalid type "+to_string(type));
@@ -116,7 +116,7 @@ Expression::Expression(Type type,const string &strval)
throw runtime_error("Expression(type,strval) called with invalid type "+to_string(type));
}
}
-Expression::Expression(Type type,const Scope &scope)
+Expression::Expression(Type type,const ScopeDef &scope)
:type(type),scope(scope){
if(type!=Type::scope){
throw runtime_error("Expression(type,scope) called with invalid type "+to_string(type));
diff --git a/ast.h b/ast.h
index de30d5a..3eec1a3 100644
--- a/ast.h
+++ b/ast.h
@@ -26,7 +26,7 @@ public:
ostream& operator<<(ostream &os,Site site);
-class Scope{
+class ScopeDef{
public:
enum class Type{
direct,
@@ -41,12 +41,12 @@ public:
Site site;
- Scope();
- Scope(Type type,const StatementList &body,const vector<Expression> &args);
- // Scope(Type type,const StatementList &body,const vector<Name> &args);
+ ScopeDef();
+ ScopeDef(Type type,const StatementList &body,const vector<Expression> &args);
+ // ScopeDef(Type type,const StatementList &body,const vector<Name> &args);
};
-ostream& operator<<(ostream &os,const Scope &scope);
+ostream& operator<<(ostream &os,const ScopeDef &scope);
class Expression{
public:
@@ -66,17 +66,17 @@ public:
vector<Expression> args;
double numval;
string strval;
- Scope scope;
+ ScopeDef scope;
Site site;
// Expression();
Expression(Type type,const Name &name,const vector<Expression> &args); // binop, call
Expression(Type type,const Name &name,const Expression &arg); // unop
- Expression(Type type,const Name &name,const vector<Expression> &args,const Scope &scope); // dive
+ Expression(Type type,const Name &name,const vector<Expression> &args,const ScopeDef &scope); // dive
Expression(Type type,double numval); // number
Expression(Type type,const string &strval); // string
- Expression(Type type,const Scope &scope); // scope
+ Expression(Type type,const ScopeDef &scope); // scope
Expression(Type type,const vector<Expression> &args); // cond
};
diff --git a/evaluate.cpp b/evaluate.cpp
index c73d59a..ebfb773 100644
--- a/evaluate.cpp
+++ b/evaluate.cpp
@@ -1,4 +1,4 @@
-#include <map>
+#include <stdexcept>
#include <cassert>
#include "evaluate.h"
@@ -9,37 +9,46 @@ Value::Value(double numval)
:type(Type::number),numval(numval){}
Value::Value(const string &strval)
:type(Type::string),strval(strval){}
-Value::Value(const Scope &scope)
+Value::Value(ScopeVal *scope)
:type(Type::scope),scope(scope){}
namespace A {
- map<Value*,int> collection;
-
- template <typename ...Args>
- Value* ref_create(Args... args){
- Value *value=new Value(args...);
- return ref(value);
+ struct CollItem{
+ int count;
+ void (*deleter)(void*);
+ };
+
+ template <typename T>
+ static void generic_deleter(void *p){
+ delete (T*)p;
}
- Value* ref(Value *value){
- auto it=collection.find(value);
+ unordered_map<void*,CollItem> collection;
+
+ template <typename T>
+ T* ref(T *p){
+ auto it=collection.find((void*)p);
if(it==collection.end()){
- collection.emplace(value,1);
+ collection.emplace((void*)p,(CollItem){1,generic_deleter<T>});
} else {
- it->second++;
+ it->second.count++;
}
- return value;
+ return p;
}
- void unref(Value *value){
- auto it=collection.find(value);
+ template <typename T>
+ void unref(T *p){
+ auto it=collection.find(p);
assert(it!=collection.end());
- if(it->second==1){
- delete value;
+ if(it->second.count==1){
+ if(it->second.deleter!=generic_deleter<T>){
+ throw runtime_error("Unref'd pointer type not the same as the ref'd version!");
+ }
+ it->second.deleter(p);
collection.erase(it);
} else {
- it->second--;
+ it->second.count--;
}
}
}
diff --git a/evaluate.h b/evaluate.h
index 09d0c81..9c50b24 100644
--- a/evaluate.h
+++ b/evaluate.h
@@ -1,11 +1,14 @@
#pragma once
#include <string>
+#include <unordered_map>
#include "ast.h"
using namespace std;
+class ScopeVal;
+
class Value{
public:
enum class Type{
@@ -17,21 +20,26 @@ public:
Type type;
double numval;
string strval;
- Scope scope;
+ ScopeVal *scope;
Value(double numval);
Value(const string &strval);
- Value(const Scope &scope);
+ Value(ScopeVal *scope);
+};
+
+class ScopeVal{
+public:
+ unordered_map<string,Value> values;
};
namespace A {
- template <typename ...Args>
- Value* ref_create(Args... args);
+ template <typename T>
+ T* ref(T *value);
- Value* ref(Value *value);
- void unref(Value *value);
+ template <typename T>
+ void unref(T *value);
}
diff --git a/parser.cpp b/parser.cpp
index e2d157c..764776c 100644
--- a/parser.cpp
+++ b/parser.cpp
@@ -340,7 +340,7 @@ static string parseString(const string &repr,Site site){
}
static Expression parseExpression(Tokeniser &tokeniser,int minprec=-1);
-static StatementList parseScope(Tokeniser &tokeniser);
+static StatementList parseScopeDef(Tokeniser &tokeniser);
static vector<Expression> parseArgumentList(Tokeniser &tokeniser){
if(tokeniser.eof())throw ParseError(tokeniser.site(),"Expected argument list but found EOF");
@@ -413,10 +413,10 @@ static Expression parseAtom(Tokeniser &tokeniser){
return expr;
}
return Expression(Expression::Type::dive,tok.str,args,
- Scope(Scope::Type::direct,parseScope(tokeniser),{}));
+ ScopeDef(ScopeDef::Type::direct,parseScopeDef(tokeniser),{}));
} else if(tok2.type==Token::Type::symbol&&tok2.str=="{"){
return Expression(Expression::Type::dive,tok.str,{},
- Scope(Scope::Type::direct,parseScope(tokeniser),{}));
+ ScopeDef(ScopeDef::Type::direct,parseScopeDef(tokeniser),{}));
} else {
Expression expr=Expression(Expression::Type::call,tok.str,vector<Expression>());
expr.site=tok.site;
@@ -450,14 +450,14 @@ static Expression parseAtom(Tokeniser &tokeniser){
tokeniser.advance();
return expr;
}
- Scope::Type sctype;
- if(tok.str=="?")sctype=Scope::Type::lazy;
- else if(tok.str=="??")sctype=Scope::Type::function;
+ ScopeDef::Type sctype;
+ if(tok.str=="?")sctype=ScopeDef::Type::lazy;
+ else if(tok.str=="??")sctype=ScopeDef::Type::function;
else if(tok.str!="{"){
throw ParseError(tok.site,"Unexpected token '"+tok.str+"' in expression atom position");
- } else sctype=Scope::Type::direct;
+ } else sctype=ScopeDef::Type::direct;
vector<Expression> args;
- if(sctype!=Scope::Type::direct){
+ if(sctype!=ScopeDef::Type::direct){
tokeniser.advance();
if(tokeniser.eof()){
throw ParseError(tokeniser.site(),"Expected scope after '"+tok.str+"' but found EOF");
@@ -477,7 +477,7 @@ static Expression parseAtom(Tokeniser &tokeniser){
if(tok2.type!=Token::Type::symbol||tok2.str!="{"){
throw ParseError(tok2.site,"Expected '{' to begin scope");
}
- Scope sc(sctype,parseScope(tokeniser),args);
+ ScopeDef sc(sctype,parseScopeDef(tokeniser),args);
return Expression(Expression::Type::scope,sc);
}
@@ -559,7 +559,7 @@ static Statement parseStatement(Tokeniser &tokeniser){
}
}
-static StatementList parseScope(Tokeniser &tokeniser){
+static StatementList parseScopeDef(Tokeniser &tokeniser){
if(tokeniser.eof())throw ParseError(tokeniser.site(),"Expected scope");
Token tok=tokeniser.get();
if(tok.type!=Token::Type::symbol||tok.str!="{"){
@@ -578,7 +578,7 @@ static StatementList parseScope(Tokeniser &tokeniser){
stl.push_back(parseStatement(tokeniser));
}
tokeniser.advance();
- // DEBUG<<"leaving parseScope with tokeniser at "<<tokeniser.site()<<endl;
+ // DEBUG<<"leaving parseScopeDef with tokeniser at "<<tokeniser.site()<<endl;
return stl;
}