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 =
|
proc toIntrinsic(self: Compiler, typ: Expression): Type =
|
||||||
## Gets an expression's
|
## Gets an expression's intrinsic type, if
|
||||||
## intrinsic type, if possible
|
## possible
|
||||||
if typ == nil:
|
if typ == nil:
|
||||||
return nil
|
return nil
|
||||||
case typ.kind:
|
case typ.kind:
|
||||||
|
@ -590,7 +590,7 @@ proc inferType(self: Compiler, node: Expression): Type =
|
||||||
if name != nil:
|
if name != nil:
|
||||||
return name.valueType
|
return name.valueType
|
||||||
else:
|
else:
|
||||||
result = node.name.lexeme.toIntrinsic()
|
result = self.toIntrinsic(Expression(node))
|
||||||
if result != nil:
|
if result != nil:
|
||||||
result.node = node
|
result.node = node
|
||||||
of unaryExpr:
|
of unaryExpr:
|
||||||
|
@ -1307,9 +1307,10 @@ proc varDecl(self: Compiler, node: VarDecl) =
|
||||||
let kind = self.inferType(node.valueType)
|
let kind = self.inferType(node.valueType)
|
||||||
let typ = self.inferType(node.value)
|
let typ = self.inferType(node.value)
|
||||||
if kind == nil and typ == nil:
|
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):
|
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.expression(node.value)
|
||||||
self.declareName(node)
|
self.declareName(node)
|
||||||
|
|
||||||
|
@ -1326,12 +1327,12 @@ proc funDecl(self: Compiler, node: FunDecl) =
|
||||||
# TODO: Forward declarations
|
# TODO: Forward declarations
|
||||||
if node.body != nil:
|
if node.body != nil:
|
||||||
if BlockStmt(node.body).code.len() == 0:
|
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 fnType = self.inferType(node)
|
||||||
let impl = self.findByType(node.name.token.lexeme, fnType)
|
let impl = self.findByType(node.name.token.lexeme, fnType)
|
||||||
if impl.len() > 1:
|
if impl.len() > 1:
|
||||||
# Oh-oh! We found more than one implementation of
|
# 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"
|
var msg = &"multiple matching implementations of '{node.name.token.lexeme}' found:\n"
|
||||||
for fn in reversed(impl):
|
for fn in reversed(impl):
|
||||||
var node = FunDecl(fn.valueType.node)
|
var node = FunDecl(fn.valueType.node)
|
||||||
|
|
|
@ -799,6 +799,7 @@ proc varDecl(self: Parser, isLet: bool = false,
|
||||||
let isPrivate = not self.match("*")
|
let isPrivate = not self.match("*")
|
||||||
self.checkDecl(isPrivate)
|
self.checkDecl(isPrivate)
|
||||||
var valueType: IdentExpr
|
var valueType: IdentExpr
|
||||||
|
var hasInit = false
|
||||||
if self.match(":"):
|
if self.match(":"):
|
||||||
# We don't enforce it here because
|
# We don't enforce it here because
|
||||||
# the compiler may be able to infer
|
# 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 ':'")
|
self.expect(Identifier, "expecting type name after ':'")
|
||||||
valueType = newIdentExpr(self.peek(-1))
|
valueType = newIdentExpr(self.peek(-1))
|
||||||
if self.match("="):
|
if self.match("="):
|
||||||
|
hasInit = true
|
||||||
value = self.expression()
|
value = self.expression()
|
||||||
if isConst and not value.isConst():
|
if isConst and not value.isConst():
|
||||||
self.error("constant initializer is not a constant")
|
self.error("constant initializer is not a constant")
|
||||||
|
@ -813,7 +815,7 @@ proc varDecl(self: Parser, isLet: bool = false,
|
||||||
if tok.kind != Var:
|
if tok.kind != Var:
|
||||||
self.error(&"{tok.lexeme} declaration requires an initializer")
|
self.error(&"{tok.lexeme} declaration requires an initializer")
|
||||||
value = newNilExpr(Token(lexeme: "nil"))
|
value = newNilExpr(Token(lexeme: "nil"))
|
||||||
self.expect(Semicolon, &"expecting semicolon after declaration")
|
self.expect(Semicolon, "expecting semicolon after declaration")
|
||||||
case tok.kind:
|
case tok.kind:
|
||||||
of Var:
|
of Var:
|
||||||
result = newVarDecl(name, value, isPrivate = isPrivate, token = tok,
|
result = newVarDecl(name, value, isPrivate = isPrivate, token = tok,
|
||||||
|
@ -826,6 +828,8 @@ proc varDecl(self: Parser, isLet: bool = false,
|
||||||
isLet = isLet, valueType = valueType, pragmas = (@[]))
|
isLet = isLet, valueType = valueType, pragmas = (@[]))
|
||||||
else:
|
else:
|
||||||
discard # Unreachable
|
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]],
|
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
|
proc getLineEditor: LineEditor
|
||||||
|
|
||||||
# Handy dandy compile-time constants
|
# Handy dandy compile-time constants
|
||||||
const debugLexer = false
|
const debugLexer = true
|
||||||
const debugParser = false
|
const debugParser = true
|
||||||
const debugCompiler = true
|
const debugCompiler = true
|
||||||
const debugSerializer = false
|
const debugSerializer = true
|
||||||
const debugRuntime = false
|
const debugRuntime = false
|
||||||
|
|
||||||
when debugSerializer:
|
when debugSerializer:
|
||||||
|
@ -106,7 +106,7 @@ proc repl =
|
||||||
var hashMatches = computeSHA256(input).toHex().toLowerAscii() == serialized.fileHash
|
var hashMatches = computeSHA256(input).toHex().toLowerAscii() == serialized.fileHash
|
||||||
styledEcho fgCyan, "Serialization step: "
|
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- 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.styledWriteLine(fgBlue, "\t- Compilation date & time: ", fgYellow, fromUnix(serialized.compileDate).format("d/M/yyyy HH:mm:ss"))
|
||||||
stdout.styledWrite(fgBlue, &"\t- Constants segment: ")
|
stdout.styledWrite(fgBlue, &"\t- Constants segment: ")
|
||||||
if serialized.chunk.consts == compiled.consts:
|
if serialized.chunk.consts == compiled.consts:
|
||||||
|
|
Loading…
Reference in New Issue