diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-03-07 12:55:38 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-03-07 12:55:38 -0300 |
| commit | 4a1612ff9b968fe446bc4dd20460bfaccabeb3b3 (patch) | |
| tree | aef8f8c476e0814c357ead6248a614fb0ca07eac /lcode.c | |
| parent | 464658b16a1a539fd590e1696bfcfb572a77fe13 (diff) | |
| download | lua-4a1612ff9b968fe446bc4dd20460bfaccabeb3b3.tar.gz lua-4a1612ff9b968fe446bc4dd20460bfaccabeb3b3.tar.bz2 lua-4a1612ff9b968fe446bc4dd20460bfaccabeb3b3.zip | |
new experimental syntax using reserved word 'undef'
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: { |
