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 );
{
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;
}
namespace {
//-------------------------------------------------------------------------
- // Recognize Individual Operators
+ // Recognize and Ignore Whitespace
//-------------------------------------------------------------------------
TEST(Recognize_And_Ignore_Whitespace)
{
}
//-------------------------------------------------------------------------
- // Recognize Individual Operators
+ // Recognize and Ignore Comments
//-------------------------------------------------------------------------
TEST(Recognize_And_Ignore_Comments)
{
}
//-------------------------------------------------------------------------
- // Recognize Individual Operators
+ // Recognize Valid IDs
//-------------------------------------------------------------------------
TEST(Recognize_Valid_IDs)
{
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
//-------------------------------------------------------------------------
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 );
}
//-------------------------------------------------------------------------
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 );
}
// 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);
+ //}
}