Improvements to type signature matching and fixed some bugs

This commit is contained in:
Mattia Giambirtone 2023-08-05 12:22:40 +02:00
parent eccb2b5372
commit f34b71ec0b
Signed by: nocturn9x
GPG Key ID: 8270F9F467971E59
1 changed files with 26 additions and 4 deletions

View File

@ -1197,9 +1197,31 @@ proc checkTypeSignature(self: PeonCompiler, typ: Type, sig: seq[tuple[name: stri
## the given type signature
case typ.kind:
of TypeKind.Function:
if typ.args.len() != sig.len():
if typ.args.len() < sig.len():
# If the function has less arguments than
# we have in our signature, then we surely
# can't match to it. This is different from
# the code in self.compare() (which checks that
# both signatures have the same length) because
# of how we handle default arguments; This is to
# address a problem that arises that when we have
# a function that looks like (a, b, c = someDefault) -> z
# and we're looking for a signature (a, b) -> y: if
# we enforced that the length of the signatures must
# be equal for them to match, we'd consider that function
# to not be a good match, even though it is because the
# third argument has a default value
return false
for (argA, argB) in zip(typ.args, sig):
# We construct a new signature, without the function's default arguments
var args: seq[tuple[name: string, kind: Type, default: Expression]] = @[]
for argument in typ.args:
if argument.default.isNil():
args.add(argument)
else:
break
if args.len() != sig.len():
return false
for (argA, argB) in zip(args, sig):
if not self.compare(argA.kind, argB.kind):
return false
if argA.name == "" or argB.name == "":
@ -1305,7 +1327,7 @@ proc match(self: PeonCompiler, name: string, sig: seq[tuple[name: string, kind:
discard
else:
# We either found no matches or too many, woopsie daisy! That's definitely an error
var msg: string = &"dispatch failed while looking for '{name}' -> "
var msg: string = ""
case matches.len():
of 0:
# No matches
@ -1710,7 +1732,7 @@ proc call(self: PeonCompiler, node: CallExpr): TypedExpr =
var node = GenericExpr(node.callee)
# TODO
else:
let typ = self.infer(node)
let typ = self.infer(node.callee)
if typ.isNil():
self.error(&"expression has no type", node)
else: