]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
Parser now recognizes variable references and literals
authorMichael D. Lowis <mike@mdlowis.com>
Mon, 12 Oct 2015 01:42:08 +0000 (21:42 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Mon, 12 Oct 2015 01:42:08 +0000 (21:42 -0400)
source/ast.c
source/gc.c
source/grammar.c
source/main.c
source/parser.c
source/pprint.c
source/sclpl.h
spec/parser_spec.rb

index 2b8769dcc71bad8b5c955f98e9b067da7857f95a..71aeeb6af5e80945c7c2edd3b107aabe74e47e2a 100644 (file)
@@ -1,4 +1,130 @@
 #include <sclpl.h>
+
+static void ast_free(void* ptr)
+{
+}
+
+static AST* ast(ASTType type)
+{
+    AST* tree = gc_alloc(sizeof(AST), &ast_free);
+    memset(tree, 0, sizeof(AST));
+    tree->type = type;
+    return tree;
+}
+
+AST* String(char* val)
+{
+    AST* node = ast(AST_STRING);
+    node->value.text = val;
+    return node;
+}
+
+char* string_value(AST* val)
+{
+    assert(val->type == AST_STRING);
+    return val->value.text;
+}
+
+AST* Symbol(char* val)
+{
+    AST* node = ast(AST_SYMBOL);
+    node->value.text = val;
+    return node;
+}
+
+char* symbol_value(AST* val)
+{
+    assert(val->type == AST_SYMBOL);
+    return val->value.text;
+}
+
+AST* Char(uint32_t val)
+{
+    AST* node = ast(AST_CHAR);
+    node->value.character = val;
+    return node;
+}
+
+uint32_t char_value(AST* val)
+{
+    assert(val->type == AST_CHAR);
+    return val->value.character;
+}
+
+AST* Integer(intptr_t val)
+{
+    AST* node = ast(AST_INT);
+    node->value.integer = val;
+    return node;
+}
+
+intptr_t integer_value(AST* val)
+{
+    assert(val->type == AST_INT);
+    return val->value.integer;
+}
+
+AST* Float(double val)
+{
+    AST* node = ast(AST_FLOAT);
+    node->value.floating = val;
+    return node;
+}
+
+double float_value(AST* val)
+{
+    assert(val->type == AST_FLOAT);
+    return val->value.floating;
+}
+
+AST* Bool(bool val)
+{
+    AST* node = ast(AST_BOOL);
+    node->value.boolean = val;
+    return node;
+}
+
+bool bool_value(AST* val)
+{
+    assert(val->type == AST_BOOL);
+    return val->value.boolean;
+}
+
+AST* Ident(char* val)
+{
+    AST* node = ast(AST_IDENT);
+    node->value.text = val;
+    return node;
+}
+
+char* ident_value(AST* val)
+{
+    assert(val->type == AST_IDENT);
+    return val->value.text;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 AST* Require(char* name)
 {
@@ -117,87 +243,3 @@ AST* block_get(size_t index)
     return NULL;
 }
 
-AST* String(char* val)
-{
-    (void)val;
-    return NULL;
-}
-
-char* string_value(AST* val)
-{
-    (void)val;
-    return NULL;
-}
-
-AST* Symbol(char* val)
-{
-    (void)val;
-    return NULL;
-}
-
-char* symbol_value(AST* val)
-{
-    (void)val;
-    return NULL;
-}
-
-AST* Char(uint32_t val)
-{
-    (void)val;
-    return NULL;
-}
-
-uint32_t char_value(AST* val)
-{
-    (void)val;
-    return 0;
-}
-
-AST* Integer(intptr_t val)
-{
-    (void)val;
-    return NULL;
-}
-
-intptr_t integer_value(AST* val)
-{
-    (void)val;
-    return 0;
-}
-
-AST* Float(double val)
-{
-    (void)val;
-    return NULL;
-}
-
-double float_value(AST* val)
-{
-    (void)val;
-    return 0.0;
-}
-
-AST* Bool(bool val)
-{
-    (void)val;
-    return NULL;
-}
-
-bool bool_value(AST* val)
-{
-    (void)val;
-    return false;
-}
-
-AST* Ident(char* val)
-{
-    (void)val;
-    return NULL;
-}
-
-char ident_value(AST* val)
-{
-    (void)val;
-    return 0;
-}
-
index 24ded9a0a02459d8bb610dfc817b137b6764d1aa..0e1ebbc7fc1dd3d83ea62b9cee1d31e3060eacbb 100644 (file)
@@ -246,12 +246,14 @@ void* gc_addref(void* ptr)
     hash_entry_t lookup = {0, 0, 0};
     hash_entry_t* entry;
     obj_t* obj = ((obj_t*)ptr-1);
-    obj->refs++;
-    if (obj->refs == 1) {
-        lookup.object = obj;
-        entry = hash_del(&Zero_Count_Table, &lookup);
-        assert(entry != NULL);
-        hash_set(&Multi_Ref_Table, entry);
+    if (ptr != NULL) {
+        obj->refs++;
+        if (obj->refs == 1) {
+            lookup.object = obj;
+            entry = hash_del(&Zero_Count_Table, &lookup);
+            assert(entry != NULL);
+            hash_set(&Multi_Ref_Table, entry);
+        }
     }
     return ptr;
 }
@@ -261,12 +263,14 @@ void gc_delref(void* ptr)
     hash_entry_t lookup = {0, 0, 0};
     hash_entry_t* entry;
     obj_t* obj = ((obj_t*)ptr-1);
-    obj->refs--;
-    if (obj->refs == 0) {
-        lookup.object = obj;
-        entry = hash_del(&Multi_Ref_Table, &lookup);
-        assert(entry != NULL);
-        hash_set(&Zero_Count_Table, entry);
+    if (ptr != NULL) {
+        obj->refs--;
+        if (obj->refs == 0) {
+            lookup.object = obj;
+            entry = hash_del(&Multi_Ref_Table, &lookup);
+            assert(entry != NULL);
+            hash_set(&Zero_Count_Table, entry);
+        }
     }
 }
 
index 3c8d7f2662b6a638b97430ee0e6a0000a18d2e45..41e01fc5687741fae936a96510587c2f6b0d85ee 100644 (file)
@@ -6,6 +6,107 @@
 */
 #include <sclpl.h>
 
+static AST* expression(Parser* p);
+static AST* ident(Parser* p);
+static AST* literal(Parser* p);
+
+AST* toplevel(Parser* p)
+{
+    AST* ret = NULL;
+    if (peek(p)->type != T_END_FILE) {
+        ret = expression(p);
+    }
+    //if (accept_str(p, T_ID, "require"))
+    //    return require(p);
+    //else if (accept_str(p, T_ID, "type"))
+    //    return type_definition(p);
+    //else if (accept_str(p, T_ID, "ann"))
+    //    return type_annotation(p);
+    //else if (accept_str(p, T_ID, "def"))
+    //    return definition(p);
+    //else
+    //    return expression(p);
+    return ret;
+}
+
+static AST* expression(Parser* p)
+{
+    if (peek(p)->type == T_ID) {
+        return ident(p);
+        //if (peek(p)->type == T_LPAR) {
+        //    arglist(p);
+        //}
+    } else {
+        return literal(p);
+    }
+
+    //if (accept(p, T_LPAR)) {
+    //    //size_t mrk = mark(p);
+    //    expression(p);
+    //    expect(p, T_RPAR);
+    //    //reduce(p, mrk);
+    //} else if (accept_str(p, T_ID, "if")) {
+    //    if_stmnt(p);
+    //} else if (accept_str(p, T_ID, "fn")) {
+    //    fn_stmnt(p);
+    //} else if (peek(p)->type == T_ID) {
+    //    expect(p, T_ID);
+    //    if (peek(p)->type == T_LPAR) {
+    //        arglist(p);
+    //    }
+    //} else {
+    //    return literal(p);
+    //}
+}
+
+static AST* ident(Parser* p)
+{
+    Tok* tok = peek(p);
+    expect(p, T_ID);
+    return Ident(tok->value.text);
+}
+
+static AST* literal(Parser* p)
+{
+    AST* ret = NULL;
+    Tok* tok = peek(p);
+    switch (tok->type) {
+        case T_BOOL:
+            ret = Bool(tok->value.boolean);
+            accept(p, tok->type);
+            break;
+
+        case T_CHAR:
+            ret = Char(tok->value.character);
+            accept(p, tok->type);
+            break;
+
+        case T_STRING:
+            ret = String(tok->value.text);
+            accept(p, tok->type);
+            break;
+
+        case T_INT:
+            ret = Integer(tok->value.integer);
+            accept(p, tok->type);
+            break;
+
+        case T_FLOAT:
+            ret = Float(tok->value.floating);
+            accept(p, tok->type);
+            break;
+
+        default:
+            error(p, "Expected a literal");
+    }
+    return ret;
+}
+
+
+
+
+#if 0
+
 static AST* require(Parser* p);
 static AST* type_annotation(Parser* p);
 static AST* type_definition(Parser* p);
@@ -14,29 +115,14 @@ static AST* tuple(Parser* p);
 static AST* function(Parser* p);
 static AST* definition(Parser* p);
 static AST* expression(Parser* p);
-static AST* literal(Parser* p);
 static AST* arglist(Parser* p);
 static AST* if_stmnt(Parser* p);
 static AST* fn_stmnt(Parser* p);
 
-AST* toplevel(Parser* p)
-{
-    if (accept_str(p, T_ID, "require"))
-        return require(p);
-    else if (accept_str(p, T_ID, "type"))
-        return type_definition(p);
-    else if (accept_str(p, T_ID, "ann"))
-        return type_annotation(p);
-    else if (accept_str(p, T_ID, "def"))
-        return definition(p);
-    else
-        return expression(p);
-}
-
 static AST* require(Parser* p)
 {
     //shifttok(p, T_STRING);
-    expect(p, T_END);
+    //expect(p, T_END);
     //reduce(Require);
     return NULL;
 }
@@ -44,8 +130,8 @@ static AST* require(Parser* p)
 static AST* type_annotation(Parser* p)
 {
     //shifttok(p, T_ID);
-    type(p);
-    expect(p, T_END);
+    //type(p);
+    //expect(p, T_END);
     //reduce(Annotation);
     return NULL;
 }
@@ -54,147 +140,109 @@ static AST* type_annotation(Parser* p)
 
 static AST* type_definition(Parser* p)
 {
-    expect(p, T_ID);
-    expect_str(p, T_ID, "is");
-    type(p);
-    expect(p, T_END);
+    //expect(p, T_ID);
+    //expect_str(p, T_ID, "is");
+    //type(p);
+    //expect(p, T_END);
     return NULL;
 }
 
 static AST* type(Parser* p) {
-    if (accept(p, T_LBRACE)) {
-        tuple(p);
-    } else {
-        expect(p, T_ID);
-        if (accept(p, T_LPAR)) {
-            function(p);
-        }
-    }
+    //if (accept(p, T_LBRACE)) {
+    //    tuple(p);
+    //} else {
+    //    expect(p, T_ID);
+    //    if (accept(p, T_LPAR)) {
+    //        function(p);
+    //    }
+    //}
     return NULL;
 }
 
 static AST* tuple(Parser* p) {
-    //size_t mrk = mark(p);
-    //insert(p, T_ID, lexer_dup("tuple"));
-    do {
-        type(p);
-    } while (accept(p, T_COMMA));
-    expect(p, T_RBRACE);
-    //reduce(p, mrk);
+    ////size_t mrk = mark(p);
+    ////insert(p, T_ID, lexer_dup("tuple"));
+    //do {
+    //    type(p);
+    //} while (accept(p, T_COMMA));
+    //expect(p, T_RBRACE);
+    ////reduce(p, mrk);
     return NULL;
 }
 
 static AST* function(Parser* p) {
-    //size_t mark1 = mark(p) - 1;
-    //size_t mark2 = mark(p);
-    while (!accept(p, T_RPAR)) {
-        type(p);
-        if (T_RPAR != peek(p)->type)
-            expect(p, T_COMMA);
-    }
-    //reduce(p, mark2);
-    //reduce(p, mark1);
+    ////size_t mark1 = mark(p) - 1;
+    ////size_t mark2 = mark(p);
+    //while (!accept(p, T_RPAR)) {
+    //    type(p);
+    //    if (T_RPAR != peek(p)->type)
+    //        expect(p, T_COMMA);
+    //}
+    ////reduce(p, mark2);
+    ////reduce(p, mark1);
     return NULL;
 }
 
 static AST* definition(Parser* p)
 {
-    //size_t mrk = mark(p);
-    expect(p,T_ID);
-    if (peek(p)->type == T_LPAR) {
-        //insert(p, T_ID, lexer_dup("fn"));
-        fn_stmnt(p);
-    } else {
-        expression(p);
-        expect(p,T_END);
-    }
-    //reduce(p, mrk);
-    return NULL;
-}
-
-static AST* expression(Parser* p)
-{
-    if (accept(p, T_LPAR)) {
-        //size_t mrk = mark(p);
-        expression(p);
-        expect(p, T_RPAR);
-        //reduce(p, mrk);
-    } else if (accept_str(p, T_ID, "if")) {
-        if_stmnt(p);
-    } else if (accept_str(p, T_ID, "fn")) {
-        fn_stmnt(p);
-    } else if (peek(p)->type == T_ID) {
-        expect(p, T_ID);
-        if (peek(p)->type == T_LPAR) {
-            arglist(p);
-        }
-    } else {
-        literal(p);
-    }
-    return NULL;
-}
-
-static AST* literal(Parser* p)
-{
-    switch (peek(p)->type) {
-        case T_BOOL:
-        case T_CHAR:
-        case T_STRING:
-        case T_INT:
-        case T_FLOAT:
-            accept(p, peek(p)->type);
-            break;
-
-        default:
-            error(p, "Expected a literal");
-    }
+    ////size_t mrk = mark(p);
+    //expect(p,T_ID);
+    //if (peek(p)->type == T_LPAR) {
+    //    //insert(p, T_ID, lexer_dup("fn"));
+    //    fn_stmnt(p);
+    //} else {
+    //    expression(p);
+    //    expect(p,T_END);
+    //}
+    ////reduce(p, mrk);
     return NULL;
 }
 
 static AST* arglist(Parser* p)
 {
-    //size_t mrk = mark(p);
-    expect(p, T_LPAR);
-    while(peek(p)->type != T_RPAR) {
-        expression(p);
-        if(peek(p)->type != T_RPAR)
-            expect(p, T_COMMA);
-    }
-    expect(p, T_RPAR);
-    //reduce(p, mrk);
+    ////size_t mrk = mark(p);
+    //expect(p, T_LPAR);
+    //while(peek(p)->type != T_RPAR) {
+    //    expression(p);
+    //    if(peek(p)->type != T_RPAR)
+    //        expect(p, T_COMMA);
+    //}
+    //expect(p, T_RPAR);
+    ////reduce(p, mrk);
     return NULL;
 }
 
 static AST* if_stmnt(Parser* p)
 {
-    //size_t mrk = mark(p);
-    expression(p);
-    expression(p);
-    if (accept_str(p, T_ID, "else")) {
-        expression(p);
-    }
-    expect(p,T_END);
-    //reduce(p, mrk);
+    ////size_t mrk = mark(p);
+    //expression(p);
+    //expression(p);
+    //if (accept_str(p, T_ID, "else")) {
+    //    expression(p);
+    //}
+    //expect(p,T_END);
+    ////reduce(p, mrk);
     return NULL;
 }
 
 static AST* fn_stmnt(Parser* p)
 {
-    //size_t mark1 = mark(p);
-    expect(p, T_LPAR);
-    //size_t mark2 = mark(p);
-    while(peek(p)->type != T_RPAR) {
-        expect(p, T_ID);
-        if(peek(p)->type != T_RPAR)
-            expect(p, T_COMMA);
-    }
-    expect(p, T_RPAR);
-    //reduce(p, mark2);
-    while(peek(p)->type != T_END) {
-        expression(p);
-    }
-    expect(p, T_END);
-    //reduce(p, mark1);
+    ////size_t mark1 = mark(p);
+    //expect(p, T_LPAR);
+    ////size_t mark2 = mark(p);
+    //while(peek(p)->type != T_RPAR) {
+    //    expect(p, T_ID);
+    //    if(peek(p)->type != T_RPAR)
+    //        expect(p, T_COMMA);
+    //}
+    //expect(p, T_RPAR);
+    ////reduce(p, mark2);
+    //while(peek(p)->type != T_END) {
+    //    expression(p);
+    //}
+    //expect(p, T_END);
+    ////reduce(p, mark1);
     return NULL;
 }
 
+#endif
index 5a53e0d9776fc7f7c50d1bc041872d9131a0a172..1f73bd72fb38737a8a069f727e3edda70200dd4a 100644 (file)
@@ -27,7 +27,7 @@ void print_usage(void) {
 /* Driver Modes
  *****************************************************************************/
 static int emit_tokens(void) {
-    Tok* token;
+    Tok* token = NULL;
     Parser* ctx = parser_new(NULL, stdin);
     while(NULL != (token = gettoken(ctx)))
         pprint_token(stdout, token, true);
@@ -35,6 +35,10 @@ static int emit_tokens(void) {
 }
 
 static int emit_tree(void) {
+    AST* tree = NULL;
+    Parser* ctx = parser_new(NULL, stdin);
+    while(NULL != (tree = toplevel(ctx)))
+        pprint_tree(stdout, tree, 0);
     return 0;
 }
 
index 1875ce7b8bf0f59955fbbe9ec26074122df6a3e3..374948cdcc502413ce40e97108843862cb20fdfe 100644 (file)
@@ -66,18 +66,6 @@ void error(Parser* parser, const char* text)
     exit(1);
 }
 
-Tok* shifttok(Parser* parser, TokType type)
-{
-    Tok* tok = NULL;
-    if (peek(parser)->type == type) {
-        //vec_push_back(parser->stack, parser->tok);
-        parser->tok = NULL;
-    } else {
-        error(parser, "Unexpected token");
-    }
-    return tok;
-}
-
 bool accept(Parser* parser, TokType type)
 {
     bool ret = false;
index 32718ecede9f9536a2f928bdd4f3214e8781f0cd..eb560e5c36ff952a0101276a398b3779a3afe4f0 100644 (file)
@@ -6,12 +6,10 @@
   */
 #include <sclpl.h>
 
-#if 0
 static void print_indent(FILE* file, int depth) {
     for(int i = 0; i < (2 * depth); i++)
         fprintf(file, "%c", ' ');
 }
-#endif
 
 static const char* token_type_to_string(TokType type) {
     switch(type) {
@@ -84,20 +82,51 @@ void pprint_token(FILE* file, Tok* token, bool print_loc)
     fprintf(file, "\n");
 }
 
+/*****************************************************************************/
 
-//void pprint_tree(FILE* file, AST* tree, int depth)
-//{
-//    print_indent(file, depth);
-//    if (tree->tag == ATOM) {
-//        pprint_token(file, tree->ptr.tok, false);
-//    } else {
-//        fputs("(tree", file);
-//        vec_t* p_vec = tree->ptr.vec;
-//        for(size_t idx = 0; idx < vec_size(p_vec); idx++) {
-//            pprint_tree(file, (AST*)vec_at(p_vec, idx), depth+1);
-//        }
-//        print_indent(file, depth);
-//        fputs(")\n", file);
-//    }
-//}
+static const char* tree_type_to_string(ASTType type) {
+    switch(type) {
+        case AST_STRING: return "T_STRING";
+        case AST_SYMBOL: return "T_SYMBOL";
+        case AST_IDENT:  return "T_IDENT";
+        case AST_CHAR:   return "T_CHAR";
+        case AST_INT:    return "T_INT";
+        case AST_FLOAT:  return "T_FLOAT";
+        case AST_BOOL:   return "T_BOOL";
+        default:         return "???";
+    }
+}
+
+static void pprint_literal(FILE* file, AST* tree, int depth)
+{
+    printf("%s:", tree_type_to_string(tree->type));
+    switch(tree->type) {
+        case AST_STRING: printf("\"%s\"", string_value(tree)); break;
+        case AST_SYMBOL: printf("%s", symbol_value(tree));     break;
+        case AST_IDENT:  printf("%s", ident_value(tree));      break;
+        case AST_CHAR:   printf("%c", char_value(tree));       break;
+        case AST_INT:    printf("%ld", integer_value(tree));   break;
+        case AST_FLOAT:  printf("%lf", float_value(tree));     break;
+        case AST_BOOL:
+            printf("%s", bool_value(tree) ? "true" : "false");
+            break;
+        default: printf("???");
+    }
+}
+
+void pprint_tree(FILE* file, AST* tree, int depth)
+{
+    print_indent(file, depth);
+    if (tree->type <= AST_IDENT) {
+        pprint_literal(file, tree, depth);
+    } else {
+        //fputs("(tree", file);
+        //vec_t* p_vec = tree->ptr.vec;
+        //for(size_t idx = 0; idx < vec_size(p_vec); idx++) {
+        //    pprint_tree(file, (AST*)vec_at(p_vec, idx), depth+1);
+        //}
+        //print_indent(file, depth);
+        //fputs(")\n", file);
+    }
+}
 
index 9ce9ff0fa52a2140a1b7e0b3ccef6d8b6acd4576..d7b51353bb66a4f0fb39ddd7505e9a4712ff54d0 100644 (file)
@@ -33,8 +33,10 @@ extern int user_main(int argc, char** argv);
 /* Token Types
  *****************************************************************************/
 typedef enum {
-    T_ID, T_CHAR, T_INT, T_FLOAT, T_BOOL, T_STRING, T_LBRACE, T_RBRACE, T_LBRACK,
-    T_RBRACK, T_LPAR, T_RPAR, T_COMMA, T_SQUOTE, T_DQUOTE, T_END, T_END_FILE
+    T_ID, T_CHAR, T_INT, T_FLOAT, T_BOOL, T_STRING,
+    T_LBRACE, T_RBRACE, T_LBRACK,
+    T_RBRACK, T_LPAR, T_RPAR, T_COMMA, T_SQUOTE, T_DQUOTE, T_END,
+    T_END_FILE
 } TokType;
 
 typedef struct {
@@ -54,8 +56,8 @@ typedef struct {
 /* AST Types
  *****************************************************************************/
 typedef enum ASTType {
-    AST_REQ, AST_DEF, AST_ANN, AST_IF, AST_FUNC, AST_STRING, AST_SYMBOL,
-    AST_CHAR, AST_INT, AST_FLOAT, AST_BOOL, AST_IDENT
+    AST_STRING = 0, AST_SYMBOL, AST_CHAR, AST_INT, AST_FLOAT, AST_BOOL, AST_IDENT,
+    AST_REQ, AST_DEF, AST_ANN, AST_IF, AST_FUNC,
 } ASTType;
 
 typedef struct AST {
@@ -86,56 +88,19 @@ typedef struct AST {
             struct AST* args;
             struct AST* body;
         } func;
-        /* Code Block */
-        //vec_t block;
-        /* String */
-        char* stringval;
-        /* Symbol */
-        char* symbolval;
+        /* String, Symbol, Identifier */
+        char* text;
         /* Character */
-        uint32_t charval;
+        uint32_t character;
         /* Integer */
-        intptr_t intval;
+        intptr_t integer;
         /* Float */
-        double floatval;
+        double floating;
         /* Bool */
-        bool boolval;
-        /* Ident */
-        char* idval;
-    } data;
+        bool boolean;
+    } value;
 } AST;
 
-/* Require */
-AST* Require(char* name);
-char* require_name(AST* req);
-
-/* Definition */
-AST* Def(char* name, AST* value);
-char* def_name(AST* def);
-AST* def_value(AST* def);
-
-/* Annotation */
-AST* Ann(char* name, AST* value);
-char* ann_name(AST* def);
-AST* ann_value(AST* def);
-
-/* If Expression */
-AST* IfExpr(AST* cond, AST* bthen, AST* belse);
-AST* ifexpr_condition(AST* ifexpr);
-AST* ifexpr_branch_then(AST* ifexpr);
-AST* ifexpr_branch_else(AST* ifexpr);
-
-/* Function */
-AST* Func(AST* args, AST* body);
-AST* func_args(AST* func);
-AST* func_body(AST* func);
-
-/* Code Block */
-AST* Block(void);
-void block_append(AST* expr);
-size_t block_size(AST* block);
-AST* block_get(size_t index);
-
 /* String */
 AST* String(char* val);
 char* string_value(AST* val);
@@ -162,8 +127,45 @@ bool bool_value(AST* val);
 
 /* Ident */
 AST* Ident(char* val);
-char ident_value(AST* val);
-
+char* ident_value(AST* val);
+
+
+
+
+
+
+
+///* Require */
+//AST* Require(char* name);
+//char* require_name(AST* req);
+//
+///* Definition */
+//AST* Def(char* name, AST* value);
+//char* def_name(AST* def);
+//AST* def_value(AST* def);
+//
+///* Annotation */
+//AST* Ann(char* name, AST* value);
+//char* ann_name(AST* def);
+//AST* ann_value(AST* def);
+//
+///* If Expression */
+//AST* IfExpr(AST* cond, AST* bthen, AST* belse);
+//AST* ifexpr_condition(AST* ifexpr);
+//AST* ifexpr_branch_then(AST* ifexpr);
+//AST* ifexpr_branch_else(AST* ifexpr);
+//
+///* Function */
+//AST* Func(AST* args, AST* body);
+//AST* func_args(AST* func);
+//AST* func_body(AST* func);
+//
+///* Code Block */
+//AST* Block(void);
+//void block_append(AST* expr);
+//size_t block_size(AST* block);
+//AST* block_get(size_t index);
+//
 /* Lexer and Parser Types
  *****************************************************************************/
 typedef struct {
@@ -199,6 +201,6 @@ AST* toplevel(Parser* p);
 void pprint_token_type(FILE* file, Tok* token);
 void pprint_token_value(FILE* file, Tok* token);
 void pprint_token(FILE* file, Tok* token, bool print_loc);
-//void pprint_tree(FILE* file, AST* tree, int depth);
+void pprint_tree(FILE* file, AST* tree, int depth);
 
 #endif /* SCLPL_H */
index ac424b1f96a55b56cf131df9b7eb1e9b11858efd..8b4f9470074c103a471d392a63ec596086bdc19e 100644 (file)
@@ -1,6 +1,32 @@
 require 'open3'
 
-#describe "sclpl grammar" do
+describe "sclpl grammar" do
+  context "literals" do
+    it "should parse a string" do
+      expect(ast('"foo"')).to eq(['T_STRING:"foo"'])
+    end
+
+    it "should parse a character" do
+      expect(ast('\\c')).to eq(['T_CHAR:c'])
+    end
+
+    it "should parse an integer" do
+      expect(ast('123')).to eq(['T_INT:123'])
+    end
+
+    it "should parse a float" do
+      expect(ast('123.0')).to eq(['T_FLOAT:123.000000'])
+    end
+
+    it "should parse boolean" do
+      expect(ast('true')).to eq(['T_BOOL:true'])
+    end
+
+    it "should parse an identifier" do
+      expect(ast('foo')).to eq(['T_IDENT:foo'])
+    end
+  end
+
 #  context "requires" do
 #    it "should parse a require statement" do
 #      expect(ast('require "foo";')).to eq([ ['T_ID:require', 'T_STRING:"foo"'] ])
@@ -188,32 +214,6 @@ require 'open3'
 #    end
 #  end
 #
-#  context "literals" do
-#    it "should parse a string" do
-#      expect(ast('"foo"')).to eq(['T_STRING:"foo"'])
-#    end
-#
-#    it "should parse a character" do
-#      expect(ast('\\c')).to eq(['T_CHAR:\\c'])
-#    end
-#
-#    it "should parse an integer" do
-#      expect(ast('123')).to eq(['T_INT:123'])
-#    end
-#
-#    it "should parse a float" do
-#      expect(ast('123.0')).to eq(['T_FLOAT:123.000000'])
-#    end
-#
-#    it "should parse boolean" do
-#      expect(ast('true')).to eq(['T_BOOL:true'])
-#    end
-#
-#    it "should parse an identifier" do
-#      expect(ast('foo')).to eq(['T_ID:foo'])
-#    end
-#  end
-#
 #  context "corner cases" do
 #    it "an unexpected terminator should error" do
 #      expect{ast(';')}.to raise_error /Error/
@@ -223,4 +223,4 @@ require 'open3'
 #      expect{ast('\'')}.to raise_error /Error/
 #    end
 #  end
-#end
+end