long size_of(Type* type);
// 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);
AstNode* ast_block(void);
} val;
} AstValue;
-static bool is_const(AstNode* node)
+bool ast_isconst(AstNode* node)
{
bool ret;
switch (node->hdr.code)
return ret;
}
-static bool both_const(AstNode* left, AstNode* right)
+bool ast_areconst(AstNode* left, AstNode* right)
{
- return is_const(left) && is_const(right);
+ return ast_isconst(left) && ast_isconst(right);
}
static AstNode* ast_new(int code, Type* type, AstNode* l0, AstNode* l1, AstNode* l2)
return (AstNode*)node;
}
+bool ast_asbool(Parser* p, AstNode* node)
+{
+ check_bool(p, node);
+ return (bool)(((AstValue*)node)->val.i);
+}
+
+long long ast_asint(Parser* p, AstNode* node)
+{
+ check_int(p, node);
+ return ((AstValue*)node)->val.i;
+}
+
+double ast_asreal(Parser* p, AstNode* node)
+{
+ check_real(p, node);
+ return ((AstValue*)node)->val.f;
+}
+
AstNode* ast_binop(int op, AstNode* left, AstNode* right)
{
assert(left);
assert(right);
AstNode* ret = NULL;
- if (both_const(left,right))
+ if (ast_areconst(left,right))
{
AstValue* a = (AstValue*)left;
AstValue* b = (AstValue*)right;
{
assert(operand);
AstNode* ret = NULL;
- if (is_const(operand))
+ if (ast_isconst(operand))
{
AstValue* a = (AstValue*)operand;
if (a->hdr.type->form == FORM_INT)
return expr;
}
-//RULE(type, Item* item)
-//{
-// ENTER_RULE();
-// (void)item;
-// if (matches(p, IDENT))
-// {
-// char* text = expect_text(p, IDENT);
-// Symbol* sym = symbol_get(p, text, SYM_TYPE);
-// item->type = sym->type;
-// }
-// else if (accept(p, ARRAY))
-// {
-// expression(p, item);
-// if (item->mode != ITEM_CONST)
-// {
-// error(p, "non-constant array size");
-// }
-// expect(p, OF);
-// Item base = {0};
-// type(p, &base);
-// item->type = calloc(1, sizeof(Type));
-// item->type->form = FORM_ARRAY;
-// item->type->size = item->imm.i;
-// item->type->base = base.type;
-// }
+static Type* type(Parser* p)
+{
+ ENTER_RULE();
+ Type* ret = NULL;
+
+ if (matches(p, IDENT))
+ {
+ char* text = expect_text(p, IDENT);
+ Symbol* sym = symbol_get(p, text, SYM_TYPE);
+ ret = sym->type;
+ }
+ else if (accept(p, ARRAY))
+ {
+ AstNode* lnode = expression(p);
+ if (!ast_isconst(lnode))
+ {
+ error(p, "non-constant array size");
+ }
+ long long length = ast_asint(p, lnode);
+ expect(p, OF);
+ Type* base = type(p);
+ ret = calloc(1, sizeof(Type));
+ ret->form = FORM_ARRAY;
+ ret->size = length;
+ ret->base = base;
+ }
// else if (accept(p, RECORD))
// {
// long offset = 0;
//
// expect(p, END);
// }
-// else
-// {
-// error(p, "expected a type");
-// }
-// EXIT_RULE();
-//}
+ else
+ {
+ error(p, "expected a type");
+ }
+ EXIT_RULE();
+ return ret;
+}
//RULE(statement_seq, Item* item)
//{
// while (matches(p, IDENT));
// EXIT_RULE();
//}
-//
-//RULE(type_decl, Item* item)
-//{
-// ENTER_RULE();
-// char* name = NULL;
-// bool export = false;
-// Symbol* sym = NULL;
-//
-// do
-// {
-// name = expect_text(p, IDENT);
-// export = accept(p, '*');
-// sym = symbol_new(p, 0, name, SYM_TYPE, export);
-// expect(p, '=');
-// type(p, item);
-// sym->type = item->type;
-// }
-// while (matches(p, IDENT));
-// EXIT_RULE();
-//}
+
+static void type_decl(Parser* p)
+{
+ ENTER_RULE();
+ char* name = NULL;
+ bool export = false;
+ Symbol* sym = NULL;
+
+ do
+ {
+ name = expect_text(p, IDENT);
+ export = accept(p, '*');
+ sym = symbol_new(p, 0, name, SYM_TYPE, export);
+ expect(p, '=');
+ sym->type = type(p);
+ }
+ while (matches(p, IDENT));
+
+ EXIT_RULE();
+}
static void const_decl(Parser* p)
{
const_decl(p);
}
-// if (accept(p, TYPE))
-// {
-// type_decl(p);
-// }
-//
+ if (accept(p, TYPE))
+ {
+ type_decl(p);
+ }
+
// if (accept(p, VAR))
// {
// var_decl(p);