diff --git a/src/backend/vm.nim b/src/backend/vm.nim index 41a6bc1..689ea94 100644 --- a/src/backend/vm.nim +++ b/src/backend/vm.nim @@ -236,9 +236,9 @@ proc markRoots(self: var PeonVM): seq[ptr HeapObject] = for p in live: obj = cast[ptr HeapObject](p) if obj.mark(): + result.add(obj) when debugGC: echo &"DEBUG - GC: Marked object: {obj[]}" - result.add(obj) when debugGC: echo "DEBUG - GC: Mark phase complete" @@ -380,7 +380,7 @@ proc getInf*(self: var PeonVM, positive: bool): uint64 = proc getNan*(self: var PeonVM): uint64 = self.cache[5] -# Thanks to nim's *genius* idea of making x !> y a template +# Thanks to nim's *genius* idea of making x > y a template # for y < x (which by itself is fine) together with the fact # that the order of evaluation of templates with the same # expression is fucking stupid (see https://nim-lang.org/docs/manual.html#order-of-evaluation @@ -659,7 +659,7 @@ when debugVM: # So nim shuts up of "n", "next": self.debugNext = true break - of "continue": + of "c", "continue": self.debugNext = false break of "s", "stack": diff --git a/src/frontend/compiler.nim b/src/frontend/compiler.nim index c0aa69d..8c109ab 100644 --- a/src/frontend/compiler.nim +++ b/src/frontend/compiler.nim @@ -490,7 +490,7 @@ proc fixJumps(self: Compiler, oldLen: int, modifiedAt: int) = proc resolve(self: Compiler, name: string): Name = ## Traverses all existing namespaces and returns ## the first object with the given name. Returns - ## nil when the name can't be found. Note that, + ## nil when the name can't be found. Note that ## when a declaration is first resolved, it is ## also compiled on-the-fly for obj in reversed(self.names): @@ -516,20 +516,20 @@ proc resolve(self: Compiler, name: string): Name = # C and D and module B imports module A, then B # might not want to also have access to C's and D's # names as they might clash with its own stuff) + continue result = obj break if not result.isNil() and not result.resolved: # There's no reason to compile a declaration # unless it is used at least once: this way # not only do we save space if a name is declared - # but never used, but it also makes it easier to - # implement generics. Yay! + # but never used, it also makes it easier to + # implement generics and lets us emit warnings for + # unused names once they go out of scope. Yay! result.resolved = true # Now we just dispatch to one of our functions to # compile the declaration case result.kind: - of NameKind.Var: - self.varDecl(VarDecl(result.node), result) of NameKind.CustomType: self.typeDecl(TypeDecl(result.node), result) of NameKind.Function: @@ -587,8 +587,6 @@ proc getStackPos(self: Compiler, name: Name): int = # we skip it and pretend it doesn't exist if variable.isPrivate or not variable.exported: continue - elif not variable.resolved: - dec(result) elif name.ident == variable.ident: # After all of these checks, we can # finally check whether the name of @@ -1251,7 +1249,7 @@ proc declareName(self: Compiler, node: ASTNode, mutable: bool = false): Name = isPrivate: node.isPrivate, owner: self.currentModule, isConst: node.isConst, - valueType: self.infer(node.value), + valueType: nil, # Done later isLet: node.isLet, line: node.token.line, belongsTo: self.currentFunction, @@ -2244,6 +2242,12 @@ proc declaration(self: Compiler, node: Declaration) = case node.kind: of NodeKind.varDecl, NodeKind.funDecl, NodeKind.typeDecl: self.dispatchPragmas(node, self.declareName(node)) + if node.kind == NodeKind.varDecl: + self.names[^1].resolved = true + # We compile this immediately because we + # need to keep the stack in the right state + # at runtime + self.varDecl(VarDecl(node), self.names[^1]) else: self.statement(Statement(node)) diff --git a/tests/gc.pn b/tests/gc.pn index 5acf3d3..311ec39 100644 --- a/tests/gc.pn +++ b/tests/gc.pn @@ -1,7 +1,7 @@ import std; -var x: uint64 = 100000'u64; +var x: uint64 = 1000000'u64; var y = "just a test"; print(y); print("Starting GC torture test");