From c3952c2b98aacebd57abf46efc61823109fe5dd0 Mon Sep 17 00:00:00 2001 From: Dibyendu Majumdar Date: Sun, 1 Sep 2019 14:28:20 +0100 Subject: [PATCH] issue #98 add type conversion for some assignments --- ravi-tests/ravi_test_ast2.expected | 140 +++++++++++++++++++++-------- ravi-tests/ravi_test_ast2.lua | 14 +++ src/ravi_ast_typecheck.c | 49 ++++++---- 3 files changed, 152 insertions(+), 51 deletions(-) diff --git a/ravi-tests/ravi_test_ast2.expected b/ravi-tests/ravi_test_ast2.expected index 0bd8601..5bbaecb 100644 --- a/ravi-tests/ravi_test_ast2.expected +++ b/ravi-tests/ravi_test_ast2.expected @@ -506,6 +506,67 @@ function() false 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() matmul --global symbol ? = @@ -573,45 +634,54 @@ function() , x --local symbol table --[expressions] - --[unary expr start] any - # - --[suffixed expr start] table - --[primary start] table - a --local symbol table - --[primary end] - --[suffixed expr end] + --[unary expr start] integer + @integer + --[unary expr start] any + # + --[suffixed expr start] table + --[primary start] table + a --local symbol table + --[primary end] + --[suffixed expr end] + --[unary expr end] --[unary expr end] , - --[unary expr start] any - # - --[suffixed expr start] any - --[primary start] table - a --local symbol table - --[primary end] - --[suffix list start] - --[Y index start] any - [ - 1 - ] - --[Y index end] - --[suffix list end] - --[suffixed expr end] + --[unary expr start] integer + @integer + --[unary expr start] any + # + --[suffixed expr start] any + --[primary start] table + a --local symbol table + --[primary end] + --[suffix list start] + --[Y index start] any + [ + 1 + ] + --[Y index end] + --[suffix list end] + --[suffixed expr end] + --[unary expr end] --[unary expr end] , - --[unary expr start] any - # - --[suffixed expr start] any - --[primary start] table - b --local symbol table - --[primary end] - --[suffix list start] - --[Y index start] any - [ - 1 - ] - --[Y index end] - --[suffix list end] - --[suffixed expr end] + --[unary expr start] integer + @integer + --[unary expr start] any + # + --[suffixed expr start] any + --[primary start] table + b --local symbol table + --[primary end] + --[suffix list start] + --[Y index start] any + [ + 1 + ] + --[Y index end] + --[suffix list end] + --[suffixed expr end] + --[unary expr end] --[unary expr end] , { --[table constructor start] table diff --git a/ravi-tests/ravi_test_ast2.lua b/ravi-tests/ravi_test_ast2.lua index bcf2076..46bc69c 100644 --- a/ravi-tests/ravi_test_ast2.lua +++ b/ravi-tests/ravi_test_ast2.lua @@ -109,6 +109,20 @@ return false ]] 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= [[function matmul(a: table, b: table) assert(@integer(#a[1]) == #b); diff --git a/src/ravi_ast_typecheck.c b/src/ravi_ast_typecheck.c index 19c6a79..5e84cfa 100644 --- a/src/ravi_ast_typecheck.c +++ b/src/ravi_ast_typecheck.c @@ -29,9 +29,6 @@ static void typecheck_unaryop(struct ast_container *container, struct ast_node * if (subexpr_type == RAVI_TARRAYINT || subexpr_type == RAVI_TARRAYFLT) { set_type(node->unary_expr.type, RAVI_TNUMINT); } - else if (subexpr_type == RAVI_TTABLE) { - // FIXME we need insert a TO_INT expression; - } break; case OPR_TO_INTEGER: 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); } -static void typecheck_var_assignment(struct ast_container *container, struct var_type *var_type, - struct var_type *expr_type, const char *var_name) { +static void insert_cast(struct ast_container *container, struct ast_node *expr, UnOpr opcode, ravitype_t target_type) { + /* 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) // 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? + struct var_type *expr_type = &expr->common_expr.type; + + if (var_type->type_code == RAVI_TNUMINT) { + /* 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); } return; } - // 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); } } @@ -232,10 +251,9 @@ static void typecheck_local_statement(struct ast_container *container, struct as break; 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(container, var_type, expr_type, var_name); + typecheck_var_assignment(container, var_type, expr, var_name); NEXT_PTR_LIST(var); NEXT_PTR_LIST(expr); @@ -261,10 +279,9 @@ static void typecheck_expr_statement(struct ast_container *container, struct ast 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(container, var_type, expr_type, var_name); + typecheck_var_assignment(container, var_type, expr, var_name); NEXT_PTR_LIST(var); NEXT_PTR_LIST(expr);