]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
implemented grammar rule for sclpl
authorMike D. Lowis <mike.lowis@gentex.com>
Mon, 12 Oct 2015 20:41:18 +0000 (16:41 -0400)
committerMike D. Lowis <mike.lowis@gentex.com>
Mon, 12 Oct 2015 20:41:18 +0000 (16:41 -0400)
source/ast.c
source/grammar.c
source/pprint.c
source/sclpl.h
spec/parser_spec.rb

index 71aeeb6af5e80945c7c2edd3b107aabe74e47e2a..aa289044570173c42ae479858cf116b355537033 100644 (file)
@@ -103,7 +103,18 @@ char* ident_value(AST* val)
     return val->value.text;
 }
 
+AST* Require(char* name)
+{
+    AST* node = ast(AST_REQ);
+    node->value.text = name;
+    return node;
+}
 
+char* require_name(AST* req)
+{
+    assert(req->type == AST_REQ);
+    return req->value.text;
+}
 
 
 
@@ -126,17 +137,7 @@ char* ident_value(AST* val)
 
 
 
-AST* Require(char* name)
-{
-    (void)name;
-    return NULL;
-}
 
-char* require_name(AST* req)
-{
-    (void)req;
-    return NULL;
-}
 
 AST* Def(char* name, AST* value)
 {
index 41e01fc5687741fae936a96510587c2f6b0d85ee..f79e934bbdddc1eb737c4883e4459b6d722e6150 100644 (file)
@@ -6,18 +6,22 @@
 */
 #include <sclpl.h>
 
+static AST* require(Parser* p);
 static AST* expression(Parser* p);
-static AST* ident(Parser* p);
 static AST* literal(Parser* p);
+static AST* expect_lit(Parser* p, TokType);
+static AST* token_to_tree(Tok* tok);
 
 AST* toplevel(Parser* p)
 {
     AST* ret = NULL;
     if (peek(p)->type != T_END_FILE) {
-        ret = expression(p);
+        if (accept_str(p, T_ID, "require"))
+            ret = require(p);
+        else
+            ret = expression(p);
     }
-    //if (accept_str(p, T_ID, "require"))
-    //    return require(p);
+    //printf("%p\n", ret);
     //else if (accept_str(p, T_ID, "type"))
     //    return type_definition(p);
     //else if (accept_str(p, T_ID, "ann"))
@@ -32,7 +36,7 @@ AST* toplevel(Parser* p)
 static AST* expression(Parser* p)
 {
     if (peek(p)->type == T_ID) {
-        return ident(p);
+        return expect_lit(p, T_ID);
         //if (peek(p)->type == T_LPAR) {
         //    arglist(p);
         //}
@@ -59,11 +63,13 @@ static AST* expression(Parser* p)
     //}
 }
 
-static AST* ident(Parser* p)
+static AST* require(Parser* p)
 {
-    Tok* tok = peek(p);
-    expect(p, T_ID);
-    return Ident(tok->value.text);
+    AST* ret = expect_lit(p, T_STRING);
+    if (ret != NULL)
+        ret = Require(string_value(ret));
+    expect(p, T_END);
+    return ret;
 }
 
 static AST* literal(Parser* p)
@@ -72,36 +78,39 @@ static AST* literal(Parser* p)
     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);
+            ret = token_to_tree(tok);
+            expect(p, tok->type);
             break;
-
         default:
             error(p, "Expected a literal");
     }
     return ret;
 }
 
+static AST* token_to_tree(Tok* tok)
+{
+    switch (tok->type) {
+        case T_BOOL:   return Bool(tok->value.boolean);
+        case T_CHAR:   return Char(tok->value.character);
+        case T_STRING: return String(tok->value.text);
+        case T_INT:    return Integer(tok->value.integer);
+        case T_FLOAT:  return Float(tok->value.floating);
+        case T_ID:     return Ident(tok->value.text);
+        default:       return NULL;
+    }
+}
+
+static AST* expect_lit(Parser* p, TokType type)
+{
+    Tok* tok = peek(p);
+    expect(p, type);
+    return token_to_tree(tok);
+}
+
 
 
 
@@ -119,13 +128,6 @@ static AST* arglist(Parser* p);
 static AST* if_stmnt(Parser* p);
 static AST* fn_stmnt(Parser* p);
 
-static AST* require(Parser* p)
-{
-    //shifttok(p, T_STRING);
-    //expect(p, T_END);
-    //reduce(Require);
-    return NULL;
-}
 
 static AST* type_annotation(Parser* p)
 {
index eb560e5c36ff952a0101276a398b3779a3afe4f0..18de8ec6595eec38ef4ebcd66ebf07973732007e 100644 (file)
@@ -119,6 +119,8 @@ void pprint_tree(FILE* file, AST* tree, int depth)
     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 {
         //fputs("(tree", file);
         //vec_t* p_vec = tree->ptr.vec;
index d7b51353bb66a4f0fb39ddd7505e9a4712ff54d0..e5f4c9a5e66d576797e427d9e6a3aa5066eb099c 100644 (file)
@@ -129,15 +129,15 @@ bool bool_value(AST* val);
 AST* Ident(char* val);
 char* ident_value(AST* val);
 
+/* Require */
+AST* Require(char* name);
+char* require_name(AST* req);
 
 
 
 
 
 
-///* Require */
-//AST* Require(char* name);
-//char* require_name(AST* req);
 //
 ///* Definition */
 //AST* Def(char* name, AST* value);
index 8b4f9470074c103a471d392a63ec596086bdc19e..4cc18eb1799a809f7acae58945fbd71833fae211 100644 (file)
@@ -27,31 +27,31 @@ describe "sclpl grammar" do
     end
   end
 
-#  context "requires" do
-#    it "should parse a require statement" do
-#      expect(ast('require "foo";')).to eq([ ['T_ID:require', 'T_STRING:"foo"'] ])
-#    end
-#
-#    it "should parse a require statement using end keyword" do
-#        expect(ast('require "foo" end')).to eq([ ['T_ID:require', 'T_STRING:"foo"'] ])
-#    end
-#
-#    it "should error on missing semicolon" do
-#      expect{ast('require "foo"')}.to raise_error /Error/
-#    end
-#
-#    it "should error on missing filename" do
-#      expect{ast('require ;')}.to raise_error /Error/
-#    end
-#
-#    it "should error on invalid filename type" do
-#      expect{ast('require 123;')}.to raise_error /Error/
-#    end
-#
-#    it "should error on too many parameters" do
-#      expect{ast('require foo bar;')}.to raise_error /Error/
-#    end
-#  end
+  context "requires" do
+    it "should parse a require statement" do
+      expect(ast('require "foo";')).to eq([ ['require', '"foo"'] ])
+    end
+
+    it "should parse a require statement using end keyword" do
+        expect(ast('require "foo" end')).to eq([ ['require', '"foo"'] ])
+    end
+
+    it "should error on missing semicolon" do
+      expect{ast('require "foo"')}.to raise_error /Error/
+    end
+
+    it "should error on missing filename" do
+      expect{ast('require ;')}.to raise_error /Error/
+    end
+
+    it "should error on invalid filename type" do
+      expect{ast('require 123;')}.to raise_error /Error/
+    end
+
+    it "should error on too many parameters" do
+      expect{ast('require foo bar;')}.to raise_error /Error/
+    end
+  end
 #
 #  context "type definitions" do
 #    it "should parse a simple type definition" do