]> git.mdlowis.com Git - archive/dlang.git/commitdiff
Updated scheme translator to keep track of variable scope using ScopeStack
authorMike D. Lowis <mike@mdlowis.com>
Tue, 13 Mar 2012 21:49:10 +0000 (17:49 -0400)
committerMike D. Lowis <mike@mdlowis.com>
Tue, 13 Mar 2012 21:49:10 +0000 (17:49 -0400)
source/visitors/scheme/scheme.cpp
source/visitors/scheme/scheme.h

index ba920f0b5ad62482ae0befa219987ff0fc182723..7232fffbfd01992db26d41e2e7eace80db52a8ac 100644 (file)
@@ -1,5 +1,6 @@
 #include <fstream>
 #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;
+    }
+}
index a6883549459c8e308c6ef63b99a064eb828065c1..72e868a9d3b6931d947f9a3b274cb35316e0ed62 100644 (file)
@@ -5,10 +5,12 @@
 #include <sstream>
 #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