diff options
Diffstat (limited to 'lcode.c')
-rw-r--r-- | lcode.c | 63 |
1 files changed, 60 insertions, 3 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.c,v 2.157 2018/02/21 15:49:32 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 2.158 2018/02/26 14:16:05 roberto Exp roberto $ |
3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -40,6 +40,14 @@ | |||
40 | static int codesJ (FuncState *fs, OpCode o, int sj, int k); | 40 | static int codesJ (FuncState *fs, OpCode o, int sj, int k); |
41 | 41 | ||
42 | 42 | ||
43 | |||
44 | /* semantic error */ | ||
45 | l_noret luaK_semerror (LexState *ls, const char *msg) { | ||
46 | ls->t.token = 0; /* remove "near <token>" from final message */ | ||
47 | luaX_syntaxerror(ls, msg); | ||
48 | } | ||
49 | |||
50 | |||
43 | /* | 51 | /* |
44 | ** If expression is a numeric constant, fills 'v' with its value | 52 | ** If expression is a numeric constant, fills 'v' with its value |
45 | ** and returns 1. Otherwise, returns 0. | 53 | ** and returns 1. Otherwise, returns 0. |
@@ -670,6 +678,10 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) { | |||
670 | e->k = VNONRELOC; /* becomes a non-relocatable value */ | 678 | e->k = VNONRELOC; /* becomes a non-relocatable value */ |
671 | break; | 679 | break; |
672 | } | 680 | } |
681 | case VUNDEF: { /* not a real expression */ | ||
682 | luaK_semerror(fs->ls, "'undef' is not a value!!"); | ||
683 | break; | ||
684 | } | ||
673 | case VUPVAL: { /* move value to some (pending) register */ | 685 | case VUPVAL: { /* move value to some (pending) register */ |
674 | e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0); | 686 | e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0); |
675 | e->k = VRELOC; | 687 | e->k = VRELOC; |
@@ -1398,6 +1410,48 @@ static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { | |||
1398 | } | 1410 | } |
1399 | 1411 | ||
1400 | 1412 | ||
1413 | static void normalizeindexed (FuncState *fs, expdesc *v) { | ||
1414 | if (v->k != VINDEXED) { /* not in proper form? */ | ||
1415 | int key = fs->freereg; /* register with key value */ | ||
1416 | luaK_reserveregs(fs, 1); | ||
1417 | switch (v->k) { | ||
1418 | case VINDEXI: | ||
1419 | luaK_int(fs, key, v->u.ind.idx); | ||
1420 | break; | ||
1421 | case VINDEXSTR: | ||
1422 | luaK_codek(fs, key, v->u.ind.idx); | ||
1423 | break; | ||
1424 | case VINDEXUP: | ||
1425 | luaK_codek(fs, key, v->u.ind.idx); | ||
1426 | luaK_codeABC(fs, OP_GETUPVAL, fs->freereg, v->u.ind.t, 0); | ||
1427 | v->u.ind.t = fs->freereg; | ||
1428 | luaK_reserveregs(fs, 1); /* one more register for the upvalue */ | ||
1429 | break; | ||
1430 | default: | ||
1431 | luaK_semerror(fs->ls, "'undef' is not a value!!"); | ||
1432 | break; | ||
1433 | } | ||
1434 | v->u.ind.idx = key; | ||
1435 | v->k = VINDEXED; | ||
1436 | } | ||
1437 | freeregs(fs, v->u.ind.t, v->u.ind.idx); | ||
1438 | } | ||
1439 | |||
1440 | |||
1441 | static void codeisdef (FuncState *fs, int eq, expdesc *v) { | ||
1442 | normalizeindexed(fs, v); | ||
1443 | v->u.info = luaK_codeABCk(fs, OP_ISDEF, 0, v->u.ind.t, v->u.ind.idx, eq); | ||
1444 | v->k = VRELOC; | ||
1445 | } | ||
1446 | |||
1447 | |||
1448 | void luaK_codeundef (FuncState *fs, expdesc *v) { | ||
1449 | normalizeindexed(fs, v); | ||
1450 | v->u.info = luaK_codeABC(fs, OP_UNDEF, v->u.ind.t, v->u.ind.idx, 0); | ||
1451 | v->k = VRELOC; | ||
1452 | } | ||
1453 | |||
1454 | |||
1401 | /* | 1455 | /* |
1402 | ** Apply prefix operation 'op' to expression 'e'. | 1456 | ** Apply prefix operation 'op' to expression 'e'. |
1403 | */ | 1457 | */ |
@@ -1446,7 +1500,7 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { | |||
1446 | break; | 1500 | break; |
1447 | } | 1501 | } |
1448 | case OPR_EQ: case OPR_NE: { | 1502 | case OPR_EQ: case OPR_NE: { |
1449 | if (!tonumeral(v, NULL)) | 1503 | if (!tonumeral(v, NULL) && fs->ls->t.token != TK_UNDEF) |
1450 | luaK_exp2RK(fs, v); | 1504 | luaK_exp2RK(fs, v); |
1451 | /* else keep numeral, which may be an immediate operand */ | 1505 | /* else keep numeral, which may be an immediate operand */ |
1452 | break; | 1506 | break; |
@@ -1543,7 +1597,10 @@ void luaK_posfix (FuncState *fs, BinOpr opr, | |||
1543 | break; | 1597 | break; |
1544 | } | 1598 | } |
1545 | case OPR_EQ: case OPR_NE: { | 1599 | case OPR_EQ: case OPR_NE: { |
1546 | codeeq(fs, opr, e1, e2); | 1600 | if (e2->k == VUNDEF) |
1601 | codeisdef(fs, opr == OPR_NE, e1); | ||
1602 | else | ||
1603 | codeeq(fs, opr, e1, e2); | ||
1547 | break; | 1604 | break; |
1548 | } | 1605 | } |
1549 | case OPR_LT: case OPR_LE: { | 1606 | case OPR_LT: case OPR_LE: { |