]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
Started adding function application to the parser
authorMichael D. Lowis <mike@mdlowis.com>
Tue, 15 Dec 2015 03:54:37 +0000 (22:54 -0500)
committerMichael D. Lowis <mike@mdlowis.com>
Tue, 15 Dec 2015 03:54:37 +0000 (22:54 -0500)
Makefile
source/ast.c
source/grammar.c
source/sclpl.h
spec/parser_spec.rb

index a6495c61a66c9443c9b3119055016d5a26e43371..281ffbad3a6a509ab77127d0803d04f1f975626d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,7 @@ LD = ${CC}
 # flags
 INCS      = -Isource/
 CPPFLAGS  = -D_XOPEN_SOURCE=700
-CFLAGS   += ${INCS} ${CPPFLAGS} -Wall -Wextra
+CFLAGS   += ${INCS} ${CPPFLAGS}
 LDFLAGS  += ${LIBS}
 
 #------------------------------------------------------------------------------
index 6eb8f66e6ec9ba91802798241186cb49de5b4af8..3332931d3d4d0f28336e7c82fd52b118141fa4d1 100644 (file)
@@ -30,7 +30,7 @@ static void ast_free(void* ptr)
             break;
 
         case AST_FUNC:
-            //vec_deinit(&(ast->value.func.args));
+            vec_deinit(&(ast->value.func.args));
             gc_delref(ast->value.func.body);
             break;
 
@@ -266,6 +266,19 @@ void func_set_body(AST* func, AST* body)
     func->value.func.body = (AST*)gc_addref(body);
 }
 
+AST* FnApp(AST* fn)
+{
+    AST* node = ast(AST_FNAPP);
+    node->value.fnapp.fn = (AST*)gc_addref(fn);
+    vec_init(&(node->value.fnapp.args));
+    return node;
+}
+
+void fnapp_add_arg(AST* func, AST* arg)
+{
+    vec_push_back(&(func->value.fnapp.args), gc_addref(arg));
+}
+
 
 //AST* Ann(char* name, AST* value)
 //{
index 49aa0845b0694eb245945e9a5a38d9ab22b502b4..aef5ce21e19076602392219107fb351c28eac6d1 100644 (file)
@@ -14,6 +14,7 @@ static AST* function(Parser* p);
 static AST* literal(Parser* p);
 static AST* expr_block(Parser* p);
 static AST* token_to_tree(Tok* tok);
+static AST* func_app(Parser* p, AST* fn);
 
 AST* toplevel(Parser* p)
 {
@@ -56,22 +57,24 @@ static AST* require(Parser* p)
 
 static AST* expression(Parser* p)
 {
+    AST* expr = NULL;
     if (accept(p, T_LPAR)) {
-        AST* expr = expression(p);
+        expr = expression(p);
         expect(p, T_RPAR);
-        return expr;
     } else if (accept_str(p, T_ID, "if")) {
-        return if_stmnt(p);
+        expr = if_stmnt(p);
     } else if (accept_str(p, T_ID, "fn")) {
-        return function(p);
+        expr = function(p);
     } else if (match(p, T_ID)) {
-        return Ident(expect(p,T_ID));
-        //if (peek(p)->type == T_LPAR) {
-        //    arglist(p);
-        //}
+        expr = Ident(expect(p,T_ID));
     } else {
-        return literal(p);
+        expr = literal(p);
     }
+    /* Check if this is a function application */
+    if (peek(p)->type == T_LPAR) {
+        expr = func_app(p, expr);
+    }
+    return expr;
 }
 
 static AST* if_stmnt(Parser* p)
@@ -141,24 +144,21 @@ static AST* token_to_tree(Tok* tok)
     }
 }
 
-
+static AST* func_app(Parser* p, AST* fn)
+{
+    AST* app = FnApp(fn);
+    expect(p,T_LPAR);
+    while (peek(p)->type != T_RPAR) {
+        fnapp_add_arg(p, expression(p));
+        if (peek(p)->type != T_RPAR)
+            expect(p, T_COMMA);
+    }
+    expect(p,T_RPAR);
+    return app;
+}
 
 
 #if 0
-
-static AST* require(Parser* p);
-static AST* type_annotation(Parser* p);
-static AST* type_definition(Parser* p);
-static AST* type(Parser* p);
-static AST* tuple(Parser* p);
-static AST* function(Parser* p);
-static AST* definition(Parser* p);
-static AST* expression(Parser* p);
-static AST* arglist(Parser* p);
-static AST* if_stmnt(Parser* p);
-static AST* fn_stmnt(Parser* p);
-
-
 static AST* type_annotation(Parser* p)
 {
     //shifttok(p, T_ID);
@@ -168,8 +168,6 @@ static AST* type_annotation(Parser* p)
     return NULL;
 }
 
-/*****************************************************************************/
-
 static AST* type_definition(Parser* p)
 {
     //expect(p, T_ID);
@@ -201,34 +199,4 @@ static AST* tuple(Parser* p) {
     ////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);
-    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);
-    return NULL;
-}
-
-
-
 #endif
index ceb023a44f65e314d6586b12d2ae305cab575e2a..b031129b7e2750af1f8a86c1f4bdadb4bd70c1a7 100644 (file)
@@ -73,7 +73,7 @@ typedef struct {
  *****************************************************************************/
 typedef enum ASTType {
     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, AST_BLOCK
+    AST_REQ, AST_DEF, AST_ANN, AST_IF, AST_FUNC, AST_FNAPP, AST_BLOCK
 } ASTType;
 
 typedef struct AST {
@@ -104,6 +104,11 @@ typedef struct AST {
             vec_t args;
             struct AST* body;
         } func;
+        /* Function Application */
+        struct {
+            struct AST* fn;
+            vec_t args;
+        } fnapp;
         /* Code Block */
         vec_t exprs;
         /* String, Symbol, Identifier */
@@ -178,16 +183,17 @@ AST* func_body(AST* func);
 void func_add_arg(AST* func, AST* arg);
 void func_set_body(AST* func, AST* body);
 
+/* Function Application */
+AST* FnApp(AST* fn);
+void fnapp_add_arg(AST* func, AST* arg);
+
 
 
 ///* Annotation */
 //AST* Ann(char* name, AST* value);
 //char* ann_name(AST* def);
 //AST* ann_value(AST* def);
-//
-//
-//
-//
+
 /* Lexer and Parser Types
  *****************************************************************************/
 typedef struct {
index 9f25e4f3e32e16b6f116b67ac2474be1e933128e..49ec1744c827805643cc7779ea824d9a2bc4e1c9 100644 (file)
@@ -205,19 +205,19 @@ describe "sclpl grammar" do
       end
     end
 
-#    context "function application" do
-#      it "should parse an application with no params " do
-#        expect(ast('foo()')).to eq([["T_ID:foo"]])
-#      end
-#
-#      it "should parse an application with one param" do
-#        expect(ast('foo(a)')).to eq([["T_ID:foo", "T_ID:a"]])
-#      end
-#
-#      it "should parse an application with two params" do
-#        expect(ast('foo(a,b)')).to eq([["T_ID:foo", "T_ID:a", "T_ID:b"]])
-#      end
-#    end
+    context "function application" do
+      it "should parse an application with no params " do
+        expect(ast('foo()')).to eq([["T_ID:foo"]])
+      end
+
+      it "should parse an application with one param" do
+        expect(ast('foo(a)')).to eq([["T_ID:foo", "T_ID:a"]])
+      end
+
+      it "should parse an application with two params" do
+        expect(ast('foo(a,b)')).to eq([["T_ID:foo", "T_ID:a", "T_ID:b"]])
+      end
+    end
   end
 
   context "corner cases" do