]> git.mdlowis.com Git - archive/dlang.git/commitdiff
Macro expansion is now fully functional!
authorMike D. Lowis <mike@mdlowis.com>
Thu, 8 Mar 2012 14:33:36 +0000 (09:33 -0500)
committerMike D. Lowis <mike@mdlowis.com>
Thu, 8 Mar 2012 14:33:36 +0000 (09:33 -0500)
example.dl
source/dlparser/dlparser.cpp
source/dlparser/macro/pattern.cpp
source/dlparser/macro/pattern.h

index 4254f91b98f21e70ac91fed54c007f0a2f6310eb..e684e126aa60d9857f289f9d22ee3bde43a5dea4 100644 (file)
@@ -3,64 +3,64 @@
 #------------------------------------------------------------------------------
 
 # VectorLiteral
-foo = []
-foo = [1]
-foo = [1,2,3]
-foo = foo[1]
-foo = [1,2,3,4,5][2]
+#foo = []
+#foo = [1]
+#foo = [1,2,3]
+#foo = foo[1]
+#foo = [1,2,3,4,5][2]
 
 # ListLiteral
-foo = ()
-foo = (1,2,3)
-foo = foo[1]
-foo = (1,2,3,4,5)[2]
+#foo = ()
+#foo = (1,2,3)
+#foo = foo[1]
+#foo = (1,2,3,4,5)[2]
 
 # FuncLiteral
 foo = { 1 + 1 }
-foo = {|a| a + 1}
-foo = {|a,b| a + b }
-foo = foo(1,2)
-foo = ({|a,b| a + b })(1,2)
+#foo = {|a| a + 1}
+#foo = {|a,b| a + b }
+#foo = foo(1,2)
+#foo = ({|a,b| a + b })(1,2)
 
 # ID
-foo = bar
-foo.bar = bar
+#foo = bar
+#foo.bar = bar
 
 # NUM
-foo = 1
-foo = 1.0
+#foo = 1
+#foo = 1.0
 
 # CHAR
-foo = 'a'
+#foo = 'a'
 
 # STRING
-foo = "some string"
-foo = "12345"[2]
+#foo = "some string"
+#foo = "12345"[2]
 
 # SYMBOL
-foo = $some_symbol
+#foo = $some_symbol
 
 # MAP
-foo = {
-    $foo : 1 + 1,
-    $bar : 2 + 2,
-    $stuff : 3 + 3
-}
+#foo = {
+#    $foo : 1 + 1,
+#    $bar : 2 + 2,
+#    $stuff : 3 + 3
+#}
 
 # Macro
-% if [
-    (Expression Block Block) : exec_if($1, $2, $3),
-    (Expression Block) : exec_if($1, $2)
-]
+#% if [
+#    (Expression Block Block) : exec_if($1, $2, $3),
+#    (Expression Block) : exec_if($1, $2)
+#]
 
-if (1==1)
-{
-    1 + 1
-}{
-
-}
-
-if (1 == 1)
-{
-
-}
+#if (1==1)
+#{
+#    1 + 1
+#}{
+#
+#}
+#
+#if (1 == 1)
+#{
+#
+#}
index 247002eb7a25747fe552b2df5d174eca2a376de7..de4f91280a29232b311d8a3a11eb117223930b77 100644 (file)
@@ -80,8 +80,10 @@ bool DLParser::speculate_MacroPatternMatch(Pattern patt)
 
 AST* DLParser::MacroPatternMatch(Pattern patt)
 {
+    AST* ret = NULL;
     std::vector<AST*> params;
     std::list<PatternType_T>::iterator patt_it;
+
     for(patt_it = patt.begin(); patt_it != patt.end(); patt_it++)
     {
         AST* param = NULL;
@@ -137,10 +139,20 @@ AST* DLParser::MacroPatternMatch(Pattern patt)
                 throw Exception(lookaheadToken(1).line(), lookaheadToken(1).column());
                 break;
         }
-        params.push_back(param);
+
+        if( !isSpeculating() )
+        {
+            params.push_back(param);
+        }
+        else
+        {
+            delete param;
+        }
     }
 
-    return patt.accept( params );
+    ret = (isSpeculating()) ? _new AST(MACRO) : patt.accept( params );
+
+    return ret;
 }
 
 bool DLParser::speculate_GroupExpr(void)
@@ -511,7 +523,6 @@ Pattern DLParser::MacroPattern(void)
     {
         std::string text = lookaheadToken(1).text();
         match(ID);
-        //pattern.push_back( str_to_patt_type(text) );
         if( pattern_types.find(text) != pattern_types.end() )
         {
             pattern.push_back( pattern_types[ text ] );
index fbf53872f61055d306e683badf368265fba9bf6e..0fcfb5b8566ee731ed88384a296435b714c71893 100644 (file)
@@ -1,4 +1,5 @@
 #include "pattern.h"
+#include "dllexer.h"
 
 Pattern::Pattern(const std::list<PatternType_T>& patt, const AST* ast) : pattern(patt), expr_ast(ast)
 {
@@ -18,16 +19,44 @@ std::list<PatternType_T>::iterator Pattern::end()
     return pattern.end();
 }
 
+void Pattern::apply(AST* cur,std::vector<AST*>& params)
+{
+    if  (cur != NULL)
+    {
+        list<AST*>* children = cur->children();
+        list<AST*>::iterator it = children->begin();
+
+        // Visit the tree
+        for(; it != children->end(); it++)
+        {
+            if ((*it)->type() == SYMBOL)
+            {
+                unsigned int arg;
+                istringstream((*it)->text()) >> arg;
+
+                if (arg <= params.size())
+                {
+                    AST* temp = *it;
+                    *it = params[ arg - 1 ];
+                    delete temp;
+                }
+                else
+                {
+                    throw "Invalid parameter number";
+                }
+            }
+            else
+            {
+                apply( *it, params );
+            }
+        }
+    }
+}
+
 AST* Pattern::accept(std::vector<AST*>& params)
 {
     AST* ret = expr_ast->clone();
-    // TODO: Perform AST substitution
-    // if size == to expected
-    //      clone exp tree
-    //      replace symbols with params
-    // else
-    //      Throw exception
-    // endif
+    apply( ret, params );
     return ret;
 }
 
index b8591baf4c2a97e1f1f0d134ac6c0afa75e3884c..225ec024a0e31c4a19a18bb1f1846e22def059d5 100644 (file)
@@ -19,9 +19,11 @@ typedef enum {
 } PatternType_T;
 
 class Pattern {
-    private:
+    protected:
         std::list<PatternType_T> pattern;
         const AST* expr_ast;
+    private:
+        void apply(AST* cur,std::vector<AST*>& params);
     public:
         Pattern(const std::list<PatternType_T>& patt, const AST* ast);
         ~Pattern();