Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement simple default parameters #531

Merged
merged 5 commits into from
Feb 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions src/nimony/sigmatch.nim
Original file line number Diff line number Diff line change
Expand Up @@ -839,12 +839,19 @@ iterator typeVars(fn: SymId): SymId =
yield tv.symId
skip c

proc collectDefaultValues(f: var Cursor): seq[Item] =
proc collectDefaultValues(m: var Match; f: Cursor): seq[Item] =
var f = f
result = @[]
while f.symKind == ParamY:
let param = asLocal(f)
if param.val.kind == DotToken: break
result.add Item(n: param.val, typ: param.typ)
# xxx getType so that in `proc foo6[T](x: T = 3); foo6()`, the type of `x` might be inferred
if param.typ.kind == Symbol and isTypevar(param.typ.symId) and
m.inferred.contains(param.typ.symId):
var prev = m.inferred[param.typ.symId]
result.add Item(n: param.val, typ: prev)
else:
result.add Item(n: param.val, typ: param.typ)
skip f

proc matchTypevars*(m: var Match; fn: FnCandidate; explicitTypeVars: Cursor) =
Expand Down Expand Up @@ -891,10 +898,8 @@ proc sigmatch*(m: var Match; fn: FnCandidate; args: openArray[Item];
# not all arguments where used, error:
m.error0 TooManyArguments
elif f.kind != ParRi:
# use default values for these parameters, but this needs to be done
# properly with generics etc. so we use a helper `args` seq and pretend
# the programmer had written out these arguments:
let moreArgs = collectDefaultValues(f)
# use default values for these parameters
let moreArgs = collectDefaultValues(m, f)
sigmatchLoop m, f, moreArgs
if f.kind != ParRi:
m.error0 TooFewArguments
Expand Down
114 changes: 114 additions & 0 deletions tests/nimony/sysbasics/tdefaultparams.nif
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
(.nif24)
0,1,tests/nimony/sysbasics/tdefaultparams.nim(stmts
(proc 5 :foo1.0.tdebp8hax . . . 9
(params 1
(param :x.0 . . 3
(i -1) .) 9
(param :y.0 . . 3
(f +64) 11 +1.2)) . . . 2,1
(stmts 4
(let :m.0 . . 7,~1
(i -1) 4 x.0))) ,3
(proc 5 :foo2.0.tdebp8hax . . . 9
(params 1
(param :x.1 . . 3,~3
(i -1) 4 +3) 8
(param :y.1 . . ~4,~3
(i -1) 4 +7)) . . . 2,1
(stmts 4
(let :s.0 . . 7,~4
(i -1) 4 x.1) 4,1
(let :j.0 . . 7,~5
(i -1) 4 y.1))) ,7
(proc 5 :foo3.0.tdebp8hax . . . 9
(params 1
(param :x.2 . . 3
(i -1) .) 9
(param :y.2 . . 3
(f +64) .) 19
(param :z.0 . . ~15,~7
(i -1) 9 +23)) . . . 2,1
(stmts
(discard .))) ,10
(proc 5 :foo4.0.tdebp8hax . . . 9
(params 1
(param :x.3 . . 3
(i -1) .) 9
(param :y.3 . . 3
(f +64) .) 19
(param :z.1 . . ~15,~10
(i -1) 9 +23) 32
(param :a.0 . . ~20,~10
(f +64) 11 +1.2)) . . . 2,1
(stmts
(discard .))) ,13
(proc 5 :foo5.0.tdebp8hax . . 9
(typevars 1
(typevar :T.0.tdebp8hax . . . .)) 12
(params 1
(param :x.4 . . 3 T.0.tdebp8hax .) 7
(param :y.4 . . ~6,~13
(i -1) 9 +7)) . . . 2,1
(stmts
(discard .))) ,16
(proc 5 :foo6.0.tdebp8hax . . 9
(typevars 1
(typevar :T.1.tdebp8hax . . . .)) 12
(params 1
(param :x.5 . . 3 T.1.tdebp8hax 7 +3) 11
(param :y.5 . . ~10,~16
(i -1) 9 +7)) . . . 2,1
(stmts
(discard .))) ,19
(proc 5 :foo.0.tdebp8hax . . 8
(typevars 1
(typevar :T.2.tdebp8hax . . . .)) 11
(params 1
(param :x.6 . . 3 T.2.tdebp8hax .) 7
(param :y.6 . . ~3 T.2.tdebp8hax 7 +7)) . . . 2,1
(stmts 4
(let :s.1 . . 9,~1 T.2.tdebp8hax 4 x.6) 4,1
(let :j.1 . . 9,~2 T.2.tdebp8hax 4 y.6))) 3,23
(call ~3 foo.1.tdebp8hax 1 +3 22,~4 +7) 4,24
(call ~4 foo2.0.tdebp8hax 10,~21 +3 17,~21 +7) 4,25
(call ~4 foo2.0.tdebp8hax 1 +1 17,~22 +7) 4,26
(call ~4 foo3.0.tdebp8hax 1 +1 4 +2.3 33,~19 +23) 4,27
(call ~4 foo4.0.tdebp8hax 1 +1 4 +234.34 33,~17 +23 48,~17 +1.2) 4,29
(call ~4 foo2.0.tdebp8hax 1 +2 4 +3) 4,31
(call ~4 foo1.0.tdebp8hax 1 +34 25,~31 +1.2) 4,33
(call ~4 foo5.1.tdebp8hax 1 +1.3 24,~20 +7) 4,34
(call ~4 foo6.1.tdebp8hax 1 +4 28,~18 +7) 9,35
(call ~9 foo6.1.tdebp8hax 11,~19 +3 23,~19 +7) 3,23
(proc :foo.1.tdebp8hax . ~3,~4 .
(at foo.0.tdebp8hax
(i -1)) 8,~4
(params 1
(param :x.10 . .
(i -1) .) 7
(param :y.10 . . ~5,~19
(i -1) 7 +7)) ~3,~4 . ~3,~4 . ~3,~4 . ~1,~3
(stmts 4
(let :s.2 . . 7,~20
(i -1) 4 x.10) 4,1
(let :j.2 . . 7,~21
(i -1) 4 y.10))) 4,33
(proc :foo5.1.tdebp8hax . ~4,~20 .
(at foo5.0.tdebp8hax
(f +64)) 8,~20
(params 1
(param :x.11 . .
(f +64) .) 7
(param :y.11 . . ~6,~13
(i -1) 9 +7)) ~4,~20 . ~4,~20 . ~4,~20 . ~2,~19
(stmts
(discard .))) 4,34
(proc :foo6.1.tdebp8hax . ~4,~18 .
(at foo6.0.tdebp8hax
(i -1)) 8,~18
(params 1
(param :x.12 . . ,~16
(i -1) 7 +3) 11
(param :y.12 . . ~10,~16
(i -1) 9 +7)) ~4,~18 . ~4,~18 . ~4,~18 . ~2,~17
(stmts
(discard .))))
37 changes: 37 additions & 0 deletions tests/nimony/sysbasics/tdefaultparams.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
proc foo1(x: int, y: float = 1.2) =
let m = x

proc foo2(x = 3, y = 7) =
let s = x
let j = y

proc foo3(x: int, y: float, z: int = 23) =
discard

proc foo4(x: int, y: float, z: int = 23, a: float = 1.2) =
discard

proc foo5[T](x: T, y: int = 7) =
discard

proc foo6[T](x: T = 3, y: int = 7) =
discard

proc foo[T](x: T, y: T = 7) =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But there is no reason this should compile as we strive to type check generics and "some T" is not necessarily compatible with the number 7.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should have been caught somewhere else though so I'm merging it as is.

let s = x
let j = y

foo(3)
foo2()
foo2(1)
foo3(1, 2.3)
foo4(1, 234.34)

foo2(2, 3)

foo1(34)

foo5(1.3)
foo6(4)
foo6[int]()
# foo6() ?
Loading