Various fixes to matchImpl. Variables can now shadow functions, but not other variables
This commit is contained in:
parent
15f412bcac
commit
dbeae16dc4
|
@ -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)
|
||||
|
|
|
@ -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!
|
||||
|
|
Loading…
Reference in New Issue