// src/ast.c
bool ast_isconst(AstNode* node);
bool ast_areconst(AstNode* left, AstNode* right);
+
AstNode* ast_ident(Parser* p, long long index);
AstNode* ast_bool(bool val);
AstNode* ast_int(long long val);
AstNode* ast_real(double val);
+
bool ast_asbool(Parser* p, AstNode* node);
long long ast_asint(Parser* p, AstNode* node);
double ast_asreal(Parser* p, AstNode* node);
+
AstNode* ast_binop(int op, AstNode* left, AstNode* right);
AstNode* ast_unop(int op, AstNode* operand);
+// TODO: Add a store operation handler
+AstNode* ast_fieldref(Parser* p, AstNode* record, char* fname);
+AstNode* ast_index(Parser* p, AstNode* array, AstNode* index);
+
AstNode* ast_block(void);
+void ast_block_add(AstNode* blk, AstNode* stmt);
AstNode* ast_call(AstNode* func);
+void ast_call_add(AstNode* func, AstNode* arg);
AstNode* ast_if(AstNode* cond, AstNode* br1, AstNode* br2);
AstNode* ast_return(AstNode* expr);
+
void ast_print(AstNode* expr);
/* Backend Code Generation and Base Type Definitions
return ret;
}
+AstNode* ast_fieldref(Parser* p, AstNode* record, char* fname)
+{
+ /* TODO: actually access the field and check that it exists */
+ return record;
+}
+
+AstNode* ast_index(Parser* p, AstNode* array, AstNode* index)
+{
+ /* TODO: actually access the array index */
+ /*
+ * offset = index * sizeof(base)
+ * array->type = array->type->base;
+ * return new ast(ARRAY, base, offset)
+ */
+ return array;
+}
+
AstNode* ast_block(void)
{
return ast_new(BEGIN, &VoidType, NULL, NULL, NULL);
}
-void ast_block_add(AstNode* func)
+void ast_block_add(AstNode* blk, AstNode* stmt)
{
/* TODO: append to linked list */
- (void)func;
+ (void)blk, (void)stmt;
}
AstNode* ast_call(AstNode* func)
return ast_new(CALL, func->hdr.type, func, NULL, NULL);
}
-void ast_call_add(AstNode* func)
+void ast_call_add(AstNode* func, AstNode* arg)
{
/* TODO: append to linked list */
- (void)func;
+ (void)func, (void)arg;
}
AstNode* ast_if(AstNode* cond, AstNode* br1, AstNode* br2)
AstNode* expr = qualident(p);
-// /* selector */
-// for (int done = 0; !done;)
-// {
-// switch ((int)peek(p)->type)
-// {
-// case '.':
-// {
-// expect(p, '.');
-// char* name = expect_text(p, IDENT);
-// if (item->type->form == FORM_RECORD)
-// {
-// codegen_field(p, item, name);
-// }
-// else
-// {
-// error(p, "attempting to access field of non-array object");
-// }
-// break;
-// }
-//
-// case '[':
-// {
-// Item index = {0};
-// expect(p, '[');
-// expression(p, &index);
-// if (item->type->form == FORM_ARRAY)
-// {
-// codegen_index(p, item, &index);
-// }
-// else
-// {
-// error(p, "attempting to index non-array value");
-// }
-// expect(p, ']');
-// break;
-// }
-//
+ /* selector */
+ for (int done = 0; !done;)
+ {
+ switch ((int)peek(p)->type)
+ {
+ case '.':
+ {
+ expect(p, '.');
+ if (expr->hdr.type->form != FORM_RECORD)
+ {
+ error(p, "attempting to access field of non-array object");
+ }
+ char* name = expect_text(p, IDENT);
+ expr = ast_fieldref(p, expr, name);
+ break;
+ }
+
+ case '[':
+ {
+ expect(p, '[');
+ if (expr->hdr.type->form != FORM_ARRAY)
+ {
+ error(p, "attempting to index non-array value");
+ }
+ AstNode* index = expression(p);
+ check_int(p, index);
+ expr = ast_index(p, expr, index);
+ expect(p, ']');
+ break;
+ }
+
// // case '^':
// // expect(p, '^');
// // break;
// // expect(p, ')');
// // break;
//
-// default:
-// done = 1;
-// break;
-// }
-// }
+ default:
+ done = 1;
+ break;
+ }
+ }
EXIT_RULE();
assert(expr != NULL);
return ret;
}
-//RULE(statement_seq, Item* item)
-//{
-// ENTER_RULE();
-// do
-// {
-// if (matches(p, IF))
-// {
-// expect(p, IF);
-// expression(p, item);
-// check_bool(p, item);
+static AstNode* statement_seq(Parser* p)
+{
+ ENTER_RULE();
+ AstNode* block = ast_block();
+
+ do
+ {
+ if (matches(p, IF))
+ {
+ expect(p, IF);
+ AstNode* cond = expression(p);
+ check_bool(p, cond);
+ expect(p, THEN);
+ AstNode* blk1 = statement_seq(p);
+ AstNode* blk2 = NULL;
+ if (accept(p, ELSE))
+ {
+ blk2 = statement_seq(p);
+ }
+ ast_block_add(block, ast_if(cond, blk1, blk2));
+ expect(p, END);
+
// codegen_if(p, item);
// expect(p, THEN);
// statement_seq(p, &(Item){0});
// }
// codegen_endif(p, elsifs, item);
// expect(p, END);
-// }
-// else /* assignments/expressions */
-// {
-// expression(p, item);
-// if (accept(p, '='))
-// {
-// Item right = { 0 };
-// expression(p, &right);
-// check_types(p, item, &right);
-// codegen_store(p, item, &right);
-// }
-// expect(p, ';');
-// }
-// }
-// while (!matches(p, END) && !matches(p, ELSE) && !matches(p, ELSIF) && !matches(p, RETURN));
-// EXIT_RULE();
-//}
+// ast_block_add(block, ast_binop('=', left, right));
+ }
+ else /* assignments/expressions */
+ {
+ AstNode* expr = expression(p);
+ if (accept(p, '='))
+ {
+ AstNode* right = expression(p);
+ check_types(p, expr, right);
+ expr = ast_binop('=', expr, right);
+ }
+ expect(p, ';');
+ ast_block_add(block, expr);
+ }
+ }
+ while (!matches(p, END) && !matches(p, ELSE) && !matches(p, ELSIF) && !matches(p, RETURN));
+
+ EXIT_RULE();
+ return block;
+}
static void var_decl(Parser* p)
{
// }
// codegen_startproc(p, NULL);
-// if (accept(p, BEGIN))
-// {
+ if (accept(p, BEGIN))
+ {
// codegen_imports(p);
-// statement_seq(p, item);
-// expect(p, END);
-// }
+ AstNode* block = statement_seq(p);
+ ast_print(block);
+ puts("");
+ expect(p, END);
+ }
// codegen_endproc(p);
if (!matches(p, END_FILE))