codegen
This commit is contained in:
parent
09d6cf4b46
commit
ed0ad1d095
14 changed files with 846 additions and 897 deletions
36
sema.c
36
sema.c
|
|
@ -26,9 +26,11 @@ static type *const_int = NULL;
|
|||
static type *const_float = NULL;
|
||||
|
||||
static bool in_loop = false;
|
||||
static bool has_errors = false;
|
||||
|
||||
static void error(ast_node *n, char *msg)
|
||||
{
|
||||
has_errors = true;
|
||||
if (n) {
|
||||
printf("\x1b[31m\x1b[1merror\x1b[0m\x1b[1m:%ld:%ld:\x1b[0m %s\n", n->position.row, n->position.column, msg);
|
||||
} else {
|
||||
|
|
@ -133,6 +135,16 @@ static type *get_type(sema *s, ast_node *n)
|
|||
char *name = NULL;
|
||||
type *t = NULL;
|
||||
switch (n->type) {
|
||||
case NODE_ACCESS:
|
||||
t = get_type(s, n->expr.access.expr);
|
||||
name = intern_string(s, n->expr.access.member->expr.string.start, n->expr.access.member->expr.string.len);
|
||||
if (t->tag != TYPE_STRUCT) {
|
||||
error(n->expr.access.expr, "expected structure.");
|
||||
return NULL;
|
||||
}
|
||||
t = shget(t->data.structure.member_types, name);
|
||||
|
||||
return t;
|
||||
case NODE_IDENTIFIER:
|
||||
name = intern_string(s, n->expr.string.start, n->expr.string.len);
|
||||
t = shget(type_reg, name);
|
||||
|
|
@ -433,7 +445,8 @@ static bool can_cast(type *source, type *dest)
|
|||
switch (dest->tag) {
|
||||
case TYPE_INTEGER:
|
||||
case TYPE_UINTEGER:
|
||||
return source->tag == TYPE_INTEGER_CONST;
|
||||
case TYPE_INTEGER_CONST:
|
||||
return source->tag == TYPE_INTEGER_CONST || source->tag == TYPE_INTEGER || source->tag == TYPE_UINTEGER;
|
||||
case TYPE_FLOAT:
|
||||
return source->tag == TYPE_FLOAT_CONST;
|
||||
default:
|
||||
|
|
@ -558,11 +571,20 @@ static type *get_expression_type(sema *s, ast_node *node)
|
|||
node->expr_type = t;
|
||||
return t;
|
||||
case NODE_CALL:
|
||||
prot = shget(prototypes, intern_string(s, node->expr.call.name, node->expr.call.name_len));
|
||||
node->expr.call.name = intern_string(s, node->expr.call.name, node->expr.call.name_len);
|
||||
prot = shget(prototypes, node->expr.call.name);
|
||||
if (!prot) {
|
||||
error(node, "unknown function.");
|
||||
return NULL;
|
||||
}
|
||||
// Process call arguments
|
||||
ast_node *arg = node->expr.call.parameters;
|
||||
while (arg && arg->type == NODE_UNIT) {
|
||||
if (arg->expr.unit_node.expr) {
|
||||
get_expression_type(s, arg->expr.unit_node.expr);
|
||||
}
|
||||
arg = arg->expr.unit_node.next;
|
||||
}
|
||||
t = prot->type;
|
||||
node->expr_type = t;
|
||||
return t;
|
||||
|
|
@ -709,8 +731,9 @@ static void check_statement(sema *s, ast_node *node)
|
|||
error(node, "redeclaration of variable.");
|
||||
break;
|
||||
}
|
||||
if (!can_cast(get_expression_type(s, node->expr.var_decl.value), t) && !match(t, get_expression_type(s, node->expr.var_decl.value))) {
|
||||
error(node, "type mismatch.");
|
||||
if (t->tag == TYPE_STRUCT) {
|
||||
} else if (!can_cast(get_expression_type(s, node->expr.var_decl.value), t) && !match(t, get_expression_type(s, node->expr.var_decl.value))) {
|
||||
error(node, "type mismatch (decl).");
|
||||
}
|
||||
shput(current_scope->defs, name, node);
|
||||
break;
|
||||
|
|
@ -815,4 +838,9 @@ void sema_init(parser *p, arena *a)
|
|||
const_float->data.flt = 0;
|
||||
|
||||
analyze_unit(s, s->ast);
|
||||
|
||||
if (has_errors) {
|
||||
printf("Compilation failed.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue