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;
+}
-AST* Require(char* name)
-{
- (void)name;
- return NULL;
-}
-char* require_name(AST* req)
-{
- (void)req;
- return NULL;
-}
AST* Def(char* name, AST* value)
{
*/
#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"))
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);
//}
//}
}
-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)
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);
+}
+
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)
{
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;
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);
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