Skip to content

Commit 7ee395d

Browse files
committed
Added named vararg support.
1 parent bb56325 commit 7ee395d

11 files changed

Lines changed: 369 additions & 10 deletions

File tree

doc/docs/doc/README.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,6 +1528,55 @@ print ok, count, first
15281528
</pre>
15291529
</YueDisplay>
15301530

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+
15311580
## Whitespace
15321581

15331582
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.

doc/docs/zh/doc/README.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,6 +1526,55 @@ print ok, count, first
15261526
</pre>
15271527
</YueDisplay>
15281528

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+
15291578
## 空白
15301579

15311580
月之脚本是一个对空白敏感的语言。你必须在相同的缩进中使用空格 **' '** 或制表符 **'\t'** 来编写一些代码块,如函数体、值列表和一些控制块。包含不同空白的表达式可能意味着不同的事情。制表符被视为4个空格,但最好不要混合使用空格和制表符。

spec/inputs/vararg.yue

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,47 @@ join = (...) ->
8686
print ...
8787
nil
8888

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

spec/outputs/codes_from_doc.lua

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,36 @@ end
737737
local first = select(1, ...)
738738
return print(ok, count, first)
739739
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)
740770
Rx.Observable.fromRange(1, 8):filter(function(x)
741771
return x % 2 == 0
742772
end):concat(Rx.Observable.of('who do we appreciate')):map(function(value)
@@ -3215,6 +3245,36 @@ end
32153245
local first = select(1, ...)
32163246
return print(ok, count, first)
32173247
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)
32183278
Rx.Observable.fromRange(1, 8):filter(function(x)
32193279
return x % 2 == 0
32203280
end):concat(Rx.Observable.of('who do we appreciate')):map(function(value)

spec/outputs/codes_from_doc_zh.lua

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,36 @@ end
737737
local first = select(1, ...)
738738
return print(ok, count, first)
739739
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)
740770
Rx.Observable.fromRange(1, 8):filter(function(x)
741771
return x % 2 == 0
742772
end):concat(Rx.Observable.of('who do we appreciate')):map(function(value)
@@ -3209,6 +3239,36 @@ end
32093239
local first = select(1, ...)
32103240
return print(ok, count, first)
32113241
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)
32123272
Rx.Observable.fromRange(1, 8):filter(function(x)
32133273
return x % 2 == 0
32143274
end):concat(Rx.Observable.of('who do we appreciate')):map(function(value)

spec/outputs/vararg.lua

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,3 +294,75 @@ join = function(...)
294294
end
295295
return nil
296296
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

src/yuescript/yue_ast.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ std::string SelfClass_t::to_string(void*) const {
8282
std::string VarArg_t::to_string(void*) const {
8383
return "..."s;
8484
}
85+
std::string VarArgDef_t::to_string(void* ud) const {
86+
return "..."s + name->to_string(ud);
87+
}
8588
std::string Seperator_t::to_string(void*) const {
8689
return {};
8790
}

0 commit comments

Comments
 (0)