From 966f97ad7c92f559ae54d0214db90c370e3b48eb Mon Sep 17 00:00:00 2001 From: Kimplul Date: Fri, 26 Apr 2024 21:08:13 +0300 Subject: add check against proc calls as statements --- src/check.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 9 deletions(-) (limited to 'src/check.c') diff --git a/src/check.c b/src/check.c index b4ea2b1..85e5459 100644 --- a/src/check.c +++ b/src/check.c @@ -35,6 +35,18 @@ static bool has_type(struct ast *n) return n->t != 0; } +static bool concrete_type(enum type_kind k) +{ + switch (k) { + case TYPE_VOID: + case TYPE_AUTO: + return false; + default: break; + } + + return true; +} + static int analyze(struct state *state, struct scope *scope, struct ast *n); static int analyze_list(struct state *state, struct scope *scope, struct ast *l) { @@ -46,6 +58,25 @@ static int analyze_list(struct state *state, struct scope *scope, struct ast *l) return 0; } +static int analyze_statement_list(struct state *state, struct scope *scope, struct ast *l) +{ + foreach_node(n, l) { + if (analyze(state, scope, n)) + return -1; + + if (n->k != AST_PROC_CALL) + continue; + + if (n->t != TYPE_VOID) { + semantic_error(scope, n, + "non-void proc call not allowed as statement"); + return -1; + } + } + + return 0; +} + static struct ast *file_scope_find_analyzed(struct state *state, struct scope *scope, char *id) { @@ -138,7 +169,7 @@ static int analyze_proc_def(struct state *state, struct scope *scope, if (analyze_list(&proc_state, proc_scope, proc_vars(p))) return -1; - if (analyze_list(&proc_state, proc_scope, proc_body(p))) + if (analyze_statement_list(&proc_state, proc_scope, proc_body(p))) return -1; struct ast *last = ast_last(proc_body(p)); @@ -168,6 +199,12 @@ static int analyze_var_def(struct state *state, struct scope *scope, if (analyze(state, scope, expr)) return -1; + if (!concrete_type(expr->t)) { + semantic_error(scope, n, "illegal type in variable definition: %s", + type_str(expr->t)); + return -1; + } + n->t = expr->t; return 0; } @@ -547,10 +584,22 @@ static int analyze_assign(struct state *state, struct scope *scope, if (analyze(state, scope, l)) return -1; + if (!concrete_type(l->t)) { + semantic_error(scope, n, "illegal type for lefthand side: %s", + type_str(l->t)); + return -1; + } + struct ast *r = assign_r(n); if (analyze(state, scope, r)) return -1; + if (!concrete_type(r->t)) { + semantic_error(scope, n, "illegal type for righthand side: %s", + type_str(r->t)); + return -1; + } + if (l->t != r->t) { semantic_error(scope, n, "type mismatch: %s vs %s", type_str(l->t), type_str(r->t)); @@ -667,7 +716,7 @@ static int analyze_until(struct state *state, struct scope *scope, scope_add_scope(scope, until_scope); struct ast *body = until_body(n); - if (analyze_list(state, until_scope, body)) + if (analyze_statement_list(state, until_scope, body)) return -1; struct ast *cond = until_cond(n); @@ -693,7 +742,7 @@ static int analyze_unless(struct state *state, struct scope *scope, scope_add_scope(scope, otherwise_scope); struct ast *body = unless_body(n); - if (analyze_list(state, unless_scope, body)) + if (analyze_statement_list(state, unless_scope, body)) return -1; struct ast *cond = unless_cond(n); @@ -707,7 +756,7 @@ static int analyze_unless(struct state *state, struct scope *scope, } struct ast *otherwise = unless_otherwise(n); - if (otherwise && analyze_list(state, otherwise_scope, otherwise)) + if (otherwise && analyze_statement_list(state, otherwise_scope, otherwise)) return -1; n->t = TYPE_VOID; @@ -824,11 +873,9 @@ int check(struct scope *scope, struct ast *root) } /* actually analyze all nodes */ - foreach_node(n, root) { - struct state state = {0}; - if (analyze(&state, scope, n)) - return -1; - } + struct state state = {0}; + if (analyze_statement_list(&state, scope, root)) + return -1; #ifdef DEBUG foreach_node(n, root) { -- cgit v1.2.3