Skip to content

Commit 470f94c

Browse files
authored
🪲 parser: Fix variadic parameter bug (#89)
Fix variadic parameter bug, where the variadic parameter gets added to the scope in its original form rather than as an array of it. Before we'd add for func x n:num... x with type `num` rather than `[]num` to the function body's scope. Fix and add tests to evaluation and parsing. Pull-Request: #89
1 parent 9ed528b commit 470f94c

File tree

3 files changed

+71
-3
lines changed

3 files changed

+71
-3
lines changed

pkg/evaluator/evaluator_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -998,6 +998,48 @@ print 5 errmsg
998998
}
999999
}
10001000

1001+
func TestVariadic(t *testing.T) {
1002+
prog := `
1003+
func fox nums:num...
1004+
for n := range nums
1005+
print n "🦊"
1006+
end
1007+
end
1008+
1009+
func fox2 strings:string...
1010+
for s := range strings
1011+
print s "🦊"
1012+
end
1013+
end
1014+
1015+
func fox3 anys:any...
1016+
for a := range anys
1017+
print a "🦊"
1018+
end
1019+
end
1020+
1021+
fox 1 2 3
1022+
fox2 "a" "b"
1023+
fox3 [1 2] true
1024+
`
1025+
out := run(prog)
1026+
want := []string{
1027+
"1 🦊",
1028+
"2 🦊",
1029+
"3 🦊",
1030+
"a 🦊",
1031+
"b 🦊",
1032+
"[1 2] 🦊",
1033+
"true 🦊",
1034+
"",
1035+
}
1036+
got := strings.Split(out, "\n")
1037+
assert.Equal(t, len(want), len(got), out)
1038+
for i := range want {
1039+
assert.Equal(t, want[i], got[i])
1040+
}
1041+
}
1042+
10011043
func TestDemo(t *testing.T) {
10021044
prog := `
10031045
move 10 10

pkg/parser/parser.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,15 @@ func (p *Parser) addParamsToScope(scope *scope, fd *FuncDecl) {
194194
scope.set(param.Name, param)
195195
}
196196
if fd.VariadicParam != nil {
197-
param := fd.VariadicParam
198-
p.validateVarDecl(scope, param, param.Token, true /* allowUnderscore */)
199-
scope.set(param.Name, param)
197+
vParam := fd.VariadicParam
198+
p.validateVarDecl(scope, vParam, vParam.Token, true /* allowUnderscore */)
199+
200+
vParamAsArray := &Var{
201+
Name: vParam.Name,
202+
Token: vParam.Token,
203+
T: &Type{Name: ARRAY, Sub: vParam.Type()},
204+
}
205+
scope.set(vParam.Name, vParamAsArray)
200206
}
201207
}
202208

pkg/parser/parser_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,26 @@ end
255255
assert.Equal(t, "return n2", returnStmt.String())
256256
}
257257

258+
func TestVariadicFuncDecl(t *testing.T) {
259+
inputs := []string{
260+
`
261+
func fox nums:num...
262+
test nums
263+
end
264+
265+
func test nums:[]num
266+
print nums
267+
end
268+
269+
fox 1 2 3`,
270+
}
271+
for _, input := range inputs {
272+
parser := New(input, testBuiltins())
273+
_ = parser.Parse()
274+
assertNoParseError(t, parser, input)
275+
}
276+
}
277+
258278
func TestReturnErr(t *testing.T) {
259279
inputs := map[string]string{
260280
`

0 commit comments

Comments
 (0)