diff options
author | Li Jin <dragon-fly@qq.com> | 2022-07-26 18:05:23 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2022-07-26 18:05:23 +0800 |
commit | 0f5bdeaeba0f04e49c47f4a2be55b14185a7dfdd (patch) | |
tree | b5baa6c385ce58c60615ff0577a1e2b6850f044d | |
parent | e191defb6545509a4ae0b402f2fac1fbe18551cd (diff) | |
download | yuescript-0f5bdeaeba0f04e49c47f4a2be55b14185a7dfdd.tar.gz yuescript-0f5bdeaeba0f04e49c47f4a2be55b14185a7dfdd.tar.bz2 yuescript-0f5bdeaeba0f04e49c47f4a2be55b14185a7dfdd.zip |
fix missing checks and issues related to destrucuring in if branches.
-rw-r--r-- | spec/inputs/assign.yue | 50 | ||||
-rw-r--r-- | spec/inputs/cond.yue | 2 | ||||
-rw-r--r-- | spec/inputs/global.yue | 4 | ||||
-rw-r--r-- | spec/inputs/metatable.yue | 2 | ||||
-rw-r--r-- | spec/inputs/using.yue | 7 | ||||
-rw-r--r-- | spec/outputs/assign.lua | 93 | ||||
-rw-r--r-- | spec/outputs/cond.lua | 2 | ||||
-rw-r--r-- | spec/outputs/global.lua | 4 | ||||
-rw-r--r-- | spec/outputs/metatable.lua | 2 | ||||
-rw-r--r-- | spec/outputs/using.lua | 7 | ||||
-rwxr-xr-x | src/yuescript/yue_compiler.cpp | 200 |
11 files changed, 273 insertions, 100 deletions
diff --git a/spec/inputs/assign.yue b/spec/inputs/assign.yue index dac2ba3..d04bcb8 100644 --- a/spec/inputs/assign.yue +++ b/spec/inputs/assign.yue | |||
@@ -8,20 +8,20 @@ _ = -> | |||
8 | 8 | ||
9 | a,b,c,d = 1,2,3,4 | 9 | a,b,c,d = 1,2,3,4 |
10 | 10 | ||
11 | hello[232], (5+5)[121], hello, x[99] = 100, 200, 300 | 11 | hello[232], (5+5)[121], hello, x[99] = 100, 200, 300, 400 |
12 | 12 | ||
13 | joop = 12 | 13 | joop = 12 |
14 | 14 | ||
15 | joop = 2345 | 15 | joop = 2345 |
16 | 16 | ||
17 | a, b = if hello | 17 | a, b = if hello |
18 | "hello" | 18 | "hello", nil |
19 | else | 19 | else |
20 | "nothing", "yeah" | 20 | "nothing", "yeah" |
21 | 21 | ||
22 | 22 | ||
23 | a, b = if hello | 23 | a, b = if hello |
24 | if yeah then "one", "two" else "mmhh" | 24 | if yeah then "one", "two" else "mmhh", nil |
25 | else | 25 | else |
26 | print "the other" | 26 | print "the other" |
27 | "nothing", "yeah" | 27 | "nothing", "yeah" |
@@ -31,3 +31,47 @@ c, d = 1, 2 if true | |||
31 | x = (do | 31 | x = (do |
32 | f! | 32 | f! |
33 | 123) if f = getHandler! | 33 | 123) if f = getHandler! |
34 | |||
35 | (using nil) <- _ | ||
36 | |||
37 | a.# = do | ||
38 | print 123 | ||
39 | {} | ||
40 | |||
41 | do | ||
42 | {a, b} = switch c | ||
43 | when "a" | ||
44 | tb | ||
45 | when "b" | ||
46 | f! | ||
47 | |||
48 | a[] = if x | ||
49 | 1 | ||
50 | else | ||
51 | 2 | ||
52 | |||
53 | do | ||
54 | a, b[] = if x | ||
55 | switch y | ||
56 | when 1 | ||
57 | f! | ||
58 | |||
59 | do | ||
60 | a, {b} = if x | ||
61 | f! | ||
62 | else | ||
63 | 123, tb | ||
64 | |||
65 | do | ||
66 | a, b[], c, d.add# = if x | ||
67 | switch y | ||
68 | when 1 | ||
69 | f! | ||
70 | elseif x2 | ||
71 | if y2 | ||
72 | f1! | ||
73 | else | ||
74 | print "hello" | ||
75 | do | ||
76 | print 123 | ||
77 | 1, f2! | ||
diff --git a/spec/inputs/cond.yue b/spec/inputs/cond.yue index 773ef91..9981e93 100644 --- a/spec/inputs/cond.yue +++ b/spec/inputs/cond.yue | |||
@@ -158,7 +158,7 @@ do | |||
158 | ---------------- | 158 | ---------------- |
159 | 159 | ||
160 | a = 12 | 160 | a = 12 |
161 | a,c,b = "cool" if something | 161 | a,c,b = "cool", nil, nil if something |
162 | 162 | ||
163 | 163 | ||
164 | 164 | ||
diff --git a/spec/inputs/global.yue b/spec/inputs/global.yue index 7d6cfde..59cf764 100644 --- a/spec/inputs/global.yue +++ b/spec/inputs/global.yue | |||
@@ -1,6 +1,6 @@ | |||
1 | 1 | ||
2 | do | 2 | do |
3 | global a,b,c = 223, 343 | 3 | global a,b,c = 223, 343, nil |
4 | global cool = "dad" | 4 | global cool = "dad" |
5 | 5 | ||
6 | do | 6 | do |
@@ -9,7 +9,7 @@ do | |||
9 | 9 | ||
10 | do | 10 | do |
11 | global a,b,c | 11 | global a,b,c |
12 | a,b,c,d = "hello" | 12 | a,b,c,d = "hello", nil, nil, nil |
13 | 13 | ||
14 | 14 | ||
15 | do | 15 | do |
diff --git a/spec/inputs/metatable.yue b/spec/inputs/metatable.yue index 7e9b4f2..86991c2 100644 --- a/spec/inputs/metatable.yue +++ b/spec/inputs/metatable.yue | |||
@@ -24,7 +24,7 @@ do | |||
24 | 24 | ||
25 | x.abc, a.b.# = 123, {} | 25 | x.abc, a.b.# = 123, {} |
26 | func!.# = mt --, extra | 26 | func!.# = mt --, extra |
27 | a, b.c.#, d, e = 1, mt, "abc" | 27 | a, b.c.#, d, e = 1, mt, "abc", nil |
28 | 28 | ||
29 | is_same = a.#.__index == a.index# | 29 | is_same = a.#.__index == a.index# |
30 | 30 | ||
diff --git a/spec/inputs/using.yue b/spec/inputs/using.yue index 9944b60..31afaab 100644 --- a/spec/inputs/using.yue +++ b/spec/inputs/using.yue | |||
@@ -20,3 +20,10 @@ _ = (a,e,f using a,b,c, hello) -> | |||
20 | 20 | ||
21 | _ = (using nil) -> | 21 | _ = (using nil) -> |
22 | hello or= 2 | 22 | hello or= 2 |
23 | |||
24 | do | ||
25 | a = {} | ||
26 | (using nil) <- _ | ||
27 | {x, y} = a | ||
28 | |||
29 | nil | ||
diff --git a/spec/outputs/assign.lua b/spec/outputs/assign.lua index 628f763..c7f2e20 100644 --- a/spec/outputs/assign.lua +++ b/spec/outputs/assign.lua | |||
@@ -7,14 +7,14 @@ _ = function() | |||
7 | local a, b, c | 7 | local a, b, c |
8 | a, b, c, d = 1, 2, 3, 4 | 8 | a, b, c, d = 1, 2, 3, 4 |
9 | local hello | 9 | local hello |
10 | hello[232], (5 + 5)[121], hello, x[99] = 100, 200, 300 | 10 | hello[232], (5 + 5)[121], hello, x[99] = 100, 200, 300, 400 |
11 | joop = 12 | 11 | joop = 12 |
12 | end | 12 | end |
13 | end | 13 | end |
14 | local joop = 2345 | 14 | local joop = 2345 |
15 | local a, b | 15 | local a, b |
16 | if hello then | 16 | if hello then |
17 | a, b = "hello" | 17 | a, b = "hello", nil |
18 | else | 18 | else |
19 | a, b = "nothing", "yeah" | 19 | a, b = "nothing", "yeah" |
20 | end | 20 | end |
@@ -22,7 +22,7 @@ if hello then | |||
22 | if yeah then | 22 | if yeah then |
23 | a, b = "one", "two" | 23 | a, b = "one", "two" |
24 | else | 24 | else |
25 | a, b = "mmhh" | 25 | a, b = "mmhh", nil |
26 | end | 26 | end |
27 | else | 27 | else |
28 | print("the other") | 28 | print("the other") |
@@ -42,3 +42,90 @@ do | |||
42 | end)()) | 42 | end)()) |
43 | end | 43 | end |
44 | end | 44 | end |
45 | return _(function() | ||
46 | setmetatable(a, (function() | ||
47 | print(123) | ||
48 | return { } | ||
49 | end)()) | ||
50 | do | ||
51 | local a, b | ||
52 | if "a" == c then | ||
53 | do | ||
54 | local _obj_0 = tb | ||
55 | a, b = _obj_0[1], _obj_0[2] | ||
56 | end | ||
57 | elseif "b" == c then | ||
58 | do | ||
59 | local _obj_0 = f() | ||
60 | a, b = _obj_0[1], _obj_0[2] | ||
61 | end | ||
62 | end | ||
63 | end | ||
64 | if x then | ||
65 | a[#a + 1] = 1 | ||
66 | else | ||
67 | a[#a + 1] = 2 | ||
68 | end | ||
69 | do | ||
70 | local a | ||
71 | if x then | ||
72 | do | ||
73 | local _exp_0 = y | ||
74 | if 1 == _exp_0 then | ||
75 | do | ||
76 | local _obj_0, _obj_1 = f() | ||
77 | b[#b + 1] = _obj_1 | ||
78 | a = _obj_0 | ||
79 | end | ||
80 | end | ||
81 | end | ||
82 | end | ||
83 | end | ||
84 | do | ||
85 | local a | ||
86 | local b | ||
87 | if x then | ||
88 | do | ||
89 | local _obj_0, _obj_1 = f() | ||
90 | a = _obj_0 | ||
91 | b = _obj_1[1] | ||
92 | end | ||
93 | else | ||
94 | a = 123 | ||
95 | b = tb[1] | ||
96 | end | ||
97 | end | ||
98 | do | ||
99 | local a, c | ||
100 | if x then | ||
101 | do | ||
102 | local _exp_0 = y | ||
103 | if 1 == _exp_0 then | ||
104 | do | ||
105 | local _obj_0, _obj_1, _obj_2, _obj_3 = f() | ||
106 | b[#b + 1] = _obj_1 | ||
107 | a, c, getmetatable(d).__add = _obj_0, _obj_2, _obj_3 | ||
108 | end | ||
109 | end | ||
110 | end | ||
111 | elseif x2 then | ||
112 | if y2 then | ||
113 | do | ||
114 | local _obj_0, _obj_1, _obj_2, _obj_3 = f1() | ||
115 | b[#b + 1] = _obj_1 | ||
116 | a, c, getmetatable(d).__add = _obj_0, _obj_2, _obj_3 | ||
117 | end | ||
118 | end | ||
119 | else | ||
120 | print("hello") | ||
121 | do | ||
122 | print(123) | ||
123 | do | ||
124 | local _obj_0, _obj_1, _obj_2 = f2() | ||
125 | b[#b + 1] = _obj_0 | ||
126 | a, c, getmetatable(d).__add = 1, _obj_1, _obj_2 | ||
127 | end | ||
128 | end | ||
129 | end | ||
130 | end | ||
131 | end) | ||
diff --git a/spec/outputs/cond.lua b/spec/outputs/cond.lua index 178bf9b..7764439 100644 --- a/spec/outputs/cond.lua +++ b/spec/outputs/cond.lua | |||
@@ -251,7 +251,7 @@ end | |||
251 | local a = 12 | 251 | local a = 12 |
252 | local c, b | 252 | local c, b |
253 | if something then | 253 | if something then |
254 | a, c, b = "cool" | 254 | a, c, b = "cool", nil, nil |
255 | end | 255 | end |
256 | local j | 256 | local j |
257 | if 1 then | 257 | if 1 then |
diff --git a/spec/outputs/global.lua b/spec/outputs/global.lua index ef73823..930ecf6 100644 --- a/spec/outputs/global.lua +++ b/spec/outputs/global.lua | |||
@@ -1,5 +1,5 @@ | |||
1 | do | 1 | do |
2 | a, b, c = 223, 343 | 2 | a, b, c = 223, 343, nil |
3 | cool = "dad" | 3 | cool = "dad" |
4 | end | 4 | end |
5 | do | 5 | do |
@@ -29,7 +29,7 @@ do | |||
29 | end | 29 | end |
30 | do | 30 | do |
31 | local d | 31 | local d |
32 | a, b, c, d = "hello" | 32 | a, b, c, d = "hello", nil, nil, nil |
33 | end | 33 | end |
34 | do | 34 | do |
35 | local What | 35 | local What |
diff --git a/spec/outputs/metatable.lua b/spec/outputs/metatable.lua index 2d72e1d..6f5ceed 100644 --- a/spec/outputs/metatable.lua +++ b/spec/outputs/metatable.lua | |||
@@ -66,7 +66,7 @@ setmetatable(a.b, { }) | |||
66 | x.abc = 123 | 66 | x.abc = 123 |
67 | setmetatable(func(), mt) | 67 | setmetatable(func(), mt) |
68 | setmetatable(b.c, mt) | 68 | setmetatable(b.c, mt) |
69 | a, d, e = 1, "abc" | 69 | a, d, e = 1, "abc", nil |
70 | local is_same = getmetatable(a).__index == getmetatable(a).__index | 70 | local is_same = getmetatable(a).__index == getmetatable(a).__index |
71 | setmetatable(a, { | 71 | setmetatable(a, { |
72 | __index = tb | 72 | __index = tb |
diff --git a/spec/outputs/using.lua b/spec/outputs/using.lua index 6d0d888..ff23a30 100644 --- a/spec/outputs/using.lua +++ b/spec/outputs/using.lua | |||
@@ -21,3 +21,10 @@ end | |||
21 | _ = function() | 21 | _ = function() |
22 | local hello = hello or 2 | 22 | local hello = hello or 2 |
23 | end | 23 | end |
24 | do | ||
25 | local a = { }; | ||
26 | _(function() | ||
27 | local x, y = a[1], a[2] | ||
28 | end) | ||
29 | end | ||
30 | return nil | ||
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 2a703d0..1a44832 100755 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
@@ -54,7 +54,7 @@ namespace yue { | |||
54 | 54 | ||
55 | typedef std::list<std::string> str_list; | 55 | typedef std::list<std::string> str_list; |
56 | 56 | ||
57 | const std::string_view version = "0.14.1"sv; | 57 | const std::string_view version = "0.14.2"sv; |
58 | const std::string_view extension = "yue"sv; | 58 | const std::string_view extension = "yue"sv; |
59 | 59 | ||
60 | class YueCompilerImpl { | 60 | class YueCompilerImpl { |
@@ -1355,13 +1355,31 @@ private: | |||
1355 | } | 1355 | } |
1356 | throw std::logic_error(_info.errorMessage(clearBuf(), values.front())); | 1356 | throw std::logic_error(_info.errorMessage(clearBuf(), values.front())); |
1357 | } | 1357 | } |
1358 | bool checkValuesLater = false; | ||
1358 | if (exprs.size() > values.size()) { | 1359 | if (exprs.size() > values.size()) { |
1359 | BLOCK_START | 1360 | BLOCK_START |
1361 | switch (values.back()->getId()) { | ||
1362 | case id<If_t>(): | ||
1363 | case id<Switch_t>(): | ||
1364 | checkValuesLater = true; | ||
1365 | break; | ||
1366 | } | ||
1367 | BREAK_IF(checkValuesLater); | ||
1360 | auto value = singleValueFrom(values.back()); | 1368 | auto value = singleValueFrom(values.back()); |
1361 | BREAK_IF(!value); | 1369 | BREAK_IF(!value); |
1370 | if (auto val = value->item.as<SimpleValue_t>()) { | ||
1371 | switch (val->value->getId()) { | ||
1372 | case id<If_t>(): | ||
1373 | case id<Switch_t>(): | ||
1374 | case id<Do_t>(): | ||
1375 | case id<Try_t>(): | ||
1376 | checkValuesLater = true; | ||
1377 | break; | ||
1378 | } | ||
1379 | BREAK_IF(checkValuesLater); | ||
1380 | } | ||
1362 | auto chainValue = value->item.as<ChainValue_t>(); | 1381 | auto chainValue = value->item.as<ChainValue_t>(); |
1363 | BREAK_IF(!chainValue); | 1382 | if (!chainValue || !ast_is<Invoke_t, InvokeArgs_t>(chainValue->items.back())) { |
1364 | if (!ast_is<Invoke_t, InvokeArgs_t>(chainValue->items.back())) { | ||
1365 | _buf << exprs.size() << " right values expected, got "sv << values.size(); | 1383 | _buf << exprs.size() << " right values expected, got "sv << values.size(); |
1366 | throw std::logic_error(_info.errorMessage(clearBuf(), values.front())); | 1384 | throw std::logic_error(_info.errorMessage(clearBuf(), values.front())); |
1367 | } | 1385 | } |
@@ -1430,96 +1448,107 @@ private: | |||
1430 | return; | 1448 | return; |
1431 | BLOCK_END | 1449 | BLOCK_END |
1432 | } | 1450 | } |
1433 | auto vit = values.begin(); | 1451 | if (!checkValuesLater) { |
1434 | for (auto it = exprs.begin(); it != exprs.end(); ++it) { | 1452 | auto vit = values.begin(); |
1435 | BLOCK_START | 1453 | for (auto it = exprs.begin(); it != exprs.end(); ++it) { |
1436 | auto value = singleValueFrom(*it); | 1454 | BLOCK_START |
1437 | BREAK_IF(!value); | 1455 | auto value = singleValueFrom(*it); |
1438 | auto chainValue = value->item.as<ChainValue_t>(); | 1456 | BREAK_IF(!value); |
1439 | BREAK_IF(!chainValue); | 1457 | auto chainValue = value->item.as<ChainValue_t>(); |
1440 | str_list temp; | 1458 | BREAK_IF(!chainValue); |
1441 | if (auto dot = ast_cast<DotChainItem_t>(chainValue->items.back())) { | 1459 | str_list temp; |
1442 | BREAK_IF(!dot->name.is<Metatable_t>()); | 1460 | if (auto dot = ast_cast<DotChainItem_t>(chainValue->items.back())) { |
1443 | str_list args; | 1461 | BREAK_IF(!dot->name.is<Metatable_t>()); |
1444 | chainValue->items.pop_back(); | 1462 | str_list args; |
1445 | if (chainValue->items.empty()) { | 1463 | auto tmpChain = chainValue->new_ptr<ChainValue_t>(); |
1446 | if (_withVars.empty()) { | 1464 | tmpChain->items.dup(chainValue->items); |
1447 | throw std::logic_error(_info.errorMessage("short dot/colon syntax must be called within a with block"sv, x)); | 1465 | tmpChain->items.pop_back(); |
1466 | if (tmpChain->items.empty()) { | ||
1467 | if (_withVars.empty()) { | ||
1468 | throw std::logic_error(_info.errorMessage("short dot/colon syntax must be called within a with block"sv, x)); | ||
1469 | } else { | ||
1470 | args.push_back(_withVars.top()); | ||
1471 | } | ||
1448 | } else { | 1472 | } else { |
1449 | args.push_back(_withVars.top()); | 1473 | auto value = tmpChain->new_ptr<Value_t>(); |
1474 | value->item.set(tmpChain); | ||
1475 | transformExp(newExp(value, tmpChain), args, ExpUsage::Closure); | ||
1450 | } | 1476 | } |
1451 | } else { | 1477 | if (vit == values.end()) { |
1452 | transformExp(static_cast<Exp_t*>(*it), args, ExpUsage::Closure); | 1478 | throw std::logic_error(_info.errorMessage("right value missing"sv, values.front())); |
1453 | } | 1479 | } |
1454 | if (vit != values.end()) transformAssignItem(*vit, args); | 1480 | transformAssignItem(*vit, args); |
1455 | else args.push_back("nil"s); | 1481 | _buf << indent() << globalVar("setmetatable"sv, x) << '(' << join(args, ", "sv) << ')' << nll(x); |
1456 | _buf << indent() << globalVar("setmetatable"sv, x) << '(' << join(args, ", "sv) << ')' << nll(x); | 1482 | temp.push_back(clearBuf()); |
1457 | temp.push_back(clearBuf()); | 1483 | } else if (ast_is<table_appending_op_t>(chainValue->items.back())) { |
1458 | } else if (ast_is<table_appending_op_t>(chainValue->items.back())) { | 1484 | auto tmpChain = chainValue->new_ptr<ChainValue_t>(); |
1459 | chainValue->items.pop_back(); | 1485 | tmpChain->items.dup(chainValue->items); |
1460 | if (chainValue->items.empty()) { | 1486 | tmpChain->items.pop_back(); |
1461 | if (_withVars.empty()) { | 1487 | if (tmpChain->items.empty()) { |
1462 | throw std::logic_error(_info.errorMessage("short table appending must be called within a with block"sv, x)); | 1488 | if (_withVars.empty()) { |
1463 | } else { | 1489 | throw std::logic_error(_info.errorMessage("short table appending must be called within a with block"sv, x)); |
1464 | chainValue->items.push_back(toAst<Callable_t>(_withVars.top(), chainValue)); | 1490 | } else { |
1491 | tmpChain->items.push_back(toAst<Callable_t>(_withVars.top(), chainValue)); | ||
1492 | } | ||
1493 | } | ||
1494 | auto varName = singleVariableFrom(tmpChain); | ||
1495 | bool isScoped = false; | ||
1496 | if (varName.empty() || !isLocal(varName)) { | ||
1497 | isScoped = true; | ||
1498 | temp.push_back(indent() + "do"s + nll(x)); | ||
1499 | pushScope(); | ||
1500 | auto objVar = getUnusedName("_obj_"sv); | ||
1501 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); | ||
1502 | newAssignment->expList.set(toAst<ExpList_t>(objVar, x)); | ||
1503 | auto assign = x->new_ptr<Assign_t>(); | ||
1504 | auto value = tmpChain->new_ptr<Value_t>(); | ||
1505 | value->item.set(tmpChain); | ||
1506 | assign->values.push_back(newExp(value, tmpChain)); | ||
1507 | newAssignment->action.set(assign); | ||
1508 | transformAssignment(newAssignment, temp); | ||
1509 | varName = objVar; | ||
1465 | } | 1510 | } |
1466 | } | ||
1467 | auto varName = singleVariableFrom(chainValue); | ||
1468 | bool isScoped = false; | ||
1469 | if (varName.empty() || !isLocal(varName)) { | ||
1470 | isScoped = true; | ||
1471 | temp.push_back(indent() + "do"s + nll(x)); | ||
1472 | pushScope(); | ||
1473 | auto objVar = getUnusedName("_obj_"sv); | ||
1474 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); | 1511 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); |
1475 | newAssignment->expList.set(toAst<ExpList_t>(objVar, x)); | 1512 | newAssignment->expList.set(toAst<ExpList_t>(varName + "[#"s + varName + "+1]"s, x)); |
1476 | auto assign = x->new_ptr<Assign_t>(); | 1513 | auto assign = x->new_ptr<Assign_t>(); |
1477 | assign->values.push_back(*it); | 1514 | if (vit == values.end()) { |
1515 | throw std::logic_error(_info.errorMessage("right value missing"sv, values.front())); | ||
1516 | } | ||
1517 | assign->values.push_back(*vit); | ||
1478 | newAssignment->action.set(assign); | 1518 | newAssignment->action.set(assign); |
1479 | transformAssignment(newAssignment, temp); | 1519 | transformAssignment(newAssignment, temp); |
1480 | varName = objVar; | 1520 | if (isScoped) { |
1481 | } | 1521 | popScope(); |
1522 | temp.push_back(indent() + "end"s + nlr(x)); | ||
1523 | } | ||
1524 | } else break; | ||
1525 | auto newExpList = x->new_ptr<ExpList_t>(); | ||
1526 | auto newAssign = x->new_ptr<Assign_t>(); | ||
1482 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); | 1527 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); |
1483 | newAssignment->expList.set(toAst<ExpList_t>(varName + "[#"s + varName + "+1]"s, x)); | 1528 | newAssignment->expList.set(newExpList); |
1484 | auto assign = x->new_ptr<Assign_t>(); | 1529 | newAssignment->action.set(newAssign); |
1485 | if (vit != values.end()) { | 1530 | for (auto exp : exprs) { |
1486 | assign->values.push_back(*vit); | 1531 | if (exp != *it) newExpList->exprs.push_back(exp); |
1487 | } else { | ||
1488 | assign->values.push_back(toAst<Exp_t>("nil"sv, *vit)); | ||
1489 | } | 1532 | } |
1490 | newAssignment->action.set(assign); | 1533 | for (auto value : values) { |
1491 | transformAssignment(newAssignment, temp); | 1534 | if (value != *vit) newAssign->values.push_back(value); |
1492 | if (isScoped) { | ||
1493 | popScope(); | ||
1494 | temp.push_back(indent() + "end"s + nlr(x)); | ||
1495 | } | 1535 | } |
1496 | } else break; | 1536 | if (newExpList->exprs.empty() && newAssign->values.empty()) { |
1497 | auto newExpList = x->new_ptr<ExpList_t>(); | 1537 | out.push_back(join(temp)); |
1498 | auto newAssign = x->new_ptr<Assign_t>(); | 1538 | return; |
1499 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); | 1539 | } |
1500 | newAssignment->expList.set(newExpList); | 1540 | if (newExpList->exprs.size() < newAssign->values.size()) { |
1501 | newAssignment->action.set(newAssign); | 1541 | auto exp = toAst<Exp_t>("_"sv, x); |
1502 | for (auto exp : exprs) { | 1542 | while (newExpList->exprs.size() < newAssign->values.size()) { |
1503 | if (exp != *it) newExpList->exprs.push_back(exp); | 1543 | newExpList->exprs.push_back(exp); |
1504 | } | 1544 | } |
1505 | for (auto value : values) { | 1545 | } |
1506 | if (value != *vit) newAssign->values.push_back(value); | 1546 | transformAssignment(newAssignment, temp); |
1507 | } | ||
1508 | if (newExpList->exprs.empty() && newAssign->values.empty()) { | ||
1509 | out.push_back(join(temp)); | 1547 | out.push_back(join(temp)); |
1510 | return; | 1548 | return; |
1549 | BLOCK_END | ||
1550 | if (vit != values.end()) ++vit; | ||
1511 | } | 1551 | } |
1512 | if (newExpList->exprs.size() < newAssign->values.size()) { | ||
1513 | auto exp = toAst<Exp_t>("_"sv, x); | ||
1514 | while (newExpList->exprs.size() < newAssign->values.size()) { | ||
1515 | newExpList->exprs.push_back(exp); | ||
1516 | } | ||
1517 | } | ||
1518 | transformAssignment(newAssignment, temp); | ||
1519 | out.push_back(join(temp)); | ||
1520 | return; | ||
1521 | BLOCK_END | ||
1522 | if (vit != values.end()) ++vit; | ||
1523 | } | 1552 | } |
1524 | BREAK_IF(assign->values.objects().size() != 1); | 1553 | BREAK_IF(assign->values.objects().size() != 1); |
1525 | auto value = assign->values.objects().back(); | 1554 | auto value = assign->values.objects().back(); |
@@ -1530,12 +1559,11 @@ private: | |||
1530 | } | 1559 | } |
1531 | switch (value->getId()) { | 1560 | switch (value->getId()) { |
1532 | case id<If_t>(): { | 1561 | case id<If_t>(): { |
1533 | auto expList = assignment->expList.get(); | 1562 | auto ifNode = static_cast<If_t*>(value); |
1534 | str_list temp; | 1563 | auto assignList = assignment->expList.get(); |
1535 | auto defs = transformAssignDefs(expList, DefOp::Mark); | 1564 | std::string preDefine = getPreDefineLine(assignment); |
1536 | if (!defs.empty()) temp.push_back(toLocalDecl(defs) + nll(expList)); | 1565 | transformIf(ifNode, out, ExpUsage::Assignment, assignList); |
1537 | transformIf(static_cast<If_t*>(value), temp, ExpUsage::Assignment, expList); | 1566 | out.back().insert(0, preDefine); |
1538 | out.push_back(join(temp)); | ||
1539 | return; | 1567 | return; |
1540 | } | 1568 | } |
1541 | case id<Switch_t>(): { | 1569 | case id<Switch_t>(): { |