From: Mike D. Lowis Date: Tue, 29 May 2012 18:49:00 +0000 (-0400) Subject: Updated parser to support all core forms except quote X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=7ea1e0f83312fe3ea569831f8788e6efd998479a;p=archive%2Fdlang.git Updated parser to support all core forms except quote --- diff --git a/example.dl b/example.dl index bf1ee18..6411a0e 100644 --- a/example.dl +++ b/example.dl @@ -15,12 +15,34 @@ foo() foo(1) foo(1 2) foo(1 2 3) -foo(1,2,3) -(foo . $bar)(1, 2, 3) +(foo . $bar)(1 2 3) # Definition and assignment -define foo 5 -set! foo 6 +define foo 5; +set! foo 6; + +# If statement +if conditional + if_branch +#else + else_branch +end + +if conditional + if_branch +end + +# Begin block +begin end + +begin + foo() +end + +begin + foo() + bar() +end # Lambda expressions lambda () end @@ -44,45 +66,39 @@ lambda (a b c) foo(a b c) end -# Begin block -begin end +# Macro expressions +macro () end +macro (a) end +macro (a b) end +macro (a b c) end -begin - foo() +macro () + foo(a) end -begin - foo() - bar() +macro (a) + foo(a) end -# If statement -if conditional - if_branch -else - else_branch +macro (a b) + foo(a b) end -if conditional - if_branch +macro (a b c) + foo(a b c) end -## Define an infix operator (No Precedence) -#infix = -# -## Define dummy keywords (Whitespace) -#keyword ; -# -#foo = (1 + 1) ; - -# Macros -macro let ( := = ) ; - ( a := b ) - define a b +# Quoting Expressions +#quote( (1 + 1) ) - ( a = b ) - set! a b -end +# Syntactic Extensions +#syntax let ( := = ) ; +# ( a := b ) +# define a b ; +# +# ( a = b ) +# set! a b ; +#end -let foo := "bar" ; -let foo = 5 ; +#let foo := "bar" ; +#let foo = 5 ; diff --git a/source/dllexer/dllexer.cpp b/source/dllexer/dllexer.cpp index 98aebb3..7eaa420 100644 --- a/source/dllexer/dllexer.cpp +++ b/source/dllexer/dllexer.cpp @@ -97,13 +97,6 @@ Token DLLexer::next(void) Symbol(ret); } - // Consume a comma - else if(lookahead(1) == ',') - { - ret = Token( COMMA, ",", line, column ); - consume(); - } - // Consume parentheses else if (lookahead(1) == '(') { @@ -127,12 +120,13 @@ Token DLLexer::next(void) Id(ret); } + } - if( !escaped && (ret.text().compare( terminator_string ) == 0) ) - { - ret.type( TERM ); - } + if( !escaped && (ret.text().compare( terminator_string ) == 0) ) + { + ret.type( TERM ); } + cout << terminator_string << " " << escaped << " " << ret.type() << " " << ret.text() << "|"<< endl; return ret; } diff --git a/source/dllexer/dllexer.h b/source/dllexer/dllexer.h index 5b7a953..391e5fb 100644 --- a/source/dllexer/dllexer.h +++ b/source/dllexer/dllexer.h @@ -6,30 +6,34 @@ typedef enum TokenTypes { - // Symbols + // Core Forms PROGRAM = 0, DEFINE = 1, ASSIGN = 2, - LAMBDA = 3, + IF = 3, BEGIN = 4, - IF = 5, - APPLY = 6, - ID_LIST = 7, - EXP_LIST = 8, - MACRO = 9, - TRANSFORM = 10, - MACRO_APP = 11, - LPAR = 12, - RPAR = 13, - COMMA = 14, - TERM = 15, + QUOTE = 5, + LAMBDA = 6, + MACRO = 7, + SYNTAX = 8, + + // Punctuation and Symbols + LPAR = 10, + RPAR = 11, + TERM = 12, + + // Actions and Virtual nodes + APPLY = 20, + EXPAND = 21, + TRANSFORM = 22, + LIST = 23, // Datatypes - ID = 16, - NUM = 17, - CHAR = 18, - STRING = 19, - SYMBOL = 20, + ID = 30, + NUM = 31, + CHAR = 32, + STRING = 33, + SYMBOL = 34, } eTokenTypes; typedef struct { diff --git a/source/dlparser/dlparser.cpp b/source/dlparser/dlparser.cpp index 25a1b24..63bef51 100644 --- a/source/dlparser/dlparser.cpp +++ b/source/dlparser/dlparser.cpp @@ -9,10 +9,12 @@ DLParser::DLParser() : BTParser() { core_forms["define"] = DEFINE; core_forms["set!"] = ASSIGN; - core_forms["lambda"] = LAMBDA; - core_forms["begin"] = BEGIN; core_forms["if"] = IF; + core_forms["begin"] = BEGIN; + core_forms["quote"] = QUOTE; + core_forms["lambda"] = LAMBDA; core_forms["macro"] = MACRO; + core_forms["syntax"] = SYNTAX; } DLParser::~DLParser() @@ -54,15 +56,17 @@ AST* DLParser::Expression(void) AST* ret = NULL; // Expression := CoreForm - // | FuncApp // | BasicExp + // | FuncApp // // CoreForm := 'define' ID Expression TERM // | 'set!' ID Expression TERM - // | 'lambda' IdList ExpList? TERM // | 'begin' ExpList* TERM + // | 'quote' ExpList* TERM // | 'if' Expression Expression 'else' Expression? TERM - // | 'macro' ID IdList ID ExpList TERM + // | 'lambda' IdList ExpList? TERM + // | 'macro' IdList ExpList? TERM + // | 'syntax' ID IdList ID ExpList TERM // // FuncApp := BasicExp '(' ParamList ')' // @@ -90,10 +94,14 @@ AST* DLParser::Expression(void) else { ret = BasicExp(); - //if ( speculate_ParamList() ) - //{ - // ret + ParamList() - //} + + // Traditional Function Application + if( lookaheadType(1) == LPAR ) + { + match(LPAR); + ret = new AST(APPLY, 2, ret, ExpList(RPAR)); + match(RPAR); + } } // Register any new macros and expand any existing macros @@ -106,38 +114,48 @@ AST* DLParser::Expression(void) AST* DLParser::CoreForm(void) { AST* ret = NULL; + std::string term = ((DLLexer*)lexer)->terminator(); eTokenTypes form_id = getCoreFormId(); consume(); // Throw away the form name (we don't need it anymore) switch( form_id ) { case DEFINE: case ASSIGN: + ((DLLexer*)lexer)->terminator(";"); ret = new AST( lookaheadToken(1) ); match(ID); ret = new AST(form_id, 2, ret, Expression()); break; - case LAMBDA: - ret = new AST(LAMBDA, 2, IdList(), ExpList(TERM)); - match(TERM); - break; - case BEGIN: + ((DLLexer*)lexer)->terminator("end"); ret = new AST(BEGIN, 1, ExpList(TERM)); - match(TERM); break; case IF: + ((DLLexer*)lexer)->terminator("end"); ret = new AST(IF, 2, Expression(), Expression()); if(lookaheadType(1) != TERM) { ret->addChild( Expression() ); } - match(TERM); break; + //case QUOTE: + // match(LPAR); + // ret = new AST(QUOTE, 1, Expression()); + // ((DLLexer*)lexer)->terminator(")"); + // break; + + case LAMBDA: case MACRO: - ret = new AST(MACRO); + ((DLLexer*)lexer)->terminator("end"); + ret = new AST(form_id, 2, IdList(), ExpList(TERM)); + break; + + case SYNTAX: + ((DLLexer*)lexer)->terminator("end"); + ret = new AST(SYNTAX); // Get the macro name ret->addChild( new AST( lookaheadToken(1) ) ); @@ -158,13 +176,15 @@ AST* DLParser::CoreForm(void) transform->addChild( Expression() ); ret->addChild( transform ); } - match(TERM); break; + case QUOTE: default: throw Exception( lookaheadToken(1) ); break; } + match(TERM); + ((DLLexer*)lexer)->terminator( term ); return ret; } @@ -185,7 +205,7 @@ AST* DLParser::BasicExp(void) // Register the new terminator // Consume the name - ret = new AST( MACRO_APP, 1, new AST( lookaheadToken(1) )); + ret = new AST( EXPAND, 1, new AST( lookaheadToken(1) )); consume(); // Consume the expressions @@ -198,16 +218,6 @@ AST* DLParser::BasicExp(void) // Reset the terminator to its old value } - //// Traditional Function Application - //else if( (lookaheadType(1) == ID) && (lookaheadType(2) == LPAR) ) - //{ - // ret = new AST( lookaheadToken(1) ); - // consume(); - // match(LPAR); - // ret = new AST(APPLY, 2, ret, ExpList(RPAR)); - // match(RPAR); - //} - // Infix Function Application else if( lookaheadType(1) == LPAR ) { @@ -222,7 +232,7 @@ AST* DLParser::BasicExp(void) operand2 = Expression(); match(RPAR); - ret = new AST( APPLY, 2, operation, new AST(EXP_LIST, 2, operand1, operand2) ); + ret = new AST( APPLY, 2, operation, new AST(LIST, 2, operand1, operand2) ); } // Literal @@ -255,23 +265,9 @@ AST* DLParser::Literal(void) return ret; } -AST* DLParser::ParamList(void) -{ - AST* ret = new AST(EXP_LIST); - match(LPAR); - ret->addChild( Expression() ); - if( COMMA == lookaheadType(1) ) - { - match(COMMA); - ret->addChild( Expression() ); - } - match(RPAR); - return ret; -} - AST* DLParser::ExpList(eTokenTypes term) { - AST* ret = new AST(EXP_LIST); + AST* ret = new AST(LIST); while(term != lookaheadType(1)) { ret->addChild( Expression() ); @@ -281,7 +277,7 @@ AST* DLParser::ExpList(eTokenTypes term) AST* DLParser::IdList(void) { - AST* ret = new AST(ID_LIST); + AST* ret = new AST(LIST); match(LPAR); while(ID == lookaheadType(1)) { diff --git a/source/dlparser/dlparser.h b/source/dlparser/dlparser.h index d2aa201..4ffb962 100644 --- a/source/dlparser/dlparser.h +++ b/source/dlparser/dlparser.h @@ -27,7 +27,6 @@ class DLParser : public BTParser AST* FuncApp(void); AST* BasicExp(void); AST* Literal(void); - AST* ParamList(void); AST* ExpList(eTokenTypes term); AST* IdList(void); }; diff --git a/source/visitors/macroprocessor.cpp b/source/visitors/macroprocessor.cpp index ae631ba..4e1d325 100644 --- a/source/visitors/macroprocessor.cpp +++ b/source/visitors/macroprocessor.cpp @@ -14,7 +14,8 @@ void MacroProcessor::afterVisit(AST* cur, int depth) void MacroProcessor::beforeChildren(AST* cur, int depth) { - if (cur->type() == MACRO_APP) + // If we reached a syntax use then expand it + if (cur->type() == EXPAND) { //expandMacro(cur); } @@ -22,7 +23,8 @@ void MacroProcessor::beforeChildren(AST* cur, int depth) void MacroProcessor::afterChildren(AST* cur, int depth) { - if (cur->type() == MACRO) + // If we have a new syntax definition then register it + if (cur->type() == SYNTAX) { std::string name = (*(cur->children()->begin()))->text(); Macro* macro = new Macro();