Fixed variable declarations not compiling in some cases
This commit is contained in:
parent
990b54fa3e
commit
5bf5c6d3fd
|
@ -562,8 +562,8 @@ proc inferType(self: Compiler, node: LiteralExpr): Type =
|
|||
|
||||
|
||||
proc toIntrinsic(self: Compiler, typ: Expression): Type =
|
||||
## Gets an expression's
|
||||
## intrinsic type, if possible
|
||||
## Gets an expression's intrinsic type, if
|
||||
## possible
|
||||
if typ == nil:
|
||||
return nil
|
||||
case typ.kind:
|
||||
|
@ -590,7 +590,7 @@ proc inferType(self: Compiler, node: Expression): Type =
|
|||
if name != nil:
|
||||
return name.valueType
|
||||
else:
|
||||
result = node.name.lexeme.toIntrinsic()
|
||||
result = self.toIntrinsic(Expression(node))
|
||||
if result != nil:
|
||||
result.node = node
|
||||
of unaryExpr:
|
||||
|
@ -1307,9 +1307,10 @@ proc varDecl(self: Compiler, node: VarDecl) =
|
|||
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}'")
|
||||
self.error(&"'{node.name.token.lexeme}' has no type")
|
||||
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)}'")
|
||||
if kind != nil:
|
||||
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)
|
||||
|
||||
|
@ -1326,12 +1327,12 @@ proc funDecl(self: Compiler, node: FunDecl) =
|
|||
# TODO: Forward declarations
|
||||
if node.body != nil:
|
||||
if BlockStmt(node.body).code.len() == 0:
|
||||
self.error("Cannot declare function with empty body")
|
||||
self.error("cannot declare function with empty body")
|
||||
let fnType = self.inferType(node)
|
||||
let impl = self.findByType(node.name.token.lexeme, fnType)
|
||||
if impl.len() > 1:
|
||||
# Oh-oh! We found more than one implementation of
|
||||
# the same function! Error!
|
||||
# the same function with the same name! Error!
|
||||
var msg = &"multiple matching implementations of '{node.name.token.lexeme}' found:\n"
|
||||
for fn in reversed(impl):
|
||||
var node = FunDecl(fn.valueType.node)
|
||||
|
|
|
@ -799,6 +799,7 @@ proc varDecl(self: Parser, isLet: bool = false,
|
|||
let isPrivate = not self.match("*")
|
||||
self.checkDecl(isPrivate)
|
||||
var valueType: IdentExpr
|
||||
var hasInit = false
|
||||
if self.match(":"):
|
||||
# We don't enforce it here because
|
||||
# the compiler may be able to infer
|
||||
|
@ -806,6 +807,7 @@ proc varDecl(self: Parser, isLet: bool = false,
|
|||
self.expect(Identifier, "expecting type name after ':'")
|
||||
valueType = newIdentExpr(self.peek(-1))
|
||||
if self.match("="):
|
||||
hasInit = true
|
||||
value = self.expression()
|
||||
if isConst and not value.isConst():
|
||||
self.error("constant initializer is not a constant")
|
||||
|
@ -813,7 +815,7 @@ proc varDecl(self: Parser, isLet: bool = false,
|
|||
if tok.kind != Var:
|
||||
self.error(&"{tok.lexeme} declaration requires an initializer")
|
||||
value = newNilExpr(Token(lexeme: "nil"))
|
||||
self.expect(Semicolon, &"expecting semicolon after declaration")
|
||||
self.expect(Semicolon, "expecting semicolon after declaration")
|
||||
case tok.kind:
|
||||
of Var:
|
||||
result = newVarDecl(name, value, isPrivate = isPrivate, token = tok,
|
||||
|
@ -826,6 +828,8 @@ proc varDecl(self: Parser, isLet: bool = false,
|
|||
isLet = isLet, valueType = valueType, pragmas = (@[]))
|
||||
else:
|
||||
discard # Unreachable
|
||||
if not hasInit and VarDecl(result).valueType == nil:
|
||||
self.error("expecting initializer or type declaration, but neither was found")
|
||||
|
||||
|
||||
proc parseDeclArguments(self: Parser, arguments: var seq[tuple[name: IdentExpr, valueType: Expression, mutable: bool, isRef: bool, isPtr: bool]],
|
||||
|
|
|
@ -27,10 +27,10 @@ proc fillSymbolTable(tokenizer: Lexer)
|
|||
proc getLineEditor: LineEditor
|
||||
|
||||
# Handy dandy compile-time constants
|
||||
const debugLexer = false
|
||||
const debugParser = false
|
||||
const debugLexer = true
|
||||
const debugParser = true
|
||||
const debugCompiler = true
|
||||
const debugSerializer = false
|
||||
const debugSerializer = true
|
||||
const debugRuntime = false
|
||||
|
||||
when debugSerializer:
|
||||
|
@ -106,7 +106,7 @@ proc repl =
|
|||
var hashMatches = computeSHA256(input).toHex().toLowerAscii() == serialized.fileHash
|
||||
styledEcho fgCyan, "Serialization step: "
|
||||
styledEcho fgBlue, &"\t- File hash: ", fgYellow, serialized.fileHash, fgBlue, " (", if hashMatches: fgGreen else: fgRed, if hashMatches: "OK" else: "Fail", fgBlue, ")"
|
||||
styledEcho fgBlue, "\t- Peon version: ", fgYellow, &"{serialized.peonVer.major}.{serialized.peonVer.minor}.{serialized.peonVer.patch}", fgBlue, " (commit ", fgYellow, serialized.commitHash[0..8], fgBlue, ") on branch ", fgYellow, serialized.peonBranch
|
||||
styledEcho fgBlue, "\t- Peon version: ", fgYellow, &"{serialized.version.major}.{serialized.version.minor}.{serialized.version.patch}", fgBlue, " (commit ", fgYellow, serialized.commit[0..8], fgBlue, ") on branch ", fgYellow, serialized.branch
|
||||
stdout.styledWriteLine(fgBlue, "\t- Compilation date & time: ", fgYellow, fromUnix(serialized.compileDate).format("d/M/yyyy HH:mm:ss"))
|
||||
stdout.styledWrite(fgBlue, &"\t- Constants segment: ")
|
||||
if serialized.chunk.consts == compiled.consts:
|
||||
|
|
Loading…
Reference in New Issue