Minor documentation changes
This commit is contained in:
parent
f10d813414
commit
bf2be7deac
|
@ -827,9 +827,11 @@ method match*(self: Compiler, name: string, kind: Type, node: ASTNode = nil, all
|
||||||
msg = &"call to undefined function '{name}'"
|
msg = &"call to undefined function '{name}'"
|
||||||
self.error(msg, node)
|
self.error(msg, node)
|
||||||
elif impl.len() > 1:
|
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)
|
impl = filterIt(impl, not it.valueType.forwarded and not it.valueType.isAuto)
|
||||||
if impl.len() > 1:
|
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"
|
var msg = &"multiple matching implementations of '{name}' found"
|
||||||
if self.showMismatches:
|
if self.showMismatches:
|
||||||
msg &= ":"
|
msg &= ":"
|
||||||
|
@ -838,6 +840,7 @@ method match*(self: Compiler, name: string, kind: Type, node: ASTNode = nil, all
|
||||||
else:
|
else:
|
||||||
msg &= " (compile with --showMismatches for more details)"
|
msg &= " (compile with --showMismatches for more details)"
|
||||||
self.error(msg, node)
|
self.error(msg, node)
|
||||||
|
# This is only true when we're called by self.patchForwardDeclarations()
|
||||||
if impl[0].valueType.forwarded and not allowFwd:
|
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)}'")
|
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]
|
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
|
# 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:
|
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})")
|
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:
|
for name in self.names:
|
||||||
if name == n:
|
if name == n:
|
||||||
break
|
break
|
||||||
|
|
|
@ -589,10 +589,14 @@ proc endScope(self: BytecodeCompiler) =
|
||||||
# Automatic functions do not materialize
|
# Automatic functions do not materialize
|
||||||
# at runtime, so their arguments don't either
|
# at runtime, so their arguments don't either
|
||||||
continue
|
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:
|
if not name.isReal:
|
||||||
continue
|
continue
|
||||||
inc(popCount)
|
inc(popCount)
|
||||||
if not name.resolved:
|
if not name.resolved:
|
||||||
|
# We emit warnings for names that are declared but never used
|
||||||
case name.kind:
|
case name.kind:
|
||||||
of NameKind.Var:
|
of NameKind.Var:
|
||||||
if not name.ident.token.lexeme.startsWith("_") and name.isPrivate:
|
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)
|
self.error("invalid type constraint in type union", condition)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
proc emitLoop(self: BytecodeCompiler, begin: int, line: int) =
|
proc emitLoop(self: BytecodeCompiler, begin: int, line: int) =
|
||||||
## Emits a JumpBackwards instruction with the correct
|
## Emits a JumpBackwards instruction with the correct
|
||||||
## jump offset
|
## jump offset
|
||||||
|
@ -1644,6 +1647,8 @@ proc exportStmt(self: BytecodeCompiler, node: ExportStmt, compile: bool = true)
|
||||||
for name in self.findInModule("", name):
|
for name in self.findInModule("", name):
|
||||||
name.exportedTo.incl(self.parentModule)
|
name.exportedTo.incl(self.parentModule)
|
||||||
of NameKind.Function:
|
of NameKind.Function:
|
||||||
|
# Only exporting a single function (or, well
|
||||||
|
# all of its implementations)
|
||||||
for name in self.findByName(name.ident.token.lexeme):
|
for name in self.findByName(name.ident.token.lexeme):
|
||||||
if name.kind != NameKind.Function:
|
if name.kind != NameKind.Function:
|
||||||
continue
|
continue
|
||||||
|
@ -1657,11 +1662,13 @@ proc breakStmt(self: BytecodeCompiler, node: BreakStmt) =
|
||||||
## to jump at the end of a loop or outside of a given
|
## to jump at the end of a loop or outside of a given
|
||||||
## block
|
## block
|
||||||
if node.label.isNil():
|
if node.label.isNil():
|
||||||
|
# Jumping out of a loop
|
||||||
self.currentLoop.breakJumps.add(self.emitJump(OpCode.JumpForwards, node.token.line))
|
self.currentLoop.breakJumps.add(self.emitJump(OpCode.JumpForwards, node.token.line))
|
||||||
if self.currentLoop.depth > self.depth:
|
if self.currentLoop.depth > self.depth:
|
||||||
# Breaking out of a loop closes its scope
|
# Breaking out of a loop closes its scope
|
||||||
self.endScope()
|
self.endScope()
|
||||||
else:
|
else:
|
||||||
|
# Jumping out of a block
|
||||||
var blocks: seq[NamedBlock] = @[]
|
var blocks: seq[NamedBlock] = @[]
|
||||||
var found: bool = false
|
var found: bool = false
|
||||||
for blk in reversed(self.namedBlocks):
|
for blk in reversed(self.namedBlocks):
|
||||||
|
@ -1709,9 +1716,15 @@ proc switchStmt(self: BytecodeCompiler, node: SwitchStmt) =
|
||||||
var fn: Type
|
var fn: Type
|
||||||
var impl: Name
|
var impl: Name
|
||||||
var default: Expression
|
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:
|
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.emitByte(DupTop, branch.body.token.line)
|
||||||
self.expression(branch.cond)
|
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)])
|
fn = Type(kind: Function, returnType: Type(kind: Bool), args: @[("", typeOfA, default), ("", self.inferOrError(branch.cond), default)])
|
||||||
impl = self.match("==", fn, node)
|
impl = self.match("==", fn, node)
|
||||||
self.generateCall(impl, @[node.switch, branch.cond], impl.line)
|
self.generateCall(impl, @[node.switch, branch.cond], impl.line)
|
||||||
|
|
Loading…
Reference in New Issue