|
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 | 3 | ** Code generator for Lua |
4 | 4 | ** See Copyright Notice in lua.h |
5 | 5 | */ |
|
40 | 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 | 52 | ** If expression is a numeric constant, fills 'v' with its value |
45 | 53 | ** and returns 1. Otherwise, returns 0. |
@@ -670,6 +678,10 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) { |
670 | 678 | e->k = VNONRELOC; /* becomes a non-relocatable value */ |
671 | 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 | 685 | case VUPVAL: { /* move value to some (pending) register */ |
674 | 686 | e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0); |
675 | 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 | 1456 | ** Apply prefix operation 'op' to expression 'e'. |
1403 | 1457 | */ |
@@ -1446,7 +1500,7 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { |
1446 | 1500 | break; |
1447 | 1501 | } |
1448 | 1502 | case OPR_EQ: case OPR_NE: { |
1449 | | - if (!tonumeral(v, NULL)) |
| 1503 | + if (!tonumeral(v, NULL) && fs->ls->t.token != TK_UNDEF) |
1450 | 1504 | luaK_exp2RK(fs, v); |
1451 | 1505 | /* else keep numeral, which may be an immediate operand */ |
1452 | 1506 | break; |
@@ -1543,7 +1597,10 @@ void luaK_posfix (FuncState *fs, BinOpr opr, |
1543 | 1597 | break; |
1544 | 1598 | } |
1545 | 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 | 1604 | break; |
1548 | 1605 | } |
1549 | 1606 | case OPR_LT: case OPR_LE: { |
|
0 commit comments