issue #98 type check for statements

pull/168/head
Dibyendu Majumdar 5 years ago
parent 22daaf8588
commit db626e34c1

@ -250,6 +250,10 @@ struct ast_node {
struct ast_node_list *suffix_list;
} suffixed_expr;
struct {
/* Note that in Ravi the results from a function call must be type asserted during assignment to variables.
* This is not explicit in the AST but is required to ensure that function return values do not
* overwrite the type of the variables in an inconsistent way.
*/
struct var_type type;
TString *method_name; /* Optional method_name */
struct ast_node_list *arg_list; /* Call arguments */

@ -1427,7 +1427,7 @@ function()
function()
--locals i
for
i --local symbol ?
i --local symbol integer
=
1
,
@ -1442,9 +1442,9 @@ function()
--[suffix list start]
--[function call start] any
(
--[suffixed expr start] any
--[primary start] any
i --local symbol ?
--[suffixed expr start] integer
--[primary start] integer
i --local symbol integer
--[primary end]
--[suffixed expr end]
)
@ -1585,3 +1585,83 @@ function()
end
--
--[[for i=1,10 do print(i+1) end return
]]
function()
--locals i
for
i --local symbol integer
=
1
,
10
do
--[expression statement start]
--[expression list start]
--[suffixed expr start] any
--[primary start] any
print --global symbol ?
--[primary end]
--[suffix list start]
--[function call start] any
(
--[binary expr start] integer
--[suffixed expr start] integer
--[primary start] integer
i --local symbol integer
--[primary end]
--[suffixed expr end]
+
1
--[binary expr end]
)
--[function call end]
--[suffix list end]
--[suffixed expr end]
--[expression list end]
--[expression statement end]
end
return
end
--
--[[for i=1.0, 10.0 do print(i+4.2) end return
]]
function()
--locals i
for
i --local symbol number
=
1.0000000000000000
,
10.0000000000000000
do
--[expression statement start]
--[expression list start]
--[suffixed expr start] any
--[primary start] any
print --global symbol ?
--[primary end]
--[suffix list start]
--[function call start] any
(
--[binary expr start] number
--[suffixed expr start] number
--[primary start] number
i --local symbol number
--[primary end]
--[suffixed expr end]
+
4.2000000000000002
--[binary expr end]
)
--[function call end]
--[suffix list end]
--[suffixed expr end]
--[expression list end]
--[expression statement end]
end
return
end
--

@ -78,4 +78,7 @@ dotest 'return @integer[] {}'
dotest 'return @number[] {}'
dotest 'return @closure function() end'
dotest 'return @number 54.4'
dotest 'return @User.Type a'
dotest 'return @User.Type a'
dotest 'for i=1,10 do print(i+1) end return'
dotest 'for i=1.0, 10.0 do print(i+4.2) end return'

@ -291,7 +291,7 @@ function()
--[symbols]
sum --local symbol ?
for
j --local symbol ?
j --local symbol integer
=
1
,
@ -310,7 +310,7 @@ function()
--[expression list end]
--[expression statement end]
for
k --local symbol ?
k --local symbol integer
=
1
,
@ -332,21 +332,21 @@ function()
--[primary end]
--[suffixed expr end]
+
--[binary expr start] any
--[binary expr start] number
1.0000000000000000
/
--[suffixed expr start] any
--[primary start] any
--[binary expr start] any
--[suffixed expr start] any
--[primary start] any
k --local symbol ?
--[suffixed expr start] integer
--[primary start] integer
--[binary expr start] integer
--[suffixed expr start] integer
--[primary start] integer
k --local symbol integer
--[primary end]
--[suffixed expr end]
*
--[suffixed expr start] any
--[primary start] any
k --local symbol ?
--[suffixed expr start] integer
--[primary start] integer
k --local symbol integer
--[primary end]
--[suffixed expr end]
--[binary expr end]

@ -129,6 +129,9 @@ static void typecheck_binaryop(struct ast_node *function, struct ast_node *node)
case OPR_MOD:
if (e1->common_expr.type.type_code == RAVI_TNUMINT && e2->common_expr.type.type_code == RAVI_TNUMINT)
set_typecode(node->binary_expr.type, RAVI_TNUMINT);
else if ((e1->common_expr.type.type_code == RAVI_TNUMINT && e2->common_expr.type.type_code == RAVI_TNUMFLT) ||
(e1->common_expr.type.type_code == RAVI_TNUMFLT && e2->common_expr.type.type_code == RAVI_TNUMINT))
set_typecode(node->binary_expr.type, RAVI_TNUMFLT);
break;
default:
set_typecode(node->binary_expr.type, RAVI_TANY);
@ -204,7 +207,7 @@ static void typecheck_var_assignment(struct var_type *var_type, struct var_type
}
// all other types must strictly match
if (!is_type_same(*var_type, *expr_type)) { // We should probably check type convertability here
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);
}
}
@ -238,7 +241,6 @@ static void typecheck_local_statement(struct ast_node *function, struct ast_node
}
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);
@ -257,7 +259,7 @@ static void typecheck_expr_statement(struct ast_node *function, struct ast_node
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?
const char *var_name = ""; // FIXME how do we get this?
typecheck_var_assignment(var_type, expr_type, var_name);
@ -266,6 +268,46 @@ static void typecheck_expr_statement(struct ast_node *function, struct ast_node
}
}
static void typecheck_for_statment(struct ast_node *function, struct ast_node *node) {
typecheck_ast_list(function, node->for_stmt.expr_list);
if (node->type != AST_FORNUM_STMT) {
typecheck_ast_list(function, node->for_stmt.for_statement_list);
return;
}
/* for num case, the index variable's type */
struct ast_node *expr;
ravitype_t index_type = RAVI_TNUMINT;
int match_count = 0; /* number of expression matching index type */
/* First expression decides between int / float types. We allow int or float in subsequent
* expressions ... TODO may need changing.
*/
FOR_EACH_PTR(node->for_stmt.expr_list, expr) {
if (expr->common_expr.type.type_code == RAVI_TNUMFLT) {
if (index_type != RAVI_TNUMFLT) {
index_type = (match_count == 0) ? RAVI_TNUMFLT : RAVI_TANY;
}
}
else if (expr->common_expr.type.type_code != RAVI_TNUMINT) {
index_type = RAVI_TANY;
}
if (index_type == RAVI_TANY)
break;
match_count++;
}
END_FOR_EACH_PTR(expr);
if (index_type == RAVI_TNUMINT || index_type == RAVI_TNUMFLT) {
struct lua_symbol_list *symbols = node->for_stmt.symbols;
struct lua_symbol *sym;
/* actually there will be only index variable */
FOR_EACH_PTR(symbols, sym) {
if (sym->symbol_type == SYM_LOCAL) {
set_typecode(sym->value_type, index_type);
}
}
END_FOR_EACH_PTR(sym);
}
typecheck_ast_list(function, node->for_stmt.for_statement_list);
}
/* Type checker - WIP */
static void typecheck_ast_node(struct ast_node *function, struct ast_node *node) {
@ -317,9 +359,11 @@ static void typecheck_ast_node(struct ast_node *function, struct ast_node *node)
break;
}
case AST_FORIN_STMT: {
typecheck_for_statment(function, node);
break;
}
case AST_FORNUM_STMT: {
typecheck_for_statment(function, node);
break;
}
case AST_SUFFIXED_EXPR: {
@ -331,10 +375,12 @@ static void typecheck_ast_node(struct ast_node *function, struct ast_node *node)
}
else {
}
typecheck_ast_list(function, node->function_call_expr.arg_list);
break;
}
case AST_SYMBOL_EXPR: {
/* type should have been set when symbol was created */
/* symbol type should have been set when symbol was created */
copy_type(node->symbol_expr.type, node->symbol_expr.var->value_type);
break;
}
case AST_BINARY_EXPR: {
@ -370,7 +416,6 @@ static void typecheck_ast_node(struct ast_node *function, struct ast_node *node)
}
}
/* Type checker - WIP */
static void typecheck_function(struct ast_node *func) {
typecheck_ast_list(func, func->function_expr.function_statement_list);

Loading…
Cancel
Save