diff --git a/src/frontend/compiler.nim b/src/frontend/compiler.nim index f95e926..e53677e 100644 --- a/src/frontend/compiler.nim +++ b/src/frontend/compiler.nim @@ -825,7 +825,11 @@ proc infer(self: Compiler, node: Expression): Type = of identExpr: let resolved = self.resolve(IdentExpr(node.callee)) if not resolved.isNil(): - result = resolved.valueType.returnType + case resolved.valueType.kind: + of Function: + result = resolved.valueType.returnType + else: + result = resolved.valueType else: result = nil of lambdaExpr: @@ -1704,8 +1708,23 @@ proc generateCall(self: Compiler, fn: Name, args: seq[Expression], line: int) = if fn.valueType.isBuiltinFunction: self.handleBuiltinFunction(fn.valueType, args, line) return - self.emitByte(LoadUInt64, line) - self.emitBytes(self.chunk.writeConstant(fn.codePos.toLong()), line) + case fn.kind: + of NameKind.Var: + # We're trying to call a function assigned to a variable, + # so we resolve it if it's an identifier (lambdas coming soon!) + case VarDecl(fn.node).value.kind: + of identExpr: + let fn = self.matchImpl(IdentExpr(VarDecl(fn.node).value).token.lexeme, fn.valueType) + self.identifier(IdentExpr(VarDecl(fn.node).value)) + else: + discard # TODO + of NameKind.Function: + # Just a regular function declaration: we can load its address + # normally + self.emitByte(LoadUInt64, line) + self.emitBytes(self.chunk.writeConstant(fn.codePos.toLong()), line) + else: + discard self.emitByte(LoadUInt64, line) self.emitBytes(self.chunk.writeConstant(0.toLong()), line) let pos = self.chunk.consts.len() - 8 diff --git a/tests/closures.pn b/tests/closures.pn index 836d40c..c9f72c4 100644 --- a/tests/closures.pn +++ b/tests/closures.pn @@ -1,6 +1,4 @@ # Tests closures - - fn makeClosure(n: int): fn: int { fn inner: int { return n; @@ -9,5 +7,5 @@ fn makeClosure(n: int): fn: int { } -var c = makeClosure(38); -c(); +var closure = makeClosure(38); +closure(); \ No newline at end of file