From 4a1612ff9b968fe446bc4dd20460bfaccabeb3b3 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 7 Mar 2018 12:55:38 -0300 Subject: new experimental syntax using reserved word 'undef' --- lcode.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 3 deletions(-) (limited to 'lcode.c') diff --git a/lcode.c b/lcode.c index 8f3c68c0..95e87f31 100644 --- a/lcode.c +++ b/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 2.157 2018/02/21 15:49:32 roberto Exp roberto $ +** $Id: lcode.c,v 2.158 2018/02/26 14:16:05 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -40,6 +40,14 @@ static int codesJ (FuncState *fs, OpCode o, int sj, int k); + +/* semantic error */ +l_noret luaK_semerror (LexState *ls, const char *msg) { + ls->t.token = 0; /* remove "near " from final message */ + luaX_syntaxerror(ls, msg); +} + + /* ** If expression is a numeric constant, fills 'v' with its value ** and returns 1. Otherwise, returns 0. @@ -670,6 +678,10 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) { e->k = VNONRELOC; /* becomes a non-relocatable value */ break; } + case VUNDEF: { /* not a real expression */ + luaK_semerror(fs->ls, "'undef' is not a value!!"); + break; + } case VUPVAL: { /* move value to some (pending) register */ e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0); e->k = VRELOC; @@ -1398,6 +1410,48 @@ static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { } +static void normalizeindexed (FuncState *fs, expdesc *v) { + if (v->k != VINDEXED) { /* not in proper form? */ + int key = fs->freereg; /* register with key value */ + luaK_reserveregs(fs, 1); + switch (v->k) { + case VINDEXI: + luaK_int(fs, key, v->u.ind.idx); + break; + case VINDEXSTR: + luaK_codek(fs, key, v->u.ind.idx); + break; + case VINDEXUP: + luaK_codek(fs, key, v->u.ind.idx); + luaK_codeABC(fs, OP_GETUPVAL, fs->freereg, v->u.ind.t, 0); + v->u.ind.t = fs->freereg; + luaK_reserveregs(fs, 1); /* one more register for the upvalue */ + break; + default: + luaK_semerror(fs->ls, "'undef' is not a value!!"); + break; + } + v->u.ind.idx = key; + v->k = VINDEXED; + } + freeregs(fs, v->u.ind.t, v->u.ind.idx); +} + + +static void codeisdef (FuncState *fs, int eq, expdesc *v) { + normalizeindexed(fs, v); + v->u.info = luaK_codeABCk(fs, OP_ISDEF, 0, v->u.ind.t, v->u.ind.idx, eq); + v->k = VRELOC; +} + + +void luaK_codeundef (FuncState *fs, expdesc *v) { + normalizeindexed(fs, v); + v->u.info = luaK_codeABC(fs, OP_UNDEF, v->u.ind.t, v->u.ind.idx, 0); + v->k = VRELOC; +} + + /* ** Apply prefix operation 'op' to expression 'e'. */ @@ -1446,7 +1500,7 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { break; } case OPR_EQ: case OPR_NE: { - if (!tonumeral(v, NULL)) + if (!tonumeral(v, NULL) && fs->ls->t.token != TK_UNDEF) luaK_exp2RK(fs, v); /* else keep numeral, which may be an immediate operand */ break; @@ -1543,7 +1597,10 @@ void luaK_posfix (FuncState *fs, BinOpr opr, break; } case OPR_EQ: case OPR_NE: { - codeeq(fs, opr, e1, e2); + if (e2->k == VUNDEF) + codeisdef(fs, opr == OPR_NE, e1); + else + codeeq(fs, opr, e1, e2); break; } case OPR_LT: case OPR_LE: { -- cgit v1.2.3-55-g6feb