diff options
| author | Li Jin <dragon-fly@qq.com> | 2026-01-19 17:11:31 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2026-01-19 17:11:31 +0800 |
| commit | ccfe66f87663e10603e453f02894bb82dd23c93b (patch) | |
| tree | 78f90066a182978bd74218440d13bd3a4dd1d269 | |
| parent | 8a01e9c4ec201ad7079f6863c9236851d162b864 (diff) | |
| download | yuescript-ccfe66f87663e10603e453f02894bb82dd23c93b.tar.gz yuescript-ccfe66f87663e10603e453f02894bb82dd23c93b.tar.bz2 yuescript-ccfe66f87663e10603e453f02894bb82dd23c93b.zip | |
Made `;` work as statements separator.
| -rwxr-xr-x | doc/docs/doc/README.md | 13 | ||||
| -rwxr-xr-x | doc/docs/zh/doc/README.md | 13 | ||||
| -rw-r--r-- | spec/inputs/syntax.yue | 49 | ||||
| -rw-r--r-- | spec/inputs/unicode/syntax.yue | 2 | ||||
| -rw-r--r-- | spec/inputs/unicode/whitespace.yue | 10 | ||||
| -rw-r--r-- | spec/inputs/whitespace.yue | 10 | ||||
| -rw-r--r-- | spec/outputs/codes_from_doc.lua | 6 | ||||
| -rw-r--r-- | spec/outputs/codes_from_doc_zh.lua | 6 | ||||
| -rw-r--r-- | spec/outputs/syntax.lua | 74 | ||||
| -rw-r--r-- | spec/outputs/unicode/syntax.lua | 4 | ||||
| -rw-r--r-- | spec/outputs/unicode/whitespace.lua | 8 | ||||
| -rw-r--r-- | spec/outputs/whitespace.lua | 8 | ||||
| -rw-r--r-- | src/yue.cpp | 2 | ||||
| -rw-r--r-- | src/yuescript/yue_ast.cpp | 7 | ||||
| -rw-r--r-- | src/yuescript/yue_ast.h | 16 | ||||
| -rw-r--r-- | src/yuescript/yue_compiler.cpp | 137 | ||||
| -rw-r--r-- | src/yuescript/yue_parser.cpp | 35 | ||||
| -rw-r--r-- | src/yuescript/yue_parser.h | 2 |
18 files changed, 248 insertions, 154 deletions
diff --git a/doc/docs/doc/README.md b/doc/docs/doc/README.md index d862777..b5051d4 100755 --- a/doc/docs/doc/README.md +++ b/doc/docs/doc/README.md | |||
| @@ -1588,6 +1588,19 @@ print ok, count, first | |||
| 1588 | 1588 | ||
| 1589 | YueScript is a whitespace significant language. You have to write some code block in the same indent with space **' '** or tab **'\t'** like function body, value list and some control blocks. And expressions containing different whitespaces might mean different things. Tab is treated like 4 space, but it's better not mix the use of spaces and tabs. | 1589 | YueScript is a whitespace significant language. You have to write some code block in the same indent with space **' '** or tab **'\t'** like function body, value list and some control blocks. And expressions containing different whitespaces might mean different things. Tab is treated like 4 space, but it's better not mix the use of spaces and tabs. |
| 1590 | 1590 | ||
| 1591 | ### Statement Separator | ||
| 1592 | |||
| 1593 | A statement normally ends at a line break. You can also use a semicolon `;` to explicitly terminate a statement, which allows writing multiple statements on the same line: | ||
| 1594 | |||
| 1595 | ```moonscript | ||
| 1596 | a = 1; b = 2; print a + b | ||
| 1597 | ``` | ||
| 1598 | <YueDisplay> | ||
| 1599 | <pre> | ||
| 1600 | a = 1; b = 2; print a + b | ||
| 1601 | </pre> | ||
| 1602 | </YueDisplay> | ||
| 1603 | |||
| 1591 | ### Multiline Chaining | 1604 | ### Multiline Chaining |
| 1592 | 1605 | ||
| 1593 | You can write multi-line chaining function calls with a same indent. | 1606 | You can write multi-line chaining function calls with a same indent. |
diff --git a/doc/docs/zh/doc/README.md b/doc/docs/zh/doc/README.md index 786892d..43713fe 100755 --- a/doc/docs/zh/doc/README.md +++ b/doc/docs/zh/doc/README.md | |||
| @@ -1586,6 +1586,19 @@ print ok, count, first | |||
| 1586 | 1586 | ||
| 1587 | 月之脚本是一个对空白敏感的语言。你必须在相同的缩进中使用空格 **' '** 或制表符 **'\t'** 来编写一些代码块,如函数体、值列表和一些控制块。包含不同空白的表达式可能意味着不同的事情。制表符被视为4个空格,但最好不要混合使用空格和制表符。 | 1587 | 月之脚本是一个对空白敏感的语言。你必须在相同的缩进中使用空格 **' '** 或制表符 **'\t'** 来编写一些代码块,如函数体、值列表和一些控制块。包含不同空白的表达式可能意味着不同的事情。制表符被视为4个空格,但最好不要混合使用空格和制表符。 |
| 1588 | 1588 | ||
| 1589 | ### 语句分隔符 | ||
| 1590 | |||
| 1591 | 一条语句通常以换行结束。你也可以使用分号 `;` 显式结束一条语句,从而在同一行中编写多条语句: | ||
| 1592 | |||
| 1593 | ```moonscript | ||
| 1594 | a = 1; b = 2; print a + b | ||
| 1595 | ``` | ||
| 1596 | <YueDisplay> | ||
| 1597 | <pre> | ||
| 1598 | a = 1; b = 2; print a + b | ||
| 1599 | </pre> | ||
| 1600 | </YueDisplay> | ||
| 1601 | |||
| 1589 | ### 多行链式调用 | 1602 | ### 多行链式调用 |
| 1590 | 1603 | ||
| 1591 | 你可以使用相同的缩进来编写多行链式函数调用。 | 1604 | 你可以使用相同的缩进来编写多行链式函数调用。 |
diff --git a/spec/inputs/syntax.yue b/spec/inputs/syntax.yue index eee518a..cef3e3d 100644 --- a/spec/inputs/syntax.yue +++ b/spec/inputs/syntax.yue | |||
| @@ -7,7 +7,7 @@ a, bunch, go, here = another, world, nil, nil | |||
| 7 | func arg1, arg2, another, arg3 | 7 | func arg1, arg2, another, arg3 |
| 8 | 8 | ||
| 9 | here, we = () ->, yeah | 9 | here, we = () ->, yeah |
| 10 | the, different = () -> approach; yeah | 10 | the, different = (() -> approach), yeah |
| 11 | 11 | ||
| 12 | dad() | 12 | dad() |
| 13 | dad(lord) | 13 | dad(lord) |
| @@ -321,7 +321,7 @@ ajax url, | |||
| 321 | (error) -> | 321 | (error) -> |
| 322 | print error | 322 | print error |
| 323 | 323 | ||
| 324 | -- | 324 | -- |
| 325 | a += 3 - 5 | 325 | a += 3 - 5 |
| 326 | a *= 3 + 5 | 326 | a *= 3 + 5 |
| 327 | a *= 3 | 327 | a *= 3 |
| @@ -480,11 +480,54 @@ do | |||
| 480 | 480 | ||
| 481 | do | 481 | do |
| 482 | return res if res ~= "" | 482 | return res if res ~= "" |
| 483 | 483 | ||
| 484 | 484 | ||
| 485 | do | 485 | do |
| 486 | return res if res ~= "" | 486 | return res if res ~= "" |
| 487 | -- | 487 | -- |
| 488 | 488 | ||
| 489 | do | ||
| 490 | a = 1; b = 2; c = a + b | ||
| 491 | print a; print b; print c | ||
| 492 | |||
| 493 | f = -> | ||
| 494 | a = 1; b = 2; a + b | ||
| 495 | |||
| 496 | a = 1; | ||
| 497 | b = 2; | ||
| 498 | |||
| 499 | success, result = try func!; print result if success | ||
| 500 | |||
| 501 | value = "foo"; print value; value = value .. "bar"; print value | ||
| 502 | |||
| 503 | do | ||
| 504 | if ok then print "ok!"; return 42 | ||
| 505 | |||
| 506 | for i=1,3 | ||
| 507 | print i; continue | ||
| 508 | |||
| 509 | n = 0 | ||
| 510 | while n < 2 | ||
| 511 | print "n=", n; n += 1 | ||
| 512 | |||
| 513 | obj = {} | ||
| 514 | obj\set 10; obj\get!; print "done" | ||
| 515 | |||
| 516 | with tbl | ||
| 517 | \push 1; print "push" | ||
| 518 | |||
| 519 | a = 5 | ||
| 520 | if a > 3 | ||
| 521 | print "big"; b = a * 2; print b | ||
| 522 | else | ||
| 523 | print "small"; b = a | ||
| 524 | |||
| 525 | try | ||
| 526 | x = 1; y = 2; print x + y | ||
| 527 | catch err | ||
| 528 | print "error:", err | ||
| 529 | |||
| 530 | q = 1;; w = 2;;; e = 3; print q, w, e; | ||
| 531 | |||
| 489 | nil | 532 | nil |
| 490 | 533 | ||
diff --git a/spec/inputs/unicode/syntax.yue b/spec/inputs/unicode/syntax.yue index 01d5c87..939579b 100644 --- a/spec/inputs/unicode/syntax.yue +++ b/spec/inputs/unicode/syntax.yue | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | 函数 参数1, 参数2, 另外, 参数3 | 7 | 函数 参数1, 参数2, 另外, 参数3 |
| 8 | 8 | ||
| 9 | 这里, 我们 = () ->, 是的 | 9 | 这里, 我们 = () ->, 是的 |
| 10 | 这个, 不同 = () -> 方法; 是的 | 10 | 这个, 不同 = (() -> 方法), 是的 |
| 11 | 11 | ||
| 12 | 爸爸() | 12 | 爸爸() |
| 13 | 爸爸(主) | 13 | 爸爸(主) |
diff --git a/spec/inputs/unicode/whitespace.yue b/spec/inputs/unicode/whitespace.yue index efe55ce..151789a 100644 --- a/spec/inputs/unicode/whitespace.yue +++ b/spec/inputs/unicode/whitespace.yue | |||
| @@ -97,19 +97,19 @@ v = -> | |||
| 97 | 变量c -- v3 | 97 | 变量c -- v3 |
| 98 | 98 | ||
| 99 | v1, v2, \ | 99 | v1, v2, \ |
| 100 | v3 = -> | 100 | v3 = (-> |
| 101 | 变量a; \-- 函数结束于v1 | 101 | 变量a), \-- 函数结束于v1 |
| 102 | 变量b, \-- v2 | 102 | 变量b, \-- v2 |
| 103 | 变量c -- v3 | 103 | 变量c -- v3 |
| 104 | 104 | ||
| 105 | 变量a, 变量b, \ | 105 | 变量a, 变量b, \ |
| 106 | 变量c, 变量d, \ | 106 | 变量c, 变量d, \ |
| 107 | 变量e, 变量f = 1, \ | 107 | 变量e, 变量f = 1, \ |
| 108 | f2 | 108 | (f2 |
| 109 | :abc; \-- 参数2 | 109 | :abc), \-- 参数2 |
| 110 | 3, \ | 110 | 3, \ |
| 111 | 4, \ | 111 | 4, \ |
| 112 | 函数5 abc; \-- 参数5 | 112 | 函数5(abc), \-- 参数5 |
| 113 | 6 | 113 | 6 |
| 114 | 114 | ||
| 115 | for 变量a, \-- 解构1 | 115 | for 变量a, \-- 解构1 |
diff --git a/spec/inputs/whitespace.yue b/spec/inputs/whitespace.yue index 2655961..e501d3d 100644 --- a/spec/inputs/whitespace.yue +++ b/spec/inputs/whitespace.yue | |||
| @@ -128,19 +128,19 @@ v = -> | |||
| 128 | c -- v3 | 128 | c -- v3 |
| 129 | 129 | ||
| 130 | v1, v2, \ | 130 | v1, v2, \ |
| 131 | v3 = -> | 131 | v3 = (-> |
| 132 | a; \-- end of function for v1 | 132 | a), \-- end of function for v1 |
| 133 | b, \-- v2 | 133 | b, \-- v2 |
| 134 | c -- v3 | 134 | c -- v3 |
| 135 | 135 | ||
| 136 | a, b, \ | 136 | a, b, \ |
| 137 | c, d, \ | 137 | c, d, \ |
| 138 | e, f = 1, \ | 138 | e, f = 1, \ |
| 139 | f2 | 139 | (f2 |
| 140 | :abc; \-- arg2 | 140 | :abc), \-- arg2 |
| 141 | 3, \ | 141 | 3, \ |
| 142 | 4, \ | 142 | 4, \ |
| 143 | f5 abc; \-- arg5 | 143 | f5(abc), \-- arg5 |
| 144 | 6 | 144 | 6 |
| 145 | 145 | ||
| 146 | for a, \-- destruct 1 | 146 | for a, \-- destruct 1 |
diff --git a/spec/outputs/codes_from_doc.lua b/spec/outputs/codes_from_doc.lua index 1df7cef..3b0724a 100644 --- a/spec/outputs/codes_from_doc.lua +++ b/spec/outputs/codes_from_doc.lua | |||
| @@ -756,6 +756,9 @@ end | |||
| 756 | local first = select(1, ...) | 756 | local first = select(1, ...) |
| 757 | return print(ok, count, first) | 757 | return print(ok, count, first) |
| 758 | end)(fn(true)) | 758 | end)(fn(true)) |
| 759 | local a = 1 | ||
| 760 | local b = 2 | ||
| 761 | print(a + b) | ||
| 759 | Rx.Observable.fromRange(1, 8):filter(function(x) | 762 | Rx.Observable.fromRange(1, 8):filter(function(x) |
| 760 | return x % 2 == 0 | 763 | return x % 2 == 0 |
| 761 | end):concat(Rx.Observable.of('who do we appreciate')):map(function(value) | 764 | end):concat(Rx.Observable.of('who do we appreciate')):map(function(value) |
| @@ -3283,6 +3286,9 @@ end | |||
| 3283 | local first = select(1, ...) | 3286 | local first = select(1, ...) |
| 3284 | return print(ok, count, first) | 3287 | return print(ok, count, first) |
| 3285 | end)(fn(true)) | 3288 | end)(fn(true)) |
| 3289 | local a = 1 | ||
| 3290 | local b = 2 | ||
| 3291 | print(a + b) | ||
| 3286 | Rx.Observable.fromRange(1, 8):filter(function(x) | 3292 | Rx.Observable.fromRange(1, 8):filter(function(x) |
| 3287 | return x % 2 == 0 | 3293 | return x % 2 == 0 |
| 3288 | end):concat(Rx.Observable.of('who do we appreciate')):map(function(value) | 3294 | end):concat(Rx.Observable.of('who do we appreciate')):map(function(value) |
diff --git a/spec/outputs/codes_from_doc_zh.lua b/spec/outputs/codes_from_doc_zh.lua index b407895..89335c9 100644 --- a/spec/outputs/codes_from_doc_zh.lua +++ b/spec/outputs/codes_from_doc_zh.lua | |||
| @@ -756,6 +756,9 @@ end | |||
| 756 | local first = select(1, ...) | 756 | local first = select(1, ...) |
| 757 | return print(ok, count, first) | 757 | return print(ok, count, first) |
| 758 | end)(fn(true)) | 758 | end)(fn(true)) |
| 759 | local a = 1 | ||
| 760 | local b = 2 | ||
| 761 | print(a + b) | ||
| 759 | Rx.Observable.fromRange(1, 8):filter(function(x) | 762 | Rx.Observable.fromRange(1, 8):filter(function(x) |
| 760 | return x % 2 == 0 | 763 | return x % 2 == 0 |
| 761 | end):concat(Rx.Observable.of('who do we appreciate')):map(function(value) | 764 | end):concat(Rx.Observable.of('who do we appreciate')):map(function(value) |
| @@ -3277,6 +3280,9 @@ end | |||
| 3277 | local first = select(1, ...) | 3280 | local first = select(1, ...) |
| 3278 | return print(ok, count, first) | 3281 | return print(ok, count, first) |
| 3279 | end)(fn(true)) | 3282 | end)(fn(true)) |
| 3283 | local a = 1 | ||
| 3284 | local b = 2 | ||
| 3285 | print(a + b) | ||
| 3280 | Rx.Observable.fromRange(1, 8):filter(function(x) | 3286 | Rx.Observable.fromRange(1, 8):filter(function(x) |
| 3281 | return x % 2 == 0 | 3287 | return x % 2 == 0 |
| 3282 | end):concat(Rx.Observable.of('who do we appreciate')):map(function(value) | 3288 | end):concat(Rx.Observable.of('who do we appreciate')):map(function(value) |
diff --git a/spec/outputs/syntax.lua b/spec/outputs/syntax.lua index 2df3473..d975ef7 100644 --- a/spec/outputs/syntax.lua +++ b/spec/outputs/syntax.lua | |||
| @@ -5,9 +5,9 @@ func(arg1, arg2, another, arg3) | |||
| 5 | local we | 5 | local we |
| 6 | here, we = function() end, yeah | 6 | here, we = function() end, yeah |
| 7 | local the, different | 7 | local the, different |
| 8 | the, different = function() | 8 | the, different = (function() |
| 9 | return approach | 9 | return approach |
| 10 | end, yeah | 10 | end), yeah |
| 11 | dad() | 11 | dad() |
| 12 | dad(lord) | 12 | dad(lord) |
| 13 | hello(one, two)(); | 13 | hello(one, two)(); |
| @@ -441,4 +441,74 @@ do | |||
| 441 | end | 441 | end |
| 442 | end)()) | 442 | end)()) |
| 443 | end | 443 | end |
| 444 | do | ||
| 445 | a = 1 | ||
| 446 | local b = 2 | ||
| 447 | local c = a + b | ||
| 448 | print(a) | ||
| 449 | print(b) | ||
| 450 | print(c) | ||
| 451 | f = function() | ||
| 452 | a = 1 | ||
| 453 | b = 2 | ||
| 454 | return a + b | ||
| 455 | end | ||
| 456 | a = 1 | ||
| 457 | b = 2 | ||
| 458 | local success, result = pcall(function() | ||
| 459 | return func() | ||
| 460 | end) | ||
| 461 | if success then | ||
| 462 | print(result) | ||
| 463 | end | ||
| 464 | local value = "foo" | ||
| 465 | print(value) | ||
| 466 | value = value .. "bar" | ||
| 467 | print(value) | ||
| 468 | do | ||
| 469 | if ok then | ||
| 470 | print("ok!") | ||
| 471 | end | ||
| 472 | return 42 | ||
| 473 | end | ||
| 474 | for i = 1, 3 do | ||
| 475 | print(i) | ||
| 476 | goto _continue_0 | ||
| 477 | ::_continue_0:: | ||
| 478 | end | ||
| 479 | local n = 0 | ||
| 480 | while n < 2 do | ||
| 481 | print("n=", n) | ||
| 482 | n = n + 1 | ||
| 483 | end | ||
| 484 | local obj = { } | ||
| 485 | obj:set(10) | ||
| 486 | obj:get() | ||
| 487 | print("done") | ||
| 488 | do | ||
| 489 | local _with_0 = tbl | ||
| 490 | _with_0:push(1) | ||
| 491 | print("push") | ||
| 492 | end | ||
| 493 | a = 5 | ||
| 494 | if a > 3 then | ||
| 495 | print("big") | ||
| 496 | b = a * 2 | ||
| 497 | print(b) | ||
| 498 | else | ||
| 499 | print("small") | ||
| 500 | b = a | ||
| 501 | end | ||
| 502 | xpcall(function() | ||
| 503 | x = 1 | ||
| 504 | y = 2 | ||
| 505 | return print(x + y) | ||
| 506 | end, function(err) | ||
| 507 | return print("error:", err) | ||
| 508 | end) | ||
| 509 | local q = 1 | ||
| 510 | local w = 2 | ||
| 511 | local e = 3 | ||
| 512 | print(q, w, e) | ||
| 513 | end | ||
| 444 | return nil | 514 | return nil |
diff --git a/spec/outputs/unicode/syntax.lua b/spec/outputs/unicode/syntax.lua index a13302b..f5d5d8a 100644 --- a/spec/outputs/unicode/syntax.lua +++ b/spec/outputs/unicode/syntax.lua | |||
| @@ -5,9 +5,9 @@ _u51fd_u6570(_u53c2_u65701, _u53c2_u65702, _u53e6_u5916, _u53c2_u65703) | |||
| 5 | local _u6211_u4eec | 5 | local _u6211_u4eec |
| 6 | _u8fd9_u91cc, _u6211_u4eec = function() end, _u662f_u7684 | 6 | _u8fd9_u91cc, _u6211_u4eec = function() end, _u662f_u7684 |
| 7 | local _u8fd9_u4e2a, _u4e0d_u540c | 7 | local _u8fd9_u4e2a, _u4e0d_u540c |
| 8 | _u8fd9_u4e2a, _u4e0d_u540c = function() | 8 | _u8fd9_u4e2a, _u4e0d_u540c = (function() |
| 9 | return _u65b9_u6cd5 | 9 | return _u65b9_u6cd5 |
| 10 | end, _u662f_u7684 | 10 | end), _u662f_u7684 |
| 11 | _u7238_u7238() | 11 | _u7238_u7238() |
| 12 | _u7238_u7238(_u4e3b) | 12 | _u7238_u7238(_u4e3b) |
| 13 | _u4f60_u597d(_u4e00, _u4e8c)(); | 13 | _u4f60_u597d(_u4e00, _u4e8c)(); |
diff --git a/spec/outputs/unicode/whitespace.lua b/spec/outputs/unicode/whitespace.lua index d026abb..7a83d9f 100644 --- a/spec/outputs/unicode/whitespace.lua +++ b/spec/outputs/unicode/whitespace.lua | |||
| @@ -82,12 +82,12 @@ v = function() | |||
| 82 | return _u53d8_u91cfa, _u53d8_u91cfb, _u53d8_u91cfc | 82 | return _u53d8_u91cfa, _u53d8_u91cfb, _u53d8_u91cfc |
| 83 | end | 83 | end |
| 84 | local v1, v2, v3 | 84 | local v1, v2, v3 |
| 85 | v1, v2, v3 = function() | 85 | v1, v2, v3 = (function() |
| 86 | return _u53d8_u91cfa | 86 | return _u53d8_u91cfa |
| 87 | end, _u53d8_u91cfb, _u53d8_u91cfc | 87 | end), _u53d8_u91cfb, _u53d8_u91cfc |
| 88 | local _u53d8_u91cfa, _u53d8_u91cfb, _u53d8_u91cfc, _u53d8_u91cfd, _u53d8_u91cfe, _u53d8_u91cff = 1, f2({ | 88 | local _u53d8_u91cfa, _u53d8_u91cfb, _u53d8_u91cfc, _u53d8_u91cfd, _u53d8_u91cfe, _u53d8_u91cff = 1, (f2({ |
| 89 | abc = abc | 89 | abc = abc |
| 90 | }), 3, 4, _u51fd_u65705(abc), 6 | 90 | })), 3, 4, _u51fd_u65705(abc), 6 |
| 91 | for _u53d8_u91cfa, _u53d8_u91cfb, _u53d8_u91cfc in pairs(_u5bf9_u8c61tb) do | 91 | for _u53d8_u91cfa, _u53d8_u91cfb, _u53d8_u91cfc in pairs(_u5bf9_u8c61tb) do |
| 92 | _u6253_u5370(_u53d8_u91cfa, _u53d8_u91cfb, _u53d8_u91cfc) | 92 | _u6253_u5370(_u53d8_u91cfa, _u53d8_u91cfb, _u53d8_u91cfc) |
| 93 | end | 93 | end |
diff --git a/spec/outputs/whitespace.lua b/spec/outputs/whitespace.lua index 0251968..864f085 100644 --- a/spec/outputs/whitespace.lua +++ b/spec/outputs/whitespace.lua | |||
| @@ -94,12 +94,12 @@ v = function() | |||
| 94 | return a, b, c | 94 | return a, b, c |
| 95 | end | 95 | end |
| 96 | local v1, v2, v3 | 96 | local v1, v2, v3 |
| 97 | v1, v2, v3 = function() | 97 | v1, v2, v3 = (function() |
| 98 | return a | 98 | return a |
| 99 | end, b, c | 99 | end), b, c |
| 100 | local a, b, c, d, e, f = 1, f2({ | 100 | local a, b, c, d, e, f = 1, (f2({ |
| 101 | abc = abc | 101 | abc = abc |
| 102 | }), 3, 4, f5(abc), 6 | 102 | })), 3, 4, f5(abc), 6 |
| 103 | for a, b, c in pairs(tb) do | 103 | for a, b, c in pairs(tb) do |
| 104 | print(a, b, c) | 104 | print(a, b, c) |
| 105 | end | 105 | end |
diff --git a/src/yue.cpp b/src/yue.cpp index b93f75e..2722c55 100644 --- a/src/yue.cpp +++ b/src/yue.cpp | |||
| @@ -341,7 +341,7 @@ int main(int narg, const char** args) { | |||
| 341 | " -- Read from standard in, print to standard out\n" | 341 | " -- Read from standard in, print to standard out\n" |
| 342 | " (Must be first and only argument)\n\n" | 342 | " (Must be first and only argument)\n\n" |
| 343 | " --target=version Specify the Lua version that codes will be generated to\n" | 343 | " --target=version Specify the Lua version that codes will be generated to\n" |
| 344 | " (version can only be 5.1, 5.2, 5.3 or 5.4)\n" | 344 | " (version can only be 5.1 to 5.5)\n" |
| 345 | " --path=path_str Append an extra Lua search path string to package.path\n\n" | 345 | " --path=path_str Append an extra Lua search path string to package.path\n\n" |
| 346 | " Execute without options to enter REPL, type symbol '$'\n" | 346 | " Execute without options to enter REPL, type symbol '$'\n" |
| 347 | " in a single line to start/stop multi-line mode\n" | 347 | " in a single line to start/stop multi-line mode\n" |
diff --git a/src/yuescript/yue_ast.cpp b/src/yuescript/yue_ast.cpp index c9fd23f..bcea4d5 100644 --- a/src/yuescript/yue_ast.cpp +++ b/src/yuescript/yue_ast.cpp | |||
| @@ -370,13 +370,6 @@ std::string PipeBody_t::to_string(void* ud) const { | |||
| 370 | } | 370 | } |
| 371 | return join(temp, "\n"sv); | 371 | return join(temp, "\n"sv); |
| 372 | } | 372 | } |
| 373 | std::string ExpListLow_t::to_string(void* ud) const { | ||
| 374 | str_list temp; | ||
| 375 | for (auto exp : exprs.objects()) { | ||
| 376 | temp.emplace_back(exp->to_string(ud)); | ||
| 377 | } | ||
| 378 | return join(temp, "; "sv); | ||
| 379 | } | ||
| 380 | std::string ExpList_t::to_string(void* ud) const { | 373 | std::string ExpList_t::to_string(void* ud) const { |
| 381 | str_list temp; | 374 | str_list temp; |
| 382 | for (auto exp : exprs.objects()) { | 375 | for (auto exp : exprs.objects()) { |
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index af2355a..5043526 100644 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h | |||
| @@ -50,7 +50,7 @@ std::string_view ast_name() { return {}; } | |||
| 50 | // clang-format off | 50 | // clang-format off |
| 51 | 51 | ||
| 52 | namespace yue { | 52 | namespace yue { |
| 53 | class ExpListLow_t; | 53 | class ExpList_t; |
| 54 | class TableBlock_t; | 54 | class TableBlock_t; |
| 55 | class SimpleTable_t; | 55 | class SimpleTable_t; |
| 56 | class TableLit_t; | 56 | class TableLit_t; |
| @@ -156,7 +156,7 @@ AST_END(NameList) | |||
| 156 | 156 | ||
| 157 | AST_NODE(LocalValues) | 157 | AST_NODE(LocalValues) |
| 158 | ast_ptr<true, NameList_t> nameList; | 158 | ast_ptr<true, NameList_t> nameList; |
| 159 | ast_sel<false, TableBlock_t, ExpListLow_t> valueList; | 159 | ast_sel<false, TableBlock_t, ExpList_t> valueList; |
| 160 | AST_MEMBER(LocalValues, &nameList, &valueList) | 160 | AST_MEMBER(LocalValues, &nameList, &valueList) |
| 161 | AST_END(LocalValues) | 161 | AST_END(LocalValues) |
| 162 | 162 | ||
| @@ -273,12 +273,6 @@ AST_NODE(Backcall) | |||
| 273 | AST_MEMBER(Backcall, &argsDef, &arrow, &value) | 273 | AST_MEMBER(Backcall, &argsDef, &arrow, &value) |
| 274 | AST_END(Backcall) | 274 | AST_END(Backcall) |
| 275 | 275 | ||
| 276 | AST_NODE(ExpListLow) | ||
| 277 | ast_ptr<true, Seperator_t> sep; | ||
| 278 | ast_list<true, Exp_t> exprs; | ||
| 279 | AST_MEMBER(ExpListLow, &sep, &exprs) | ||
| 280 | AST_END(ExpListLow) | ||
| 281 | |||
| 282 | AST_NODE(ExpList) | 276 | AST_NODE(ExpList) |
| 283 | ast_ptr<true, Seperator_t> sep; | 277 | ast_ptr<true, Seperator_t> sep; |
| 284 | ast_list<true, Exp_t> exprs; | 278 | ast_list<true, Exp_t> exprs; |
| @@ -290,7 +284,7 @@ AST_END(ExpList) | |||
| 290 | AST_NODE(Return) | 284 | AST_NODE(Return) |
| 291 | bool allowBlockMacroReturn = false; | 285 | bool allowBlockMacroReturn = false; |
| 292 | bool explicitReturn = true; | 286 | bool explicitReturn = true; |
| 293 | ast_sel<false, TableBlock_t, ExpListLow_t> valueList; | 287 | ast_sel<false, TableBlock_t, ExpList_t> valueList; |
| 294 | AST_MEMBER(Return, &valueList) | 288 | AST_MEMBER(Return, &valueList) |
| 295 | AST_END(Return) | 289 | AST_END(Return) |
| 296 | 290 | ||
| @@ -764,7 +758,7 @@ AST_END(ClassDecl) | |||
| 764 | 758 | ||
| 765 | AST_NODE(GlobalValues) | 759 | AST_NODE(GlobalValues) |
| 766 | ast_ptr<true, NameList_t> nameList; | 760 | ast_ptr<true, NameList_t> nameList; |
| 767 | ast_sel<false, TableBlock_t, ExpListLow_t> valueList; | 761 | ast_sel<false, TableBlock_t, ExpList_t> valueList; |
| 768 | AST_MEMBER(GlobalValues, &nameList, &valueList) | 762 | AST_MEMBER(GlobalValues, &nameList, &valueList) |
| 769 | AST_END(GlobalValues) | 763 | AST_END(GlobalValues) |
| 770 | 764 | ||
| @@ -819,7 +813,7 @@ AST_END(FnArrow) | |||
| 819 | 813 | ||
| 820 | AST_NODE(FunLit) | 814 | AST_NODE(FunLit) |
| 821 | ast_ptr<false, FnArgsDef_t> argsDef; | 815 | ast_ptr<false, FnArgsDef_t> argsDef; |
| 822 | ast_sel<false, ExpListLow_t, DefaultValue_t> defaultReturn; | 816 | ast_sel<false, ExpList_t, DefaultValue_t> defaultReturn; |
| 823 | ast_ptr<true, FnArrow_t> arrow; | 817 | ast_ptr<true, FnArrow_t> arrow; |
| 824 | ast_ptr<false, Body_t> body; | 818 | ast_ptr<false, Body_t> body; |
| 825 | bool noRecursion = false; | 819 | bool noRecursion = false; |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index a2d49af..c7802b6 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
| @@ -78,7 +78,7 @@ static std::unordered_set<std::string> Metamethods = { | |||
| 78 | "close"s // Lua 5.4 | 78 | "close"s // Lua 5.4 |
| 79 | }; | 79 | }; |
| 80 | 80 | ||
| 81 | const std::string_view version = "0.31.1"sv; | 81 | const std::string_view version = "0.32.0"sv; |
| 82 | const std::string_view extension = "yue"sv; | 82 | const std::string_view extension = "yue"sv; |
| 83 | 83 | ||
| 84 | class CompileError : public std::logic_error { | 84 | class CompileError : public std::logic_error { |
| @@ -1057,13 +1057,6 @@ private: | |||
| 1057 | } | 1057 | } |
| 1058 | break; | 1058 | break; |
| 1059 | } | 1059 | } |
| 1060 | case id<ExpListLow_t>(): { | ||
| 1061 | auto expList = static_cast<ExpListLow_t*>(item); | ||
| 1062 | if (expList->exprs.size() == 1) { | ||
| 1063 | exp = static_cast<Exp_t*>(expList->exprs.front()); | ||
| 1064 | } | ||
| 1065 | break; | ||
| 1066 | } | ||
| 1067 | case id<SwitchList_t>(): { | 1060 | case id<SwitchList_t>(): { |
| 1068 | auto expList = static_cast<SwitchList_t*>(item); | 1061 | auto expList = static_cast<SwitchList_t*>(item); |
| 1069 | if (expList->exprs.size() == 1) { | 1062 | if (expList->exprs.size() == 1) { |
| @@ -1092,12 +1085,12 @@ private: | |||
| 1092 | return nullptr; | 1085 | return nullptr; |
| 1093 | } | 1086 | } |
| 1094 | 1087 | ||
| 1095 | Value_t* singleValueFrom(ast_node* item) const { | 1088 | Value_t* singleValueFrom(ast_node* item, bool forceUnparened = false) const { |
| 1096 | if (auto unary = singleUnaryExpFrom(item)) { | 1089 | if (auto unary = singleUnaryExpFrom(item)) { |
| 1097 | if (unary->ops.empty()) { | 1090 | if (unary->ops.empty()) { |
| 1098 | Value_t* value = static_cast<Value_t*>(unary->expos.back()); | 1091 | Value_t* value = static_cast<Value_t*>(unary->expos.back()); |
| 1099 | if (auto chain = ast_cast<ChainValue_t>(value->item); chain && chain->items.size() == 1) { | 1092 | if (auto chain = ast_cast<ChainValue_t>(value->item); chain && chain->items.size() == 1) { |
| 1100 | if (auto parens = chain->get_by_path<Callable_t, Parens_t>(); parens && parens->extra) { | 1093 | if (auto parens = chain->get_by_path<Callable_t, Parens_t>(); parens && (forceUnparened || parens->extra)) { |
| 1101 | if (auto insideValue = singleValueFrom(parens->expr)) { | 1094 | if (auto insideValue = singleValueFrom(parens->expr)) { |
| 1102 | return insideValue; | 1095 | return insideValue; |
| 1103 | } | 1096 | } |
| @@ -1157,6 +1150,22 @@ private: | |||
| 1157 | return exp; | 1150 | return exp; |
| 1158 | } | 1151 | } |
| 1159 | 1152 | ||
| 1153 | ast_ptr<false, Return_t> newReturn(Exp_t* value) { | ||
| 1154 | auto returnNode = value->new_ptr<Return_t>(); | ||
| 1155 | returnNode->explicitReturn = false; | ||
| 1156 | auto expList = value->new_ptr<ExpList_t>(); | ||
| 1157 | expList->exprs.push_back(value); | ||
| 1158 | returnNode->valueList.set(expList); | ||
| 1159 | return returnNode; | ||
| 1160 | } | ||
| 1161 | |||
| 1162 | ast_ptr<false, Return_t> newReturn(ExpList_t* valueList) { | ||
| 1163 | auto returnNode = valueList->new_ptr<Return_t>(); | ||
| 1164 | returnNode->explicitReturn = false; | ||
| 1165 | returnNode->valueList.set(valueList); | ||
| 1166 | return returnNode; | ||
| 1167 | } | ||
| 1168 | |||
| 1160 | SimpleValue_t* simpleSingleValueFrom(ast_node* node) const { | 1169 | SimpleValue_t* simpleSingleValueFrom(ast_node* node) const { |
| 1161 | auto value = singleValueFrom(node); | 1170 | auto value = singleValueFrom(node); |
| 1162 | if (value && value->item.is<SimpleValue_t>()) { | 1171 | if (value && value->item.is<SimpleValue_t>()) { |
| @@ -1264,7 +1273,7 @@ private: | |||
| 1264 | } | 1273 | } |
| 1265 | case id<Local_t>(): { | 1274 | case id<Local_t>(): { |
| 1266 | if (auto localValues = static_cast<Local_t*>(stmt->content.get())->item.as<LocalValues_t>()) { | 1275 | if (auto localValues = static_cast<Local_t*>(stmt->content.get())->item.as<LocalValues_t>()) { |
| 1267 | if (auto expList = localValues->valueList.as<ExpListLow_t>()) { | 1276 | if (auto expList = localValues->valueList.as<ExpList_t>()) { |
| 1268 | return static_cast<Exp_t*>(expList->exprs.back()); | 1277 | return static_cast<Exp_t*>(expList->exprs.back()); |
| 1269 | } | 1278 | } |
| 1270 | } | 1279 | } |
| @@ -1272,7 +1281,7 @@ private: | |||
| 1272 | } | 1281 | } |
| 1273 | case id<Global_t>(): { | 1282 | case id<Global_t>(): { |
| 1274 | if (auto globalValues = static_cast<Global_t*>(stmt->content.get())->item.as<GlobalValues_t>()) { | 1283 | if (auto globalValues = static_cast<Global_t*>(stmt->content.get())->item.as<GlobalValues_t>()) { |
| 1275 | if (auto expList = globalValues->valueList.as<ExpListLow_t>()) { | 1284 | if (auto expList = globalValues->valueList.as<ExpList_t>()) { |
| 1276 | return static_cast<Exp_t*>(expList->exprs.back()); | 1285 | return static_cast<Exp_t*>(expList->exprs.back()); |
| 1277 | } | 1286 | } |
| 1278 | } | 1287 | } |
| @@ -3717,7 +3726,7 @@ private: | |||
| 3717 | bool oneLined = defs.size() == expList->exprs.objects().size(); | 3726 | bool oneLined = defs.size() == expList->exprs.objects().size(); |
| 3718 | bool nonRecursionFunLit = false; | 3727 | bool nonRecursionFunLit = false; |
| 3719 | for (auto val : assign->values.objects()) { | 3728 | for (auto val : assign->values.objects()) { |
| 3720 | if (auto value = singleValueFrom(val)) { | 3729 | if (auto value = singleValueFrom(val, true)) { |
| 3721 | if (auto spValue = value->item.as<SimpleValue_t>()) { | 3730 | if (auto spValue = value->item.as<SimpleValue_t>()) { |
| 3722 | if (auto funLit = spValue->value.as<FunLit_t>()) { | 3731 | if (auto funLit = spValue->value.as<FunLit_t>()) { |
| 3723 | if (funLit->noRecursion) { | 3732 | if (funLit->noRecursion) { |
| @@ -3981,14 +3990,6 @@ private: | |||
| 3981 | out.push_back(join(temp, ", "sv)); | 3990 | out.push_back(join(temp, ", "sv)); |
| 3982 | } | 3991 | } |
| 3983 | 3992 | ||
| 3984 | void transformExpListLow(ExpListLow_t* expListLow, str_list& out) { | ||
| 3985 | str_list temp; | ||
| 3986 | for (auto exp : expListLow->exprs.objects()) { | ||
| 3987 | transformExp(static_cast<Exp_t*>(exp), temp, ExpUsage::Closure); | ||
| 3988 | } | ||
| 3989 | out.push_back(join(temp, ", "sv)); | ||
| 3990 | } | ||
| 3991 | |||
| 3992 | void transform_pipe_exp(const node_container& values, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { | 3993 | void transform_pipe_exp(const node_container& values, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { |
| 3993 | if (values.size() == 1 && usage == ExpUsage::Closure) { | 3994 | if (values.size() == 1 && usage == ExpUsage::Closure) { |
| 3994 | transformUnaryExp(static_cast<UnaryExp_t*>(values.front()), out, ExpUsage::Closure); | 3995 | transformUnaryExp(static_cast<UnaryExp_t*>(values.front()), out, ExpUsage::Closure); |
| @@ -4060,11 +4061,7 @@ private: | |||
| 4060 | return; | 4061 | return; |
| 4061 | } | 4062 | } |
| 4062 | case ExpUsage::Return: { | 4063 | case ExpUsage::Return: { |
| 4063 | auto ret = x->new_ptr<Return_t>(); | 4064 | auto ret = newReturn(arg); |
| 4064 | ret->explicitReturn = false; | ||
| 4065 | auto expListLow = x->new_ptr<ExpListLow_t>(); | ||
| 4066 | expListLow->exprs.push_back(arg); | ||
| 4067 | ret->valueList.set(expListLow); | ||
| 4068 | transformReturn(ret, out); | 4065 | transformReturn(ret, out); |
| 4069 | return; | 4066 | return; |
| 4070 | } | 4067 | } |
| @@ -4289,11 +4286,7 @@ private: | |||
| 4289 | break; | 4286 | break; |
| 4290 | } | 4287 | } |
| 4291 | case ExpUsage::Return: { | 4288 | case ExpUsage::Return: { |
| 4292 | auto expListLow = exp->new_ptr<ExpListLow_t>(); | 4289 | auto returnNode = newReturn(e); |
| 4293 | expListLow->exprs.push_back(e); | ||
| 4294 | auto returnNode = exp->new_ptr<Return_t>(); | ||
| 4295 | returnNode->explicitReturn = false; | ||
| 4296 | returnNode->valueList.set(expListLow); | ||
| 4297 | transformReturn(returnNode, out); | 4290 | transformReturn(returnNode, out); |
| 4298 | break; | 4291 | break; |
| 4299 | } | 4292 | } |
| @@ -4470,11 +4463,7 @@ private: | |||
| 4470 | return getUpValueFuncFromBlock(block, ensureArgListInTheEnd, false, blockRewrite); | 4463 | return getUpValueFuncFromBlock(block, ensureArgListInTheEnd, false, blockRewrite); |
| 4471 | } | 4464 | } |
| 4472 | } | 4465 | } |
| 4473 | auto returnNode = exp->new_ptr<Return_t>(); | 4466 | auto returnNode = newReturn(exp); |
| 4474 | returnNode->explicitReturn = false; | ||
| 4475 | auto returnList = exp->new_ptr<ExpListLow_t>(); | ||
| 4476 | returnList->exprs.push_back(exp); | ||
| 4477 | returnNode->valueList.set(returnList); | ||
| 4478 | auto stmt = exp->new_ptr<Statement_t>(); | 4467 | auto stmt = exp->new_ptr<Statement_t>(); |
| 4479 | stmt->content.set(returnNode); | 4468 | stmt->content.set(returnNode); |
| 4480 | block->statementOrComments.push_back(stmt); | 4469 | block->statementOrComments.push_back(stmt); |
| @@ -4561,12 +4550,8 @@ private: | |||
| 4561 | _buf << indent(1) << "return "s << objVar << nl(x); | 4550 | _buf << indent(1) << "return "s << objVar << nl(x); |
| 4562 | _buf << indent() << "else"s << nl(x); | 4551 | _buf << indent() << "else"s << nl(x); |
| 4563 | temp.push_back(clearBuf()); | 4552 | temp.push_back(clearBuf()); |
| 4564 | auto ret = x->new_ptr<Return_t>(); | ||
| 4565 | ret->explicitReturn = false; | ||
| 4566 | auto retList = x->new_ptr<ExpListLow_t>(); | ||
| 4567 | retList->exprs.push_back(exp->nilCoalesed); | ||
| 4568 | ret->valueList.set(retList); | ||
| 4569 | incIndentOffset(); | 4553 | incIndentOffset(); |
| 4554 | auto ret = newReturn(exp->nilCoalesed); | ||
| 4570 | transformReturn(ret, temp); | 4555 | transformReturn(ret, temp); |
| 4571 | decIndentOffset(); | 4556 | decIndentOffset(); |
| 4572 | temp.push_back(indent() + "end"s + nl(x)); | 4557 | temp.push_back(indent() + "end"s + nl(x)); |
| @@ -4727,10 +4712,8 @@ private: | |||
| 4727 | default: YUEE("AST node mismatch", content); break; | 4712 | default: YUEE("AST node mismatch", content); break; |
| 4728 | } | 4713 | } |
| 4729 | } | 4714 | } |
| 4730 | if (funLit->defaultReturn.is<ExpListLow_t>()) { | 4715 | if (auto defaultReturn = funLit->defaultReturn.as<ExpList_t>()) { |
| 4731 | auto returnNode = newBlock->new_ptr<Return_t>(); | 4716 | auto returnNode = newReturn(defaultReturn); |
| 4732 | returnNode->explicitReturn = false; | ||
| 4733 | returnNode->valueList.set(funLit->defaultReturn); | ||
| 4734 | auto stmt = newBlock->new_ptr<Statement_t>(); | 4717 | auto stmt = newBlock->new_ptr<Statement_t>(); |
| 4735 | stmt->content.set(returnNode); | 4718 | stmt->content.set(returnNode); |
| 4736 | newBlock->statementOrComments.push_back(stmt); | 4719 | newBlock->statementOrComments.push_back(stmt); |
| @@ -5264,11 +5247,9 @@ private: | |||
| 5264 | auto expList = expListFrom(last); | 5247 | auto expList = expListFrom(last); |
| 5265 | BREAK_IF(!expList); | 5248 | BREAK_IF(!expList); |
| 5266 | BREAK_IF(last->appendix && !last->appendix->item.is<IfLine_t>()); | 5249 | BREAK_IF(last->appendix && !last->appendix->item.is<IfLine_t>()); |
| 5267 | auto expListLow = x->new_ptr<ExpListLow_t>(); | ||
| 5268 | expListLow->exprs.dup(expList->exprs); | ||
| 5269 | auto returnNode = x->new_ptr<Return_t>(); | 5250 | auto returnNode = x->new_ptr<Return_t>(); |
| 5270 | returnNode->explicitReturn = false; | 5251 | returnNode->explicitReturn = false; |
| 5271 | returnNode->valueList.set(expListLow); | 5252 | returnNode->valueList.set(expList); |
| 5272 | returnNode->allowBlockMacroReturn = true; | 5253 | returnNode->allowBlockMacroReturn = true; |
| 5273 | last->content.set(returnNode); | 5254 | last->content.set(returnNode); |
| 5274 | BLOCK_END | 5255 | BLOCK_END |
| @@ -5713,7 +5694,7 @@ private: | |||
| 5713 | if (!target) target = returnNode; | 5694 | if (!target) target = returnNode; |
| 5714 | throw CompileError("explicit return statement is not allowed in this context"sv, target); | 5695 | throw CompileError("explicit return statement is not allowed in this context"sv, target); |
| 5715 | } | 5696 | } |
| 5716 | if (auto valueList = returnNode->valueList.as<ExpListLow_t>()) { | 5697 | if (auto valueList = returnNode->valueList.as<ExpList_t>()) { |
| 5717 | if (valueList->exprs.size() == 1) { | 5698 | if (valueList->exprs.size() == 1) { |
| 5718 | auto exp = static_cast<Exp_t*>(valueList->exprs.back()); | 5699 | auto exp = static_cast<Exp_t*>(valueList->exprs.back()); |
| 5719 | if (isPurePipeChain(exp)) { | 5700 | if (isPurePipeChain(exp)) { |
| @@ -5783,7 +5764,7 @@ private: | |||
| 5783 | return; | 5764 | return; |
| 5784 | } else { | 5765 | } else { |
| 5785 | str_list temp; | 5766 | str_list temp; |
| 5786 | transformExpListLow(valueList, temp); | 5767 | transformExpList(valueList, temp); |
| 5787 | out.push_back(indent() + "return "s + temp.back() + nl(returnNode)); | 5768 | out.push_back(indent() + "return "s + temp.back() + nl(returnNode)); |
| 5788 | } | 5769 | } |
| 5789 | } else if (auto tableBlock = returnNode->valueList.as<TableBlock_t>()) { | 5770 | } else if (auto tableBlock = returnNode->valueList.as<TableBlock_t>()) { |
| @@ -6250,11 +6231,7 @@ private: | |||
| 6250 | case ExpUsage::Return: | 6231 | case ExpUsage::Return: |
| 6251 | case ExpUsage::Closure: { | 6232 | case ExpUsage::Closure: { |
| 6252 | auto exp = newExp(partTwo, x); | 6233 | auto exp = newExp(partTwo, x); |
| 6253 | auto ret = x->new_ptr<Return_t>(); | 6234 | auto ret = newReturn(exp); |
| 6254 | ret->explicitReturn = false; | ||
| 6255 | auto expListLow = x->new_ptr<ExpListLow_t>(); | ||
| 6256 | expListLow->exprs.push_back(exp); | ||
| 6257 | ret->valueList.set(expListLow); | ||
| 6258 | transformReturn(ret, temp); | 6235 | transformReturn(ret, temp); |
| 6259 | break; | 6236 | break; |
| 6260 | } | 6237 | } |
| @@ -6349,11 +6326,7 @@ private: | |||
| 6349 | switch (usage) { | 6326 | switch (usage) { |
| 6350 | case ExpUsage::Closure: | 6327 | case ExpUsage::Closure: |
| 6351 | case ExpUsage::Return: { | 6328 | case ExpUsage::Return: { |
| 6352 | auto returnNode = x->new_ptr<Return_t>(); | 6329 | auto returnNode = newReturn(funLit); |
| 6353 | returnNode->explicitReturn = false; | ||
| 6354 | auto expListLow = x->new_ptr<ExpListLow_t>(); | ||
| 6355 | expListLow->exprs.push_back(funLit); | ||
| 6356 | returnNode->valueList.set(expListLow); | ||
| 6357 | transformReturn(returnNode, temp); | 6330 | transformReturn(returnNode, temp); |
| 6358 | break; | 6331 | break; |
| 6359 | } | 6332 | } |
| @@ -6484,11 +6457,7 @@ private: | |||
| 6484 | } | 6457 | } |
| 6485 | switch (usage) { | 6458 | switch (usage) { |
| 6486 | case ExpUsage::Closure: { | 6459 | case ExpUsage::Closure: { |
| 6487 | auto returnNode = x->new_ptr<Return_t>(); | 6460 | auto returnNode = newReturn(newChainExp); |
| 6488 | returnNode->explicitReturn = false; | ||
| 6489 | auto values = x->new_ptr<ExpListLow_t>(); | ||
| 6490 | values->exprs.push_back(newChainExp); | ||
| 6491 | returnNode->valueList.set(values); | ||
| 6492 | transformReturn(returnNode, temp); | 6461 | transformReturn(returnNode, temp); |
| 6493 | popScope(); | 6462 | popScope(); |
| 6494 | *funcStart = anonFuncStart() + nl(x); | 6463 | *funcStart = anonFuncStart() + nl(x); |
| @@ -6498,11 +6467,7 @@ private: | |||
| 6498 | break; | 6467 | break; |
| 6499 | } | 6468 | } |
| 6500 | case ExpUsage::Return: { | 6469 | case ExpUsage::Return: { |
| 6501 | auto returnNode = x->new_ptr<Return_t>(); | 6470 | auto returnNode = newReturn(newChainExp); |
| 6502 | returnNode->explicitReturn = false; | ||
| 6503 | auto values = x->new_ptr<ExpListLow_t>(); | ||
| 6504 | values->exprs.push_back(newChainExp); | ||
| 6505 | returnNode->valueList.set(values); | ||
| 6506 | transformReturn(returnNode, temp); | 6471 | transformReturn(returnNode, temp); |
| 6507 | break; | 6472 | break; |
| 6508 | } | 6473 | } |
| @@ -7361,11 +7326,7 @@ private: | |||
| 7361 | break; | 7326 | break; |
| 7362 | } | 7327 | } |
| 7363 | case ExpUsage::Return: { | 7328 | case ExpUsage::Return: { |
| 7364 | auto expListLow = x->new_ptr<ExpListLow_t>(); | 7329 | auto returnNode = newReturn(node.to<Exp_t>()); |
| 7365 | expListLow->exprs.push_back(node); | ||
| 7366 | auto returnNode = x->new_ptr<Return_t>(); | ||
| 7367 | returnNode->explicitReturn = false; | ||
| 7368 | returnNode->valueList.set(expListLow); | ||
| 7369 | transformReturn(returnNode, out); | 7330 | transformReturn(returnNode, out); |
| 7370 | break; | 7331 | break; |
| 7371 | } | 7332 | } |
| @@ -8377,11 +8338,7 @@ private: | |||
| 8377 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | 8338 | auto simpleValue = x->new_ptr<SimpleValue_t>(); |
| 8378 | simpleValue->value.set(tableLit); | 8339 | simpleValue->value.set(tableLit); |
| 8379 | auto exp = newExp(simpleValue, x); | 8340 | auto exp = newExp(simpleValue, x); |
| 8380 | auto returnNode = x->new_ptr<Return_t>(); | 8341 | auto returnNode = newReturn(exp); |
| 8381 | returnNode->explicitReturn = false; | ||
| 8382 | auto expList = x->new_ptr<ExpListLow_t>(); | ||
| 8383 | expList->exprs.push_back(exp); | ||
| 8384 | returnNode->valueList.set(expList); | ||
| 8385 | transformReturn(returnNode, out); | 8342 | transformReturn(returnNode, out); |
| 8386 | break; | 8343 | break; |
| 8387 | } | 8344 | } |
| @@ -9190,10 +9147,7 @@ private: | |||
| 9190 | } | 9147 | } |
| 9191 | } else { | 9148 | } else { |
| 9192 | auto accum = transformForNumInner(forNum, temp); | 9149 | auto accum = transformForNumInner(forNum, temp); |
| 9193 | auto returnNode = x->new_ptr<Return_t>(); | 9150 | auto returnNode = newReturn(toAst<Exp_t>(accum, forNum)); |
| 9194 | returnNode->explicitReturn = false; | ||
| 9195 | auto expListLow = toAst<ExpListLow_t>(accum, x); | ||
| 9196 | returnNode->valueList.set(expListLow); | ||
| 9197 | transformReturn(returnNode, temp); | 9151 | transformReturn(returnNode, temp); |
| 9198 | } | 9152 | } |
| 9199 | out.push_back(join(temp)); | 9153 | out.push_back(join(temp)); |
| @@ -9304,10 +9258,7 @@ private: | |||
| 9304 | } | 9258 | } |
| 9305 | } else { | 9259 | } else { |
| 9306 | auto accum = transformForEachInner(forEach, temp); | 9260 | auto accum = transformForEachInner(forEach, temp); |
| 9307 | auto returnNode = x->new_ptr<Return_t>(); | 9261 | auto returnNode = newReturn(toAst<Exp_t>(accum, forEach)); |
| 9308 | returnNode->explicitReturn = false; | ||
| 9309 | auto expListLow = toAst<ExpListLow_t>(accum, x); | ||
| 9310 | returnNode->valueList.set(expListLow); | ||
| 9311 | transformReturn(returnNode, temp); | 9262 | transformReturn(returnNode, temp); |
| 9312 | } | 9263 | } |
| 9313 | out.push_back(join(temp)); | 9264 | out.push_back(join(temp)); |
| @@ -10393,8 +10344,8 @@ private: | |||
| 10393 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 10344 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
| 10394 | assignment->expList.set(expList); | 10345 | assignment->expList.set(expList); |
| 10395 | auto assign = x->new_ptr<Assign_t>(); | 10346 | auto assign = x->new_ptr<Assign_t>(); |
| 10396 | if (auto expListLow = values->valueList.as<ExpListLow_t>()) { | 10347 | if (auto expList = values->valueList.as<ExpList_t>()) { |
| 10397 | assign->values.dup(expListLow->exprs); | 10348 | assign->values.dup(expList->exprs); |
| 10398 | } else { | 10349 | } else { |
| 10399 | auto tableBlock = values->valueList.to<TableBlock_t>(); | 10350 | auto tableBlock = values->valueList.to<TableBlock_t>(); |
| 10400 | assign->values.push_back(tableBlock); | 10351 | assign->values.push_back(tableBlock); |
| @@ -11897,8 +11848,8 @@ private: | |||
| 11897 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 11848 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
| 11898 | assignment->expList.set(expList); | 11849 | assignment->expList.set(expList); |
| 11899 | auto assign = x->new_ptr<Assign_t>(); | 11850 | auto assign = x->new_ptr<Assign_t>(); |
| 11900 | if (auto expListLow = values->valueList.as<ExpListLow_t>()) { | 11851 | if (auto expList = values->valueList.as<ExpList_t>()) { |
| 11901 | assign->values.dup(expListLow->exprs); | 11852 | assign->values.dup(expList->exprs); |
| 11902 | } else { | 11853 | } else { |
| 11903 | auto tableBlock = values->valueList.to<TableBlock_t>(); | 11854 | auto tableBlock = values->valueList.to<TableBlock_t>(); |
| 11904 | assign->values.push_back(tableBlock); | 11855 | assign->values.push_back(tableBlock); |
| @@ -11906,7 +11857,7 @@ private: | |||
| 11906 | assignment->action.set(assign); | 11857 | assignment->action.set(assign); |
| 11907 | bool oneLined = transformAssignment(assignment, temp); | 11858 | bool oneLined = transformAssignment(assignment, temp); |
| 11908 | for (auto val : assign->values.objects()) { | 11859 | for (auto val : assign->values.objects()) { |
| 11909 | if (auto value = singleValueFrom(val)) { | 11860 | if (auto value = singleValueFrom(val, true)) { |
| 11910 | if (auto spValue = value->item.as<SimpleValue_t>()) { | 11861 | if (auto spValue = value->item.as<SimpleValue_t>()) { |
| 11911 | if (auto funLit = spValue->value.as<FunLit_t>()) { | 11862 | if (auto funLit = spValue->value.as<FunLit_t>()) { |
| 11912 | if (!funLit->noRecursion) { | 11863 | if (!funLit->noRecursion) { |
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index ab1ba7a..b032826 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
| @@ -393,7 +393,7 @@ YueParser::YueParser() { | |||
| 393 | in_block = space_break >> *(*set(" \t") >> line_break) >> advance_match >> ensure(Block, pop_indent); | 393 | in_block = space_break >> *(*set(" \t") >> line_break) >> advance_match >> ensure(Block, pop_indent); |
| 394 | 394 | ||
| 395 | LocalFlag = expr('*') | '^'; | 395 | LocalFlag = expr('*') | '^'; |
| 396 | LocalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpListLow | expected_expression_error)); | 396 | LocalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpList | expected_expression_error)); |
| 397 | Local = key("local") >> space >> (LocalFlag | LocalValues | invalid_local_declaration_error); | 397 | Local = key("local") >> space >> (LocalFlag | LocalValues | invalid_local_declaration_error); |
| 398 | 398 | ||
| 399 | ConstAttrib = key("const"); | 399 | ConstAttrib = key("const"); |
| @@ -478,7 +478,7 @@ YueParser::YueParser() { | |||
| 478 | Continue = key("continue"); | 478 | Continue = key("continue"); |
| 479 | BreakLoop = (Break >> -(space >> Exp) | Continue) >> not_alpha_num; | 479 | BreakLoop = (Break >> -(space >> Exp) | Continue) >> not_alpha_num; |
| 480 | 480 | ||
| 481 | Return = key("return") >> -(space >> (TableBlock | ExpListLow)); | 481 | Return = key("return") >> -(space >> (TableBlock | ExpList)); |
| 482 | 482 | ||
| 483 | must_exp = Exp | expected_expression_error; | 483 | must_exp = Exp | expected_expression_error; |
| 484 | 484 | ||
| @@ -674,7 +674,7 @@ YueParser::YueParser() { | |||
| 674 | 674 | ||
| 675 | Assign = '=' >> space >> Seperator >> ( | 675 | Assign = '=' >> space >> Seperator >> ( |
| 676 | With | If | Switch | TableBlock | | 676 | With | If | Switch | TableBlock | |
| 677 | (SpreadListExp | Exp) >> *(space >> set(",;") >> space >> (SpreadListExp | Exp)) | | 677 | (SpreadListExp | Exp) >> *(space >> set(",") >> space >> (SpreadListExp | Exp)) | |
| 678 | expected_expression_error | 678 | expected_expression_error |
| 679 | ); | 679 | ); |
| 680 | 680 | ||
| @@ -927,7 +927,7 @@ YueParser::YueParser() { | |||
| 927 | -(space >> key("using") >> prevent_indent >> space >> ensure(ExpList | expected_expression_error, pop_indent)) | 927 | -(space >> key("using") >> prevent_indent >> space >> ensure(ExpList | expected_expression_error, pop_indent)) |
| 928 | ) >> -ClassBlock; | 928 | ) >> -ClassBlock; |
| 929 | 929 | ||
| 930 | GlobalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpListLow | expected_expression_error)); | 930 | GlobalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpList | expected_expression_error)); |
| 931 | GlobalOp = expr('*') | '^'; | 931 | GlobalOp = expr('*') | '^'; |
| 932 | Global = key("global") >> space >> ( | 932 | Global = key("global") >> space >> ( |
| 933 | -(ConstAttrib >> space) >> ClassDecl | | 933 | -(ConstAttrib >> space) >> ClassDecl | |
| @@ -1056,7 +1056,7 @@ YueParser::YueParser() { | |||
| 1056 | return st->fnArrowAvailable; | 1056 | return st->fnArrowAvailable; |
| 1057 | }) >> -(FnArgsDef >> | 1057 | }) >> -(FnArgsDef >> |
| 1058 | -(':' >> space >> | 1058 | -(':' >> space >> |
| 1059 | disable_fun_lit >> ensure(ExpListLow | DefaultValue, enable_fun_lit) | 1059 | disable_fun_lit >> ensure(ExpList | DefaultValue, enable_fun_lit) |
| 1060 | ) | 1060 | ) |
| 1061 | ) >> space >> FnArrow >> -(space >> Body); | 1061 | ) >> space >> FnArrow >> -(space >> Body); |
| 1062 | 1062 | ||
| @@ -1087,7 +1087,6 @@ YueParser::YueParser() { | |||
| 1087 | *(+space_break >> check_indent_match >> space >> pipe_operator >> space >> must_unary_exp); | 1087 | *(+space_break >> check_indent_match >> space >> pipe_operator >> space >> must_unary_exp); |
| 1088 | 1088 | ||
| 1089 | ExpList = Seperator >> Exp >> *(space >> ',' >> space >> Exp); | 1089 | ExpList = Seperator >> Exp >> *(space >> ',' >> space >> Exp); |
| 1090 | ExpListLow = Seperator >> Exp >> *(space >> set(",;") >> space >> Exp); | ||
| 1091 | 1090 | ||
| 1092 | arg_line = check_indent_match >> space >> Exp >> *(space >> ',' >> space >> Exp); | 1091 | arg_line = check_indent_match >> space >> Exp >> *(space >> ',' >> space >> Exp); |
| 1093 | arg_block = arg_line >> *(space >> ',' >> space_break >> arg_line) >> pop_indent; | 1092 | arg_block = arg_line >> *(space >> ',' >> space_break >> arg_line) >> pop_indent; |
| @@ -1124,17 +1123,18 @@ YueParser::YueParser() { | |||
| 1124 | 1123 | ||
| 1125 | ChainAssign = Seperator >> Exp >> +(space >> '=' >> space >> Exp >> space >> and_('=')) >> space >> Assign; | 1124 | ChainAssign = Seperator >> Exp >> +(space >> '=' >> space >> Exp >> space >> and_('=')) >> space >> Assign; |
| 1126 | 1125 | ||
| 1127 | StatementAppendix = (IfLine | WhileLine | CompFor) >> space; | 1126 | StatementAppendix = IfLine | WhileLine | CompFor; |
| 1128 | Statement = | 1127 | Statement = ( |
| 1129 | ( | 1128 | ( |
| 1130 | Import | Export | Global | Macro | MacroInPlace | Label | 1129 | Import | Export | Global | Macro | MacroInPlace | Label |
| 1131 | ) >> space | ( | 1130 | ) | ( |
| 1132 | Local | While | Repeat | For | Return | | 1131 | Local | While | Repeat | For | Return | |
| 1133 | BreakLoop | Goto | ShortTabAppending | | 1132 | BreakLoop | Goto | ShortTabAppending | |
| 1134 | LocalAttrib | Backcall | PipeBody | ExpListAssign | ChainAssign | | 1133 | LocalAttrib | Backcall | PipeBody | ExpListAssign | ChainAssign | |
| 1135 | StatementAppendix >> empty_block_error | | 1134 | StatementAppendix >> empty_block_error | |
| 1136 | and_(key("else") | key("elseif") | key("when")) >> dangling_clause_error | 1135 | and_(key("else") | key("elseif") | key("when")) >> dangling_clause_error |
| 1137 | ) >> space >> -StatementAppendix; | 1136 | ) >> space >> -StatementAppendix |
| 1137 | ) >> space; | ||
| 1138 | 1138 | ||
| 1139 | StatementSep = white >> (set("('\"") | "[[" | "[="); | 1139 | StatementSep = white >> (set("('\"") | "[[" | "[="); |
| 1140 | 1140 | ||
| @@ -1158,15 +1158,20 @@ YueParser::YueParser() { | |||
| 1158 | return false; | 1158 | return false; |
| 1159 | }); | 1159 | }); |
| 1160 | 1160 | ||
| 1161 | is_lax = pl::user(true_(), [](const item_t& item) { | ||
| 1162 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 1163 | return st->lax; | ||
| 1164 | }); | ||
| 1165 | |||
| 1161 | line = *(EmptyLine >> line_break) >> ( | 1166 | line = *(EmptyLine >> line_break) >> ( |
| 1162 | check_indent_match >> space >> Statement | | 1167 | check_indent_match >> space >> Statement >> *(';' >> -(space >> Statement)) | |
| 1163 | YueComment | | 1168 | YueComment | |
| 1164 | advance_match >> ensure(space >> (indentation_error | Statement), pop_indent) | 1169 | advance_match >> ensure(space >> (indentation_error | Statement), pop_indent) |
| 1165 | ); | 1170 | ); |
| 1166 | Block = Seperator >> (pl::user(true_(), [](const item_t& item) { | 1171 | Block = Seperator >> ( |
| 1167 | State* st = reinterpret_cast<State*>(item.user_data); | 1172 | is_lax >> lax_line >> *(line_break >> lax_line) | |
| 1168 | return st->lax; | 1173 | line >> *(line_break >> line) |
| 1169 | }) >> lax_line >> *(line_break >> lax_line) | line >> *(line_break >> line)); | 1174 | ); |
| 1170 | 1175 | ||
| 1171 | shebang = "#!" >> *(not_(stop) >> any_char); | 1176 | shebang = "#!" >> *(not_(stop) >> any_char); |
| 1172 | BlockEnd = Block >> plain_white >> stop; | 1177 | BlockEnd = Block >> plain_white >> stop; |
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index c516ccd..df9f39c 100644 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h | |||
| @@ -319,6 +319,7 @@ private: | |||
| 319 | NONE_AST_RULE(yue_multiline_comment); | 319 | NONE_AST_RULE(yue_multiline_comment); |
| 320 | NONE_AST_RULE(line); | 320 | NONE_AST_RULE(line); |
| 321 | NONE_AST_RULE(shebang); | 321 | NONE_AST_RULE(shebang); |
| 322 | NONE_AST_RULE(is_lax); | ||
| 322 | NONE_AST_RULE(lax_line); | 323 | NONE_AST_RULE(lax_line); |
| 323 | 324 | ||
| 324 | AST_RULE(Num); | 325 | AST_RULE(Num); |
| @@ -361,7 +362,6 @@ private: | |||
| 361 | AST_RULE(Backcall); | 362 | AST_RULE(Backcall); |
| 362 | AST_RULE(SubBackcall); | 363 | AST_RULE(SubBackcall); |
| 363 | AST_RULE(PipeBody); | 364 | AST_RULE(PipeBody); |
| 364 | AST_RULE(ExpListLow); | ||
| 365 | AST_RULE(ExpList); | 365 | AST_RULE(ExpList); |
| 366 | AST_RULE(Return); | 366 | AST_RULE(Return); |
| 367 | AST_RULE(With); | 367 | AST_RULE(With); |
