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/',
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)
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);
}
// 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;
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);
}
{
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) );
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;
}
}
struct AST* args;
struct AST* body;
} func;
+ /* Code Block */
+ vec_t exprs;
/* String, Symbol, Identifier */
char* text;
/* Character */
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
# 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"]])