From: Mike D. Lowis Date: Mon, 12 Oct 2015 20:41:18 +0000 (-0400) Subject: implemented grammar rule for sclpl X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=96a0f66a1b5fb9b694d352757f00fa0c2eb8db54;p=proto%2Fsclpl.git implemented grammar rule for sclpl --- diff --git a/source/ast.c b/source/ast.c index 71aeeb6..aa28904 100644 --- a/source/ast.c +++ b/source/ast.c @@ -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) { diff --git a/source/grammar.c b/source/grammar.c index 41e01fc..f79e934 100644 --- a/source/grammar.c +++ b/source/grammar.c @@ -6,18 +6,22 @@ */ #include +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) { diff --git a/source/pprint.c b/source/pprint.c index eb560e5..18de8ec 100644 --- a/source/pprint.c +++ b/source/pprint.c @@ -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; diff --git a/source/sclpl.h b/source/sclpl.h index d7b5135..e5f4c9a 100644 --- a/source/sclpl.h +++ b/source/sclpl.h @@ -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); diff --git a/spec/parser_spec.rb b/spec/parser_spec.rb index 8b4f947..4cc18eb 100644 --- a/spec/parser_spec.rb +++ b/spec/parser_spec.rb @@ -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