From 3c86cbe72964f0e3860e12742c0800de18a173cf Mon Sep 17 00:00:00 2001 From: "Mike D. Lowis" Date: Tue, 13 Mar 2012 17:49:10 -0400 Subject: [PATCH] Updated scheme translator to keep track of variable scope using ScopeStack --- source/visitors/scheme/scheme.cpp | 89 +++++++++++++++++++++++++++++-- source/visitors/scheme/scheme.h | 7 +++ 2 files changed, 91 insertions(+), 5 deletions(-) diff --git a/source/visitors/scheme/scheme.cpp b/source/visitors/scheme/scheme.cpp index ba920f0..7232fff 100644 --- a/source/visitors/scheme/scheme.cpp +++ b/source/visitors/scheme/scheme.cpp @@ -1,5 +1,6 @@ #include #include "scheme.h" +#include "exception.h" using namespace std; @@ -98,13 +99,9 @@ void Scheme::afterVisit(AST* cur, int depth) void Scheme::beforeChildren(AST* cur, int depth) { + nodeTypeBeginAction(cur); if( cur->type() != MACRO ) { - if (cur->type() == MEMB) - { - cur->children()->back()->type(STRING); - } - if( isDatatype( cur->type() ) ) { printDatatype( cur ); @@ -118,6 +115,7 @@ void Scheme::beforeChildren(AST* cur, int depth) void Scheme::afterChildren(AST* cur, int depth) { + nodeTypeEndAction(cur); if( !isDatatype( cur->type() ) && (cur->type() != MACRO)) { stream << ")"; @@ -196,3 +194,84 @@ void Scheme::charToString(string ch) stream << "#\\" << ch; } } + +void Scheme::nodeTypeBeginAction(AST* cur) +{ + std::string text = cur->text(); + switch( cur->type() ) + { + case MEMB: + cur->children()->back()->type( STRING ); + break; + + case BLOCK: + scope_stack.startScope(); + break; + + case DEFN: + defineSymbol(cur); + break; + + case ASSIGN: + assignSymbol(cur); + break; + + //TODO: Define builtin symbols and enable adding function args to scope + //case ID: + // referenceSymbol(cur); + // break; + + default: + break; + } +} + +void Scheme::nodeTypeEndAction(AST* cur) +{ + switch( cur->type() ) + { + case BLOCK: + scope_stack.stopScope(); + break; + + default: + break; + } +} + +void Scheme::defineSymbol(AST* cur) +{ + string text = cur->children()->front()->text(); + if( scope_stack.lookup( text ) == NULL ) + { + scope_stack.define( text ); + } + else if ( scope_stack.isLocal(text) ) + { + Exception ex; + ex << "Redefining local symbol: '" << text << "'."; + throw ex; + } +} + +void Scheme::assignSymbol(AST* cur) +{ + string text = cur->children()->front()->text(); + if( scope_stack.lookup( text ) == NULL ) + { + Exception ex; + ex << "Symbol '" << text << "' has not been defined in this scope."; + throw ex; + } +} + +void Scheme::referenceSymbol(AST* cur) +{ + string text = cur->text(); + if( scope_stack.lookup( text ) == NULL ) + { + Exception ex; + ex << "Symbol '" << text << "' has not been defined in this scope."; + throw ex; + } +} diff --git a/source/visitors/scheme/scheme.h b/source/visitors/scheme/scheme.h index a688354..72e868a 100644 --- a/source/visitors/scheme/scheme.h +++ b/source/visitors/scheme/scheme.h @@ -5,10 +5,12 @@ #include #include "ivisitor.h" #include "dllexer.h" +#include "scopestack.h" class Scheme : public IVisitor { protected: std::ostream& stream; + ScopeStack scope_stack; public: Scheme(std::ostream& in); std::string typeToString(ASTNodeType type); @@ -22,6 +24,11 @@ class Scheme : public IVisitor { void afterChildren(AST* cur, int depth); void beforeChild(AST* cur, int depth); void afterChild(AST* cur, int depth); + void nodeTypeBeginAction(AST* cur); + void nodeTypeEndAction(AST* cur); + void defineSymbol(AST* cur); + void assignSymbol(AST* cur); + void referenceSymbol(AST* cur); }; #endif -- 2.52.0