derete the fil #2
|
@ -522,11 +522,7 @@ proc declareName(self: Compiler, node: ASTNode) =
|
|||
else:
|
||||
discard # TODO: Classes
|
||||
|
||||
|
||||
proc varDecl(self: Compiler, node: VarDecl) =
|
||||
## Compiles variable declarations
|
||||
self.expression(node.value)
|
||||
self.declareName(node)
|
||||
proc varDecl(self: Compiler, node: VarDecl)
|
||||
|
||||
|
||||
proc resolveStatic(self: Compiler, name: IdentExpr,
|
||||
|
@ -919,9 +915,54 @@ proc statement(self: Compiler, node: ASTNode) =
|
|||
self.expression(node)
|
||||
|
||||
|
||||
proc inferValueType(self: Compiler, node: ASTNode): ASTNode =
|
||||
## Infers the type of a given literal expression
|
||||
case node.kind:
|
||||
of listExpr:
|
||||
return ListExpr(node).valueType
|
||||
of dictExpr:
|
||||
# It's not important that we don't use
|
||||
# valueType here, we just need to return
|
||||
# a non-nil value so we don't error out
|
||||
return DictExpr(node).keyType
|
||||
else:
|
||||
discard # TODO
|
||||
|
||||
proc inferExprType(self: Compiler, node: Expression): ASTNode =
|
||||
## Infers the type of a given expression and
|
||||
## returns it
|
||||
# TODO
|
||||
|
||||
|
||||
|
||||
proc inferDeclType(self: Compiler, node: Declaration): ASTNode =
|
||||
## Infers the type of a given declaration if it's
|
||||
## not already defined and returns it
|
||||
case node.kind:
|
||||
of funDecl:
|
||||
var node = FunDecl(node)
|
||||
if node.returnType != nil:
|
||||
return node.returnType
|
||||
of NodeKind.varDecl:
|
||||
var node = VarDecl(node)
|
||||
if node.valueType != nil:
|
||||
return node.valueType
|
||||
else:
|
||||
return # Unreachable
|
||||
|
||||
|
||||
proc varDecl(self: Compiler, node: VarDecl) =
|
||||
## Compiles variable declarations
|
||||
if self.inferDeclType(node) == nil:
|
||||
self.error(&"Cannot determine the type of '{node.name.token.lexeme}'")
|
||||
self.expression(node.value)
|
||||
self.declareName(node)
|
||||
|
||||
|
||||
proc funDecl(self: Compiler, node: FunDecl) =
|
||||
## Compiles function declarations
|
||||
|
||||
if self.inferDeclType(node) == nil:
|
||||
self.error(&"Cannot determine the return type of '{node.name.token.lexeme}'")
|
||||
# We store the current function
|
||||
var function = self.currentFunction
|
||||
self.currentFunction = node
|
||||
|
|
|
@ -115,17 +115,13 @@ type
|
|||
FloatExpr* = ref object of LiteralExpr
|
||||
StrExpr* = ref object of LiteralExpr
|
||||
|
||||
# There are technically keywords, not literals!
|
||||
TrueExpr* = ref object of ASTNode
|
||||
FalseExpr* = ref object of ASTNode
|
||||
NilExpr* = ref object of ASTNode
|
||||
NanExpr* = ref object of ASTNode
|
||||
InfExpr* = ref object of ASTNode
|
||||
TrueExpr* = ref object of LiteralExpr
|
||||
FalseExpr* = ref object of LiteralExpr
|
||||
NilExpr* = ref object of LiteralExpr
|
||||
NanExpr* = ref object of LiteralExpr
|
||||
InfExpr* = ref object of LiteralExpr
|
||||
|
||||
# Although this is *technically* a literal, Nim doesn't
|
||||
# allow us to redefine fields from supertypes so it's
|
||||
# a tough luck for us
|
||||
ListExpr* = ref object of ASTNode
|
||||
ListExpr* = ref object of LiteralExpr
|
||||
members*: seq[ASTNode]
|
||||
valueType*: IdentExpr
|
||||
|
||||
|
@ -310,8 +306,12 @@ proc isConst*(self: ASTNode): bool =
|
|||
return false
|
||||
|
||||
|
||||
# TODO: Fix (not all literals are constants)
|
||||
proc isLiteral*(self: ASTNode): bool {.inline.} = self.isConst()
|
||||
proc isLiteral*(self: ASTNode): bool {.inline.} =
|
||||
self.kind in {intExpr, hexExpr, binExpr, octExpr,
|
||||
strExpr, falseExpr, trueExpr, infExpr,
|
||||
nanExpr, floatExpr, nilExpr, listExpr,
|
||||
dictExpr, setExpr, tupleExpr
|
||||
}
|
||||
|
||||
|
||||
proc newIntExpr*(literal: Token): IntExpr =
|
||||
|
@ -344,11 +344,11 @@ proc newFloatExpr*(literal: Token): FloatExpr =
|
|||
result.token = literal
|
||||
|
||||
|
||||
proc newTrueExpr*(token: Token): LiteralExpr = LiteralExpr(kind: trueExpr, token: token)
|
||||
proc newFalseExpr*(token: Token): LiteralExpr = LiteralExpr(kind: falseExpr, token: token)
|
||||
proc newNaNExpr*(token: Token): LiteralExpr = LiteralExpr(kind: nanExpr, token: token)
|
||||
proc newNilExpr*(token: Token): LiteralExpr = LiteralExpr(kind: nilExpr, token: token)
|
||||
proc newInfExpr*(token: Token): LiteralExpr = LiteralExpr(kind: infExpr, token: token)
|
||||
proc newTrueExpr*(token: Token): LiteralExpr = LiteralExpr(kind: trueExpr, token: token, literal: token)
|
||||
proc newFalseExpr*(token: Token): LiteralExpr = LiteralExpr(kind: falseExpr, token: token, literal: token)
|
||||
proc newNaNExpr*(token: Token): LiteralExpr = LiteralExpr(kind: nanExpr, token: token, literal: token)
|
||||
proc newNilExpr*(token: Token): LiteralExpr = LiteralExpr(kind: nilExpr, token: token, literal: token)
|
||||
proc newInfExpr*(token: Token): LiteralExpr = LiteralExpr(kind: infExpr, token: token, literal: token)
|
||||
|
||||
|
||||
proc newStrExpr*(literal: Token): StrExpr =
|
||||
|
@ -391,18 +391,21 @@ proc newListExpr*(members: seq[ASTNode], token: Token): ListExpr =
|
|||
result = ListExpr(kind: listExpr)
|
||||
result.members = members
|
||||
result.token = token
|
||||
result.literal = result.token
|
||||
|
||||
|
||||
proc newSetExpr*(members: seq[ASTNode], token: Token): SetExpr =
|
||||
result = SetExpr(kind: setExpr)
|
||||
result.members = members
|
||||
result.token = token
|
||||
result.literal = result.token
|
||||
|
||||
|
||||
proc newTupleExpr*(members: seq[ASTNode], token: Token): TupleExpr =
|
||||
result = TupleExpr(kind: tupleExpr)
|
||||
result.members = members
|
||||
result.token = token
|
||||
result.literal = result.token
|
||||
|
||||
|
||||
proc newDictExpr*(keys, values: seq[ASTNode], token: Token): DictExpr =
|
||||
|
|
|
@ -821,7 +821,7 @@ proc varDecl(self: Parser, isLet: bool = false, isConst: bool = false): ASTNode
|
|||
# the compiler may be able to infer
|
||||
# the type later!
|
||||
self.expect(Identifier, "expecting type name after ':'")
|
||||
valueType = newIdentExpr(self.peek(-1))
|
||||
valueType = newIdentExpr(self.peek(-1))
|
||||
if self.match(Equal):
|
||||
value = self.expression()
|
||||
if isConst and not value.isConst():
|
||||
|
|
|
@ -143,6 +143,14 @@ when isMainModule:
|
|||
echo getCurrentExceptionMsg()
|
||||
echo &"Source line: {line}"
|
||||
echo " ".repeat(relPos.start + len("Source line: ")) & "^".repeat(relPos.stop - parser.getCurrentToken().lexeme.len())
|
||||
except CompileError:
|
||||
let lineNo = compiler.getCurrentNode().token.line
|
||||
let relPos = tokenizer.getRelPos(lineNo)
|
||||
let line = tokenizer.getSource().splitLines()[lineNo - 1].strip()
|
||||
echo getCurrentExceptionMsg()
|
||||
echo &"Source line: {line}"
|
||||
echo " ".repeat(relPos.start + len("Source line: ")) & "^".repeat(relPos.stop - compiler.getCurrentNode().token.lexeme.len())
|
||||
|
||||
quit(0)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue