This commit is contained in:
Mattia Giambirtone 2023-05-22 15:54:38 +02:00
parent b281961a5c
commit 789462c86a
Signed by: nocturn9x
GPG Key ID: 8270F9F467971E59
2 changed files with 24 additions and 27 deletions

View File

@ -120,6 +120,7 @@ proc newBytecodeCompiler*(replMode: bool = false): BytecodeCompiler =
result.depth = 0 result.depth = 0
result.lines = @[] result.lines = @[]
result.jumps = @[] result.jumps = @[]
result.modules = newTable[string, Name]()
result.lambdas = @[] result.lambdas = @[]
result.currentFunction = nil result.currentFunction = nil
result.replMode = replMode result.replMode = replMode
@ -1170,11 +1171,10 @@ method unary(self: BytecodeCompiler, node: UnaryExpr, compile: bool = true): Typ
let fn = Type(kind: Function, let fn = Type(kind: Function,
returnType: Type(kind: Any), returnType: Type(kind: Any),
args: @[("", self.inferOrError(node.a), default)]) args: @[("", self.inferOrError(node.a), default)])
let impl = self.match(node.token.lexeme, fn, node) var impl = self.match(node.token.lexeme, fn, node)
result = impl.valueType if impl.valueType.isAuto:
if impl.isGeneric: impl = self.prepareAutoFunction(impl, fn.args)
result = self.specialize(result, @[node.a]) result = impl.valueType.returnType
result = result.returnType
if compile: if compile:
self.generateCall(impl, @[node.a], impl.line) self.generateCall(impl, @[node.a], impl.line)
@ -1183,11 +1183,10 @@ method binary(self: BytecodeCompiler, node: BinaryExpr, compile: bool = true): T
## Compiles all binary expressions ## Compiles all binary expressions
var default: Expression var default: Expression
let fn = Type(kind: Function, returnType: Type(kind: Any), args: @[("", self.inferOrError(node.a), default), ("", self.inferOrError(node.b), default)]) let fn = Type(kind: Function, returnType: Type(kind: Any), args: @[("", self.inferOrError(node.a), default), ("", self.inferOrError(node.b), default)])
let impl = self.match(node.token.lexeme, fn, node) var impl = self.match(node.token.lexeme, fn, node)
result = impl.valueType if impl.valueType.isAuto:
if impl.isGeneric: impl = self.prepareAutoFunction(impl, fn.args)
result = self.specialize(result, @[node.a, node.b]) result = impl.valueType.returnType
result = result.returnType
if compile: if compile:
self.generateCall(impl, @[node.a, node.b], impl.line) self.generateCall(impl, @[node.a, node.b], impl.line)
@ -1280,7 +1279,7 @@ method assignment(self: BytecodeCompiler, node: ASTNode, compile: bool = true):
method call(self: BytecodeCompiler, node: CallExpr, compile: bool = true): Type {.discardable.} = method call(self: BytecodeCompiler, node: CallExpr, compile: bool = true): Type {.discardable.} =
## Compiles code to call a chain of function calls ## Compiles function calls
var args: seq[tuple[name: string, kind: Type, default: Expression]] = @[] var args: seq[tuple[name: string, kind: Type, default: Expression]] = @[]
var argExpr: seq[Expression] = @[] var argExpr: seq[Expression] = @[]
var default: Expression var default: Expression
@ -1306,14 +1305,12 @@ method call(self: BytecodeCompiler, node: CallExpr, compile: bool = true): Type
# Calls like hi() # Calls like hi()
var impl = self.match(IdentExpr(node.callee).name.lexeme, Type(kind: Function, returnType: Type(kind: All), args: args), node) var impl = self.match(IdentExpr(node.callee).name.lexeme, Type(kind: Function, returnType: Type(kind: All), args: args), node)
result = impl.valueType result = impl.valueType
if impl.isGeneric:
result = self.specialize(result, argExpr)
if impl.valueType.isAuto: if impl.valueType.isAuto:
impl = self.prepareAutoFunction(impl, args) impl = self.prepareAutoFunction(impl, args)
result = impl.valueType result = impl.valueType
if result.fun.kind == NodeKind.lambdaExpr: if result.fun.kind == NodeKind.lambdaExpr:
self.lambdaExpr(LambdaExpr(result.fun), compile=compile) self.lambdaExpr(LambdaExpr(result.fun), compile=compile)
elif not impl.valueType.compiled: if not impl.valueType.compiled:
self.funDecl(FunDecl(result.fun), impl) self.funDecl(FunDecl(result.fun), impl)
result = result.returnType result = result.returnType
if compile: if compile:
@ -1353,13 +1350,15 @@ method call(self: BytecodeCompiler, node: CallExpr, compile: bool = true): Type
result = result.returnType result = result.returnType
of NodeKind.getItemExpr: of NodeKind.getItemExpr:
var node = GetItemExpr(node.callee) var node = GetItemExpr(node.callee)
let impl = self.match(node.name.token.lexeme, let impl = self.getItemExpr(node, compile=false, matching=Type(kind: Function, args: args, returnType: Type(kind: All)))
self.getItemExpr(node, compile=false, matching=Type(kind: Function, args: args, returnType: Type(kind: All))), node) var fn: Name
result = impl.valueType for name in self.names:
if impl.isGeneric: if name.valueType == impl:
result = self.specialize(result, argExpr) fn = name
result = result.returnType break
self.generateCall(impl, argExpr, node.token.line) result = impl.returnType
if compile:
self.generateCall(fn, argExpr, node.token.line)
of NodeKind.lambdaExpr: of NodeKind.lambdaExpr:
var node = LambdaExpr(node.callee) var node = LambdaExpr(node.callee)
var impl = self.lambdaExpr(node, compile=compile) var impl = self.lambdaExpr(node, compile=compile)
@ -1394,7 +1393,7 @@ method getItemExpr(self: BytecodeCompiler, node: GetItemExpr, compile: bool = tr
for name in values: for name in values:
if self.compare(name.valueType, matching): if self.compare(name.valueType, matching):
result = name.valueType result = name.valueType
return break
if len(values) == 1: if len(values) == 1:
result = values[0].valueType result = values[0].valueType
else: else:
@ -1689,6 +1688,9 @@ proc importStmt(self: BytecodeCompiler, node: ImportStmt, compile: bool = true)
# its public names to us # its public names to us
for name in self.findInModule("", module): for name in self.findInModule("", module):
name.exportedTo.incl(self.currentModule.path) name.exportedTo.incl(self.currentModule.path)
# We also need to export public names from other modules
# that we have explicitly exported because imports are
# compiled only once
for module in self.modules.values(): for module in self.modules.values():
if self.currentModule.path in module.exportedTo: if self.currentModule.path in module.exportedTo:
for name in self.findInModule("", module): for name in self.findInModule("", module):

View File

@ -2,11 +2,6 @@
import values; import values;
fn clock*: float {
#pragma[magic: "SysClock64"]
}
fn print*[T: any](x: T) { fn print*[T: any](x: T) {
#pragma[magic: "print"] #pragma[magic: "print"]
} }