]> git.mdlowis.com Git - archive/dlang.git/commitdiff
Overhauled parser and lexer for symbolic based syntax
authorMike D. Lowis <mike@mdlowis.com>
Thu, 3 May 2012 19:13:43 +0000 (15:13 -0400)
committerMike D. Lowis <mike@mdlowis.com>
Thu, 3 May 2012 19:13:43 +0000 (15:13 -0400)
example.dl
source/dllexer/dllexer.cpp
source/dllexer/dllexer.h
source/dlparser/dlparser.cpp
source/dlparser/dlparser.h
source/main.cpp
source/visitors/scheme/scheme.cpp
tests/test_dllexer.cpp
tests/test_dlparser.cpp

index fcacd8aafa0643f629253d3485dbcf62089eaec8..6890240d22ca34cd489ec98195ce17891199241c 100644 (file)
-#------------------------------------------------------------------------------
-# Literal Definition and Usage
-#------------------------------------------------------------------------------
-
-# Nums
-foo := 1
-foo = -1
-foo = 1.0
-foo = -1.0
-foo = 10.0e1
-foo = 10.0e-1
-foo = -10.0e1
-foo = -10.0e-1
-
-# Char
-foo = 'a'
-foo = '\a'
-foo = '\b'
-foo = '\n'
-foo = '\r'
-foo = '\t'
-foo = '\v'
-
-# String
-foo = "some string"
-foo = "foo \a \b \f \n \r \t \v \' \" \\ \xFF bar"
-foo = "12345"[2]
-
-# Symbol
-foo = $some_symbol
-
-# Map
-foo = @{}
-foo.stuff = "bar"
-foo = @{
-    $foo : 1 + 1,
-    "stuff" : 2 + 2,
-    $stuff : 2 + 2,
-    $bar : 3 + 3,
-}
-
-# Setting map elements
-foo["stuff"] = 3
-foo.stuff = 5
-
-# Vector
-foo = []
-foo = [1]
-foo = [1,2,3]
-foo = foo[1]
-foo = [1,2,3,4,5][2]
-
-# Setting Vector Elements
-foo[2] = 6
-
-# List
-foo = ()
-foo = (1,)
-foo = (1,2,3)
-foo = foo[1]
-foo = (1,2,3,4,5)[2]
-
-# Setting List Elements
-foo[2] = 6
-
-# Block
-foo = { 1 + 1 }
-foo = {|a| a + 1}
-foo = {|a,b| a + b }
-foo = foo(1,2)
-foo = ({|a,b| a + b })(1,2)
-
-#------------------------------------------------------------------------------
-# Operators and Precedence Tests
-#------------------------------------------------------------------------------
-
-
-#------------------------------------------------------------------------------
-# Macro Definition and Usage
-#------------------------------------------------------------------------------
-assert := {|cond,msg|
-    exec_if(cond,{},{ print(msg) })
-}
-
-# Define a macro that represents a traditional if statement
-% if [
-    (E B B) : exec_if($1, $2, $3),
-    (E B)   : exec_if($1, $2),
-]
-
-test_result = false
-if (1 < 2)
-{
-    test_result = true
-}{
-    test_result = false
-}
-assert( test_result, "First branch should be taken when test condition is true" )
-
-test_result = false
-if (1 > 2)
-{
-    test_result = false
-}{
-    test_result = true
-}
-assert( test_result, "Second branch should be taken when test condition is false" )
-
-test_result = false
-if (1 < 2)
-{
-    test_result = true
-}
-assert( test_result, "Branch should be taken when test condition is true" )
-
-test_result = true
-if (1 > 2)
-{
-    test_result = false
-}
-assert( test_result, "Branch should not be taken when test condition is false" )
-
-#------------------------------------------------------------------------------
-# Delayed Evaluation
-#------------------------------------------------------------------------------
-
-###############################################################################
-# WARNING: This Section is a work in progress. Please ignore it for now.      #
-###############################################################################
-
-# Define a function that makes a promise
-#make_promise := {|expr|
-#    result := expr
-#    {
-#        print( "expr: ", expr )
-#        print( "result: ", result )
-#        result
-#        #if result_ready == true {
-#        #    print("Returning cached results")
-#        #    result
-#        #}{
-#        #    print("Caching results")
-#        #    result
-#        #}
-#    }
-#}
-
-# Define a macro that will delay the evaluation of the following expression
-#% delay [
-#    (E) : make_promise({ $1 })
-#]
-
-# Define a macro that will force the evaluation of the following delayed statement
-#% force [
-#    (E) : $1()
-#]
+# Literals
+"foo"
+'a'
+1.0
+$foo
+
+# Function Application
+foo()
+foo(1)
+foo(1 2)
+foo(1 2 3)
+
+# Definition and assignment
+define(foo 5)
+set(foo 6)
+
+# Lambda expressions
+lambda(())
+lambda((a))
+lambda((a b))
+lambda((a b c))
+
+lambda(()
+    foo())
+lambda((a)
+    foo(a))
+lambda((a b)
+    foo(a b))
+lambda((a b c)
+    foo(a b c))
+
+# Begin block
+begin()
+begin( foo() )
+begin(
+    foo()
+    bar())
+
+# If statement
+if( conditional
+    if_branch
+    else_branch )
+
+if( conditional
+    if_branch )
+
+# Infix operator expression
+(1 add 1)
+((1 add 1) add 1)
+(1 add (1 add 1))
+
+# Macros
+#macro(
+#    [(_ a ':=' b)
+#        define(a b)]
+#    [(_ a '=' b)
+#        set(a b)])
 #
-#foo = delay 1 + 1
-#print("foo: ", foo)
-#foo = force foo
-#print("foo: ", foo)
-#print( force foo )
-#print( force foo )
-#print( force foo )
-
-#------------------------------------------------------------------------------
-# Classes
-#------------------------------------------------------------------------------
-
-# Define a macro for creating new classes
-% class [
-    (B)   : {
-        this := @{}
-        $1()
-        this
-    },
-]
-
-# Simple class definition (No inheritance supported)
-Animal := class {
-    # The sound of the mating call is kept private
-    priv_call := "Moo!"
-
-    # Define a method to print the mating call sound
-    this.mating_call = {
-        print( priv_call )
-    }
-}
-
-# Animal is a constructor so call it to create a new cow
-Cow := Animal()
-
-# And call the method to print the sound (This syntax needs to be cleaned up a bit)
-(Cow.mating_call)()
-
index ebf4896196805e4868a637ef1423f1d43b801bc4..a3fd9e73052093ca21ce18ef8cc5c85e655bb51c 100644 (file)
@@ -4,22 +4,6 @@
 
 using namespace std;
 
-#define NUM_SINGLE_CHAR_MATCHES 12
-SingleCharMatch_T Single_Character_Matches[ NUM_SINGLE_CHAR_MATCHES ] = {
-    { '[', LBRACK },
-    { ']', RBRACK },
-    { '(', LPAR },
-    { ')', RPAR },
-    { '{', LBRACE },
-    { '}', RBRACE },
-    { ',', COMMA },
-    { '+', ADD },
-    { '*', MUL },
-    { '/', DIV },
-    { '.', MEMB },
-    { '%', MACRO },
-};
-
 DLLexer::DLLexer(std::istream& in) : LLNLexer(in)
 {
 }
@@ -43,18 +27,6 @@ bool DLLexer::isDigit(void)
     return ((lookahead(1) >= '0') && (lookahead(1) <= '9'));
 }
 
-bool DLLexer::isOperator(void)
-{
-    return (   (lookahead(1) == '=')
-            || (lookahead(1) == '!')
-            || (lookahead(1) == '<')
-            || (lookahead(1) == '>')
-            || (lookahead(1) == '|')
-            || (lookahead(1) == '&')
-            || (lookahead(1) == ':')
-            || (lookahead(1) == '@'));
-}
-
 bool DLLexer::isStringChar(void)
 {
     return (    (lookahead(1) != '"')
@@ -70,7 +42,7 @@ Token DLLexer::next(void)
     // the EOF and skipping the loop
     (void)lookahead(1);
 
-    // If we have non-EOF chars tehn process them
+    // If we have non-EOF chars then process them
     while ( !eof() && (ret.type() == EOF) )
     {
         if (isWhiteSpace())
@@ -81,18 +53,22 @@ Token DLLexer::next(void)
         {
             COMMENT();
         }
-        else if (isLetter())
-        {
-            Id(ret);
-        }
-        else if( isOperator() )
-        {
-            MultiCharOp(ret);
-        }
         else if (isDigit())
         {
             Number(ret,false);
         }
+        else if(lookahead(1) == '-')
+        {
+            consume();
+            if(isDigit())
+            {
+                Number(ret,true);
+            }
+            else
+            {
+                throw Exception(line,column);
+            }
+        }
         else if(lookahead(1) == '\'')
         {
             Char(ret);
@@ -105,21 +81,21 @@ Token DLLexer::next(void)
         {
             Symbol(ret);
         }
-        else if(lookahead(1) == '-')
+        //*
+        else if (lookahead(1) == '(')
         {
             consume();
-            if(isDigit())
-            {
-                Number(ret,true);
-            }
-            else
-            {
-                ret = Token(SUB, line, column - 1);
-            }
+            ret = Token( LPAR, "(", line, column );
         }
+        else if (lookahead(1) == ')')
+        {
+            consume();
+            ret = Token( RPAR, ")", line, column );
+        }
+        // */
         else
         {
-            SingleCharOp(ret);
+            Id(ret);
         }
     }
 
@@ -295,131 +271,6 @@ void DLLexer::Symbol(Token& tok)
     tok = Token( SYMBOL, oss.str(), line, column );
 }
 
-void DLLexer::SingleCharOp(Token& tok)
-{
-    for(int i = 0; i < NUM_SINGLE_CHAR_MATCHES; i++)
-    {
-        if(lookahead(1) == Single_Character_Matches[i].match)
-        {
-            consume();
-            tok = Token( Single_Character_Matches[i].type, line, column );
-            break;
-        }
-    }
-
-    if( tok.type() == EOF)
-    {
-        Exception ex(line,column);
-        ex << "Unrecognized token";
-        throw ex;
-    }
-}
-
-void DLLexer::MultiCharOp(Token& tok)
-{
-    // save the current token so we can refer back to it
-    char last = lookahead(1);
-    // remove the current token from the buffer so we cna see the next
-    consume();
-
-    if(last == '=')
-    {
-        if(lookahead(1) == '=')
-        {
-            consume();
-            tok = Token(EQ, line, column);
-        }
-        else
-        {
-            tok = Token(ASSIGN, line, column);
-        }
-    }
-    else if(last == '!')
-    {
-        if(lookahead(1) == '=')
-        {
-            consume();
-            tok = Token(NE, line, column);
-        }
-        else
-        {
-            tok = Token(NOT, line, column);
-        }
-    }
-    else if(last == '<')
-    {
-        if(lookahead(1) == '=')
-        {
-            consume();
-            tok = Token(LTE, line, column);
-        }
-        else
-        {
-            tok = Token(LT, line, column);
-        }
-    }
-    else if(last == '>')
-    {
-        if(lookahead(1) == '=')
-        {
-            consume();
-            tok = Token(GTE, line, column);
-        }
-        else
-        {
-            tok = Token(GT, line, column);
-        }
-    }
-    else if(last == '|')
-    {
-        if(lookahead(1) == '|')
-        {
-            consume();
-            tok = Token(OR, line, column);
-        }
-        else
-        {
-            tok = Token(PIPE, line, column);
-        }
-    }
-    else if((last == '&') && (lookahead(1) == '&'))
-    {
-        consume();
-        tok = Token(AND, line, column);
-    }
-    else if(last == ':')
-    {
-        if(lookahead(1) == '=')
-        {
-            consume();
-            tok = Token(DEFN, line, column);
-        }
-        else
-        {
-            tok = Token(SEP, line, column);
-        }
-    }
-    else if(last == '@')
-    {
-        if(lookahead(1) == '=')
-        {
-            consume();
-            tok = Token(IMPORT, line, column);
-        }
-        else
-        {
-            tok = Token(MAP, line, column);
-        }
-    }
-
-    if (tok.type() == EOF)
-    {
-        Exception ex(line,column);
-        ex << "Unexpected token";
-        throw ex;
-    }
-}
-
 std::string DLLexer::EscapeSequence()
 {
     ostringstream oss;
index 636f36cde1126002f6d01e702b28d255d01061ef..dfd3701f7e3754b9baf1c09a6d0d7144a33765b3 100644 (file)
@@ -6,56 +6,25 @@
 
 typedef enum TokenTypes
 {
-    // Datatypes
-    ID       = 0,
-    NUM      = 1,
-    CHAR     = 2,
-    STRING   = 3,
-    SYMBOL   = 4,
-    LIST     = 5,
-    VECTOR   = 6,
-    FUNC     = 7,
-    MAP      = 8,
-
     // Symbols
-    LBRACK   = 10,
-    RBRACK   = 11,
-    LPAR     = 12,
-    RPAR     = 13,
-    LBRACE   = 14,
-    RBRACE   = 15,
-    COMMA    = 16,
-    PIPE     = 17,
+    PROGRAM  = 0,
+    DEFINE   = 1,
+    ASSIGN   = 2,
+    LAMBDA   = 3,
+    BEGIN    = 4,
+    IF       = 5,
+    APPLY    = 6,
+    ID_LIST  = 7,
+    EXP_LIST = 8,
+    LPAR     = 9,
+    RPAR     = 10,
 
-    // Operators
-    AND      = 20,
-    OR       = 21,
-    NOT      = 22,
-    EQ       = 23,
-    NE       = 24,
-    LT       = 25,
-    GT       = 26,
-    LTE      = 27,
-    GTE      = 28,
-    ADD      = 29,
-    SUB      = 30,
-    MUL      = 31,
-    DIV      = 32,
-    DEFN     = 33,
-    ASSIGN   = 34,
-    MEMB     = 35,
-    SEP      = 36,
-    ARRY_IDX = 37,
-    MACRO    = 38,
-    IMPORT   = 39,
-    MUTATE   = 40,
-
-    // AST "Virtual" Node Types
-    PROGRAM  = 50,
-    BLOCK    = 51,
-    FN_CALL  = 52,
-    PARAMS   = 53,
-    PATT     = 54,
+    // Datatypes
+    ID       = 11,
+    NUM      = 12,
+    CHAR     = 13,
+    STRING   = 14,
+    SYMBOL   = 15,
 } eTokenTypes;
 
 typedef struct {
@@ -69,7 +38,6 @@ class DLLexer : public LLNLexer {
         bool isWhiteSpace(void);
         bool isLetter(void);
         bool isDigit(void);
-        bool isOperator(void);
         bool isStringChar(void);
         void WS(void);
         void COMMENT(void);
@@ -82,8 +50,6 @@ class DLLexer : public LLNLexer {
         void Char(Token& tok);
         void String(Token& tok);
         void Symbol(Token& tok);
-        void SingleCharOp(Token& tok);
-        void MultiCharOp(Token& tok);
         std::string EscapeSequence();
 };
 
index ecd93d5f1aa652e8cbf2dd83727e392507389227..2c1eb78e4789050bed61404a6cafed93114ef68c 100644 (file)
@@ -27,156 +27,6 @@ void DLParser::parse(void)
     result = Program();
 }
 
-bool DLParser::isMacro( Token& token )
-{
-    bool ret = false;
-    if( (token.type() == ID)
-        && (macros.find(token.text()) != macros.end()) )
-    {
-        ret = true;
-    }
-    return ret;
-}
-
-AST* DLParser::MacroExpansion()
-{
-    AST* ret = NULL;
-    string macro_name = lookaheadToken(1).text();
-    Macro macro = macros[ macro_name ];
-    std::list<Pattern>::iterator patt_it;
-
-    match(ID);
-    for(patt_it = macro.begin(); patt_it != macro.end(); patt_it++)
-    {
-        if( speculate_MacroPatternMatch(*patt_it) )
-        {
-            ret = MacroPatternMatch(*patt_it);
-            break;
-        }
-    }
-
-    if (ret == NULL)
-    {
-        Exception ex;
-        ex << "Did not find a matching pattern for keyword " << macro_name << ".";
-        throw ex;
-    }
-
-    return ret;
-}
-
-bool DLParser::speculate_MacroPatternMatch(Pattern patt)
-{
-    bool success = true;
-
-    mark();
-    try
-    {
-        delete MacroPatternMatch(patt);
-    }
-    catch (Exception e)
-    {
-        success = false;
-    }
-    release();
-
-    return success;
-
-}
-
-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;
-        string text = lookaheadToken(1).text();
-        switch( *patt_it )
-        {
-            case MAP_TYP:
-                param = MapLiteral();
-                break;
-
-            case VECT_TYP:
-                param = VectorLiteral();
-                break;
-
-            case LIST_TYP:
-                param = ListLiteral();
-                break;
-
-            case BLK_TYP:
-                param = FuncLiteral();
-                break;
-
-            case ID_TYP:
-                match(ID);
-                param = _new AST(ID,text);
-                break;
-
-            case NUM_TYP:
-                match(NUM);
-                param = _new AST(NUM,text);
-                break;
-
-            case CHAR_TYP:
-                match(CHAR);
-                param = _new AST(CHAR,text);
-                break;
-
-            case STR_TYP:
-                match(STRING);
-                param = _new AST(STRING,text);
-                break;
-
-            case SYM_TYP:
-                match(SYMBOL);
-                param = _new AST(SYMBOL,text);
-                break;
-
-            case EXPR_TYP:
-                param = LogicalExpr();
-                break;
-        }
-
-        if( !isSpeculating() )
-        {
-            params.push_back(param);
-        }
-        else
-        {
-            delete param;
-        }
-    }
-
-    ret = (isSpeculating()) ? _new AST(MACRO) : patt.accept( params );
-
-    return ret;
-}
-
-bool DLParser::speculate_GroupExpr(void)
-{
-    bool success = true;
-
-    mark();
-    try
-    {
-        match(LPAR);
-        delete LogicalExpr();
-        match(RPAR);
-    }
-    catch (Exception e)
-    {
-        success = false;
-    }
-    release();
-
-    return success;
-}
-
 AST* DLParser::Program(void)
 {
     AST* node = _new AST( PROGRAM );
@@ -191,396 +41,123 @@ AST* DLParser::Expression(void)
 {
     AST* ret = NULL;
 
-    if( (lookaheadType(1) == MACRO) && (lookaheadType(2) == ID))
-    {
-        ret = MacroDefinition();
-    }
-    else
-    {
-        ret = AssignExpr();
-    }
-
-    return ret;
-}
+    // Expression := Application
+    //             | Literal
+    //
+    // Application := define '(' ID Expression ')'
+    //              | set '(' ID Expression ')'
+    //              | lambda '(' IdList ExpList? ')'
+    //              | begin '(' ExpList* ')'
+    //              | if '(' Expression Expression Expression? ')'
+    //              | ID '(' ExpList ')'
+    //
+    // ExpList := Expression+
+    //
+    // IdList := '(' ID* ')'
+    //
+    // Literal := ID
+    //          | CHAR
+    //          | SYMBOL
+    //          | STRING
+    //          | NUMBER
+
+    if ((ID == lookaheadType(1)) && (LPAR == lookaheadType(2)))
+    {
+        // Get the ID text
+        Token id = lookaheadToken(1);
+        std::string id_text = id.text();
+        consume();
 
-AST* DLParser::AssignExpr(void)
-{
-    AST* ret = LogicalExpr();
-    AST* child = NULL;
-    if(lookaheadType(1) == DEFN)
-    {
-        match(DEFN);
-        ret = new AST(DEFN, 2, ret, LogicalExpr());
-    }
-    else if(lookaheadType(1) == ASSIGN)
-    {
-        match(ASSIGN);
-        child = LogicalExpr();
-        if( (ret->type() != ID) && (ret->type() != ARRY_IDX) && (ret->type() != MEMB))
+        match(LPAR);
+        if (0 == id_text.compare("define"))
         {
-            Exception ex;
-            ex << "Expected ID or object reference on left hand side of assignment.";
-            throw ex;
+            ret = new AST( lookaheadToken(1) );
+            match(ID);
+            ret = new AST(DEFINE, 2, ret, Expression());
         }
-        else if( (ret->type() == ARRY_IDX) || (ret->type() == MEMB) )
+        else if (0 == id_text.compare("set"))
         {
-            AST* obj = NULL;
-            AST* idx = NULL;
-            list<AST*>::iterator it = ret->children()->begin();
-            obj = *it;
-            it++;
-            idx = *it;
-            idx->type( (ret->type() == MEMB) ? SYMBOL : idx->type() );
-            ret = new AST(MUTATE, 3, obj, idx, child );
+            ret = new AST( lookaheadToken(1) );
+            match(ID);
+            ret = new AST(ASSIGN, 2, ret, Expression());
         }
-        else
+        else if (0 == id_text.compare("lambda"))
         {
-            ret = new AST(ASSIGN, 2, ret, child);
+            ret = new AST(LAMBDA, 2, IdList(), ExpList());
         }
-    }
-    return ret;
-}
-
-AST* DLParser::LogicalExpr(void)
-{
-    AST* ret = NULL;
-    if( isMacro( lookaheadToken(1) ) )
-    {
-        ret = MacroExpansion();
-    }
-    else
-    {
-        ret = CompExpr();
-        while((lookaheadType(1) == AND) || (lookaheadType(1) == OR))
+        else if (0 == id_text.compare("begin"))
         {
-            ret = _new AST( lookaheadType(1), 1, ret);
-            consume();
-            ret->addChild( CompExpr() );
+            ret = new AST(BEGIN, 1, ExpList());
+        }
+        else if (0 == id_text.compare("if"))
+        {
+            ret = new AST(IF, 2, Expression(), Expression());
+            if(lookaheadType(1) != RPAR)
+            {
+                ret->addChild( Expression() );
+            }
+        }
+        //else if (0 == id_text.compare("macro"))
+        //{
+        //}
+        else
+        {
+            ret = new AST( id );
+            ret = new AST(APPLY, 2, ret, ExpList());
         }
-    }
-    return ret;
-}
-
-AST* DLParser::CompExpr(void)
-{
-    AST* ret = AddSubExpr();
-    while(   (lookaheadType(1) == EQ)  || (lookaheadType(1) == NE)
-       || (lookaheadType(1) == LT)  || (lookaheadType(1) == GT)
-       || (lookaheadType(1) == LTE) || (lookaheadType(1) == GTE))
-    {
-        ret = _new AST( lookaheadType(1), 1, ret);
-        consume();
-        ret->addChild( AddSubExpr() );
-    }
-    return ret;
-}
-
-AST* DLParser::AddSubExpr(void)
-{
-    AST* ret = MulDivExpr();
-    while((lookaheadType(1) == ADD) || (lookaheadType(1) == SUB))
-    {
-        ret = _new AST( lookaheadType(1), 1, ret);
-        consume();
-        ret->addChild( MulDivExpr() );
-    }
-    return ret;
-}
-
-AST* DLParser::MulDivExpr(void)
-{
-    AST* ret = UnaryExpr();
-    while((lookaheadType(1) == MUL) || (lookaheadType(1) == DIV))
-    {
-        ret = _new AST( lookaheadType(1), 1, ret);
-        consume();
-        ret->addChild( UnaryExpr() );
-    }
-    return ret;
-}
-
-AST* DLParser::UnaryExpr(void)
-{
-    AST* ret = NULL;
-    if(lookaheadType(1) == NOT)
-    {
-        consume();
-        ret = _new AST(NOT, 1, GroupExpr() );
-    }
-    else
-    {
-        ret = GroupExpr();
-    }
-    return ret;
-}
-
-AST* DLParser::GroupExpr(void)
-{
-    AST* ret = NULL;
-
-    if(speculate_GroupExpr())
-    {
-        match(LPAR);
-        ret = LogicalExpr();
         match(RPAR);
     }
-    else
+    else if( LPAR == lookaheadType(1) )
     {
-        ret = MemberExpr();
-    }
+        AST* op       = NULL;
+        AST* operand1 = NULL;
+        AST* operand2 = NULL;
+        Token op_tok;
 
-    if( lookaheadType(1) == LPAR )
-    {
+        // Left Operand
         match(LPAR);
-        ret = _new AST( FN_CALL, 2, ret, ExpList( LIST, RPAR ) );
-        match(RPAR);
-    }
-    else if( lookaheadType(1) == LBRACK )
-    {
-        match(LBRACK);
-        ret = _new AST( ARRY_IDX, 2, ret, LogicalExpr() );
-        match(RBRACK);
-    }
-
-    return ret;
-}
-
-AST* DLParser::MemberExpr(void)
-{
-    AST* ret = NULL;
-    ret = Literal();
-    if ( lookaheadType(1) == MEMB )
-    {
-        match(MEMB);
-        ret = new AST(MEMB, 2, ret, LogicalExpr());
-    }
-    return ret;
-}
-
-AST* DLParser::Literal(void)
-{
-    AST* node = NULL;
-    switch(lookaheadType(1))
-    {
-        // Literal = VectorLiteral
-        case LBRACK:
-            node = VectorLiteral();
-            break;
-
-        // Literal = ListLiteral
-        case LPAR:
-            node = ListLiteral();
-            break;
-
-        // Literal = FuncLiteral
-        case LBRACE:
-            node = FuncLiteral();
-            break;
-
-        case MAP:
-            node = MapLiteral();
-            break;
-
-        // Literal = ID
-        case ID:
-            node = _new AST( ID, lookaheadToken(1).text() );
-            consume();
-            break;
+        operand1 = Expression();
 
-        // Literal = NUM
-        case NUM:
-            node = _new AST( NUM, lookaheadToken(1).text() );
-            consume();
-            break;
-
-        // Literal = CHAR
-        case CHAR:
-            node = _new AST( CHAR, lookaheadToken(1).text() );
-            consume();
-            break;
-
-        // Literal = STRING
-        case STRING:
-            node = _new AST( STRING, lookaheadToken(1).text() );
-            consume();
-            break;
+        // Operator
+        op_tok = lookaheadToken(1);
+        match(ID);
+        op = new AST(op_tok);
 
-        // Literal = SYMBOL
-        case SYMBOL:
-            node = _new AST( SYMBOL, lookaheadToken(1).text() );
-            consume();
-            break;
+        // Right Operand
+        operand2 = Expression();
+        match(RPAR);
 
-        default:
-            Exception ex( lookaheadToken(1) );
-            ex << "Expected literal type, recieved type " << lookaheadToken(1).type() << ".";
-            throw ex;
+        ret = new AST(APPLY, 3, op, operand1, operand2);
     }
-    return node;
-}
-
-// MapLiteral = '{' (Literal ':' LogicalExpr)* '}'
-AST* DLParser::MapLiteral(void)
-{
-    AST* ret = _new AST(MAP);
-    AST* child = NULL;
-    match(MAP);
-    match(LBRACE);
-    while( lookaheadType(1) != RBRACE )
+    else
     {
-        child = Literal();
-        match(SEP);
-        child = _new AST(SEP, 2, child, LogicalExpr());
-        ret->addChild(child);
-
-        if( lookaheadType(1) == COMMA ) consume();
+        ret = new AST( lookaheadToken(1) );
+        consume();
     }
-    match(RBRACE);
-    return ret;
-}
 
-AST* DLParser::VectorLiteral(void)
-{
-    AST* ret = NULL;
-    match(LBRACK);
-    ret = ExpList(VECTOR, RBRACK);
-    match(RBRACK);
     return ret;
 }
 
-AST* DLParser::ListLiteral(void)
+AST* DLParser::ExpList(void)
 {
-    AST* ret = NULL;
-    match(LPAR);
-    ret = ExpList(LIST, RPAR);
-    match(RPAR);
-    return ret;
-}
-
-AST* DLParser::FuncLiteral(void)
-{
-    AST* ret = NULL;
-
-    match(LBRACE);
-    if(lookaheadType(1) == PIPE)
-    {
-        match(PIPE);
-        ret = ExpList(PARAMS, PIPE);
-        match(PIPE);
-        ret = _new AST(FUNC, 2, ret, ExpBlock(BLOCK,RBRACE));
-    }
-    else
+    AST* ret = new AST(EXP_LIST);
+    while(RPAR != lookaheadType(1))
     {
-        ret = _new AST(FUNC, 2, _new AST(PARAMS), ExpBlock(BLOCK,RBRACE));
+        ret->addChild( Expression() );
     }
-    match(RBRACE);
     return ret;
 }
 
-// MacroDefinition = '%' ID '[' MacroPatternList ']'
-AST* DLParser::MacroDefinition(void)
-{
-    std::list<Pattern> patterns;
-    std::string name;
-
-    match(MACRO);
-
-    // Get the macro's name
-    name = lookaheadToken(1).text();
-    match(ID);
-
-    // Parse the macro param list
-    match(LBRACK);
-    patterns = MacroPatternList();
-    match(RBRACK);
-
-    // Build and register the macro
-    macros.insert( std::pair<std::string,Macro>(name, Macro(patterns)) );
-
-    return _new AST(MACRO);
-}
-
-// MacroPatternList = MacroPattern (',' MacroPattern)*
-std::list<Pattern> DLParser::MacroPatternList(void)
+AST* DLParser::IdList(void)
 {
-    std::list<Pattern> patterns;
-
-    patterns.push_back( MacroPattern() );
-    while (lookaheadType(1) != RBRACK)
-    {
-        if ( lookaheadType(1) == COMMA )
-        {
-            consume();
-            if (lookaheadType(1) != RBRACK)
-            {
-                patterns.push_back( MacroPattern() );
-            }
-        }
-    }
-
-    return patterns;
-}
-
-// MacroPattern = '(' ID+ ')' ':' LogicalExpr
-Pattern DLParser::MacroPattern(void)
-{
-    AST* expr = NULL;
-    std::list<PatternType_T> pattern;
-
+    AST* ret = new AST(ID_LIST);
     match(LPAR);
-    do
+    while(ID == lookaheadType(1))
     {
-        std::string text = lookaheadToken(1).text();
-        match(ID);
-        if( pattern_types.find(text) != pattern_types.end() )
-        {
-            pattern.push_back( pattern_types[ text ] );
-        }
-        else
-        {
-            Exception ex( lookaheadToken(1) );
-            ex << "Unrecognized macro parameter type: " << lookaheadToken(1).text();
-            throw ex;
-        }
+        ret->addChild( new AST( lookaheadToken(1) ) );
+        consume();
     }
-    while( lookaheadType(1) == ID );
     match(RPAR);
-    match(SEP);
-    expr = LogicalExpr();
-
-    return Pattern( pattern, expr );
-}
-
-// ExpList = (Expression (',' Expression)*)?
-AST* DLParser::ExpList(TokenType_T node_type, TokenType_T terminator)
-{
-    AST* node = _new AST( node_type );
-    if(lookaheadType(1) != terminator)
-    {
-        node->addChild( Expression() );
-        while(lookaheadType(1) != terminator)
-        {
-            if ( lookaheadType(1) == COMMA )
-            {
-                consume();
-                if (lookaheadType(1) != terminator)
-                {
-                    node->addChild( Expression() );
-                }
-            }
-        }
-    }
-    return node;
-}
-
-// ExpBlock = Expression+
-AST* DLParser::ExpBlock(TokenType_T node_type, TokenType_T terminator)
-{
-    AST* node = _new AST(node_type);
-    while(lookaheadType(1) != RBRACE)
-    {
-        node->addChild( Expression() );
-    }
-    return node;
+    return ret;
 }
 
index 8fc35308532167d6899c0cf1ec73dca33b84bb5a..20d968e7734932b47464f9f257ad504016c7ce6e 100644 (file)
@@ -19,97 +19,14 @@ class DLParser : public BTParser
         bool speculate_GroupExpr(void);
         bool speculate_MacroPatternMatch(Pattern patt);
 
-        /**********************************************************************
-         * EBNF Syntax Grammar
-         *********************************************************************/
-        // Program    = Expression*
-        //
-        // Expression = ID '=' LogicalExpr
-        //            | MacroDefinition
-        //            | $MacroExpansion$
-        //            | LogicalExpr
-        //
-        // AssignExpr = LogicalExpr '=' LogicalExpr
-        //
-        // LogicalExpr = CompExpr (('&&' | '||') CompExpr)*
-        //
-        // CompExpr = AddSubExpr (('==' | '!=' | '<' | '>' | '<=' | '>=') AddSubExpr)*
-        //
-        // AddSubExpr = MulDivExpr (('+' | '-') MulDivExpr)*
-        //
-        // MulDivExpr = UnaryExpr (('*' | '/') UnaryExpr)*
-        //
-        // UnaryExpr = '!' GroupExpr
-        //           | GroupExpr
-        //
-        // GroupExpr = '(' LogicalExpr ')'
-        //           | '(' LogicalExpr ')' '(' ExpList ')'
-        //           | '(' LogicalExpr ')' '[' LogicalExpr ']'
-        //           | Literal
-        //           | Literal '(' ExpList ')'
-        //           | Literal '[' LogicalExpr ']'
-        //
-        // MemberExpr = Literal '.' LogicalExpr
-        //
-        // Literal = VectorLiteral
-        //         | ListLiteral
-        //         | FuncLiteral
-        //         | ID
-        //         | NUM
-        //         | CHAR
-        //         | STRING
-        //         | SYMBOL
-        //
-        // MapLiteral = '{' (Literal ':' AssignExpr)* '}'
-        //
-        // VectorLiteral = '[' ExpList ']'
-        //
-        // ListLiteral = '(' ExpList ')'
-        //
-        // FuncLiteral = '{' ExpBlock '}'
-        //             |  '{' '|' ExpList '|' ExpBlock '}'
-        //
-        // MacroDefinition = '%' ID '[' MacroParamList ']'
-        //
-        // MacroPatternList = MacroPattern (',' MacroPattern)*
-        //
-        // MacroPattern = '(' ID+ ')' ':' LogicalExpr
-        //
-        // ExpList = (GroupExpr (',' GroupExpr)*)?
-        //
-        // ExpBlock = Expression*
     private:
         // Entry Rules
         AST* Program(void);
-
-        // Order of Precedence rules for expressions
         AST* Expression(void);
-        AST* AssignExpr(void);
-        AST* LogicalExpr(void);
-        AST* CompExpr(void);
-        AST* AddSubExpr(void);
-        AST* MulDivExpr(void);
-        AST* UnaryExpr(void);
-        AST* GroupExpr(void);
-        AST* MemberExpr(void);
-
-        // Literal Type Rules
+        AST* Application(void);
         AST* Literal(void);
-        AST* MapLiteral(void);
-        AST* VectorLiteral(void);
-        AST* ListLiteral(void);
-        AST* FuncLiteral(void);
-
-        // Macro Rules
-        AST* MacroDefinition(void);
-        std::list<Pattern> MacroPatternList(void);
-        Pattern MacroPattern(void);
-        AST* MacroExpansion();
-        AST* MacroPatternMatch(Pattern patt);
-
-        // Helper rules for lists and blocks of expressions
-        AST* ExpList(TokenType_T node_type, TokenType_T terminator);
-        AST* ExpBlock(TokenType_T node_type, TokenType_T terminator);
+        AST* ExpList(void);
+        AST* IdList(void);
 };
 
 #endif
index 15e68421089d7d61e7b69f02b99acbb7b28831cb..bc55de87765e3a9a0e8c73d73a8e7f7168c5c136 100644 (file)
@@ -7,6 +7,7 @@
 #include "common.h"
 #include "macro.h"
 #include "options.h"
+#include "astprinter.h"
 
 using namespace std;
 
@@ -31,8 +32,9 @@ int main(int argc, char** argv)
 
         // Setup Parser and Visitors
         DLParser parser;
-        Scheme printer(output);
-        Scheme debug_printer(std::cout);
+        //Scheme printer(output);
+        //Scheme debug_printer(std::cout);
+        ASTPrinter debug_printer;
         parser.input(new DLLexer(input));
 
         // Parse the input stream
@@ -40,16 +42,17 @@ int main(int argc, char** argv)
 
         // Post process the AST (converts to scheme and prints to output file)
         parser.process( debug_printer );
-        parser.process( printer );
+        //parser.process( printer );
 
         // Close the output file
         output.close();
 
         // Compile the temporary file with chicken scheme
-        system( string("csc -O5 -v " + temp_fname).c_str() );
+        //system( string("csc -O5 -v " + temp_fname).c_str() );
+        (void)temp_fname;
 
-        cout << "Removing temporary files..." << endl;
-        (void)remove( temp_fname.c_str() );
+        //cout << "Removing temporary files..." << endl;
+        //(void)remove( temp_fname.c_str() );
     }
     else
     {
index 8bd10a9de081a6383a623a7b4966ad10b9bcf607..089926215b96aed919da7d2810d28b946c6a89ad 100644 (file)
@@ -23,69 +23,69 @@ string Scheme::typeToString(ASTNodeType type)
 
     switch (type)
     {
-        case ID:
-            ret << "ID "; break;
-        case NUM:
-            ret << "NUM "; break;
-        case MAP:
-            ret << "MAP "; break;
-        case CHAR:
-            ret << "CHAR "; break;
-        case ADD:
-            ret << "+ "; break;
-        case SUB:
-            ret << "- "; break;
-        case MUL:
-            ret << "* "; break;
-        case DIV:
-            ret << "/ "; break;
-        case AND:
-            ret << "and "; break;
-        case OR:
-            ret << "or "; break;
-        case NOT:
-            ret << "not "; break;
-        case EQ:
-            ret << "equal? "; break;
-        case NE:
-            ret << "NE "; break;
-        case LT:
-            ret << "< "; break;
-        case GT:
-            ret << "> "; break;
-        case LTE:
-            ret << "<= "; break;
-        case GTE:
-            ret << ">= "; break;
-        case DEFN:
-            ret << "define "; break;
-        case ASSIGN:
-            ret << "set! "; break;
-        case MUTATE:
-            ret << "obj-set! "; break;
-        case PROGRAM:
-            ret << "begin "; break;
-        case VECTOR:
-            ret << "vector "; break;
-        case LIST:
-            ret << "list "; break;
-        case BLOCK:
-            ret << "begin "; break;
-        case FUNC:
-            ret << "lambda "; break;
-        case FN_CALL:
-            ret << "apply "; break;
-        case ARRY_IDX:
-            ret << "ARRY_IDX "; break;
-        case SEP:
-            ret << "cons "; break;
-        case MEMB:
-            ret << "hash-table-ref "; break;
-
-        // Print nothing for the following nodes
-        case MACRO:
-        case PARAMS:
-            break;
+        //case ID:
+        //    ret << "ID "; break;
+        //case NUM:
+        //    ret << "NUM "; break;
+        //case MAP:
+        //    ret << "MAP "; break;
+        //case CHAR:
+        //    ret << "CHAR "; break;
+        //case ADD:
+        //    ret << "+ "; break;
+        //case SUB:
+        //    ret << "- "; break;
+        //case MUL:
+        //    ret << "* "; break;
+        //case DIV:
+        //    ret << "/ "; break;
+        //case AND:
+        //    ret << "and "; break;
+        //case OR:
+        //    ret << "or "; break;
+        //case NOT:
+        //    ret << "not "; break;
+        //case EQ:
+        //    ret << "equal? "; break;
+        //case NE:
+        //    ret << "NE "; break;
+        //case LT:
+        //    ret << "< "; break;
+        //case GT:
+        //    ret << "> "; break;
+        //case LTE:
+        //    ret << "<= "; break;
+        //case GTE:
+        //    ret << ">= "; break;
+        //case DEFN:
+        //    ret << "define "; break;
+        //case ASSIGN:
+        //    ret << "set! "; break;
+        //case MUTATE:
+        //    ret << "obj-set! "; break;
+        //case PROGRAM:
+        //    ret << "begin "; break;
+        //case VECTOR:
+        //    ret << "vector "; break;
+        //case LIST:
+        //    ret << "list "; break;
+        //case BLOCK:
+        //    ret << "begin "; break;
+        //case FUNC:
+        //    ret << "lambda "; break;
+        //case FN_CALL:
+        //    ret << "apply "; break;
+        //case ARRY_IDX:
+        //    ret << "ARRY_IDX "; break;
+        //case SEP:
+        //    ret << "cons "; break;
+        //case MEMB:
+        //    ret << "hash-table-ref "; break;
+
+        //// Print nothing for the following nodes
+        //case MACRO:
+        //case PARAMS:
+        //    break;
 
         // Print out the type id (this will probably cause an error but also
         // alert us to the fact that it is not properly handled)
@@ -108,7 +108,7 @@ void Scheme::afterVisit(AST* cur, int depth)
 void Scheme::beforeChildren(AST* cur, int depth)
 {
     nodeTypeBeginAction(cur);
-    if( cur->type() != MACRO )
+    //if( cur->type() != MACRO )
     {
         if( isDatatype( cur->type() ) )
         {
@@ -124,7 +124,7 @@ void Scheme::beforeChildren(AST* cur, int depth)
 void Scheme::afterChildren(AST* cur, int depth)
 {
     nodeTypeEndAction(cur);
-    if( !isDatatype( cur->type() ) && (cur->type() != MACRO))
+    if( !isDatatype( cur->type() ) )
     {
         stream << ")";
     }
@@ -237,21 +237,21 @@ void Scheme::nodeTypeBeginAction(AST* cur)
     std::string text = cur->text();
     switch( cur->type() )
     {
-        case MEMB:
-            cur->children()->back()->type( SYMBOL );
-            break;
+       // case MEMB:
+       //     cur->children()->back()->type( SYMBOL );
+       //     break;
 
-        case BLOCK:
-            scope_stack.startScope();
-            break;
+       // case BLOCK:
+       //     scope_stack.startScope();
+       //     break;
 
-        case DEFN:
-            defineSymbol(cur);
-            break;
+       // case DEFN:
+       //     defineSymbol(cur);
+       //     break;
 
-        case ASSIGN:
-            assignSymbol(cur);
-            break;
+       // case ASSIGN:
+       //     assignSymbol(cur);
+       //     break;
 
         //TODO: Define builtin symbols and enable adding function args to scope
         //case ID:
@@ -267,9 +267,9 @@ void Scheme::nodeTypeEndAction(AST* cur)
 {
     switch( cur->type() )
     {
-        case BLOCK:
-            scope_stack.stopScope();
-            break;
+       // case BLOCK:
+       //     scope_stack.stopScope();
+       //     break;
 
         default:
             break;
index 93c64cff3e2d0e5362d7f7b9e9cc3f17b000ded4..9c0b6bfb2dec928b448f29c20c8264c3388fcf12 100644 (file)
@@ -57,7 +57,7 @@ void TestLexerThrowsException(std::string& input)
 namespace {
 
     //-------------------------------------------------------------------------
-    // Recognize Individual Operators
+    // Recognize and Ignore Whitespace
     //-------------------------------------------------------------------------
     TEST(Recognize_And_Ignore_Whitespace)
     {
@@ -67,7 +67,7 @@ namespace {
     }
 
     //-------------------------------------------------------------------------
-    // Recognize Individual Operators
+    // Recognize and Ignore Comments
     //-------------------------------------------------------------------------
     TEST(Recognize_And_Ignore_Comments)
     {
@@ -85,7 +85,7 @@ namespace {
     }
 
     //-------------------------------------------------------------------------
-    // Recognize Individual Operators
+    // Recognize Valid IDs
     //-------------------------------------------------------------------------
     TEST(Recognize_Valid_IDs)
     {
@@ -182,205 +182,6 @@ namespace {
         TestLexerWithInput( input, expected );
     }
 
-    //-------------------------------------------------------------------------
-    // Test Individual Operators
-    //-------------------------------------------------------------------------
-    TEST(Recognize_Left_Bracket)
-    {
-        std::string input("[");
-        eTokenTypes expected[] = { LBRACK, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Right_Bracket)
-    {
-        std::string input("]");
-        eTokenTypes expected[] = { RBRACK, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Left_Paren)
-    {
-        std::string input("(");
-        eTokenTypes expected[] = { LPAR, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Right_Paren)
-    {
-        std::string input(")");
-        eTokenTypes expected[] = { RPAR, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Left_Brace)
-    {
-        std::string input("{");
-        eTokenTypes expected[] = { LBRACE, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Right_Brace)
-    {
-        std::string input("}");
-        eTokenTypes expected[] = { RBRACE, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Comma)
-    {
-        std::string input(",");
-        eTokenTypes expected[] = { COMMA, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Addition_Op)
-    {
-        std::string input("+");
-        eTokenTypes expected[] = { ADD, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Multiplication_Op)
-    {
-        std::string input("*");
-        eTokenTypes expected[] = { MUL, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Division_Op)
-    {
-        std::string input("/");
-        eTokenTypes expected[] = { DIV, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Member_Accessor_Op)
-    {
-        std::string input(".");
-        eTokenTypes expected[] = { MEMB, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Macro_Op)
-    {
-        std::string input("%");
-        eTokenTypes expected[] = { MACRO, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Subtraction_Op)
-    {
-        std::string input("-");
-        eTokenTypes expected[] = { SUB, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Assignment_Op)
-    {
-        std::string input("=");
-        eTokenTypes expected[] = { ASSIGN, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Equal_Comparison_Op)
-    {
-        std::string input("==");
-        eTokenTypes expected[] = { EQ, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Not_Op)
-    {
-        std::string input("!");
-        eTokenTypes expected[] = { NOT, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Not_Equal_Op)
-    {
-        std::string input("!=");
-        eTokenTypes expected[] = { NE, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Less_Than_Op)
-    {
-        std::string input("<");
-        eTokenTypes expected[] = { LT, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Less_Than_Equal_Op)
-    {
-        std::string input("<=");
-        eTokenTypes expected[] = { LTE, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Greater_Than_Op)
-    {
-        std::string input(">");
-        eTokenTypes expected[] = { GT, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Greater_Than_Or_Equal_Op)
-    {
-        std::string input(">=");
-        eTokenTypes expected[] = { GTE, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Pipe)
-    {
-        std::string input("|");
-        eTokenTypes expected[] = { PIPE, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Or_Op)
-    {
-        std::string input("||");
-        eTokenTypes expected[] = { OR, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_And_Op)
-    {
-        std::string input("&&");
-        eTokenTypes expected[] = { AND, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Seperator)
-    {
-        std::string input(":");
-        eTokenTypes expected[] = { SEP, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Definition_Op)
-    {
-        std::string input(":=");
-        eTokenTypes expected[] = { DEFN, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Map_Op)
-    {
-        std::string input("@");
-        eTokenTypes expected[] = { MAP, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
-    TEST(Recognize_Import_Op)
-    {
-        std::string input("@=");
-        eTokenTypes expected[] = { IMPORT, (eTokenTypes)EOF };
-        TestLexerWithInput( input, expected );
-    }
-
     //-------------------------------------------------------------------------
     // Test Exceptional Cases
     //-------------------------------------------------------------------------
@@ -398,14 +199,6 @@ namespace {
 
         std::string num_exception4("1.a");
         TestLexerThrowsException( num_exception4 );
-
-        // Make sure we throw an exception for an invalid operator
-        std::string op_exception1("^");
-        TestLexerThrowsException( op_exception1 );
-
-        // Make sure we throw an exception for an invalid operator
-        std::string multi_op_exception1("&");
-        TestLexerThrowsException( multi_op_exception1 );
     }
 
     //-------------------------------------------------------------------------
@@ -420,8 +213,8 @@ namespace {
 
     TEST(Handle_Recognition_At_The_End_Of_Input)
     {
-        std::string input("[");
-        eTokenTypes expected[] = { LBRACK, (eTokenTypes)EOF };
+        std::string input("a");
+        eTokenTypes expected[] = { ID, (eTokenTypes)EOF };
         TestLexerWithInput( input, expected );
     }
 
index 1b0e3561f1564373d0f9239fbdd0c23112cd39e3..44aa96e1ad574885e5d62663e24d1e1ea30a89d4 100644 (file)
@@ -68,882 +68,882 @@ void TestParserThrowsException(std::string& input)
 // Begin Unit Tests
 //-----------------------------------------------------------------------------
 namespace {
-    //-------------------------------------------------------------------------
-    // Test Parsing of Data Type Literals
-    //-------------------------------------------------------------------------
-
-    // Vector Literals
-    //----------------
-    TEST(Parse_An_Empty_Vector)
-    {
-        std::string input("[]");
-        eTokenTypes expected[] = {
-            VECTOR,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_An_Vector_With_One_Item)
-    {
-        std::string input("[1]");
-        eTokenTypes expected[] = {
-            NUM, VECTOR,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_Vector_Of_Two_Items)
-    {
-        std::string input("[1,2]");
-        eTokenTypes expected[] = {
-            NUM, NUM, VECTOR,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_Vector_Of_Three_Items)
-    {
-        std::string input("[1,2,3]");
-        eTokenTypes expected[] = {
-            NUM, NUM, NUM, VECTOR,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_Vector_With_Trailing_Commas)
-    {
-        std::string input("[1,]");
-        eTokenTypes expected[] = {
-            NUM, VECTOR,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // List Literals
-    //--------------
-    TEST(Parse_A_List)
-    {
-        std::string input("()");
-        eTokenTypes expected[] = {
-            LIST,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_An_List_With_One_Item)
-    {
-        std::string input("(1,)"); // Comma is required here
-        eTokenTypes expected[] = {
-            NUM, LIST,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_List_Of_Two_Items)
-    {
-        std::string input("(1,2)");
-        eTokenTypes expected[] = {
-            NUM, NUM, LIST,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_List_Of_Three_Items)
-    {
-        std::string input("(1,2,3)");
-        eTokenTypes expected[] = {
-            NUM, NUM, NUM, LIST,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_List_With_Trailing_Commas)
-    {
-        std::string input("(1,)");
-        eTokenTypes expected[] = {
-            NUM, LIST,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_List_With_Heterogeneous_Elements)
-    {
-        std::string input("(1,$foo,bar)");
-        eTokenTypes expected[] = {
-            NUM, SYMBOL, ID, LIST,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // Block Literals
-    //---------------
-    TEST(Parse_A_Block_With_No_Parameters)
-    {
-        std::string input("{}");
-        eTokenTypes expected[] = {
-            PARAMS, BLOCK, FUNC,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_Block_With_One_Param)
-    {
-        std::string input("{|a|}");
-        eTokenTypes expected[] = {
-            ID, PARAMS, BLOCK, FUNC,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_Block_With_Two_Params)
-    {
-        std::string input("{|a,b|}");
-        eTokenTypes expected[] = {
-            ID, ID, PARAMS, BLOCK, FUNC,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_Block_With_Two_Params_That_Performs_An_Addition_Operation)
-    {
-        std::string input("{|a,b| a + b}");
-        eTokenTypes expected[] = {
-            ID, ID, PARAMS, ID, ID, ADD, BLOCK, FUNC,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // Map Literals
-    //-------------
-    TEST(Parse_An_Empty_Map)
-    {
-        std::string input("@{}");
-        eTokenTypes expected[] = {
-            MAP,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_Map_With_One_Entry)
-    {
-        std::string input("@{ $foo : 42 }");
-        eTokenTypes expected[] = {
-            SYMBOL, NUM, SEP, MAP,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_Map_With_Two_Entries)
-    {
-        std::string input("@{ $foo : 42, $bar : 42 }");
-        eTokenTypes expected[] = {
-            SYMBOL, NUM, SEP, SYMBOL, NUM, SEP, MAP,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Maps_Should_Allow_A_Trailing_Comma)
-    {
-        std::string input("@{ $foo : 42, $bar : 42, }");
-        eTokenTypes expected[] = {
-            SYMBOL, NUM, SEP, SYMBOL, NUM, SEP, MAP,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // Id Literals
-    //------------
-    TEST(Parse_An_Id)
-    {
-        std::string input("foo");
-        eTokenTypes expected[] = {
-            ID,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // Number Literals
-    //----------------
-    TEST(Parse_A_Num)
-    {
-        std::string input("42");
-        eTokenTypes expected[] = {
-            NUM,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // Character Literals
-    //-------------------
-    TEST(Parse_A_Char)
-    {
-        std::string input("'a'");
-        eTokenTypes expected[] = {
-            CHAR,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // String Literals
-    //----------------
-    TEST(Parse_A_String)
-    {
-        std::string input("\"\"");
-        eTokenTypes expected[] = {
-            STRING,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // Symbol Literals
-    //----------------
-    TEST(Parse_A_Symbol)
-    {
-        std::string input("$foo");
-        eTokenTypes expected[] = {
-            SYMBOL,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    //-------------------------------------------------------------------------
-    // Test Operators And Operator Precedence
-    //-------------------------------------------------------------------------
-
-    // Member Accessor
-    //----------------
-    TEST(Parse_A_Member_Acces_One_Level_Deep)
-    {
-        std::string input("foo.bar");
-        eTokenTypes expected[] = {
-            ID, ID, MEMB,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_Member_Acces_Two_Levels_Deep)
-    {
-        std::string input("foo.bar.somethin");
-        eTokenTypes expected[] = {
-            ID, ID, ID, MEMB, MEMB,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // Grouping Expression
-    //--------------------
-    TEST(Parse_A_Grouping_Expression)
-    {
-        std::string input("( 1 + 1 )");
-        eTokenTypes expected[] = {
-            NUM, NUM, ADD,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_Grouping_Expression_With_A_Lower_Priority_Statement)
-    {
-        std::string input("(1 + 2) * 3");
-        eTokenTypes expected[] = {
-            NUM, NUM, ADD, NUM, MUL,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_Grouping_Expression_With_A_Higher_Priority_Statement)
-    {
-        std::string input("1 + (2 * 3)");
-        eTokenTypes expected[] = {
-            NUM, NUM, NUM, MUL, ADD,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // Function Application
-    //---------------------
-    TEST(Parse_A_Simple_Function_Application)
-    {
-        std::string input("foo()");
-        eTokenTypes expected[] = {
-            ID, LIST, FN_CALL,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // Collection Access
-    //------------------
-    TEST(Parse_An_Array_Indexing_Expression)
-    {
-        std::string input("foo[1]");
-        eTokenTypes expected[] = {
-            ID, NUM, ARRY_IDX,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // Logical Operators
-    //------------------
-    TEST(Parse_A_Logical_And_Operation)
-    {
-        std::string input("foo && bar");
-        eTokenTypes expected[] = {
-            ID, ID, AND,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_Logical_Or_Operation)
-    {
-        std::string input("foo || bar");
-        eTokenTypes expected[] = {
-            ID, ID, OR,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_Logical_Not_Operation)
-    {
-        std::string input("! foo");
-        eTokenTypes expected[] = {
-            ID, NOT,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // Arithmetic Operators
-    //---------------------
-    TEST(Parse_An_Addition_Operation)
-    {
-        std::string input("foo + bar");
-        eTokenTypes expected[] = {
-            ID, ID, ADD,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_Subtraction_Operation)
-    {
-        std::string input("foo - bar");
-        eTokenTypes expected[] = {
-            ID, ID, SUB,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_Multiplication_Operation)
-    {
-        std::string input("foo * bar");
-        eTokenTypes expected[] = {
-            ID, ID, MUL,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_Division_Operation)
-    {
-        std::string input("foo / bar");
-        eTokenTypes expected[] = {
-            ID, ID, DIV,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // Comparison Operators
-    //---------------------
-    TEST(Parse_An_Equal_Operation)
-    {
-        std::string input("foo == bar");
-        eTokenTypes expected[] = {
-            ID, ID, EQ,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_Not_Equal_Operation)
-    {
-        std::string input("foo != bar");
-        eTokenTypes expected[] = {
-            ID, ID, NE,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_Less_Than_Operation)
-    {
-        std::string input("foo < bar");
-        eTokenTypes expected[] = {
-            ID, ID, LT,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_Greater_Than_Operation)
-    {
-        std::string input("foo > bar");
-        eTokenTypes expected[] = {
-            ID, ID, GT,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_Less_Than_Or_Equal_Operation)
-    {
-        std::string input("foo <= bar");
-        eTokenTypes expected[] = {
-            ID, ID, LTE,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_Greater_Than_Or_Equal_Operation)
-    {
-        std::string input("foo >= bar");
-        eTokenTypes expected[] = {
-            ID, ID, GTE,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // Definition and Assignment
-    //--------------------------
-    TEST(Parse_A_Definition_Operation)
-    {
-        std::string input("foo := 1");
-        eTokenTypes expected[] = {
-            ID, NUM, DEFN,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_An_Assignment_Operation)
-    {
-        std::string input("foo = bar");
-        eTokenTypes expected[] = {
-            ID, ID, ASSIGN,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_An_Assignment_To_An_Array_Member)
-    {
-        std::string input("foo[1] = bar");
-        eTokenTypes expected[] = {
-            ID, NUM, ID, MUTATE,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_An_Assignment_To_A_Map_Member)
-    {
-        std::string input("foo[\"bar\"] = bar");
-        eTokenTypes expected[] = {
-            ID, STRING, ID, MUTATE,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    //-------------------------------------------------------------------------
-    // Test Macro Definition and Expansion
-    //-------------------------------------------------------------------------
-
-    // Map
-    //----
-    TEST(Parse_A_Macro_Taking_One_Map)
-    {
-        std::string input("\% foo [ (M) : $1 ]");
-        eTokenTypes expected[] = {
-            MACRO,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Use_A_Macro_With_A_Map_Parameter)
-    {
-        std::string input(
-            "\% foo [ (M) : $1 ]\n"
-            "foo @{}"
-        );
-        eTokenTypes expected[] = {
-            MACRO,
-            MAP,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // Vector
-    //-------
-    TEST(Parse_A_Macro_Taking_One_Vector)
-    {
-        std::string input("\% foo [ (V) : $1 ]");
-        eTokenTypes expected[] = {
-            MACRO,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Use_A_Macro_With_A_Vector_Parameter)
-    {
-        std::string input(
-            "\% foo [ (V) : $1 ]\n"
-            "foo []"
-        );
-        eTokenTypes expected[] = {
-            MACRO,
-            VECTOR,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // List
-    //-----
-    TEST(Parse_A_Macro_Taking_One_List)
-    {
-        std::string input("\% foo [ (L) : $1 ]");
-        eTokenTypes expected[] = {
-            MACRO,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Use_A_Macro_With_A_List_Parameter)
-    {
-        std::string input(
-            "\% foo [ (L) : $1 ]\n"
-            "foo ()"
-        );
-        eTokenTypes expected[] = {
-            MACRO,
-            LIST,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // Block
-    //------
-    TEST(Parse_A_Macro_Taking_One_Block)
-    {
-        std::string input("\% foo [ (B) : $1 ]");
-        eTokenTypes expected[] = {
-            MACRO,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Use_A_Macro_With_A_Block_Parameter)
-    {
-        std::string input(
-            "\% foo [ (B) : $1 ]\n"
-            "foo {}"
-        );
-        eTokenTypes expected[] = {
-            MACRO,
-            PARAMS, BLOCK, FUNC,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // Id
-    //---
-    TEST(Parse_A_Macro_taking_One_Id)
-    {
-        std::string input("\% foo [ (I) : $1 ]");
-        eTokenTypes expected[] = {
-            MACRO,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Use_A_Macro_With_A_Id_Parameter)
-    {
-        std::string input(
-            "\% foo [ (I) : $1 ]\n"
-            "foo bar"
-        );
-        eTokenTypes expected[] = {
-            MACRO,
-            ID,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // Number
-    //-------
-    TEST(Parse_A_Macro_Taking_One_Number)
-    {
-        std::string input("\% foo [ (N) : $1 ]");
-        eTokenTypes expected[] = {
-            MACRO,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Use_A_Macro_With_A_Number_Parameter)
-    {
-        std::string input(
-            "\% foo [ (N) : $1 ]\n"
-            "foo 1.0"
-        );
-        eTokenTypes expected[] = {
-            MACRO,
-            NUM,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // Character
-    //----------
-    TEST(Parse_A_Macro_Taking_One_Character)
-    {
-        std::string input("\% foo [ (C) : $1 ]");
-        eTokenTypes expected[] = {
-            MACRO,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Use_A_Macro_With_A_Character_Parameter)
-    {
-        std::string input(
-            "\% foo [ (C) : $1 ]\n"
-            "foo 'a'"
-        );
-        eTokenTypes expected[] = {
-            MACRO,
-            CHAR,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // String
-    //-------
-    TEST(Parse_A_Macro_Taking_One_String)
-    {
-        std::string input("\% foo [ (St) : $1 ]");
-        eTokenTypes expected[] = {
-            MACRO,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Use_A_Macro_With_A_String_Parameter)
-    {
-        std::string input(
-            "\% foo [ (St) : $1 ]\n"
-            "foo \"\""
-        );
-        eTokenTypes expected[] = {
-            MACRO,
-            STRING,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // Symbol
-    //-------
-    TEST(Parse_A_Macro_Taking_One_Symbol)
-    {
-        std::string input("\% foo [ (Sy) : $1 ]");
-        eTokenTypes expected[] = {
-            MACRO,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Use_A_Macro_With_A_Symbol_Parameter)
-    {
-        std::string input(
-            "\% foo [ (Sy) : $1 ]\n"
-            "foo $bar"
-        );
-        eTokenTypes expected[] = {
-            MACRO,
-            SYMBOL,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // Expression
-    //-----------
-    TEST(Parse_A_Macro_Taking_One_Expression)
-    {
-        std::string input("\% foo [ (E) : $1 ]");
-        eTokenTypes expected[] = {
-            MACRO,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Use_A_Macro_With_A_Expression_Parameter)
-    {
-        std::string input(
-            "\% foo [ (E) : $1 ]\n"
-            "foo 1 + 1"
-        );
-        eTokenTypes expected[] = {
-            MACRO,
-            NUM, NUM, ADD,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    // Corner Cases
-    //-------------
-    TEST(Throw_Exception_When_Invalid_Macro_Param_Type_Used)
-    {
-        std::string input("\% foo [ (Z) : $1 ]");
-        TestParserThrowsException(input);
-    }
-
-    TEST(Throw_Exception_When_No_Macro_Pattern_Matches)
-    {
-        std::string input(
-            "\% foo [ (I) : $1 ]\n"
-            "foo 1.0" //Expecting and ID but a number is given
-        );
-        TestParserThrowsException(input);
-    }
-
-    TEST(Parse_A_Macro_With_Multiple_Parameter_Types)
-    {
-        std::string input("\% tuple [ (E E) : ($1,$2) ]");
-        eTokenTypes expected[] = {
-            MACRO,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Use_A_Macro_With_Multiple_Parameter_Types)
-    {
-        std::string input(
-            "\% tuple [ (E E) : ($1,$2) ]\n"
-            "tuple 1.0 'a'"
-        );
-        eTokenTypes expected[] = {
-            MACRO,
-            NUM, CHAR, LIST,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Parse_A_Macro_With_Multiple_Patterns)
-    {
-        std::string input(
-            // Emulate an If statement
-            "\% if [\n"
-            "        (E B B) : exec_if($1,$2,$3),\n"
-            "        (E B)   : exec_if($1,$2)\n"
-            "]"
-        );
-        eTokenTypes expected[] = {
-            MACRO,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Use_A_Macro_With_Multiple_Patterns)
-    {
-        std::string input(
-            // Emulate an If statement
-            "\% if [\n"
-            "        (E B B) : exec_if($1,$2,$3),\n"
-            "        (E B)   : exec_if($1,$2)\n"
-            "]\n"
-            "if (1 == 1) {}\n"
-            "if (1 == 1) {} {}\n"
-        );
-        eTokenTypes expected[] = {
-            MACRO,
-            ID, NUM, NUM, EQ, PARAMS, BLOCK, FUNC, LIST, FN_CALL,
-            ID, NUM, NUM, EQ, PARAMS, BLOCK, FUNC, PARAMS, BLOCK, FUNC, LIST, FN_CALL,
-            PROGRAM
-        };
-        TestParserWithInput( input, expected );
-    }
-
-    //-------------------------------------------------------------------------
-    // Test General Corner Cases
-    //-------------------------------------------------------------------------
-    TEST(Parse_An_Empty_Program)
-    {
-        std::string input("");
-        eTokenTypes expected[] = { PROGRAM };
-        TestParserWithInput( input, expected );
-    }
-
-    TEST(Throw_Exception_When_Literal_On_Left_Side_Of_Assignment)
-    {
-        std::string input("[] = 5");
-        TestParserThrowsException(input);
-    }
+    ////-------------------------------------------------------------------------
+    //// Test Parsing of Data Type Literals
+    ////-------------------------------------------------------------------------
+
+    //// Vector Literals
+    ////----------------
+    //TEST(Parse_An_Empty_Vector)
+    //{
+    //    std::string input("[]");
+    //    eTokenTypes expected[] = {
+    //        VECTOR,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_An_Vector_With_One_Item)
+    //{
+    //    std::string input("[1]");
+    //    eTokenTypes expected[] = {
+    //        NUM, VECTOR,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_Vector_Of_Two_Items)
+    //{
+    //    std::string input("[1,2]");
+    //    eTokenTypes expected[] = {
+    //        NUM, NUM, VECTOR,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_Vector_Of_Three_Items)
+    //{
+    //    std::string input("[1,2,3]");
+    //    eTokenTypes expected[] = {
+    //        NUM, NUM, NUM, VECTOR,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_Vector_With_Trailing_Commas)
+    //{
+    //    std::string input("[1,]");
+    //    eTokenTypes expected[] = {
+    //        NUM, VECTOR,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// List Literals
+    ////--------------
+    //TEST(Parse_A_List)
+    //{
+    //    std::string input("()");
+    //    eTokenTypes expected[] = {
+    //        LIST,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_An_List_With_One_Item)
+    //{
+    //    std::string input("(1,)"); // Comma is required here
+    //    eTokenTypes expected[] = {
+    //        NUM, LIST,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_List_Of_Two_Items)
+    //{
+    //    std::string input("(1,2)");
+    //    eTokenTypes expected[] = {
+    //        NUM, NUM, LIST,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_List_Of_Three_Items)
+    //{
+    //    std::string input("(1,2,3)");
+    //    eTokenTypes expected[] = {
+    //        NUM, NUM, NUM, LIST,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_List_With_Trailing_Commas)
+    //{
+    //    std::string input("(1,)");
+    //    eTokenTypes expected[] = {
+    //        NUM, LIST,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_List_With_Heterogeneous_Elements)
+    //{
+    //    std::string input("(1,$foo,bar)");
+    //    eTokenTypes expected[] = {
+    //        NUM, SYMBOL, ID, LIST,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// Block Literals
+    ////---------------
+    //TEST(Parse_A_Block_With_No_Parameters)
+    //{
+    //    std::string input("{}");
+    //    eTokenTypes expected[] = {
+    //        PARAMS, BLOCK, FUNC,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_Block_With_One_Param)
+    //{
+    //    std::string input("{|a|}");
+    //    eTokenTypes expected[] = {
+    //        ID, PARAMS, BLOCK, FUNC,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_Block_With_Two_Params)
+    //{
+    //    std::string input("{|a,b|}");
+    //    eTokenTypes expected[] = {
+    //        ID, ID, PARAMS, BLOCK, FUNC,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_Block_With_Two_Params_That_Performs_An_Addition_Operation)
+    //{
+    //    std::string input("{|a,b| a + b}");
+    //    eTokenTypes expected[] = {
+    //        ID, ID, PARAMS, ID, ID, ADD, BLOCK, FUNC,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// Map Literals
+    ////-------------
+    //TEST(Parse_An_Empty_Map)
+    //{
+    //    std::string input("@{}");
+    //    eTokenTypes expected[] = {
+    //        MAP,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_Map_With_One_Entry)
+    //{
+    //    std::string input("@{ $foo : 42 }");
+    //    eTokenTypes expected[] = {
+    //        SYMBOL, NUM, SEP, MAP,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_Map_With_Two_Entries)
+    //{
+    //    std::string input("@{ $foo : 42, $bar : 42 }");
+    //    eTokenTypes expected[] = {
+    //        SYMBOL, NUM, SEP, SYMBOL, NUM, SEP, MAP,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Maps_Should_Allow_A_Trailing_Comma)
+    //{
+    //    std::string input("@{ $foo : 42, $bar : 42, }");
+    //    eTokenTypes expected[] = {
+    //        SYMBOL, NUM, SEP, SYMBOL, NUM, SEP, MAP,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// Id Literals
+    ////------------
+    //TEST(Parse_An_Id)
+    //{
+    //    std::string input("foo");
+    //    eTokenTypes expected[] = {
+    //        ID,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// Number Literals
+    ////----------------
+    //TEST(Parse_A_Num)
+    //{
+    //    std::string input("42");
+    //    eTokenTypes expected[] = {
+    //        NUM,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// Character Literals
+    ////-------------------
+    //TEST(Parse_A_Char)
+    //{
+    //    std::string input("'a'");
+    //    eTokenTypes expected[] = {
+    //        CHAR,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// String Literals
+    ////----------------
+    //TEST(Parse_A_String)
+    //{
+    //    std::string input("\"\"");
+    //    eTokenTypes expected[] = {
+    //        STRING,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// Symbol Literals
+    ////----------------
+    //TEST(Parse_A_Symbol)
+    //{
+    //    std::string input("$foo");
+    //    eTokenTypes expected[] = {
+    //        SYMBOL,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    ////-------------------------------------------------------------------------
+    //// Test Operators And Operator Precedence
+    ////-------------------------------------------------------------------------
+
+    //// Member Accessor
+    ////----------------
+    //TEST(Parse_A_Member_Acces_One_Level_Deep)
+    //{
+    //    std::string input("foo.bar");
+    //    eTokenTypes expected[] = {
+    //        ID, ID, MEMB,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_Member_Acces_Two_Levels_Deep)
+    //{
+    //    std::string input("foo.bar.somethin");
+    //    eTokenTypes expected[] = {
+    //        ID, ID, ID, MEMB, MEMB,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// Grouping Expression
+    ////--------------------
+    //TEST(Parse_A_Grouping_Expression)
+    //{
+    //    std::string input("( 1 + 1 )");
+    //    eTokenTypes expected[] = {
+    //        NUM, NUM, ADD,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_Grouping_Expression_With_A_Lower_Priority_Statement)
+    //{
+    //    std::string input("(1 + 2) * 3");
+    //    eTokenTypes expected[] = {
+    //        NUM, NUM, ADD, NUM, MUL,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_Grouping_Expression_With_A_Higher_Priority_Statement)
+    //{
+    //    std::string input("1 + (2 * 3)");
+    //    eTokenTypes expected[] = {
+    //        NUM, NUM, NUM, MUL, ADD,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// Function Application
+    ////---------------------
+    //TEST(Parse_A_Simple_Function_Application)
+    //{
+    //    std::string input("foo()");
+    //    eTokenTypes expected[] = {
+    //        ID, LIST, FN_CALL,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// Collection Access
+    ////------------------
+    //TEST(Parse_An_Array_Indexing_Expression)
+    //{
+    //    std::string input("foo[1]");
+    //    eTokenTypes expected[] = {
+    //        ID, NUM, ARRY_IDX,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// Logical Operators
+    ////------------------
+    //TEST(Parse_A_Logical_And_Operation)
+    //{
+    //    std::string input("foo && bar");
+    //    eTokenTypes expected[] = {
+    //        ID, ID, AND,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_Logical_Or_Operation)
+    //{
+    //    std::string input("foo || bar");
+    //    eTokenTypes expected[] = {
+    //        ID, ID, OR,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_Logical_Not_Operation)
+    //{
+    //    std::string input("! foo");
+    //    eTokenTypes expected[] = {
+    //        ID, NOT,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// Arithmetic Operators
+    ////---------------------
+    //TEST(Parse_An_Addition_Operation)
+    //{
+    //    std::string input("foo + bar");
+    //    eTokenTypes expected[] = {
+    //        ID, ID, ADD,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_Subtraction_Operation)
+    //{
+    //    std::string input("foo - bar");
+    //    eTokenTypes expected[] = {
+    //        ID, ID, SUB,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_Multiplication_Operation)
+    //{
+    //    std::string input("foo * bar");
+    //    eTokenTypes expected[] = {
+    //        ID, ID, MUL,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_Division_Operation)
+    //{
+    //    std::string input("foo / bar");
+    //    eTokenTypes expected[] = {
+    //        ID, ID, DIV,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// Comparison Operators
+    ////---------------------
+    //TEST(Parse_An_Equal_Operation)
+    //{
+    //    std::string input("foo == bar");
+    //    eTokenTypes expected[] = {
+    //        ID, ID, EQ,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_Not_Equal_Operation)
+    //{
+    //    std::string input("foo != bar");
+    //    eTokenTypes expected[] = {
+    //        ID, ID, NE,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_Less_Than_Operation)
+    //{
+    //    std::string input("foo < bar");
+    //    eTokenTypes expected[] = {
+    //        ID, ID, LT,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_Greater_Than_Operation)
+    //{
+    //    std::string input("foo > bar");
+    //    eTokenTypes expected[] = {
+    //        ID, ID, GT,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_Less_Than_Or_Equal_Operation)
+    //{
+    //    std::string input("foo <= bar");
+    //    eTokenTypes expected[] = {
+    //        ID, ID, LTE,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_Greater_Than_Or_Equal_Operation)
+    //{
+    //    std::string input("foo >= bar");
+    //    eTokenTypes expected[] = {
+    //        ID, ID, GTE,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// Definition and Assignment
+    ////--------------------------
+    //TEST(Parse_A_Definition_Operation)
+    //{
+    //    std::string input("foo := 1");
+    //    eTokenTypes expected[] = {
+    //        ID, NUM, DEFN,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_An_Assignment_Operation)
+    //{
+    //    std::string input("foo = bar");
+    //    eTokenTypes expected[] = {
+    //        ID, ID, ASSIGN,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_An_Assignment_To_An_Array_Member)
+    //{
+    //    std::string input("foo[1] = bar");
+    //    eTokenTypes expected[] = {
+    //        ID, NUM, ID, MUTATE,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_An_Assignment_To_A_Map_Member)
+    //{
+    //    std::string input("foo[\"bar\"] = bar");
+    //    eTokenTypes expected[] = {
+    //        ID, STRING, ID, MUTATE,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    ////-------------------------------------------------------------------------
+    //// Test Macro Definition and Expansion
+    ////-------------------------------------------------------------------------
+
+    //// Map
+    ////----
+    //TEST(Parse_A_Macro_Taking_One_Map)
+    //{
+    //    std::string input("\% foo [ (M) : $1 ]");
+    //    eTokenTypes expected[] = {
+    //        MACRO,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Use_A_Macro_With_A_Map_Parameter)
+    //{
+    //    std::string input(
+    //        "\% foo [ (M) : $1 ]\n"
+    //        "foo @{}"
+    //    );
+    //    eTokenTypes expected[] = {
+    //        MACRO,
+    //        MAP,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// Vector
+    ////-------
+    //TEST(Parse_A_Macro_Taking_One_Vector)
+    //{
+    //    std::string input("\% foo [ (V) : $1 ]");
+    //    eTokenTypes expected[] = {
+    //        MACRO,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Use_A_Macro_With_A_Vector_Parameter)
+    //{
+    //    std::string input(
+    //        "\% foo [ (V) : $1 ]\n"
+    //        "foo []"
+    //    );
+    //    eTokenTypes expected[] = {
+    //        MACRO,
+    //        VECTOR,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// List
+    ////-----
+    //TEST(Parse_A_Macro_Taking_One_List)
+    //{
+    //    std::string input("\% foo [ (L) : $1 ]");
+    //    eTokenTypes expected[] = {
+    //        MACRO,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Use_A_Macro_With_A_List_Parameter)
+    //{
+    //    std::string input(
+    //        "\% foo [ (L) : $1 ]\n"
+    //        "foo ()"
+    //    );
+    //    eTokenTypes expected[] = {
+    //        MACRO,
+    //        LIST,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// Block
+    ////------
+    //TEST(Parse_A_Macro_Taking_One_Block)
+    //{
+    //    std::string input("\% foo [ (B) : $1 ]");
+    //    eTokenTypes expected[] = {
+    //        MACRO,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Use_A_Macro_With_A_Block_Parameter)
+    //{
+    //    std::string input(
+    //        "\% foo [ (B) : $1 ]\n"
+    //        "foo {}"
+    //    );
+    //    eTokenTypes expected[] = {
+    //        MACRO,
+    //        PARAMS, BLOCK, FUNC,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// Id
+    ////---
+    //TEST(Parse_A_Macro_taking_One_Id)
+    //{
+    //    std::string input("\% foo [ (I) : $1 ]");
+    //    eTokenTypes expected[] = {
+    //        MACRO,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Use_A_Macro_With_A_Id_Parameter)
+    //{
+    //    std::string input(
+    //        "\% foo [ (I) : $1 ]\n"
+    //        "foo bar"
+    //    );
+    //    eTokenTypes expected[] = {
+    //        MACRO,
+    //        ID,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// Number
+    ////-------
+    //TEST(Parse_A_Macro_Taking_One_Number)
+    //{
+    //    std::string input("\% foo [ (N) : $1 ]");
+    //    eTokenTypes expected[] = {
+    //        MACRO,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Use_A_Macro_With_A_Number_Parameter)
+    //{
+    //    std::string input(
+    //        "\% foo [ (N) : $1 ]\n"
+    //        "foo 1.0"
+    //    );
+    //    eTokenTypes expected[] = {
+    //        MACRO,
+    //        NUM,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// Character
+    ////----------
+    //TEST(Parse_A_Macro_Taking_One_Character)
+    //{
+    //    std::string input("\% foo [ (C) : $1 ]");
+    //    eTokenTypes expected[] = {
+    //        MACRO,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Use_A_Macro_With_A_Character_Parameter)
+    //{
+    //    std::string input(
+    //        "\% foo [ (C) : $1 ]\n"
+    //        "foo 'a'"
+    //    );
+    //    eTokenTypes expected[] = {
+    //        MACRO,
+    //        CHAR,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// String
+    ////-------
+    //TEST(Parse_A_Macro_Taking_One_String)
+    //{
+    //    std::string input("\% foo [ (St) : $1 ]");
+    //    eTokenTypes expected[] = {
+    //        MACRO,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Use_A_Macro_With_A_String_Parameter)
+    //{
+    //    std::string input(
+    //        "\% foo [ (St) : $1 ]\n"
+    //        "foo \"\""
+    //    );
+    //    eTokenTypes expected[] = {
+    //        MACRO,
+    //        STRING,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// Symbol
+    ////-------
+    //TEST(Parse_A_Macro_Taking_One_Symbol)
+    //{
+    //    std::string input("\% foo [ (Sy) : $1 ]");
+    //    eTokenTypes expected[] = {
+    //        MACRO,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Use_A_Macro_With_A_Symbol_Parameter)
+    //{
+    //    std::string input(
+    //        "\% foo [ (Sy) : $1 ]\n"
+    //        "foo $bar"
+    //    );
+    //    eTokenTypes expected[] = {
+    //        MACRO,
+    //        SYMBOL,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// Expression
+    ////-----------
+    //TEST(Parse_A_Macro_Taking_One_Expression)
+    //{
+    //    std::string input("\% foo [ (E) : $1 ]");
+    //    eTokenTypes expected[] = {
+    //        MACRO,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Use_A_Macro_With_A_Expression_Parameter)
+    //{
+    //    std::string input(
+    //        "\% foo [ (E) : $1 ]\n"
+    //        "foo 1 + 1"
+    //    );
+    //    eTokenTypes expected[] = {
+    //        MACRO,
+    //        NUM, NUM, ADD,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //// Corner Cases
+    ////-------------
+    //TEST(Throw_Exception_When_Invalid_Macro_Param_Type_Used)
+    //{
+    //    std::string input("\% foo [ (Z) : $1 ]");
+    //    TestParserThrowsException(input);
+    //}
+
+    //TEST(Throw_Exception_When_No_Macro_Pattern_Matches)
+    //{
+    //    std::string input(
+    //        "\% foo [ (I) : $1 ]\n"
+    //        "foo 1.0" //Expecting and ID but a number is given
+    //    );
+    //    TestParserThrowsException(input);
+    //}
+
+    //TEST(Parse_A_Macro_With_Multiple_Parameter_Types)
+    //{
+    //    std::string input("\% tuple [ (E E) : ($1,$2) ]");
+    //    eTokenTypes expected[] = {
+    //        MACRO,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Use_A_Macro_With_Multiple_Parameter_Types)
+    //{
+    //    std::string input(
+    //        "\% tuple [ (E E) : ($1,$2) ]\n"
+    //        "tuple 1.0 'a'"
+    //    );
+    //    eTokenTypes expected[] = {
+    //        MACRO,
+    //        NUM, CHAR, LIST,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Parse_A_Macro_With_Multiple_Patterns)
+    //{
+    //    std::string input(
+    //        // Emulate an If statement
+    //        "\% if [\n"
+    //        "        (E B B) : exec_if($1,$2,$3),\n"
+    //        "        (E B)   : exec_if($1,$2)\n"
+    //        "]"
+    //    );
+    //    eTokenTypes expected[] = {
+    //        MACRO,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Use_A_Macro_With_Multiple_Patterns)
+    //{
+    //    std::string input(
+    //        // Emulate an If statement
+    //        "\% if [\n"
+    //        "        (E B B) : exec_if($1,$2,$3),\n"
+    //        "        (E B)   : exec_if($1,$2)\n"
+    //        "]\n"
+    //        "if (1 == 1) {}\n"
+    //        "if (1 == 1) {} {}\n"
+    //    );
+    //    eTokenTypes expected[] = {
+    //        MACRO,
+    //        ID, NUM, NUM, EQ, PARAMS, BLOCK, FUNC, LIST, FN_CALL,
+    //        ID, NUM, NUM, EQ, PARAMS, BLOCK, FUNC, PARAMS, BLOCK, FUNC, LIST, FN_CALL,
+    //        PROGRAM
+    //    };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    ////-------------------------------------------------------------------------
+    //// Test General Corner Cases
+    ////-------------------------------------------------------------------------
+    //TEST(Parse_An_Empty_Program)
+    //{
+    //    std::string input("");
+    //    eTokenTypes expected[] = { PROGRAM };
+    //    TestParserWithInput( input, expected );
+    //}
+
+    //TEST(Throw_Exception_When_Literal_On_Left_Side_Of_Assignment)
+    //{
+    //    std::string input("[] = 5");
+    //    TestParserThrowsException(input);
+    //}
 }