]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
Completed function literal parsing
authorMichael D. Lowis <mike@mdlowis.com>
Sun, 13 Dec 2015 03:41:40 +0000 (22:41 -0500)
committerMichael D. Lowis <mike@mdlowis.com>
Sun, 13 Dec 2015 03:41:40 +0000 (22:41 -0500)
source/ast.c
source/grammar.c
source/pprint.c
source/sclpl.h
spec/parser_spec.rb

index 2497c9130605966b2fd78a0ffcd52185928418a3..c7f696431466e3d327e5f348b7c22c30bfc4a0fd 100644 (file)
@@ -30,7 +30,7 @@ static void ast_free(void* ptr)
             break;
 
         case AST_FUNC:
-            gc_delref(ast->value.func.args);
+            //vec_deinit(&(ast->value.func.args));
             gc_delref(ast->value.func.body);
             break;
 
@@ -238,17 +238,17 @@ AST* block_get(AST* block, size_t index)
     return (AST*)vec_at(&(block->value.exprs), index);
 }
 
-AST* Func(AST* args, AST* body)
+AST* Func(void)
 {
     AST* node = ast(AST_FUNC);
-    node->value.func.args = args;
-    node->value.func.body = body;
+    vec_init(&(node->value.func.args));
+    node->value.func.body = NULL;
     return node;
 }
 
-AST* func_args(AST* func)
+vec_t* func_args(AST* func)
 {
-    return func->value.func.args;
+    return &(func->value.func.args);
 }
 
 AST* func_body(AST* func)
@@ -256,6 +256,17 @@ AST* func_body(AST* func)
     return func->value.func.body;
 }
 
+void func_add_arg(AST* func, AST* arg)
+{
+    vec_push_back(func_args(func), arg);
+}
+
+void func_set_body(AST* func, AST* body)
+{
+    func->value.func.body = body;
+}
+
+
 //AST* Ann(char* name, AST* value)
 //{
 //    (void)name;
index f70a25cb93a66cfe22bbac81a086493437b4ddf1..49aa0845b0694eb245945e9a5a38d9ab22b502b4 100644 (file)
@@ -21,9 +21,9 @@ AST* toplevel(Parser* p)
     if (!match(p, T_END_FILE)) {
         if (accept_str(p, T_ID, "require"))
             ret = require(p);
-        else if (accept_str(p, T_ID, "def")) {
+        else if (accept_str(p, T_ID, "def"))
             ret = definition(p);
-        else
+        else
             ret = expression(p);
     }
     //printf("%p\n", ret);
@@ -49,15 +49,13 @@ static AST* definition(Parser* p)
 
 static AST* require(Parser* p)
 {
-    Tok* tok = expect(p, T_STRING);
-    AST* ast = Require(tok);
+    AST* ast = Require(expect(p, T_STRING));
     expect(p, T_END);
     return ast;
 }
 
 static AST* expression(Parser* p)
 {
-
     if (accept(p, T_LPAR)) {
         AST* expr = expression(p);
         expect(p, T_RPAR);
@@ -74,7 +72,6 @@ static AST* expression(Parser* p)
     } else {
         return literal(p);
     }
-
 }
 
 static AST* if_stmnt(Parser* p)
@@ -91,16 +88,17 @@ static AST* if_stmnt(Parser* p)
 
 static AST* function(Parser* p)
 {
+    AST* func = Func();
     expect(p, T_LPAR);
-    //while(peek(p)->type != T_RPAR) {
-    //    expect(p, T_ID);
-    //    if(peek(p)->type != T_RPAR)
-    //        expect(p, T_COMMA);
-    //}
+    while(peek(p)->type != T_RPAR) {
+        func_add_arg(func, Ident(expect(p,T_ID)));
+        if(peek(p)->type != T_RPAR)
+            expect(p, T_COMMA);
+    }
     expect(p, T_RPAR);
-    AST* body = expr_block(p);
+    func_set_body(func, expr_block(p));
     expect(p, T_END);
-    return Func(NULL,body);
+    return func;
 }
 
 static AST* literal(Parser* p)
index 52721e3a12de1129b60751b9ba20a7749c8759eb..9b49226fbf4031358e969865b4a1c9ba9e81de71 100644 (file)
@@ -88,7 +88,7 @@ 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_IDENT:  return "T_ID";
         case AST_CHAR:   return "T_CHAR";
         case AST_INT:    return "T_INT";
         case AST_FLOAT:  return "T_FLOAT";
@@ -153,7 +153,12 @@ void pprint_tree(FILE* file, AST* tree, int depth)
             break;
 
         case AST_FUNC:
-            printf("(fn ()");
+            printf("(fn (");
+            for (size_t i = 0; i < vec_size(func_args(tree)); i++) {
+                printf(" ");
+                pprint_literal(file, vec_at(func_args(tree), i), depth);
+            }
+            printf(")");
             for (size_t i = 0; i < block_size(func_body(tree)); i++) {
                 printf(" ");
                 pprint_tree(file, block_get(func_body(tree), i), depth);
index 14a5700320753b029c5b1c8dd5239cebc557c715..ceb023a44f65e314d6586b12d2ae305cab575e2a 100644 (file)
@@ -101,7 +101,7 @@ typedef struct AST {
         } ifexpr;
         /* Function */
         struct {
-            struct AST* args;
+            vec_t args;
             struct AST* body;
         } func;
         /* Code Block */
@@ -172,9 +172,13 @@ size_t block_size(AST* block);
 AST* block_get(AST* block, size_t index);
 
 /* Function */
-AST* Func(AST* args, AST* body);
-AST* func_args(AST* func);
+AST* Func(void);
+vec_t* func_args(AST* func);
 AST* func_body(AST* func);
+void func_add_arg(AST* func, AST* arg);
+void func_set_body(AST* func, AST* body);
+
+
 
 ///* Annotation */
 //AST* Ann(char* name, AST* value);
index 545e4c61767e494c619375385d848bbca12dbb85..9f25e4f3e32e16b6f116b67ac2474be1e933128e 100644 (file)
@@ -23,7 +23,7 @@ describe "sclpl grammar" do
     end
 
     it "should parse an identifier" do
-      expect(ast('foo')).to eq(['T_IDENT:foo'])
+      expect(ast('foo')).to eq(['T_ID:foo'])
     end
   end
 
@@ -143,23 +143,23 @@ describe "sclpl grammar" do
       expect(ast('def foo() 123 321;')).to eq([
         ['def', 'foo', ['fn', [], 'T_INT:123', 'T_INT:321']] ])
     end
-#
-#    it "should parse a function definition with one argument" do
-#      expect(ast('def foo(a) 123;')).to eq([
-#        ['T_ID:def', 'T_ID:foo', ['T_ID:fn', ['T_ID:a'], 'T_INT:123']] ])
-#    end
-#
-#    it "should parse a function definition with two arguments" do
-#      expect(ast('def foo(a,b) 123;')).to eq([
-#        ['T_ID:def', 'T_ID:foo', ['T_ID:fn', ['T_ID:a', 'T_ID:b'], 'T_INT:123']] ])
-#    end
-#
-#    it "should parse a function definition with three arguments" do
-#      expect(ast('def foo(a,b,c) 123;')).to eq([
-#        ['T_ID:def', 'T_ID:foo', ['T_ID:fn', ['T_ID:a', 'T_ID:b', 'T_ID:c'], 'T_INT:123']] ])
-#    end
+
+    it "should parse a function definition with one argument" do
+      expect(ast('def foo(a) 123;')).to eq([
+        ['def', 'foo', ['fn', ['T_ID:a'], 'T_INT:123']] ])
+    end
+
+    it "should parse a function definition with two arguments" do
+      expect(ast('def foo(a,b) 123;')).to eq([
+        ['def', 'foo', ['fn', ['T_ID:a', 'T_ID:b'], 'T_INT:123']] ])
+    end
+
+    it "should parse a function definition with three arguments" do
+      expect(ast('def foo(a,b,c) 123;')).to eq([
+        ['def', 'foo', ['fn', ['T_ID:a', 'T_ID:b', 'T_ID:c'], 'T_INT:123']] ])
+    end
   end
-#
+
 #  context "annotations" do
 #    it "should parse a type annotation for a simple type" do
 #      expect(ast('ann foo int;')).to eq([ ['T_ID:ann', 'T_ID:foo', 'T_ID:int'] ])
@@ -195,16 +195,16 @@ describe "sclpl grammar" do
       it "should parse a function with no params" do
         expect(ast('fn() 123;')).to eq([["fn", [], "T_INT:123"]])
       end
-#
-#      it "should parse a function with one param" do
-#        expect(ast('fn(a) 123;')).to eq([["T_ID:fn", ["T_ID:a"], "T_INT:123"]])
-#      end
-#
-#      it "should parse a function with two params" do
-#        expect(ast('fn(a,b) 123;')).to eq([["T_ID:fn", ["T_ID:a", "T_ID:b"], "T_INT:123"]])
-#      end
+
+      it "should parse a function with one param" do
+        expect(ast('fn(a) 123;')).to eq([["fn", ["T_ID:a"], "T_INT:123"]])
+      end
+
+      it "should parse a function with two params" do
+        expect(ast('fn(a,b) 123;')).to eq([["fn", ["T_ID:a", "T_ID:b"], "T_INT:123"]])
+      end
     end
-#
+
 #    context "function application" do
 #      it "should parse an application with no params " do
 #        expect(ast('foo()')).to eq([["T_ID:foo"]])