@ -141,7 +189,55 @@ The entry point for parsing a local statement is ``localstat()`` in ``lparser.c`
The do-while loop is responsible for parsing the variable names and the type annotations. As each variable name is parsed we detect if there is a type annotation, if and if present the type is recorded in the array ``vars``.
The type of the variable is also passed to ``new_localvar()`` which records this in the ``LocVar`` structure associated with the variable.
Parameter lists have to treated the same way.
::
static void parlist (LexState *ls) {
/* parlist -> [ param { ',' param } ] */
FuncState *fs = ls->fs;
Proto *f = fs->f;
int nparams = 0;
f->is_vararg = 0;
if (ls->t.token != ')') { /* is 'parlist' not empty? */
do {
switch (ls->t.token) {
case TK_NAME: { /* param -> NAME */
/* RAVI change - add type */
declare_localvar(ls);
nparams++;
break;
}
case TK_DOTS: { /* param -> '...' */
luaX_next(ls);
f->is_vararg = 1;
break;
}
default: luaX_syntaxerror(ls, "<name> or '...' expected");
}
} while (!f->is_vararg && testnext(ls, ','));
}
adjustlocalvars(ls, nparams);
f->numparams = cast_byte(fs->nactvar);
luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */
For parameters that are decorated with statc types we need to introduce new instructions to coerce the types at run time. That is what is happening in the for loop at the end.
The ``declare_localvar()`` function passes the type of the variable to ``new_localvar()`` which records this in the ``LocVar`` structure associated with the variable.
::
@ -650,6 +746,10 @@ Additionally when arithmetic operations take place two things need to happen: a)
else
e1->ravi_type = RAVI_TANY;
}
else {
if (op == OP_LEN || op == OP_BNOT)
e1->ravi_type = RAVI_TNUMINT;
}
luaK_fixline(fs, line);
}
}
@ -707,10 +807,79 @@ When expression reference indexed variables, i.e., tables, we need to emit speci
fornum statements
-----------------
The Lua fornum statements create special variables. In order to allows the loop variable to be used in expressions within the loop body we need to set the types of these variables. This is handled in ``fornum()`` as shown below.
The Lua fornum statements create special variables. In order to allows the loop variable to be used in expressions within the loop body we need to set the types of these variables. This is handled in ``fornum()`` as shown below. Additional complexity is due to the fact that Ravi tries to detect when fornum loops use positive integer step and if this step is ``1``; specialized bytecodes are generated for these scenarios.
::
typedef struct Fornuminfo {
ravitype_t type;
int is_constant;
int int_value;
} Fornuminfo;
/* parse the single expressions needed in numerical for loops
* called by fornum()
*/
static int exp1 (LexState *ls, Fornuminfo *info) {
/* Since the local variable in a fornum loop is local to the loop and does
* not use any variable in outer scope we don't need to check its
* type - also the loop is already optimised so no point trying to