Various fixes to matchImpl. Variables can now shadow functions, but not other variables

This commit is contained in:
Mattia Giambirtone 2022-05-24 10:23:34 +02:00
parent 15f412bcac
commit dbeae16dc4
2 changed files with 29 additions and 10 deletions

View File

@ -574,7 +574,9 @@ proc inferType(self: Compiler, node: Expression): Type =
if name != nil:
return name.valueType
else:
return node.name.lexeme.toIntrinsic()
result = node.name.lexeme.toIntrinsic()
if result != nil:
result.node = node
of unaryExpr:
return self.inferType(UnaryExpr(node).a)
of binaryExpr:
@ -608,14 +610,14 @@ proc typeToStr(self: Compiler, typ: Type): string =
of funDecl:
var node = FunDecl(typ.node)
for i, argument in node.arguments:
result &= &"{argument.name.token.lexeme}: {self.typeToStr(self.inferType(argument.name))}"
result &= &"{argument.name.token.lexeme}: {self.typeToStr(self.inferType(argument.valueType))}"
if i < node.arguments.len() - 1:
result &= ", "
result &= ")"
of lambdaExpr:
var node = LambdaExpr(typ.node)
for i, argument in node.arguments:
result &= &"{argument.name.token.lexeme}: {argument.valueType}"
result &= &"{argument.name.token.lexeme}: {self.typeToStr(self.inferType(argument.name))}"
if i < node.arguments.len() - 1:
result &= ", "
result &= ")"
@ -735,16 +737,25 @@ proc matchImpl(self: Compiler, name: string, kind: Type): Name =
## Tries to find a matching function implementation
## compatible with the given type and returns its
## name object
let impl = self.findByType(name, kind)
if impl.len() == 0:
var msg = &"cannot find a suitable implementation for '{name}'"
let names = self.findByName(name)
if names.len() > 0:
msg &= &", found {len(names)} candidates:"
msg &= &", found {len(names)} candidate"
if names.len() > 1:
msg &= "s"
msg &= ": "
for name in names:
echo name[]
msg &= &"- '{name.name.token.lexeme}' of type {self.typeToStr(name.valueType)}\n"
msg &= &"\n - '{name.name.token.lexeme}' of type '{self.typeToStr(name.valueType)}'"
if name.valueType.kind != Function:
msg &= ", not a callable"
elif kind.args.len() != name.valueType.args.len():
msg &= &", wrong number of arguments ({name.valueType.args.len()} expected, got {kind.args.len()})\n"
else:
for i, arg in kind.args:
if not self.compareTypes(arg, name.valueType.args[i]):
msg &= &", first mismatch at position {i + 1}: expected argument of type '{self.typeToStr(name.valueType.args[i])}', got '{self.typeToStr(arg)}' instead"
self.error(msg)
elif impl.len() > 1:
var msg = &"multiple matching implementations of '{name}' found:\n"
@ -752,6 +763,7 @@ proc matchImpl(self: Compiler, name: string, kind: Type): Name =
var node = FunDecl(fn.valueType.node)
msg &= &"- '{node.name.token.lexeme}' at line {node.token.line} of type {self.typeToStr(fn.valueType)}\n"
self.error(msg)
return impl[0]
proc callUnaryOp(self: Compiler, fn: Name, op: UnaryExpr) =
@ -839,7 +851,7 @@ proc declareName(self: Compiler, node: Declaration) =
# slap myself 100 times with a sign saying "I'm dumb". Mark my words
self.error("cannot declare more than 16777216 variables at a time")
for name in self.findByName(node.name.token.lexeme):
if name.name.token.lexeme == node.name.token.lexeme:
if name.name.token.lexeme == node.name.token.lexeme and name.depth == self.scopeDepth and name.valueType.node.kind == varDecl:
self.error(&"attempt to redeclare '{node.name.token.lexeme}', which was previously defined in '{name.owner}' at line {name.valueType.node.token.line}")
self.names.add(Name(depth: self.scopeDepth,
name: node.name,
@ -1276,11 +1288,11 @@ proc statement(self: Compiler, node: Statement) =
proc varDecl(self: Compiler, node: VarDecl) =
## Compiles variable declarations
let kind = self.toIntrinsic(node.valueType)
let kind = self.inferType(node.valueType)
let typ = self.inferType(node.value)
if kind == nil and typ == nil:
self.error(&"cannot determine the type of '{node.name.token.lexeme}'")
elif typ != kind and kind != nil:
elif not self.compareTypes(typ, kind):
self.error(&"expected value of type '{self.typeToStr(kind)}', but '{node.name.token.lexeme}' is of type '{self.typeToStr(typ)}'")
self.expression(node.value)
self.declareName(node)

View File

@ -2,4 +2,11 @@ operator `+`(a: int): int {
return a;
}
operator `+`(a: int32): int32 {
return a;
}
var `+`: int = 1; # hehehehe
+1; # Works: defined for int64
+1'u8; # Nope!