diff options
| -rwxr-xr-x | doc/docs/doc/README.md | 49 | ||||
| -rwxr-xr-x | doc/docs/zh/doc/README.md | 49 | ||||
| -rw-r--r-- | spec/inputs/vararg.yue | 44 | ||||
| -rw-r--r-- | spec/outputs/codes_from_doc.lua | 60 | ||||
| -rw-r--r-- | spec/outputs/codes_from_doc_zh.lua | 60 | ||||
| -rw-r--r-- | spec/outputs/vararg.lua | 72 | ||||
| -rw-r--r-- | src/yuescript/yue_ast.cpp | 3 | ||||
| -rw-r--r-- | src/yuescript/yue_ast.h | 7 | ||||
| -rw-r--r-- | src/yuescript/yue_compiler.cpp | 29 | ||||
| -rw-r--r-- | src/yuescript/yue_parser.cpp | 5 | ||||
| -rw-r--r-- | src/yuescript/yue_parser.h | 1 |
11 files changed, 369 insertions, 10 deletions
diff --git a/doc/docs/doc/README.md b/doc/docs/doc/README.md index 1a46e59..d2f838d 100755 --- a/doc/docs/doc/README.md +++ b/doc/docs/doc/README.md | |||
| @@ -1528,6 +1528,55 @@ print ok, count, first | |||
| 1528 | </pre> | 1528 | </pre> |
| 1529 | </YueDisplay> | 1529 | </YueDisplay> |
| 1530 | 1530 | ||
| 1531 | ### Named Varargs | ||
| 1532 | |||
| 1533 | You can use the `(...t) ->` syntax to automatically store varargs into a named table. This table will contain all passed arguments (including `nil` values), and the `n` field of the table will store the actual number of arguments passed (including `nil` values). | ||
| 1534 | |||
| 1535 | ```moonscript | ||
| 1536 | f = (...t) -> | ||
| 1537 | print "argument count:", t.n | ||
| 1538 | print "table length:", #t | ||
| 1539 | for i = 1, t.n | ||
| 1540 | print t[i] | ||
| 1541 | |||
| 1542 | f 1, 2, 3 | ||
| 1543 | f "a", "b", "c", "d" | ||
| 1544 | f! | ||
| 1545 | |||
| 1546 | -- Handling cases with nil values | ||
| 1547 | process = (...args) -> | ||
| 1548 | sum = 0 | ||
| 1549 | for i = 1, args.n | ||
| 1550 | if args[i] != nil and type(args[i]) == "number" | ||
| 1551 | sum += args[i] | ||
| 1552 | sum | ||
| 1553 | |||
| 1554 | process 1, nil, 3, nil, 5 | ||
| 1555 | ``` | ||
| 1556 | <YueDisplay> | ||
| 1557 | <pre> | ||
| 1558 | f = (...t) -> | ||
| 1559 | print "argument count:", t.n | ||
| 1560 | print "table length:", #t | ||
| 1561 | for i = 1, t.n | ||
| 1562 | print t[i] | ||
| 1563 | |||
| 1564 | f 1, 2, 3 | ||
| 1565 | f "a", "b", "c", "d" | ||
| 1566 | f! | ||
| 1567 | |||
| 1568 | -- Handling cases with nil values | ||
| 1569 | process = (...args) -> | ||
| 1570 | sum = 0 | ||
| 1571 | for i = 1, args.n | ||
| 1572 | if args[i] != nil and type(args[i]) == "number" | ||
| 1573 | sum += args[i] | ||
| 1574 | sum | ||
| 1575 | |||
| 1576 | process 1, nil, 3, nil, 5 | ||
| 1577 | </pre> | ||
| 1578 | </YueDisplay> | ||
| 1579 | |||
| 1531 | ## Whitespace | 1580 | ## Whitespace |
| 1532 | 1581 | ||
| 1533 | 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. | 1582 | 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. |
diff --git a/doc/docs/zh/doc/README.md b/doc/docs/zh/doc/README.md index b348e06..34d577c 100755 --- a/doc/docs/zh/doc/README.md +++ b/doc/docs/zh/doc/README.md | |||
| @@ -1526,6 +1526,55 @@ print ok, count, first | |||
| 1526 | </pre> | 1526 | </pre> |
| 1527 | </YueDisplay> | 1527 | </YueDisplay> |
| 1528 | 1528 | ||
| 1529 | ### 命名变长参数 | ||
| 1530 | |||
| 1531 | 你可以使用 `(...t) ->` 语法来将变长参数自动存储到一个命名表中。这个表会包含所有传入的参数(包括 `nil` 值),并且会在表的 `n` 字段中存储实际传入的参数个数(包括 `nil` 值在内的个数)。 | ||
| 1532 | |||
| 1533 | ```moonscript | ||
| 1534 | f = (...t) -> | ||
| 1535 | print "参数个数:", t.n | ||
| 1536 | print "表长度:", #t | ||
| 1537 | for i = 1, t.n | ||
| 1538 | print t[i] | ||
| 1539 | |||
| 1540 | f 1, 2, 3 | ||
| 1541 | f "a", "b", "c", "d" | ||
| 1542 | f! | ||
| 1543 | |||
| 1544 | -- 处理包含 nil 的情况 | ||
| 1545 | process = (...args) -> | ||
| 1546 | sum = 0 | ||
| 1547 | for i = 1, args.n | ||
| 1548 | if args[i] != nil and type(args[i]) == "number" | ||
| 1549 | sum += args[i] | ||
| 1550 | sum | ||
| 1551 | |||
| 1552 | process 1, nil, 3, nil, 5 | ||
| 1553 | ``` | ||
| 1554 | <YueDisplay> | ||
| 1555 | <pre> | ||
| 1556 | f = (...t) -> | ||
| 1557 | print "参数个数:", t.n | ||
| 1558 | print "表长度:", #t | ||
| 1559 | for i = 1, t.n | ||
| 1560 | print t[i] | ||
| 1561 | |||
| 1562 | f 1, 2, 3 | ||
| 1563 | f "a", "b", "c", "d" | ||
| 1564 | f! | ||
| 1565 | |||
| 1566 | -- 处理包含 nil 的情况 | ||
| 1567 | process = (...args) -> | ||
| 1568 | sum = 0 | ||
| 1569 | for i = 1, args.n | ||
| 1570 | if args[i] != nil and type(args[i]) == "number" | ||
| 1571 | sum += args[i] | ||
| 1572 | sum | ||
| 1573 | |||
| 1574 | process 1, nil, 3, nil, 5 | ||
| 1575 | </pre> | ||
| 1576 | </YueDisplay> | ||
| 1577 | |||
| 1529 | ## 空白 | 1578 | ## 空白 |
| 1530 | 1579 | ||
| 1531 | 月之脚本是一个对空白敏感的语言。你必须在相同的缩进中使用空格 **' '** 或制表符 **'\t'** 来编写一些代码块,如函数体、值列表和一些控制块。包含不同空白的表达式可能意味着不同的事情。制表符被视为4个空格,但最好不要混合使用空格和制表符。 | 1580 | 月之脚本是一个对空白敏感的语言。你必须在相同的缩进中使用空格 **' '** 或制表符 **'\t'** 来编写一些代码块,如函数体、值列表和一些控制块。包含不同空白的表达式可能意味着不同的事情。制表符被视为4个空格,但最好不要混合使用空格和制表符。 |
diff --git a/spec/inputs/vararg.yue b/spec/inputs/vararg.yue index 6100250..4f8a0d7 100644 --- a/spec/inputs/vararg.yue +++ b/spec/inputs/vararg.yue | |||
| @@ -86,3 +86,47 @@ join = (...) -> | |||
| 86 | print ... | 86 | print ... |
| 87 | nil | 87 | nil |
| 88 | 88 | ||
| 89 | do | ||
| 90 | f1 = (...t) -> | ||
| 91 | print t.n | ||
| 92 | print #t | ||
| 93 | for i = 1, t.n | ||
| 94 | print t[i] | ||
| 95 | |||
| 96 | f1 1, 2, 3 | ||
| 97 | f1 "a", "b", "c", "d" | ||
| 98 | f1! | ||
| 99 | |||
| 100 | f2 = (...args) -> | ||
| 101 | print "args count:", args.n | ||
| 102 | print "args length:", #args | ||
| 103 | for i = 1, args.n | ||
| 104 | if args[i] == nil | ||
| 105 | print "position", i, "is nil" | ||
| 106 | else | ||
| 107 | print "position", i, ":", args[i] | ||
| 108 | |||
| 109 | f2 1, nil, 3, nil, 5 | ||
| 110 | |||
| 111 | f3 = (prefix, ...items) -> | ||
| 112 | result = {} | ||
| 113 | for i = 1, items.n | ||
| 114 | result[i] = prefix .. tostring items[i] | ||
| 115 | result | ||
| 116 | |||
| 117 | f3 "item_", 1, 2, 3 | ||
| 118 | |||
| 119 | f4 = (...empty) -> | ||
| 120 | print "empty count:", empty.n | ||
| 121 | print "empty length:", #empty | ||
| 122 | |||
| 123 | f4! | ||
| 124 | |||
| 125 | process = (...data) -> | ||
| 126 | sum = 0 | ||
| 127 | for i = 1, data.n | ||
| 128 | if type(data[i]) == "number" | ||
| 129 | sum += data[i] | ||
| 130 | sum | ||
| 131 | |||
| 132 | process 1, 2, 3, "skip", 5 | ||
diff --git a/spec/outputs/codes_from_doc.lua b/spec/outputs/codes_from_doc.lua index d6617a9..de5abdd 100644 --- a/spec/outputs/codes_from_doc.lua +++ b/spec/outputs/codes_from_doc.lua | |||
| @@ -737,6 +737,36 @@ end | |||
| 737 | local first = select(1, ...) | 737 | local first = select(1, ...) |
| 738 | return print(ok, count, first) | 738 | return print(ok, count, first) |
| 739 | end)(fn(true)) | 739 | end)(fn(true)) |
| 740 | local f | ||
| 741 | f = function(...) | ||
| 742 | local t = { | ||
| 743 | n = select("#", ...), | ||
| 744 | ... | ||
| 745 | } | ||
| 746 | print("argument count:", t.n) | ||
| 747 | print("table length:", #t) | ||
| 748 | for i = 1, t.n do | ||
| 749 | print(t[i]) | ||
| 750 | end | ||
| 751 | end | ||
| 752 | f(1, 2, 3) | ||
| 753 | f("a", "b", "c", "d") | ||
| 754 | f() | ||
| 755 | local process | ||
| 756 | process = function(...) | ||
| 757 | local args = { | ||
| 758 | n = select("#", ...), | ||
| 759 | ... | ||
| 760 | } | ||
| 761 | local sum = 0 | ||
| 762 | for i = 1, args.n do | ||
| 763 | if args[i] ~= nil and type(args[i]) == "number" then | ||
| 764 | sum = sum + args[i] | ||
| 765 | end | ||
| 766 | end | ||
| 767 | return sum | ||
| 768 | end | ||
| 769 | process(1, nil, 3, nil, 5) | ||
| 740 | Rx.Observable.fromRange(1, 8):filter(function(x) | 770 | Rx.Observable.fromRange(1, 8):filter(function(x) |
| 741 | return x % 2 == 0 | 771 | return x % 2 == 0 |
| 742 | end):concat(Rx.Observable.of('who do we appreciate')):map(function(value) | 772 | end):concat(Rx.Observable.of('who do we appreciate')):map(function(value) |
| @@ -3215,6 +3245,36 @@ end | |||
| 3215 | local first = select(1, ...) | 3245 | local first = select(1, ...) |
| 3216 | return print(ok, count, first) | 3246 | return print(ok, count, first) |
| 3217 | end)(fn(true)) | 3247 | end)(fn(true)) |
| 3248 | local f | ||
| 3249 | f = function(...) | ||
| 3250 | local t = { | ||
| 3251 | n = select("#", ...), | ||
| 3252 | ... | ||
| 3253 | } | ||
| 3254 | print("argument count:", t.n) | ||
| 3255 | print("table length:", #t) | ||
| 3256 | for i = 1, t.n do | ||
| 3257 | print(t[i]) | ||
| 3258 | end | ||
| 3259 | end | ||
| 3260 | f(1, 2, 3) | ||
| 3261 | f("a", "b", "c", "d") | ||
| 3262 | f() | ||
| 3263 | local process | ||
| 3264 | process = function(...) | ||
| 3265 | local args = { | ||
| 3266 | n = select("#", ...), | ||
| 3267 | ... | ||
| 3268 | } | ||
| 3269 | local sum = 0 | ||
| 3270 | for i = 1, args.n do | ||
| 3271 | if args[i] ~= nil and type(args[i]) == "number" then | ||
| 3272 | sum = sum + args[i] | ||
| 3273 | end | ||
| 3274 | end | ||
| 3275 | return sum | ||
| 3276 | end | ||
| 3277 | process(1, nil, 3, nil, 5) | ||
| 3218 | Rx.Observable.fromRange(1, 8):filter(function(x) | 3278 | Rx.Observable.fromRange(1, 8):filter(function(x) |
| 3219 | return x % 2 == 0 | 3279 | return x % 2 == 0 |
| 3220 | end):concat(Rx.Observable.of('who do we appreciate')):map(function(value) | 3280 | 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 ec84112..6a6c38c 100644 --- a/spec/outputs/codes_from_doc_zh.lua +++ b/spec/outputs/codes_from_doc_zh.lua | |||
| @@ -737,6 +737,36 @@ end | |||
| 737 | local first = select(1, ...) | 737 | local first = select(1, ...) |
| 738 | return print(ok, count, first) | 738 | return print(ok, count, first) |
| 739 | end)(fn(true)) | 739 | end)(fn(true)) |
| 740 | local f | ||
| 741 | f = function(...) | ||
| 742 | local t = { | ||
| 743 | n = select("#", ...), | ||
| 744 | ... | ||
| 745 | } | ||
| 746 | print("参数个数:", t.n) | ||
| 747 | print("表长度:", #t) | ||
| 748 | for i = 1, t.n do | ||
| 749 | print(t[i]) | ||
| 750 | end | ||
| 751 | end | ||
| 752 | f(1, 2, 3) | ||
| 753 | f("a", "b", "c", "d") | ||
| 754 | f() | ||
| 755 | local process | ||
| 756 | process = function(...) | ||
| 757 | local args = { | ||
| 758 | n = select("#", ...), | ||
| 759 | ... | ||
| 760 | } | ||
| 761 | local sum = 0 | ||
| 762 | for i = 1, args.n do | ||
| 763 | if args[i] ~= nil and type(args[i]) == "number" then | ||
| 764 | sum = sum + args[i] | ||
| 765 | end | ||
| 766 | end | ||
| 767 | return sum | ||
| 768 | end | ||
| 769 | process(1, nil, 3, nil, 5) | ||
| 740 | Rx.Observable.fromRange(1, 8):filter(function(x) | 770 | Rx.Observable.fromRange(1, 8):filter(function(x) |
| 741 | return x % 2 == 0 | 771 | return x % 2 == 0 |
| 742 | end):concat(Rx.Observable.of('who do we appreciate')):map(function(value) | 772 | end):concat(Rx.Observable.of('who do we appreciate')):map(function(value) |
| @@ -3209,6 +3239,36 @@ end | |||
| 3209 | local first = select(1, ...) | 3239 | local first = select(1, ...) |
| 3210 | return print(ok, count, first) | 3240 | return print(ok, count, first) |
| 3211 | end)(fn(true)) | 3241 | end)(fn(true)) |
| 3242 | local f | ||
| 3243 | f = function(...) | ||
| 3244 | local t = { | ||
| 3245 | n = select("#", ...), | ||
| 3246 | ... | ||
| 3247 | } | ||
| 3248 | print("参数个数:", t.n) | ||
| 3249 | print("表长度:", #t) | ||
| 3250 | for i = 1, t.n do | ||
| 3251 | print(t[i]) | ||
| 3252 | end | ||
| 3253 | end | ||
| 3254 | f(1, 2, 3) | ||
| 3255 | f("a", "b", "c", "d") | ||
| 3256 | f() | ||
| 3257 | local process | ||
| 3258 | process = function(...) | ||
| 3259 | local args = { | ||
| 3260 | n = select("#", ...), | ||
| 3261 | ... | ||
| 3262 | } | ||
| 3263 | local sum = 0 | ||
| 3264 | for i = 1, args.n do | ||
| 3265 | if args[i] ~= nil and type(args[i]) == "number" then | ||
| 3266 | sum = sum + args[i] | ||
| 3267 | end | ||
| 3268 | end | ||
| 3269 | return sum | ||
| 3270 | end | ||
| 3271 | process(1, nil, 3, nil, 5) | ||
| 3212 | Rx.Observable.fromRange(1, 8):filter(function(x) | 3272 | Rx.Observable.fromRange(1, 8):filter(function(x) |
| 3213 | return x % 2 == 0 | 3273 | return x % 2 == 0 |
| 3214 | end):concat(Rx.Observable.of('who do we appreciate')):map(function(value) | 3274 | end):concat(Rx.Observable.of('who do we appreciate')):map(function(value) |
diff --git a/spec/outputs/vararg.lua b/spec/outputs/vararg.lua index 254aa6a..9f97681 100644 --- a/spec/outputs/vararg.lua +++ b/spec/outputs/vararg.lua | |||
| @@ -294,3 +294,75 @@ join = function(...) | |||
| 294 | end | 294 | end |
| 295 | return nil | 295 | return nil |
| 296 | end | 296 | end |
| 297 | do | ||
| 298 | local f1 | ||
| 299 | f1 = function(...) | ||
| 300 | local t = { | ||
| 301 | n = select("#", ...), | ||
| 302 | ... | ||
| 303 | } | ||
| 304 | print(t.n) | ||
| 305 | print(#t) | ||
| 306 | for i = 1, t.n do | ||
| 307 | print(t[i]) | ||
| 308 | end | ||
| 309 | end | ||
| 310 | f1(1, 2, 3) | ||
| 311 | f1("a", "b", "c", "d") | ||
| 312 | f1() | ||
| 313 | local f2 | ||
| 314 | f2 = function(...) | ||
| 315 | local args = { | ||
| 316 | n = select("#", ...), | ||
| 317 | ... | ||
| 318 | } | ||
| 319 | print("args count:", args.n) | ||
| 320 | print("args length:", #args) | ||
| 321 | for i = 1, args.n do | ||
| 322 | if args[i] == nil then | ||
| 323 | print("position", i, "is nil") | ||
| 324 | else | ||
| 325 | print("position", i, ":", args[i]) | ||
| 326 | end | ||
| 327 | end | ||
| 328 | end | ||
| 329 | f2(1, nil, 3, nil, 5) | ||
| 330 | local f3 | ||
| 331 | f3 = function(prefix, ...) | ||
| 332 | local items = { | ||
| 333 | n = select("#", ...), | ||
| 334 | ... | ||
| 335 | } | ||
| 336 | local result = { } | ||
| 337 | for i = 1, items.n do | ||
| 338 | result[i] = prefix .. tostring(items[i]) | ||
| 339 | end | ||
| 340 | return result | ||
| 341 | end | ||
| 342 | f3("item_", 1, 2, 3) | ||
| 343 | local f4 | ||
| 344 | f4 = function(...) | ||
| 345 | local empty = { | ||
| 346 | n = select("#", ...), | ||
| 347 | ... | ||
| 348 | } | ||
| 349 | print("empty count:", empty.n) | ||
| 350 | return print("empty length:", #empty) | ||
| 351 | end | ||
| 352 | f4() | ||
| 353 | local process | ||
| 354 | process = function(...) | ||
| 355 | local data = { | ||
| 356 | n = select("#", ...), | ||
| 357 | ... | ||
| 358 | } | ||
| 359 | local sum = 0 | ||
| 360 | for i = 1, data.n do | ||
| 361 | if type(data[i]) == "number" then | ||
| 362 | sum = sum + data[i] | ||
| 363 | end | ||
| 364 | end | ||
| 365 | return sum | ||
| 366 | end | ||
| 367 | return process(1, 2, 3, "skip", 5) | ||
| 368 | end | ||
diff --git a/src/yuescript/yue_ast.cpp b/src/yuescript/yue_ast.cpp index be0ec45..55b5d03 100644 --- a/src/yuescript/yue_ast.cpp +++ b/src/yuescript/yue_ast.cpp | |||
| @@ -82,6 +82,9 @@ std::string SelfClass_t::to_string(void*) const { | |||
| 82 | std::string VarArg_t::to_string(void*) const { | 82 | std::string VarArg_t::to_string(void*) const { |
| 83 | return "..."s; | 83 | return "..."s; |
| 84 | } | 84 | } |
| 85 | std::string VarArgDef_t::to_string(void* ud) const { | ||
| 86 | return "..."s + name->to_string(ud); | ||
| 87 | } | ||
| 85 | std::string Seperator_t::to_string(void*) const { | 88 | std::string Seperator_t::to_string(void*) const { |
| 86 | return {}; | 89 | return {}; |
| 87 | } | 90 | } |
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index b7cd73e..885a038 100644 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h | |||
| @@ -134,6 +134,11 @@ AST_NODE(KeyName) | |||
| 134 | AST_MEMBER(KeyName, &name) | 134 | AST_MEMBER(KeyName, &name) |
| 135 | AST_END(KeyName) | 135 | AST_END(KeyName) |
| 136 | 136 | ||
| 137 | AST_NODE(VarArgDef) | ||
| 138 | ast_ptr<false, Variable_t> name; | ||
| 139 | AST_MEMBER(VarArgDef, &name) | ||
| 140 | AST_END(VarArgDef) | ||
| 141 | |||
| 137 | AST_LEAF(VarArg) | 142 | AST_LEAF(VarArg) |
| 138 | AST_END(VarArg) | 143 | AST_END(VarArg) |
| 139 | 144 | ||
| @@ -790,7 +795,7 @@ AST_END(FnArgDef) | |||
| 790 | AST_NODE(FnArgDefList) | 795 | AST_NODE(FnArgDefList) |
| 791 | ast_ptr<true, Seperator_t> sep; | 796 | ast_ptr<true, Seperator_t> sep; |
| 792 | ast_list<false, FnArgDef_t> definitions; | 797 | ast_list<false, FnArgDef_t> definitions; |
| 793 | ast_ptr<false, VarArg_t> varArg; | 798 | ast_ptr<false, VarArgDef_t> varArg; |
| 794 | ast_ptr<false, Name_t> label; | 799 | ast_ptr<false, Name_t> label; |
| 795 | AST_MEMBER(FnArgDefList, &sep, &definitions, &varArg, &label) | 800 | AST_MEMBER(FnArgDefList, &sep, &definitions, &varArg, &label) |
| 796 | AST_END(FnArgDefList) | 801 | AST_END(FnArgDefList) |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 77643d3..cae01dd 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.30.3"sv; | 81 | const std::string_view version = "0.30.4"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 { |
| @@ -5872,18 +5872,33 @@ private: | |||
| 5872 | temp.emplace_back(indent() + "local "s + join(names, ", "sv) + nl(def)); | 5872 | temp.emplace_back(indent() + "local "s + join(names, ", "sv) + nl(def)); |
| 5873 | transformAssignment(arg.assignment, temp); | 5873 | transformAssignment(arg.assignment, temp); |
| 5874 | } | 5874 | } |
| 5875 | if (varNames.empty()) | 5875 | if (varNames.empty()) { |
| 5876 | varNames = arg.name; | 5876 | varNames = arg.name; |
| 5877 | else | 5877 | } else { |
| 5878 | varNames.append(", "s + arg.name); | 5878 | varNames.append(", "s + arg.name); |
| 5879 | } | ||
| 5879 | } | 5880 | } |
| 5880 | if (argDefList->varArg) { | 5881 | if (argDefList->varArg) { |
| 5882 | std::string varStr; | ||
| 5883 | if (auto varName = argDefList->varArg->name.get()) { | ||
| 5884 | varStr = variableToString(varName); | ||
| 5885 | int target = getLuaTarget(varName); | ||
| 5886 | forceAddToScope(varStr); | ||
| 5887 | if (target < 505) { | ||
| 5888 | temp.push_back(indent() + "local "s + varStr + " = {"s + nl(varName)); | ||
| 5889 | temp.push_back(indent(1) + "n = "s + globalVar("select", varName, AccessType::Read) + "(\"#\", ...),"s + nl(varName)); | ||
| 5890 | temp.push_back(indent(1) + "..."s + nl(varName)); | ||
| 5891 | temp.push_back(indent() + '}' + nl(varName)); | ||
| 5892 | varStr.clear(); | ||
| 5893 | } | ||
| 5894 | } | ||
| 5881 | auto& arg = argItems.emplace_back(); | 5895 | auto& arg = argItems.emplace_back(); |
| 5882 | arg.name = "..."sv; | 5896 | arg.name = "..."sv; |
| 5883 | if (varNames.empty()) | 5897 | if (varNames.empty()) { |
| 5884 | varNames = arg.name; | 5898 | varNames = arg.name + varStr; |
| 5885 | else | 5899 | } else { |
| 5886 | varNames.append(", "s + arg.name); | 5900 | varNames.append(", "s + arg.name + varStr); |
| 5901 | } | ||
| 5887 | _varArgs.top().hasVar = true; | 5902 | _varArgs.top().hasVar = true; |
| 5888 | } | 5903 | } |
| 5889 | if (assignSelf) { | 5904 | if (assignSelf) { |
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 1999721..17b10c6 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
| @@ -308,6 +308,7 @@ YueParser::YueParser() { | |||
| 308 | 308 | ||
| 309 | SelfItem = SelfClassName | SelfClass | SelfName | Self; | 309 | SelfItem = SelfClassName | SelfClass | SelfName | Self; |
| 310 | KeyName = SelfItem | Name | UnicodeName; | 310 | KeyName = SelfItem | Name | UnicodeName; |
| 311 | VarArgDef = "..." >> -(space >> Variable); | ||
| 311 | VarArg = "..."; | 312 | VarArg = "..."; |
| 312 | 313 | ||
| 313 | auto getIndent = [](const item_t& item) -> int { | 314 | auto getIndent = [](const item_t& item) -> int { |
| @@ -1032,8 +1033,8 @@ YueParser::YueParser() { | |||
| 1032 | check_vararg_position = and_(white >> (')' | key("using"))) | white >> -(',' >> white) >> vararg_position_error; | 1033 | check_vararg_position = and_(white >> (')' | key("using"))) | white >> -(',' >> white) >> vararg_position_error; |
| 1033 | 1034 | ||
| 1034 | var_arg_def = ( | 1035 | var_arg_def = ( |
| 1035 | VarArg | | 1036 | VarArgDef | |
| 1036 | +space_break >> push_indent_match >> ensure(space >> VarArg >> -(space >> '`' >> space >> Name), pop_indent) | 1037 | +space_break >> push_indent_match >> ensure(space >> VarArgDef >> -(space >> '`' >> space >> Name), pop_indent) |
| 1037 | ) >> check_vararg_position; | 1038 | ) >> check_vararg_position; |
| 1038 | 1039 | ||
| 1039 | FnArgDefList = Seperator >> | 1040 | FnArgDefList = Seperator >> |
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index b68742f..7deaa18 100644 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h | |||
| @@ -333,6 +333,7 @@ private: | |||
| 333 | AST_RULE(SelfItem); | 333 | AST_RULE(SelfItem); |
| 334 | AST_RULE(KeyName); | 334 | AST_RULE(KeyName); |
| 335 | AST_RULE(VarArg); | 335 | AST_RULE(VarArg); |
| 336 | AST_RULE(VarArgDef); | ||
| 336 | AST_RULE(Seperator); | 337 | AST_RULE(Seperator); |
| 337 | AST_RULE(NameList); | 338 | AST_RULE(NameList); |
| 338 | AST_RULE(LocalFlag); | 339 | AST_RULE(LocalFlag); |
