From 269f28df980f34895c3c7181140963b4a86a1afc Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Thu, 9 Feb 2017 22:20:56 +0100 Subject: Split the Scope types, and generic ref/unref --- ast.cpp | 18 +++++++++--------- ast.h | 16 ++++++++-------- evaluate.cpp | 45 +++++++++++++++++++++++++++------------------ evaluate.h | 20 ++++++++++++++------ parser.cpp | 22 +++++++++++----------- 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 &args) +ScopeDef::ScopeDef():type(Type::direct){} +ScopeDef::ScopeDef(Type type,const StatementList &body,const vector &args) :type(type),body(body),args(args){} -/*Scope::Scope(Type type,const StatementList &body,const vector &nameargs) +/*ScopeDef::ScopeDef(Type type,const StatementList &body,const vector &nameargs) :type(type),body(body){ for(const Name &n : nameargs){ args.emplace_back(Expression::Type::call,n,vector()); @@ -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 &args,const Scope &scope) +Expression::Expression(Type type,const Name &name,const vector &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 &args); - // Scope(Type type,const StatementList &body,const vector &args); + ScopeDef(); + ScopeDef(Type type,const StatementList &body,const vector &args); + // ScopeDef(Type type,const StatementList &body,const vector &args); }; -ostream& operator<<(ostream &os,const Scope &scope); +ostream& operator<<(ostream &os,const ScopeDef &scope); class Expression{ public: @@ -66,17 +66,17 @@ public: vector args; double numval; string strval; - Scope scope; + ScopeDef scope; Site site; // Expression(); Expression(Type type,const Name &name,const vector &args); // binop, call Expression(Type type,const Name &name,const Expression &arg); // unop - Expression(Type type,const Name &name,const vector &args,const Scope &scope); // dive + Expression(Type type,const Name &name,const vector &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 &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 +#include #include #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 collection; - - template - Value* ref_create(Args... args){ - Value *value=new Value(args...); - return ref(value); + struct CollItem{ + int count; + void (*deleter)(void*); + }; + + template + static void generic_deleter(void *p){ + delete (T*)p; } - Value* ref(Value *value){ - auto it=collection.find(value); + unordered_map collection; + + template + 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}); } else { - it->second++; + it->second.count++; } - return value; + return p; } - void unref(Value *value){ - auto it=collection.find(value); + template + 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){ + 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 +#include #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 values; }; namespace A { - template - Value* ref_create(Args... args); + template + T* ref(T *value); - Value* ref(Value *value); - void unref(Value *value); + template + 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 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()); 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 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 "<