issue #61 more tests

pull/81/head
Dibyendu Majumdar 9 years ago
parent 41ccddecb2
commit 085f035917

@ -23,7 +23,7 @@ typedef enum {
VFALSE,
VK, /* info = index of constant in 'k' */
VKFLT, /* nval = numerical float value */
VKINT, /* nval = numerical integer value */
VKINT, /* ival = numerical integer value */
VNONRELOC, /* info = result register */
VLOCAL, /* info = local register */
VUPVAL, /* info = index of upvalue in 'upvalues' */
@ -128,13 +128,11 @@ struct BlockCnt; /* defined in lparser.c */
When a function is the topmost function being parsed, the
registers between LexState->dyd.actvar.arr[nactvar]
and LexState->dyd.actvar.arr[freereg-1]
are used by the parser for evaluating expressions -
i.e. these are part of the local registers available to
the function
are used by the parser for evaluating expressions.
Note that function parameters are handled in the
same way as local variables.
example of what all this means:
Example of what all this means:
Let's say we are parsing following chunk of code
function testfunc()
@ -227,6 +225,8 @@ LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
Dyndata *dyd, const char *name, int firstchar);
LUAI_FUNC const char *raviY_typename(ravitype_t tt);
/* Special printf that recognises following conversions:
* %e - expdesc *
* %v - LocVar *

@ -16,7 +16,7 @@ end
local function checkmessage (prog, msg)
local m = doit(prog)
--print(m)
-- print(m)
assert(string.find(m, msg, 1, true))
end
@ -83,3 +83,7 @@ checkmessage('local t: number = function() return "hell" end', 'Invalid local as
checkmessage('local function j() return "hell" end; local t: number = j()', 'number expected')
checkmessage('local t: number = 5.5; local x=function() return "string" end; local f=function() t = x() end; f()', 'upvalue of number type, cannot be set to non number value')
checkmessage('local t: number = 5', 'Invalid local assignment')
checkmessage('for i=1,10 do i="a" end', 'Invalid assignment: integer expected')
checkmessage('for i=1,10 do local f = function() i="a" end; f(); end', 'upvalue of integer type, cannot be set to non integer value')

@ -446,14 +446,12 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
op = OP_RAVI_GETTABLE_AF;
else if (e->ravi_type == RAVI_TARRAYINT && e->u.ind.key_type == RAVI_TNUMINT)
op = OP_RAVI_GETTABLE_AI;
else {
if (e->ravi_type == RAVI_TTABLE && e->u.ind.key_type == RAVI_TSTRING)
op = OP_RAVI_GETTABLE_S;
else if (e->ravi_type == RAVI_TTABLE && e->u.ind.key_type == RAVI_TNUMINT)
op = OP_RAVI_GETTABLE_I;
else
op = OP_GETTABLE;
}
else if (e->ravi_type == RAVI_TTABLE && e->u.ind.key_type == RAVI_TSTRING)
op = OP_RAVI_GETTABLE_S;
else if (e->ravi_type == RAVI_TTABLE && e->u.ind.key_type == RAVI_TNUMINT)
op = OP_RAVI_GETTABLE_I;
else
op = OP_GETTABLE;
if (e->ravi_type == RAVI_TARRAYFLT || e->ravi_type == RAVI_TARRAYINT)
/* set the type of resulting expression */
e->ravi_type = e->ravi_type == RAVI_TARRAYFLT ? RAVI_TNUMFLT : RAVI_TNUMINT;
@ -720,8 +718,8 @@ static OpCode check_valid_setupval(FuncState *fs, expdesc *var, expdesc *ex) {
luaX_syntaxerror(fs->ls,
luaO_pushfstring(fs->ls->L, "Invalid assignment of "
"upvalue: upvalue type "
"%d, expression type %d",
var->ravi_type, ex->ravi_type));
"%s, expression type %s",
raviY_typename(var->ravi_type), raviY_typename(ex->ravi_type)));
}
return op;
}
@ -919,8 +917,9 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
values (see for example Lua test events.lua) so we can't raise an error
here.
*/
if (t->ravi_type != RAVI_TTABLE && t->ravi_type != RAVI_TARRAYFLT && t->ravi_type != RAVI_TARRAYINT)
if (t->ravi_type != RAVI_TTABLE && t->ravi_type != RAVI_TARRAYFLT && t->ravi_type != RAVI_TARRAYINT) {
t->ravi_type = RAVI_TANY;
}
}

@ -65,28 +65,28 @@ typedef struct BlockCnt {
void ravi_set_debuglevel(int level) { ravi_parser_debug = level; }
/* RAVI - return the type name */
static const char *get_typename(ravitype_t tt) {
const char *raviY_typename(ravitype_t tt) {
switch (tt) {
case RAVI_TNIL:
return "nil";
case RAVI_TBOOLEAN:
return "B";
return "boolean";
case RAVI_TNUMFLT:
return "D";
return "number";
case RAVI_TNUMINT:
return "I";
return "integr";
case RAVI_TSTRING:
return "S";
return "string";
case RAVI_TFUNCTION:
return "F";
return "function";
case RAVI_TARRAYINT:
return "[I";
return "integer[]";
case RAVI_TARRAYFLT:
return "[F";
return "number[]";
case RAVI_TUSERDATA:
return "U";
return "userdata";
case RAVI_TTABLE:
return "T";
return "table";
default:
return "?";
}
@ -97,73 +97,73 @@ static void print_expdesc(FILE *fp, FuncState *fs, const expdesc *e) {
char buf[80] = {0};
switch (e->k) {
case VVOID:
fprintf(fp, "{p=%p, k=VVOID, type=%s}", e, get_typename(e->ravi_type));
fprintf(fp, "{p=%p, k=VVOID, type=%s}", e, raviY_typename(e->ravi_type));
break;
case VNIL:
fprintf(fp, "{p=%p, k=VNIL, type=%s}", e, get_typename(e->ravi_type));
fprintf(fp, "{p=%p, k=VNIL, type=%s}", e, raviY_typename(e->ravi_type));
break;
case VTRUE:
fprintf(fp, "{p=%p, k=VTRUE, type=%s}", e, get_typename(e->ravi_type));
fprintf(fp, "{p=%p, k=VTRUE, type=%s}", e, raviY_typename(e->ravi_type));
break;
case VFALSE:
fprintf(fp, "{p=%p, k=VFALSE, type=%s}", e, get_typename(e->ravi_type));
fprintf(fp, "{p=%p, k=VFALSE, type=%s}", e, raviY_typename(e->ravi_type));
break;
case VK:
fprintf(fp, "{p=%p, k=VK, Kst=%d, type=%s}", e, e->u.info,
get_typename(e->ravi_type));
raviY_typename(e->ravi_type));
break;
case VKFLT:
fprintf(fp, "{p=%p, k=VKFLT, n=%f, type=%s}", e, e->u.nval,
get_typename(e->ravi_type));
raviY_typename(e->ravi_type));
break;
case VKINT:
fprintf(fp, "{p=%p, k=VKINT, n=%lld, type=%s}", e, e->u.ival,
get_typename(e->ravi_type));
raviY_typename(e->ravi_type));
break;
case VNONRELOC:
fprintf(fp, "{p=%p, k=VNONRELOC, register=%d %s, type=%s}", e, e->u.info,
get_typename(raviY_get_register_typeinfo(fs, e->u.info)),
get_typename(e->ravi_type));
raviY_typename(raviY_get_register_typeinfo(fs, e->u.info)),
raviY_typename(e->ravi_type));
break;
case VLOCAL:
fprintf(fp, "{p=%p, k=VLOCAL, register=%d, type=%s}", e, e->u.info,
get_typename(e->ravi_type));
raviY_typename(e->ravi_type));
break;
case VUPVAL:
fprintf(fp, "{p=%p, k=VUPVAL, idx=%d, type=%s}", e, e->u.info,
get_typename(e->ravi_type));
raviY_typename(e->ravi_type));
break;
case VINDEXED:
fprintf(fp,
"{p=%p, k=VINDEXED, tablereg=%d, indexreg=%d, vtype=%s, type=%s}",
e, e->u.ind.t, e->u.ind.idx,
(e->u.ind.vt == VLOCAL) ? "VLOCAL" : "VUPVAL",
get_typename(e->ravi_type));
raviY_typename(e->ravi_type));
break;
case VJMP:
fprintf(fp, "{p=%p, k=VJMP, pc=%d, instruction=(%s), type=%s}", e,
e->u.info,
raviP_instruction_to_str(buf, sizeof buf, getcode(fs, e)),
get_typename(e->ravi_type));
raviY_typename(e->ravi_type));
break;
case VRELOCABLE:
fprintf(fp, "{p=%p, k=VRELOCABLE, pc=%d, instruction=(%s), type=%s}", e,
e->u.info,
raviP_instruction_to_str(buf, sizeof buf, getcode(fs, e)),
get_typename(e->ravi_type));
raviY_typename(e->ravi_type));
break;
case VCALL:
fprintf(
fp, "{p=%p, k=VCALL, pc=%d, instruction=(%s %s), type=%s}", e,
e->u.info, raviP_instruction_to_str(buf, sizeof buf, getcode(fs, e)),
get_typename(raviY_get_register_typeinfo(fs, GETARG_A(getcode(fs, e)))),
get_typename(e->ravi_type));
raviY_typename(raviY_get_register_typeinfo(fs, GETARG_A(getcode(fs, e)))),
raviY_typename(e->ravi_type));
break;
case VVARARG:
fprintf(fp, "{p=%p, k=VVARARG, pc=%d, instruction=(%s), type=%s}", e,
e->u.info,
raviP_instruction_to_str(buf, sizeof buf, getcode(fs, e)),
get_typename(e->ravi_type));
raviY_typename(e->ravi_type));
break;
}
}
@ -185,7 +185,7 @@ void raviY_printf(FuncState *fs, const char *format, ...) {
v = va_arg(ap, LocVar *);
const char *s = getstr(v->varname);
printf("var={%s startpc=%d endpc=%d, type=%s}", s, v->startpc, v->endpc,
get_typename(v->ravi_type));
raviY_typename(v->ravi_type));
cp++;
} else if (cp[0] == '%' && cp[1] == 'o') {
Instruction i;
@ -211,7 +211,7 @@ void raviY_printf(FuncState *fs, const char *format, ...) {
} else if (cp[0] == '%' && cp[1] == 't') {
ravitype_t i;
i = va_arg(ap, ravitype_t);
fputs(get_typename(i), stdout);
fputs(raviY_typename(i), stdout);
cp++;
} else {
fputc(*cp, stdout);
@ -317,7 +317,7 @@ static void init_exp (expdesc *e, expkind k, int info, ravitype_t tt) {
}
/* create a string constant expression, constant's location stored in
* e->u.info, e->ravi_type = RAVI_TSTRING
* e->u.info, e->ravi_type = RAVI_TSTRING, e->k = VK
*/
static void codestring (LexState *ls, expdesc *e, TString *s) {
init_exp(e, VK, luaK_stringK(ls->fs, s), RAVI_TSTRING);
@ -576,7 +576,10 @@ static void ravi_code_typecoersion(LexState *ls, int reg, ravitype_t ravi_type)
// TODO handle string, function, userdata, boolean types
}
/* RAVI code an instruction to initialize a typed value */
/* RAVI code an instruction to initialize a scalar typed value
For array and table types however raise an error as uninitialized value
would cause a null pointer and therefore memory fault
*/
static void ravi_code_setzero(FuncState *fs, int reg, ravitype_t ravi_type) {
if (ravi_type == RAVI_TNUMFLT || ravi_type == RAVI_TNUMINT)
/* code an instruction to convert in place */

Loading…
Cancel
Save