From 92707f8402af4653baf254cfeb9a214baea03176 Mon Sep 17 00:00:00 2001 From: "Mike D. Lowis" Date: Mon, 5 Mar 2012 13:49:49 -0500 Subject: [PATCH] Added infrastructure for hash maps and added support for prototype member access via the . operator --- example.dl | 56 ++++++++--- source/dllexer/dllexer.cpp | 3 +- source/dllexer/dllexer.h | 1 + source/dlparser/dlparser.cpp | 176 ++++++++++++++++++++++------------- source/dlparser/dlparser.h | 8 ++ 5 files changed, 165 insertions(+), 79 deletions(-) diff --git a/example.dl b/example.dl index 4ac171e..bbc0c66 100644 --- a/example.dl +++ b/example.dl @@ -1,14 +1,46 @@ -foo = () -foo = (1) -foo = (1,2) +#------------------------------------------------------------------------------ +# Literals +#------------------------------------------------------------------------------ + +# VectorLiteral foo = [] foo = [1] -foo = [1,2] -foo = "" -foo = "1" -foo = "12" - -% if [ - (Ex Bk) : exec_if($1, $2), - (Ex Bk Bk) : exec_if($1, $2, $3) -] +foo = [1,2,3] +foo = foo[1] +foo = [1,2,3,4,5][2] + +# ListLiteral +foo = () +foo = (1,2,3) +foo = foo[1] +foo = (1,2,3,4,5)[2] + +# FuncLiteral +foo = { 1 + 1 } +foo = {|a| a + 1} +foo = {|a,b| a + b } +foo = foo(1,2) +foo = ({|a,b| a + b })(1,2) + +# ID +foo = bar +foo.bar = bar + +# NUM +foo = 1 +foo = 1.0 + +# CHAR +foo = 'a' + +# STRING +foo = "some string" +foo = "12345"[2] + +# SYMBOL +foo = $some_symbol + +#% if [ +# (Ex Bk) : exec_if($1, $2), +# (Ex Bk Bk) : exec_if($1, $2, $3) +#] diff --git a/source/dllexer/dllexer.cpp b/source/dllexer/dllexer.cpp index eb9cfa6..7a1f6d4 100644 --- a/source/dllexer/dllexer.cpp +++ b/source/dllexer/dllexer.cpp @@ -4,7 +4,7 @@ using namespace std; -#define NUM_SINGLE_CHAR_MATCHES 13 +#define NUM_SINGLE_CHAR_MATCHES 14 SingleCharMatch_T Single_Character_Matches[ NUM_SINGLE_CHAR_MATCHES ] = { { '[', LBRACK }, { ']', RBRACK }, @@ -19,6 +19,7 @@ SingleCharMatch_T Single_Character_Matches[ NUM_SINGLE_CHAR_MATCHES ] = { { '/', DIV }, { '%', MACRO }, { ':', SEP }, + { '.', MEMB }, }; bool DLLexer::isWhiteSpace(void) diff --git a/source/dllexer/dllexer.h b/source/dllexer/dllexer.h index 0e50a7a..620d766 100644 --- a/source/dllexer/dllexer.h +++ b/source/dllexer/dllexer.h @@ -41,6 +41,7 @@ typedef enum TokenTypes SUB = 31, MUL = 32, DIV = 33, + MEMB = 34, // AST "Virtual" Node Types MACRO = 40, diff --git a/source/dlparser/dlparser.cpp b/source/dlparser/dlparser.cpp index fbb4b60..22b3965 100644 --- a/source/dlparser/dlparser.cpp +++ b/source/dlparser/dlparser.cpp @@ -31,7 +31,6 @@ bool DLParser::isMacro( Token& token ) bool DLParser::speculate_GroupExpr(void) { - AST* throw_away = NULL; bool success = true; mark(); @@ -47,10 +46,23 @@ bool DLParser::speculate_GroupExpr(void) } release(); - if (throw_away != NULL) + return success; +} + +bool DLParser::speculate_MapLiteral(void) +{ + bool success = true; + + mark(); + try + { + delete MapLiteral(); + } + catch (Exception e) { - delete throw_away; + success = false; } + release(); return success; } @@ -68,14 +80,8 @@ AST* DLParser::Program(void) AST* DLParser::Expression(void) { AST* ret = NULL; - if((lookaheadType(1) == ID) && (lookaheadType(2) == ASSIGN)) - { - AST* id_node = _new AST( ID,(char*)(lookaheadToken(1).text().c_str()) ); - consume(); - match(ASSIGN); - ret = _new AST( ASSIGN, 2, id_node, Expression()); - } - else if( (lookaheadType(1) == MACRO) && (lookaheadType(2) == ID)) + + if( (lookaheadType(1) == MACRO) && (lookaheadType(2) == ID)) { ret = MacroDefinition(); } @@ -85,7 +91,19 @@ AST* DLParser::Expression(void) //} else { - ret = LogicalExpr(); + ret = AssignExpr(); + } + return ret; +} + +AST* DLParser::AssignExpr(void) +{ + AST* ret = NULL; + ret = LogicalExpr(); + if(lookaheadType(1) == ASSIGN) + { + match(ASSIGN); + ret = new AST(ASSIGN, 2, ret, LogicalExpr()); } return ret; } @@ -167,7 +185,7 @@ AST* DLParser::GroupExpr(void) } else { - ret = Literal(); + ret = MemberExpr(); } if( lookaheadType(1) == LPAR ) @@ -186,67 +204,93 @@ AST* DLParser::GroupExpr(void) 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)) + if(speculate_MapLiteral()) + { + node = MapLiteral(); + } + else { - // Literal = VectorLiteral - case LBRACK: - node = VectorLiteral(); - break; - - // Literal = ListLiteral - case LPAR: - node = ListLiteral(); - break; - - // Literal = FuncLiteral - case LBRACE: - node = FuncLiteral(); - break; - - // Literal = ID - case ID: - node = _new AST( ID, lookaheadToken(1).text() ); - consume(); - break; - - // 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; - - // Literal = SYMBOL - case SYMBOL: - node = _new AST( SYMBOL, lookaheadToken(1).text() ); - consume(); - break; - - default: - Token& tok = lookaheadToken(1); - ostringstream oss; - oss << "Expected literal type, recieved type " << tok.type() << "."; - Exception ex( tok.line(), tok.column() ); - ex.setMessage(oss.str()); - throw ex; + switch(lookaheadType(1)) + { + // Literal = VectorLiteral + case LBRACK: + node = VectorLiteral(); + break; + + // Literal = ListLiteral + case LPAR: + node = ListLiteral(); + break; + + // Literal = FuncLiteral + case LBRACE: + node = FuncLiteral(); + break; + + // Literal = ID + case ID: + node = _new AST( ID, lookaheadToken(1).text() ); + consume(); + break; + + // 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; + + // Literal = SYMBOL + case SYMBOL: + node = _new AST( SYMBOL, lookaheadToken(1).text() ); + consume(); + break; + + default: + Token& tok = lookaheadToken(1); + ostringstream oss; + oss << "Expected literal type, recieved type " << tok.type() << "."; + Exception ex( tok.line(), tok.column() ); + ex.setMessage(oss.str()); + throw ex; + } } return node; } +AST* DLParser::MapLiteral(void) +{ + AST* ret = NULL; + throw Exception(lookaheadToken(1).line(), lookaheadToken(1).column()); + return ret; +} + AST* DLParser::VectorLiteral(void) { AST* ret = NULL; diff --git a/source/dlparser/dlparser.h b/source/dlparser/dlparser.h index 5a0b667..b3553d0 100644 --- a/source/dlparser/dlparser.h +++ b/source/dlparser/dlparser.h @@ -17,6 +17,7 @@ class DLParser : public BTParser AST* parse(void); bool isMacro(Token& token); bool speculate_GroupExpr(void); + bool speculate_MapLiteral(void); /********************************************************************** * EBNF Syntax Grammar @@ -28,6 +29,8 @@ class DLParser : public BTParser // | $MacroExpansion$ // | LogicalExpr // + // AssignExpr = LogicalExpr '=' LogicalExpr + // // LogicalExpr = CompExpr (('&&' | '||') CompExpr)* // // CompExpr = AddSubExpr (('==' | '!=' | '<' | '>' | '<=' | '>=') AddSubExpr)* @@ -46,6 +49,8 @@ class DLParser : public BTParser // | Literal '(' ExpList ')' // | Literal '[' LogicalExpr ']' // + // MemberExpr = Literal '.' LogicalExpr + // // Literal = VectorLiteral // | ListLiteral // | FuncLiteral @@ -77,15 +82,18 @@ class DLParser : public BTParser // 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* Literal(void); + AST* MapLiteral(void); AST* VectorLiteral(void); AST* ListLiteral(void); AST* FuncLiteral(void); -- 2.54.0