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

@ -249,7 +249,7 @@ function()
function() function()
--[expression statement start] --[expression statement start]
--[expression list start] --[expression list start]
--[suffixed expr start] closure --[suffixed expr start] any
--[primary start] --[primary start]
function() function()
end 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); 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) { static void typecheck_local_statement(struct ast_node *function, struct ast_node *node) {
// The local vars should already be annotated // The local vars should already be annotated
// We need to typecheck the expressions to the right of = // 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) if (!var || !expr)
break; 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 struct var_type *var_type = &var->value_type;
fprintf(stderr, "Assignment to local symbol %s is not type compatible\n", getstr(var->var.var_name)); 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(var);
NEXT_PTR_LIST(expr); NEXT_PTR_LIST(expr);
} }
} }
/* Type checker - WIP */ /* Type checker - WIP */
static void typecheck_ast_node(struct ast_node *function, struct ast_node *node) { static void typecheck_ast_node(struct ast_node *function, struct ast_node *node) {
switch (node->type) { switch (node->type) {
@ -248,6 +302,7 @@ static void typecheck_ast_node(struct ast_node *function, struct ast_node *node)
break; break;
} }
case AST_EXPR_STMT: { case AST_EXPR_STMT: {
typecheck_expr_statement(function, node);
break; break;
} }
case AST_IF_STMT: { case AST_IF_STMT: {

Loading…
Cancel
Save