issue #98 typecheck expression statements

pull/168/head
Dibyendu Majumdar 5 years ago
parent 271bbc7e5a
commit 4ad83f8abf

@ -155,11 +155,11 @@ struct ast_node {
struct {
struct lua_symbol_list *var_list;
struct ast_node_list *expr_list;
} local_stmt;
} local_stmt; /* local declarations */
struct {
struct ast_node_list *var_expr_list; /* Optional var expressions, comma separated */
struct ast_node_list *expr_list; /* Comma separated expressions */
} expression_stmt; /* Also covers assignments*/
} expression_stmt; /* Also covers assignments */
struct {
struct ast_node *name; /* base symbol to be looked up */
struct ast_node_list *selectors; /* Optional */
@ -194,6 +194,7 @@ struct ast_node {
struct {
struct var_type type;
} common_expr; /* To access the type field common to all expr objects */
/* all expr types must be compatible with common_expr */
struct {
struct var_type type;
union {

@ -249,7 +249,7 @@ function()
function()
--[expression statement start]
--[expression list start]
--[suffixed expr start] closure
--[suffixed expr start] any
--[primary start]
function()
end

@ -190,6 +190,28 @@ static void typecheck_suffixedexpr(struct ast_node *function, struct ast_node *n
copy_type(node->suffixed_expr.type, prev_node->common_expr.type);
}
static void typecheck_var_assignment(struct var_type *var_type, struct var_type *expr_type, const char *var_name) {
if (var_type->type_code == RAVI_TANY)
// Any value can be assigned to type ANY
return;
if (var_type->type_code == RAVI_TNUMINT || var_type->type_code == RAVI_TNUMFLT) {
if (expr_type->type_code == RAVI_TNUMINT || expr_type->type_code == RAVI_TNUMFLT) {
// Okay
// TODO insert a typecast?
}
else {
fprintf(stderr, "Assignment to local symbol %s is not type compatible\n", var_name);
}
return;
}
// all other types must strictly match
if (!is_type_same(*var_type, *expr_type)) { // We should probably check type convertability here
fprintf(stderr, "Assignment to local symbol %s is not type compatible\n", var_name);
}
}
static void typecheck_local_statement(struct ast_node *function, struct ast_node *node) {
// The local vars should already be annotated
// We need to typecheck the expressions to the right of =
@ -207,15 +229,47 @@ static void typecheck_local_statement(struct ast_node *function, struct ast_node
if (!var || !expr)
break;
if (var->value_type.type_code != RAVI_TANY && !is_type_same(var->value_type, expr->common_expr.type)) { // We should probably check type convertability here
fprintf(stderr, "Assignment to local symbol %s is not type compatible\n", getstr(var->var.var_name));
}
struct var_type *var_type = &var->value_type;
struct var_type *expr_type = &expr->common_expr.type;
const char *var_name = getstr(var->var.var_name);
typecheck_var_assignment(var_type, expr_type, var_name);
NEXT_PTR_LIST(var);
NEXT_PTR_LIST(expr);
}
}
static void typecheck_expr_statement(struct ast_node *function, struct ast_node *node) {
if (node->expression_stmt.var_expr_list)
typecheck_ast_list(function, node->expression_stmt.var_expr_list);
typecheck_ast_list(function, node->expression_stmt.expr_list);
if (!node->expression_stmt.var_expr_list)
return;
struct ast_node *var;
struct ast_node *expr;
PREPARE_PTR_LIST(node->expression_stmt.var_expr_list, var);
PREPARE_PTR_LIST(node->local_stmt.expr_list, expr);
for (;;) {
if (!var || !expr)
break;
struct var_type *var_type = &var->common_expr.type;
struct var_type *expr_type = &expr->common_expr.type;
const char *var_name = ""; // FIXME how do we get this?
typecheck_var_assignment(var_type, expr_type, var_name);
NEXT_PTR_LIST(var);
NEXT_PTR_LIST(expr);
}
}
/* Type checker - WIP */
static void typecheck_ast_node(struct ast_node *function, struct ast_node *node) {
switch (node->type) {
@ -248,6 +302,7 @@ static void typecheck_ast_node(struct ast_node *function, struct ast_node *node)
break;
}
case AST_EXPR_STMT: {
typecheck_expr_statement(function, node);
break;
}
case AST_IF_STMT: {

Loading…
Cancel
Save