]> git.mdlowis.com Git - archive/dlang.git/commitdiff
Finished tests for DLParser
authorMike D. Lowis <mike@mdlowis.com>
Sun, 17 Jun 2012 22:36:53 +0000 (18:36 -0400)
committerMike D. Lowis <mike@mdlowis.com>
Sun, 17 Jun 2012 22:36:53 +0000 (18:36 -0400)
tests/test_dlparser.cpp

index a8d3ca757e390c2502bd2a7790f69816bb3e126e..a179c099b21bda8bc4862ee7af5c5ed730290e0a 100644 (file)
@@ -16,6 +16,22 @@ using namespace UnitTest;
 //-----------------------------------------------------------------------------
 // Helper Functions
 //-----------------------------------------------------------------------------
+
+#define PROGRAM(num, ...) new AST(PROGRAM, "", num, __VA_ARGS__)
+#define DEFINE(a,b) new AST(DEFINE,"", 2, a, b)
+#define ASSIGN(a,b) new AST(ASSIGN,"", 2, a, b)
+#define BEGIN(num, ...) new AST(BEGIN, "", num, __VA_ARGS__)
+#define IF(num, ...) new AST(IF,"", num, __VA_ARGS__)
+#define LAMBDA(num, ...) new AST(LAMBDA,"", num, __VA_ARGS__)
+#define MACRO(num, ...) new AST(MACRO,"", num, __VA_ARGS__)
+#define LIST(num, ...) new AST(LIST,"", num, __VA_ARGS__)
+#define APPLY(a,b) new AST(APPLY, "", 2, a, b)
+#define ID(text) new AST(ID,text)
+#define NUM(text) new AST(NUM,text)
+#define CHAR(text) new AST(CHAR,text)
+#define STRING(text) new AST(STRING,text)
+#define SYMBOL(text) new AST(SYMBOL,text)
+
 #define CHECK_AST(left,right) CheckASTsForEquality( left, right, __LINE__ )
 void CheckASTsForEquality(AST* left, AST* right, int line)
 {
@@ -50,9 +66,18 @@ namespace {
     //-------------------------------------------------------------------------
     TEST(Verify_isSyntaxName_recognizes_a_registered_syntax)
     {
-        DLParser parser;
+        class TestDLParser : public DLParser
+        {
+            public:
+                using DLParser::syntaxes;
+        };
+        std::string syn_name ("foobar");
+        Syntax* syntax = new Syntax();
+        TestDLParser parser;
         std::istringstream input("foobar");
         parser.input(new DLLexer(input));
+        syntax->name( syn_name );
+        parser.syntaxes[ syntax->name() ] = syntax;
         CHECK( true == parser.isSyntaxName() );
     }
 
@@ -211,7 +236,391 @@ namespace {
         DLParser parser;
         std::istringstream input("foobar");
         parser.input(new DLLexer(input));
-        //CHECK( false == parser.getCoreFormId() );
-        CHECK( false );
+        CHECK( UNKNOWN == parser.getCoreFormId() );
+    }
+
+    //-------------------------------------------------------------------------
+    // Test parse
+    //-------------------------------------------------------------------------
+    TEST(Verify_parse_calls_Program_subrule)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = PROGRAM( 1, NUM("+5") );
+        std::istringstream input("5");
+        parser.input(new DLLexer(input));
+        parser.parse();
+        result = parser.ast()->clone();
+        CHECK_AST( result, expected );
+    }
+
+    //-------------------------------------------------------------------------
+    // Test Program
+    //-------------------------------------------------------------------------
+    TEST(Verify_Program_can_parse_a_group_of_expressions)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = PROGRAM( 2, NUM("+5"), NUM("+5") );
+        std::istringstream input("5 5");
+        parser.input(new DLLexer(input));
+        parser.parse();
+        result = parser.ast()->clone();
+        CHECK_AST( result, expected );
+    }
+
+    //-------------------------------------------------------------------------
+    // Test Expression
+    //-------------------------------------------------------------------------
+    TEST(Verify_Expression_parses_a_core_form)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = DEFINE( ID("foo"), NUM("+5") );
+        std::istringstream input("def foo 5");
+        parser.input(new DLLexer(input));
+        result = parser.CoreForm();
+        CHECK_AST( result, expected );
+    }
+
+    TEST(Verify_Expression_parses_a_basic_expression)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = ID("foo");
+        std::istringstream input("foo");
+        parser.input(new DLLexer(input));
+        result = parser.Expression();
+        CHECK_AST( result, expected );
+    }
+
+    TEST(Verify_Expression_parses_a_traditional_function_call)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = APPLY(
+                          ID("foo"),
+                          LIST( 2,
+                            NUM("+5"),
+                            NUM("+5") ));
+        std::istringstream input("foo(5 5)");
+        parser.input(new DLLexer(input));
+        result = parser.Expression();
+        CHECK_AST( result, expected );
+    }
+
+    //-------------------------------------------------------------------------
+    // Test CoreForm
+    //-------------------------------------------------------------------------
+    TEST(Verify_CoreForm_parses_def_expression)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = DEFINE( ID("foo"), NUM("+5") );
+        std::istringstream input("def foo 5");
+        parser.input(new DLLexer(input));
+        result = parser.CoreForm();
+        CHECK_AST( result, expected );
+    }
+
+    TEST(Verify_CoreForm_parses_set_expression)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = ASSIGN( ID("foo"), NUM("+5") );
+        std::istringstream input("set foo 5");
+        parser.input(new DLLexer(input));
+        result = parser.CoreForm();
+        CHECK_AST( result, expected );
+    }
+
+    TEST(Verify_CoreForm_parses_begin_expression)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = BEGIN( 1,
+                          LIST( 1,
+                            APPLY(
+                              ID("+"),
+                              LIST( 2,
+                                NUM("+1"),
+                                NUM("+1") ))));
+        std::istringstream input("begin (1 + 1) end");
+        parser.input(new DLLexer(input));
+        result = parser.CoreForm();
+        CHECK_AST( result, expected );
+    }
+
+    TEST(Verify_CoreForm_parses_if_expression_with_no_else)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = IF( 2, NUM("+1"), NUM("+2") );
+        std::istringstream input("if 1 2 end");
+        parser.input(new DLLexer(input));
+        result = parser.CoreForm();
+        CHECK_AST( result, expected );
+    }
+
+    TEST(Verify_CoreForm_parses_if_expression_with_else)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = IF( 3, NUM("+1"), NUM("+2"), NUM("+3"));
+        std::istringstream input("if 1 2 3 end");
+        parser.input(new DLLexer(input));
+        result = parser.CoreForm();
+        CHECK_AST( result, expected );
+    }
+
+    TEST(Verify_CoreForm_parses_function_expression)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = LAMBDA( 2,
+                          LIST( 1,
+                            ID("a" )),
+                          LIST( 1,
+                            APPLY(
+                              ID( "+" ),
+                                LIST( 2,
+                                  ID( "a" ),
+                                  NUM( "+1" ) ))));
+        std::istringstream input("func(a) (a + 1) end");
+        parser.input(new DLLexer(input));
+        result = parser.CoreForm();
+        CHECK_AST( result, expected );
+    }
+
+    TEST(Verify_CoreForm_parses_macro_expression)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = MACRO( 2,
+                          LIST( 1,
+                            ID("a" )),
+                          LIST( 1,
+                            APPLY(
+                              ID( "+" ),
+                                LIST( 2,
+                                  ID( "a" ),
+                                  NUM( "+1" ) ))));
+        std::istringstream input("macro(a) (a + 1) end");
+        parser.input(new DLLexer(input));
+        result = parser.CoreForm();
+        CHECK_AST( result, expected );
+    }
+
+    TEST(Verify_CoreForm_throws_exception_for_unknown_form)
+    {
+        DLParser parser;
+        std::istringstream input("foo");
+        parser.input(new DLLexer(input));
+        CHECK_THROW( parser.CoreForm(), Exception );
+    }
+
+    //-------------------------------------------------------------------------
+    // Test BasicExp
+    //-------------------------------------------------------------------------
+    TEST(Verify_BasicExp_recognizes_an_infix_function_application)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = new AST( APPLY, "", 2,
+                            new AST( ID, "+" ),
+                            new AST( LIST, "", 2,
+                                new AST( NUM, "+1" ),
+                                new AST( NUM, "+2" ) ));
+        std::istringstream input("(1 + 2)");
+        parser.input(new DLLexer(input));
+        result = parser.BasicExp();
+        CHECK_AST( result, expected );
+    }
+
+    TEST(Verify_BasicExp_recognizes_a_literal)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = new AST( ID, "foo" );
+        std::istringstream input("foo");
+        parser.input(new DLLexer(input));
+        result = parser.BasicExp();
+        CHECK_AST( result, expected );
+    }
+
+    //-------------------------------------------------------------------------
+    // Test Literal
+    //-------------------------------------------------------------------------
+    TEST(Verify_Literal_parses_an_id)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = new AST( ID, "foo" );
+        std::istringstream input("foo");
+        parser.input(new DLLexer(input));
+        result = parser.Literal();
+        CHECK_AST( result, expected );
+    }
+
+    TEST(Verify_Literal_parses_a_char)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = new AST( CHAR, "a" );
+        std::istringstream input("'a'");
+        parser.input(new DLLexer(input));
+        result = parser.Literal();
+        CHECK_AST( result, expected );
+    }
+
+    TEST(Verify_Literal_parses_a_string)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = new AST( STRING, "" );
+        std::istringstream input("\"\"");
+        parser.input(new DLLexer(input));
+        result = parser.Literal();
+        CHECK_AST( result, expected );
+    }
+
+    TEST(Verify_Literal_parses_a_symbol)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = new AST( SYMBOL, "foo" );
+        std::istringstream input("$foo");
+        parser.input(new DLLexer(input));
+        result = parser.Literal();
+        CHECK_AST( result, expected );
+    }
+
+    TEST(Verify_Literal_parses_a_num)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = new AST( NUM, "+5" );
+        std::istringstream input("5");
+        parser.input(new DLLexer(input));
+        result = parser.Literal();
+        CHECK_AST( result, expected );
+    }
+
+    TEST(Verify_Literal_throws_exception_if_no_literal_found)
+    {
+        DLParser parser;
+        std::istringstream input("(");
+        parser.input(new DLLexer(input));
+        CHECK_THROW( parser.Literal(), Exception );
+    }
+
+    //-------------------------------------------------------------------------
+    // Test ExpList
+    //-------------------------------------------------------------------------
+    TEST(Verify_ExpList_parses_an_empty_exp_list)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = new AST( LIST, "" );
+        std::istringstream input("end");
+        parser.input(new DLLexer(input));
+        result = parser.ExpList(TERM);
+        CHECK_AST( result, expected );
+    }
+
+    TEST(Verify_ExpList_parses_an_exp_list_with_1_item)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = new AST( LIST, "", 1,
+                            new AST(NUM, "+5") );
+        std::istringstream input("5 end");
+        parser.input(new DLLexer(input));
+        result = parser.ExpList(TERM);
+        CHECK_AST( result, expected );
+    }
+
+    TEST(Verify_ExpList_parses_an_exp_list_with_2_items)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = new AST( LIST, "", 2,
+                            new AST(NUM, "+5"),
+                            new AST(NUM, "+5") );
+        std::istringstream input("5 5 end");
+        parser.input(new DLLexer(input));
+        result = parser.ExpList(TERM);
+        CHECK_AST( result, expected );
+    }
+
+    TEST(Verify_ExpList_throws_an_exception_when_no_terminator_found)
+    {
+        DLParser parser;
+        std::istringstream input("a");
+        parser.input(new DLLexer(input));
+        CHECK_THROW( parser.ExpList(TERM), Exception );
+    }
+
+    //-------------------------------------------------------------------------
+    // Test IdList
+    //-------------------------------------------------------------------------
+    TEST(Verify_IdList_parses_an_empty_list)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = new AST( LIST, "" );
+        std::istringstream input("()");
+        parser.input(new DLLexer(input));
+        result = parser.IdList();
+        CHECK_AST( result, expected );
+    }
+
+    TEST(Verify_IdList_parses_a_list_with_one_id)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = new AST( LIST, "", 1,
+                            new AST(ID,"a") );
+        std::istringstream input("(a)");
+        parser.input(new DLLexer(input));
+        result = parser.IdList();
+        CHECK_AST( result, expected );
+    }
+
+    TEST(Verify_IdList_parses_a_list_with_two_ids)
+    {
+        DLParser parser;
+        AST* result = NULL;
+        AST* expected = new AST( LIST, "", 2,
+                            new AST(ID,"a"),
+                            new AST(ID,"b") );
+        std::istringstream input("(a b)");
+        parser.input(new DLLexer(input));
+        result = parser.IdList();
+        CHECK_AST( result, expected );
+    }
+
+    TEST(Verify_IdList_throws_exception_on_missing_left_paren)
+    {
+        DLParser parser;
+        std::istringstream input("a b)");
+        parser.input(new DLLexer(input));
+        CHECK_THROW( parser.IdList(), Exception );
+    }
+
+    TEST(Verify_IdList_throws_exception_on_missing_right_paren)
+    {
+        DLParser parser;
+        std::istringstream input("(a b");
+        parser.input(new DLLexer(input));
+        CHECK_THROW( parser.IdList(), Exception );
+    }
+
+    TEST(Verify_IdList_throws_exception_when_list_contains_non_id)
+    {
+        DLParser parser;
+        std::istringstream input("(a 5)");
+        parser.input(new DLLexer(input));
+        CHECK_THROW( parser.IdList(), Exception );
     }
 }