issue #98 add type conversion for some assignments

pull/168/head
Dibyendu Majumdar 5 years ago
parent e4f0b7aa1a
commit c3952c2b98

@ -506,6 +506,67 @@ function()
false false
end end
function()
--locals t, len
local
--[symbols]
t --local symbol table
local
--[symbols]
len --local symbol integer
--[expressions]
--[unary expr start] integer
@integer
--[unary expr start] any
#
--[suffixed expr start] table
--[primary start] table
t --local symbol table
--[primary end]
--[suffixed expr end]
--[unary expr end]
--[unary expr end]
return
--[suffixed expr start] integer
--[primary start] integer
len --local symbol integer
--[primary end]
--[suffixed expr end]
end
function()
return
function(
t --local symbol table
,
i --local symbol integer
)
--locals t, i
--[expression statement start]
--[var list start]
--[suffixed expr start] integer
--[primary start] integer
i --local symbol integer
--[primary end]
--[suffixed expr end]
= --[var list end]
--[expression list start]
--[unary expr start] integer
@integer
--[unary expr start] any
#
--[suffixed expr start] table
--[primary start] table
t --local symbol table
--[primary end]
--[suffixed expr end]
--[unary expr end]
--[unary expr end]
--[expression list end]
--[expression statement end]
end
end
function() function()
matmul --global symbol ? matmul --global symbol ?
= =
@ -573,45 +634,54 @@ function()
, ,
x --local symbol table x --local symbol table
--[expressions] --[expressions]
--[unary expr start] any --[unary expr start] integer
# @integer
--[suffixed expr start] table --[unary expr start] any
--[primary start] table #
a --local symbol table --[suffixed expr start] table
--[primary end] --[primary start] table
--[suffixed expr end] a --local symbol table
--[primary end]
--[suffixed expr end]
--[unary expr end]
--[unary expr end] --[unary expr end]
, ,
--[unary expr start] any --[unary expr start] integer
# @integer
--[suffixed expr start] any --[unary expr start] any
--[primary start] table #
a --local symbol table --[suffixed expr start] any
--[primary end] --[primary start] table
--[suffix list start] a --local symbol table
--[Y index start] any --[primary end]
[ --[suffix list start]
1 --[Y index start] any
] [
--[Y index end] 1
--[suffix list end] ]
--[suffixed expr end] --[Y index end]
--[suffix list end]
--[suffixed expr end]
--[unary expr end]
--[unary expr end] --[unary expr end]
, ,
--[unary expr start] any --[unary expr start] integer
# @integer
--[suffixed expr start] any --[unary expr start] any
--[primary start] table #
b --local symbol table --[suffixed expr start] any
--[primary end] --[primary start] table
--[suffix list start] b --local symbol table
--[Y index start] any --[primary end]
[ --[suffix list start]
1 --[Y index start] any
] [
--[Y index end] 1
--[suffix list end] ]
--[suffixed expr end] --[Y index end]
--[suffix list end]
--[suffixed expr end]
--[unary expr end]
--[unary expr end] --[unary expr end]
, ,
{ --[table constructor start] table { --[table constructor start] table

@ -109,6 +109,20 @@ return false
]] ]]
doast(str) doast(str)
str=
[[local t: table
local len: integer = #t
return len
]]
doast(str)
str=
[[return function(t: table, i: integer)
i = #t
end
]]
doast(str)
str= str=
[[function matmul(a: table, b: table) [[function matmul(a: table, b: table)
assert(@integer(#a[1]) == #b); assert(@integer(#a[1]) == #b);

@ -29,9 +29,6 @@ static void typecheck_unaryop(struct ast_container *container, struct ast_node *
if (subexpr_type == RAVI_TARRAYINT || subexpr_type == RAVI_TARRAYFLT) { if (subexpr_type == RAVI_TARRAYINT || subexpr_type == RAVI_TARRAYFLT) {
set_type(node->unary_expr.type, RAVI_TNUMINT); set_type(node->unary_expr.type, RAVI_TNUMINT);
} }
else if (subexpr_type == RAVI_TTABLE) {
// FIXME we need insert a TO_INT expression;
}
break; break;
case OPR_TO_INTEGER: case OPR_TO_INTEGER:
set_type(node->unary_expr.type, RAVI_TNUMINT); set_type(node->unary_expr.type, RAVI_TNUMINT);
@ -190,25 +187,47 @@ static void typecheck_suffixedexpr(struct ast_container *container, struct ast_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 ast_container *container, struct var_type *var_type, static void insert_cast(struct ast_container *container, struct ast_node *expr, UnOpr opcode, ravitype_t target_type) {
struct var_type *expr_type, const char *var_name) { /* convert the node to @integer node, the original content of node goes into the subexpr */
struct ast_node *copy_expr = dmrC_allocator_allocate(&container->ast_node_allocator, 0);
*copy_expr = *expr;
expr->type = AST_UNARY_EXPR;
expr->unary_expr.expr = copy_expr;
expr->unary_expr.unary_op = opcode;
set_typecode(expr->unary_expr.type, target_type);
}
static void typecheck_var_assignment(struct ast_container *container, struct var_type *var_type, struct ast_node *expr,
const char *var_name) {
if (var_type->type_code == RAVI_TANY) if (var_type->type_code == RAVI_TANY)
// Any value can be assigned to type ANY // Any value can be assigned to type ANY
return; return;
if (var_type->type_code == RAVI_TNUMINT || var_type->type_code == RAVI_TNUMFLT) { struct var_type *expr_type = &expr->common_expr.type;
if (expr_type->type_code == RAVI_TNUMINT || expr_type->type_code == RAVI_TNUMFLT) {
// Okay if (var_type->type_code == RAVI_TNUMINT) {
// TODO insert a typecast? /* if the expr is of type number or # operator then insert @integer operator */
if (expr_type->type_code == RAVI_TNUMFLT ||
(expr->type == AST_UNARY_EXPR && expr->unary_expr.unary_op == OPR_LEN)) {
insert_cast(container, expr, OPR_TO_INTEGER, RAVI_TNUMINT);
} }
else { else if (expr_type->type_code != RAVI_TNUMINT) {
fprintf(stderr, "Assignment to local symbol %s is not type compatible\n", var_name);
}
return;
}
if (var_type->type_code == RAVI_TNUMFLT) {
if (expr_type->type_code == RAVI_TNUMINT) {
/* cast to number */
insert_cast(container, expr, OPR_TO_NUMBER, RAVI_TNUMFLT);
}
else if (expr_type->type_code != RAVI_TNUMFLT) {
fprintf(stderr, "Assignment to local symbol %s is not type compatible\n", var_name); fprintf(stderr, "Assignment to local symbol %s is not type compatible\n", var_name);
} }
return; return;
} }
// all other types must strictly match // 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 convert-ability here
fprintf(stderr, "Assignment to local symbol %s is not type compatible\n", var_name); fprintf(stderr, "Assignment to local symbol %s is not type compatible\n", var_name);
} }
} }
@ -232,10 +251,9 @@ static void typecheck_local_statement(struct ast_container *container, struct as
break; break;
struct var_type *var_type = &var->value_type; 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); const char *var_name = getstr(var->var.var_name);
typecheck_var_assignment(container, var_type, expr_type, var_name); typecheck_var_assignment(container, var_type, expr, var_name);
NEXT_PTR_LIST(var); NEXT_PTR_LIST(var);
NEXT_PTR_LIST(expr); NEXT_PTR_LIST(expr);
@ -261,10 +279,9 @@ static void typecheck_expr_statement(struct ast_container *container, struct ast
break; break;
struct var_type *var_type = &var->common_expr.type; 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(container, var_type, expr_type, var_name); typecheck_var_assignment(container, var_type, expr, var_name);
NEXT_PTR_LIST(var); NEXT_PTR_LIST(var);
NEXT_PTR_LIST(expr); NEXT_PTR_LIST(expr);

Loading…
Cancel
Save