]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
Added grammar rule for if statements with optional else branch and optional then...
authorMike D. Lowis <mike.lowis@gentex.com>
Wed, 14 Oct 2015 18:33:50 +0000 (14:33 -0400)
committerMike D. Lowis <mike.lowis@gentex.com>
Wed, 14 Oct 2015 18:33:50 +0000 (14:33 -0400)
build.rb
source/ast.c
source/grammar.c
source/main.c
source/pprint.c
source/sclpl.h
spec/parser_spec.rb

index 1863c86be4250c63223c0f660069f4b0d00d1f2c..9f4095dea2388f1c737343033665c64c2fb4d0ae 100755 (executable)
--- a/build.rb
+++ b/build.rb
@@ -14,7 +14,7 @@ base_env = BuildEnv.new do |env|
   env.build_dir('source','build/obj/source')
   env.build_dir('modules','build/obj/modules')
   # Compiler options
-  env["CFLAGS"] += ['-g', '-DLEAK_DETECT_LEVEL=1', '--std=c99', '-Wall', '-Wextra']#, '-Werror']
+  env["CFLAGS"] += ['-DLEAK_DETECT_LEVEL=1', '--std=c99', '-Wall', '-Wextra']#, '-Werror']
   env["CPPPATH"] += Dir['modules/libcds/source/**/'] + [
     'modules/libopts/source',
     'source/',
index 45120d7dfabc992f4a2db4031fdd70a88cc41c54..3f92fff924f40ff07d70a5071681d32749d97d0d 100644 (file)
@@ -203,7 +203,7 @@ AST* ifexpr_then(AST* ifexpr)
 
 void ifexpr_set_then(AST* ifexpr, AST* bthen)
 {
-    ifexpr->value.ifexpr.cond = (AST*)gc_addref(bthen);
+    ifexpr->value.ifexpr.bthen = (AST*)gc_addref(bthen);
 }
 
 AST* ifexpr_else(AST* ifexpr)
@@ -213,26 +213,29 @@ AST* ifexpr_else(AST* ifexpr)
 
 void ifexpr_set_else(AST* ifexpr, AST* belse)
 {
-    ifexpr->value.ifexpr.cond = (AST*)gc_addref(belse);
+    ifexpr->value.ifexpr.belse = (AST*)gc_addref(belse);
 }
 
 AST* Block(void)
 {
-    return ast(AST_BLOCK);
+    AST* node = ast(AST_BLOCK);
+    vec_init(&(node->value.exprs));
+    return node;
 }
 
 void block_append(AST* block, AST* expr)
 {
+    vec_push_back(&(block->value.exprs), expr);
 }
 
 size_t block_size(AST* block)
 {
-    return 0;
+    return vec_size(&(block->value.exprs));
 }
 
 AST* block_get(AST* block, size_t index)
 {
-    return NULL;
+    return (AST*)vec_at(&(block->value.exprs), index);
 }
 
 
@@ -258,32 +261,6 @@ AST* block_get(AST* block, size_t index)
 //    return NULL;
 //}
 //
-//AST* IfExpr(AST* cond, AST* bthen, AST* belse)
-//{
-//    (void)cond;
-//    (void)bthen;
-//    (void)belse;
-//    return NULL;
-//}
-//
-//AST* ifexpr_condition(AST* ifexpr)
-//{
-//    (void)ifexpr;
-//    return NULL;
-//}
-//
-//AST* ifexpr_branch_then(AST* ifexpr)
-//{
-//    (void)ifexpr;
-//    return NULL;
-//}
-//
-//AST* ifexpr_branch_else(AST* ifexpr)
-//{
-//    (void)ifexpr;
-//    return NULL;
-//}
-//
 //AST* Func(AST* args, AST* body)
 //{
 //    (void)args;
index 83acff6d591af6141ddd0d2d005d64a162c85dc0..1025e597f260421f06a23d10a9cc2a184da6d8dc 100644 (file)
@@ -55,13 +55,13 @@ static AST* require(Parser* p)
 
 static AST* expression(Parser* p)
 {
-    if (match(p, T_ID)) {
+    if (accept_str(p, T_ID, "if")) {
+        return if_stmnt(p);
+    } else if (match(p, T_ID)) {
         return Ident(expect(p,T_ID));
         //if (peek(p)->type == T_LPAR) {
         //    arglist(p);
         //}
-    } else if (accept_str(p, T_ID, "if")) {
-        return if_stmnt(p);
     } else {
         return literal(p);
     }
@@ -84,6 +84,7 @@ static AST* if_stmnt(Parser* p)
 {
     AST* ifexpr = IfExpr();
     ifexpr_set_cond( ifexpr, expression(p) );
+    accept_str(p, T_ID, "then");
     ifexpr_set_then( ifexpr, expr_block(p) );
     if (accept_str(p, T_ID, "else"))
         ifexpr_set_else( ifexpr, expr_block(p) );
index 19e945f5edf6b9f54eeaf7a193d2e91eafebe17f..b6c5ad701633672c49fcfc64b1bf542210e65daa 100644 (file)
@@ -100,3 +100,4 @@ int user_main(int argc, char **argv) {
     }
     return 1;
 }
+
index 77cff04d6312e50ed6d1b5abd47452a8ebdf12a8..53fcad2f2ae83407c30c86db48009e0ad5f4325f 100644 (file)
@@ -116,23 +116,48 @@ static void pprint_literal(FILE* file, AST* tree, int depth)
 
 void pprint_tree(FILE* file, AST* tree, int depth)
 {
+    if (tree == NULL)
+        return;
     print_indent(file, depth);
-    if (tree->type <= AST_IDENT) {
-        pprint_literal(file, tree, depth);
-    } else if (tree->type == AST_REQ) {
-        printf("(require \"%s\")", require_name(tree));
-    } else if (tree->type == AST_DEF) {
-        printf("(def %s ", def_name(tree));
-        pprint_tree(file, def_value(tree), depth);
-        printf(")");
-    } 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);
+    switch (tree->type) {
+        case AST_REQ:
+            printf("(require \"%s\")", require_name(tree));
+            break;
+
+        case AST_DEF:
+            printf("(def %s ", def_name(tree));
+            pprint_tree(file, def_value(tree), depth);
+            printf(")");
+            break;
+
+        case AST_IF:
+            printf("(if ");
+            pprint_tree(file, ifexpr_cond(tree), depth);
+            printf(" ");
+            pprint_tree(file, ifexpr_then(tree), depth);
+            printf(" ");
+            pprint_tree(file, ifexpr_else(tree), depth);
+            printf(")");
+            break;
+
+        case AST_BLOCK:
+            printf("(block ");
+            for (size_t i = 0; i < block_size(tree); i++) {
+                printf(" ");
+                pprint_tree(file, block_get(tree, i), depth);
+            }
+            printf(")");
+            break;
+
+        case AST_ANN:
+            break;
+
+        case AST_FUNC:
+            break;
+
+        default:
+            pprint_literal(file, tree, depth);
+            break;
     }
 }
 
index b13c4c1d6d324bfca4580c0e1c8f8219de3b41ac..e44782f61c22545b662840f90a091bf9bcd308fd 100644 (file)
@@ -104,6 +104,8 @@ typedef struct AST {
             struct AST* args;
             struct AST* body;
         } func;
+        /* Code Block */
+        vec_t exprs;
         /* String, Symbol, Identifier */
         char* text;
         /* Character */
index 4cc18eb1799a809f7acae58945fbd71833fae211..eb01dcfd2b2b88d879632a1e1f044e8b6fb99def 100644 (file)
@@ -52,6 +52,24 @@ describe "sclpl grammar" do
       expect{ast('require foo bar;')}.to raise_error /Error/
     end
   end
+
+  context "if statements" do
+    it "should parse an if statement with no else clause" do
+      expect(ast('if 123 321 end')).to eq([
+        ["if", "T_INT:123", ["block", "T_INT:321"]]])
+    end
+
+    it "should parse an if statement with an optional then keyword" do
+      expect(ast('if 123 then 321 end')).to eq([
+        ["if", "T_INT:123", ["block", "T_INT:321"]]])
+    end
+
+    it "should parse an if statement with an else clause " do
+      expect(ast('if 123 321 else 456 end')).to eq([
+        ["if", "T_INT:123", ["block", "T_INT:321"], ["block", "T_INT:456"]]])
+    end
+  end
+#
 #
 #  context "type definitions" do
 #    it "should parse a simple type definition" do
@@ -174,17 +192,6 @@ describe "sclpl grammar" do
 #      end
 #    end
 #
-#    context "if statements" do
-#      it "should parse an if statement with no else clause" do
-#        expect(ast('if 123 321 end')).to eq([["T_ID:if", "T_INT:123", "T_INT:321"]])
-#      end
-#
-#      it "should parse an if statement with an else clause " do
-#        expect(ast('if 123 321 else 456 end')).to eq([
-#          ["T_ID:if", "T_INT:123", "T_INT:321", "T_ID:else", "T_INT:456"]])
-#      end
-#    end
-#
 #    context "function literals" do
 #      it "should parse a function with no params" do
 #        expect(ast('fn() 123;')).to eq([["T_ID:fn", [], "T_INT:123"]])