Minor documentation changes

This commit is contained in:
Mattia Giambirtone 2023-01-24 12:19:06 +01:00
parent f10d813414
commit bf2be7deac
2 changed files with 19 additions and 2 deletions

View File

@ -827,9 +827,11 @@ method match*(self: Compiler, name: string, kind: Type, node: ASTNode = nil, all
msg = &"call to undefined function '{name}'"
self.error(msg, node)
elif impl.len() > 1:
# If we happen to find more than one match, we try again
# and ignore forward declarations and automatic functions
impl = filterIt(impl, not it.valueType.forwarded and not it.valueType.isAuto)
if impl.len() > 1:
# If it's *still* more than one match, then it's an error
# If there's *still* more than one match, then it's an error
var msg = &"multiple matching implementations of '{name}' found"
if self.showMismatches:
msg &= ":"
@ -838,6 +840,7 @@ method match*(self: Compiler, name: string, kind: Type, node: ASTNode = nil, all
else:
msg &= " (compile with --showMismatches for more details)"
self.error(msg, node)
# This is only true when we're called by self.patchForwardDeclarations()
if impl[0].valueType.forwarded and not allowFwd:
self.error(&"expecting an implementation for function '{impl[0].ident.token.lexeme}' declared in module '{impl[0].owner.ident.token.lexeme}' at line {impl[0].ident.token.line} of type '{self.stringify(impl[0].valueType)}'")
result = impl[0]
@ -1036,6 +1039,7 @@ proc declare*(self: Compiler, node: ASTNode): Name {.discardable.} =
# We don't check for name clashes with functions because self.match() does that
if name.kind in [NameKind.Var, NameKind.Module, NameKind.CustomType, NameKind.Enum] and name.depth == n.depth and name.owner == n.owner:
self.error(&"re-declaration of {declaredName} is not allowed (previously declared in {name.owner.ident.token.lexeme}:{name.ident.token.line}:{name.ident.token.relPos.start})")
# We emit a bunch of warnings, mostly for QoL
for name in self.names:
if name == n:
break

View File

@ -589,10 +589,14 @@ proc endScope(self: BytecodeCompiler) =
# Automatic functions do not materialize
# at runtime, so their arguments don't either
continue
# This name has been generated internally by the
# compiler and is a copy of an already existing
# one, so we only need to pop its "real" counterpart
if not name.isReal:
continue
inc(popCount)
if not name.resolved:
# We emit warnings for names that are declared but never used
case name.kind:
of NameKind.Var:
if not name.ident.token.lexeme.startsWith("_") and name.isPrivate:
@ -681,7 +685,6 @@ proc unpackUnion(self: BytecodeCompiler, condition: Expression, list: var seq[tu
self.error("invalid type constraint in type union", condition)
proc emitLoop(self: BytecodeCompiler, begin: int, line: int) =
## Emits a JumpBackwards instruction with the correct
## jump offset
@ -1644,6 +1647,8 @@ proc exportStmt(self: BytecodeCompiler, node: ExportStmt, compile: bool = true)
for name in self.findInModule("", name):
name.exportedTo.incl(self.parentModule)
of NameKind.Function:
# Only exporting a single function (or, well
# all of its implementations)
for name in self.findByName(name.ident.token.lexeme):
if name.kind != NameKind.Function:
continue
@ -1657,11 +1662,13 @@ proc breakStmt(self: BytecodeCompiler, node: BreakStmt) =
## to jump at the end of a loop or outside of a given
## block
if node.label.isNil():
# Jumping out of a loop
self.currentLoop.breakJumps.add(self.emitJump(OpCode.JumpForwards, node.token.line))
if self.currentLoop.depth > self.depth:
# Breaking out of a loop closes its scope
self.endScope()
else:
# Jumping out of a block
var blocks: seq[NamedBlock] = @[]
var found: bool = false
for blk in reversed(self.namedBlocks):
@ -1709,9 +1716,15 @@ proc switchStmt(self: BytecodeCompiler, node: SwitchStmt) =
var fn: Type
var impl: Name
var default: Expression
# Note that, unlike C switch statements, we don't
# cascade to other branches once the first one matches
for branch in node.branches:
# We duplicate the top of the stack so we can safely
# pop the topmost expression without losing its value
# for later comparisons
self.emitByte(DupTop, branch.body.token.line)
self.expression(branch.cond)
# We look for a matching equality implementation
fn = Type(kind: Function, returnType: Type(kind: Bool), args: @[("", typeOfA, default), ("", self.inferOrError(branch.cond), default)])
impl = self.match("==", fn, node)
self.generateCall(impl, @[node.switch, branch.cond], impl.line)