Skip to content

Commit

Permalink
#230 allow values of type ANY to be assigned to variables with static…
Browse files Browse the repository at this point in the history
… types, but insert type assertion
  • Loading branch information
dibyendumajumdar committed Jul 11, 2021
1 parent a4b7079 commit c4be299
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 5 deletions.
37 changes: 37 additions & 0 deletions src/lcode.c
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,11 @@ static void check_valid_store(FuncState *fs, expdesc *var, expdesc *ex) {
if (var->ravi_type_map == RAVI_TM_FLOAT) {
if (ex_ravi_type_map == RAVI_TM_FLOAT)
return;
if (ex_ravi_type_map == RAVI_TM_ANY) {
int e = luaK_exp2RK(fs, ex);
luaK_codeABC(fs, OP_RAVI_TOFLT, e, 0, 0);
return;
}
luaX_syntaxerror(
fs->ls,
luaO_pushfstring(
Expand All @@ -897,6 +902,11 @@ static void check_valid_store(FuncState *fs, expdesc *var, expdesc *ex) {
else if (var->ravi_type_map == RAVI_TM_INTEGER) {
if (ex_ravi_type_map == RAVI_TM_INTEGER)
return;
if (ex_ravi_type_map == RAVI_TM_ANY) {
int e = luaK_exp2RK(fs, ex);
luaK_codeABC(fs, OP_RAVI_TOINT, e, 0, 0);
return;
}
luaX_syntaxerror(
fs->ls,
luaO_pushfstring(
Expand All @@ -906,6 +916,18 @@ static void check_valid_store(FuncState *fs, expdesc *var, expdesc *ex) {
else if ((var->ravi_type_map & (~(RAVI_TM_INTEGER_ARRAY | RAVI_TM_FLOAT_ARRAY | RAVI_TM_TABLE))) == 0) {
if (ex_ravi_type_map == var->ravi_type_map)
return;
if (ex_ravi_type_map == RAVI_TM_ANY) {
OpCode opCode;
if (var->ravi_type_map & RAVI_TM_INTEGER_ARRAY)
opCode = OP_RAVI_TOIARRAY;
else if (var->ravi_type_map & RAVI_TM_FLOAT_ARRAY)
opCode = OP_RAVI_TOFARRAY;
else
opCode = OP_RAVI_TOTAB;
int e = luaK_exp2RK(fs, ex);
luaK_codeABC(fs, opCode, e, 0, 0);
return;
}
luaX_syntaxerror(
fs->ls,
luaO_pushfstring(
Expand All @@ -916,6 +938,11 @@ static void check_valid_store(FuncState *fs, expdesc *var, expdesc *ex) {
else if (var->ravi_type_map == RAVI_TM_STRING_OR_NIL) {
if ((ex_ravi_type_map & ~RAVI_TM_STRING_OR_NIL) == 0)
return;
if (ex_ravi_type_map == RAVI_TM_ANY) {
int e = luaK_exp2RK(fs, ex);
luaK_codeABC(fs, OP_RAVI_TOSTRING, e, 0, 0);
return;
}
luaX_syntaxerror(
fs->ls,
luaO_pushfstring(
Expand All @@ -925,6 +952,11 @@ static void check_valid_store(FuncState *fs, expdesc *var, expdesc *ex) {
else if (var->ravi_type_map == RAVI_TM_FUNCTION_OR_NIL) {
if ((ex_ravi_type_map & ~RAVI_TM_FUNCTION_OR_NIL) == 0)
return;
if (ex_ravi_type_map == RAVI_TM_ANY) {
int e = luaK_exp2RK(fs, ex);
luaK_codeABC(fs, OP_RAVI_TOCLOSURE, e, 0, 0);
return;
}
luaX_syntaxerror(
fs->ls,
luaO_pushfstring(
Expand All @@ -935,6 +967,11 @@ static void check_valid_store(FuncState *fs, expdesc *var, expdesc *ex) {
if ((ex_ravi_type_map & ~RAVI_TM_USERDATA_OR_NIL) == 0 &&
(!(ex_ravi_type_map & RAVI_TM_USERDATA) || (var->usertype && var->usertype == ex->usertype)))
return;
if (ex_ravi_type_map == RAVI_TM_ANY) {
int e = luaK_exp2RK(fs, ex);
luaK_codeABx(fs, OP_RAVI_TOTYPE, e, luaK_stringK(fs, var->usertype));
return;
}
luaX_syntaxerror(
fs->ls,
luaO_pushfstring(
Expand Down
6 changes: 5 additions & 1 deletion src/lparser.c
Original file line number Diff line number Diff line change
Expand Up @@ -1498,7 +1498,11 @@ static void ravi_typecheck(LexState *ls, expdesc *v, ravi_type_map *var_types,
luaK_exp2nextreg(ls->fs, v);
ravi_code_typecoersion(ls, v->u.info, vartype, usertype);
}
else {
else if (v_type_map == RAVI_TM_ANY) {
luaK_exp2nextreg(ls->fs, v);
ravi_code_typecoersion(ls, v->u.info, vartype, NULL);
}
else {
luaX_syntaxerror(ls, "Invalid local assignment");
}
}
Expand Down
4 changes: 0 additions & 4 deletions tests/language/ravi_errors.ravi
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,9 @@ local function checksyntax (prog, extra, token, line)
end
-- =================== end copy from Lua testsuite ===============

checkmessage('local t: table = {}; local t2: table = {}; t=t2[1]', 'Invalid assignment: table expected')
checkmessage('local t: table = {}; t=1', 'Invalid assignment: table expected')
checkmessage('local t: table = {}; t=function() end', 'table expected')
checkmessage('local t: table = {}; local t2: number[] = {}; t=t2', 'Invalid assignment: table expected')
checkmessage('local t: table = {}; local t2: table = { data={} }; t=t2.data', 'Invalid assignment: table expected')
checkmessage('local t: table = {}; local f=function() t = 1 end; f()', 'upvalue of table type, cannot be set to non table value')
checkmessage('local t: table = {}; local x=function() return 0 end; local f=function() t = x() end; f()', 'upvalue of table type, cannot be set to non table value')
checkmessage('local t: table = {}; local x=function() t[1] = 1; local f=function() t = 1 end; f(); end; x()', 'upvalue of table type, cannot be set to non table value')
Expand All @@ -49,7 +47,6 @@ checkmessage('local t: integer[] = {}; local t2: number[] = {}; t=t2', 'Invalid
checkmessage('local t: integer[] = {}; local t2: table = {}; t=t2', 'Invalid assignment: integer[] expected')
checkmessage('local t: integer[] = {}; local t2: table = {true}; t[1]=t2[1]', 'integer expected')
checkmessage('local t: integer[] = {}; local t2: table = {"hi"}; t[1]=t2[1]', 'integer expected')
checkmessage('local t: integer[] = {}; local t2: table = { data={} }; t=t2.data', 'Invalid assignment: integer[] expected')
checkmessage('local t: integer[] = {}; local f=function() t = 1 end; f()', 'upvalue of integer[] type, cannot be set to non integer[] value')
checkmessage('local t: integer[] = {}; local x=function() return 0 end; local f=function() t = x() end; f()', 'upvalue of integer[] type, cannot be set to non integer[] value')
checkmessage('local t: integer[] = {}; local x=function() t[1] = 1; local f=function() t = 1 end; f(); end; x()', 'upvalue of integer[] type, cannot be set to non integer[] value')
Expand All @@ -75,7 +72,6 @@ checkmessage('local t: number[] = {}; local t2: integer[] = {}; t=t2', 'Invalid
checkmessage('local t: number[] = {}; local t2: table = {}; t=t2', 'Invalid assignment: number[] expected')
checkmessage('local t: number[] = {}; local t2: table = {true}; t[1]=t2[1]', 'number expected')
checkmessage('local t: number[] = {}; local t2: table = {"hi"}; t[1]=t2[1]', 'number expected')
checkmessage('local t: number[] = {}; local t2: table = { data={} }; t=t2.data', 'Invalid assignment: number[] expected')
checkmessage('local t: number[] = {}; local f=function() t = 1 end; f()', 'upvalue of number[] type, cannot be set to non number[] value')
checkmessage('local t: number[] = {}; local x=function() return 0 end; local f=function() t = x() end; f()', 'upvalue of number[] type, cannot be set to non number[] value')
checkmessage('local t: number[] = {}; local x=function() t[1] = 1; local f=function() t = 1 end; f(); end; x()', 'upvalue of number[] type, cannot be set to non number[] value')
Expand Down

0 comments on commit c4be299

Please sign in to comment.