From 16968c511418dcc4e5e145feb3dd8cf2a952e7e3 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 18 Jun 2023 13:04:12 +0100 Subject: Create separate namespace import function --- .../compiler/backends/llvm/LlvmCompiler.java | 4 +- .../backends/llvm/LlvmCompilerNamespaces.java | 48 +++++++++++++++++----- .../backends/llvm/ir/LlvmIrSerializer.java | 7 +++- .../llvm/ir/ast/instructions/LlvmCall.java | 16 +++++++- 4 files changed, 59 insertions(+), 16 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompiler.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompiler.java index e705ce8f..a126fda1 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompiler.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompiler.java @@ -23,7 +23,7 @@ public class LlvmCompiler { // TODO: remove duplication of definition/declaration context = context.addTopLevelEntity(new LlvmFunctionDeclaration( - LlvmCompilerNamespaces.globalNameNamespaceInit(main), + LlvmCompilerNamespaces.globalNameNamespaceImport(main), LlvmCompilerTypes.VALUE_TYPE, List.of() )); @@ -40,7 +40,7 @@ public class LlvmCompiler { mainContext = mainContext.addInstruction(new LlvmCall( namespace, LlvmCompilerTypes.VALUE_TYPE, - new LlvmVariableGlobal(LlvmCompilerNamespaces.globalNameNamespaceInit(main)), + new LlvmVariableGlobal(LlvmCompilerNamespaces.globalNameNamespaceImport(main)), List.of() )); diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerNamespaces.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerNamespaces.java index 5296ec49..7694c66a 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerNamespaces.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerNamespaces.java @@ -1,5 +1,6 @@ package org.shedlang.compiler.backends.llvm; +import org.shedlang.compiler.backends.llvm.ir.ast.LlvmBasicBlock; import org.shedlang.compiler.backends.llvm.ir.ast.LlvmFunctionDefinition; import org.shedlang.compiler.backends.llvm.ir.ast.LlvmGlobalDefinition; import org.shedlang.compiler.backends.llvm.ir.ast.instructions.*; @@ -7,6 +8,7 @@ import org.shedlang.compiler.backends.llvm.ir.ast.operands.*; import org.shedlang.compiler.backends.llvm.ir.ast.types.LlvmType; import org.shedlang.compiler.backends.llvm.ir.ast.types.LlvmTypePointer; import org.shedlang.compiler.backends.llvm.ir.ast.types.LlvmTypeStructure; +import org.shedlang.compiler.backends.llvm.ir.ast.types.LlvmTypes; import org.shedlang.compiler.types.NamespaceName; import org.shedlang.compiler.types.NamespaceTypeInfo; @@ -19,25 +21,25 @@ public class LlvmCompilerNamespaces { private LlvmCompilerNamespaces() { } - public static LlvmTypePointer typeNamespacePointer(NamespaceTypeInfo namespaceTypeInfo) { + private static LlvmTypePointer typeNamespacePointer(NamespaceTypeInfo namespaceTypeInfo) { return new LlvmTypePointer(typeNamespaceStruct(namespaceTypeInfo)); } - public static LlvmType typeNamespaceStruct(NamespaceTypeInfo namespaceTypeInfo) { + private static LlvmType typeNamespaceStruct(NamespaceTypeInfo namespaceTypeInfo) { return new LlvmTypeStructure(Collections.nCopies( namespaceTypeInfo.fieldCount(), LlvmCompilerTypes.VALUE_TYPE )); } - public static LlvmOperand operandNamespaceValue(NamespaceName namespaceName) { + private static LlvmOperand operandNamespaceValue(NamespaceName namespaceName) { return new LlvmOperandPtrToInt( LlvmCompilerNamespaces.operandNamespaceStruct(namespaceName), LlvmCompilerTypes.VALUE_TYPE ); } - public static LlvmOperand operandNamespaceStruct(NamespaceName namespaceName) { + private static LlvmOperand operandNamespaceStruct(NamespaceName namespaceName) { return new LlvmVariableGlobal(globalNameNamespaceValue(namespaceName)); } @@ -45,7 +47,11 @@ public class LlvmCompilerNamespaces { return "shed__namespace__" + namespaceNameToLlvmIdentifier(namespaceName); } - public static String globalNameNamespaceInit(NamespaceName namespaceName) { + public static String globalNameNamespaceImport(NamespaceName namespaceName) { + return "shed__namespaceImport__" + namespaceNameToLlvmIdentifier(namespaceName); + } + + private static String globalNameNamespaceInit(NamespaceName namespaceName) { return "shed__namespaceInit__" + namespaceNameToLlvmIdentifier(namespaceName); } @@ -57,24 +63,44 @@ public class LlvmCompilerNamespaces { NamespaceName namespaceName, LlvmCompilerContext context ) { - context = context.addTerminatorInstruction(new LlvmReturn( - LlvmCompilerTypes.VALUE_TYPE, - LlvmCompilerNamespaces.operandNamespaceValue(namespaceName) - )); + context = context.addTerminatorInstruction(new LlvmReturnVoid()); var basicBlocks = context.basicBlocks(); var namespaceInitFunction = new LlvmFunctionDefinition( LlvmCompilerNamespaces.globalNameNamespaceInit(namespaceName), - LlvmCompilerTypes.VALUE_TYPE, + LlvmTypes.VOID, List.of(), basicBlocks ); + var namespaceImportFunction = new LlvmFunctionDefinition( + globalNameNamespaceImport(namespaceName), + LlvmCompilerTypes.VALUE_TYPE, + List.of(), + List.of(new LlvmBasicBlock( + Optional.empty(), + List.of( + // TODO: only call if not yet initialized + new LlvmCall( + Optional.empty(), + LlvmTypes.VOID, + new LlvmVariableGlobal(globalNameNamespaceInit(namespaceName)), + List.of() + ) + ), + new LlvmReturn( + LlvmCompilerTypes.VALUE_TYPE, + LlvmCompilerNamespaces.operandNamespaceValue(namespaceName) + ) + )) + ); + return context .addTopLevelEntity(LlvmCompilerNamespaces.defineGlobal( namespaceName, context.typeInfo().namespaceTypeInfo(namespaceName) )) - .addTopLevelEntity(namespaceInitFunction); + .addTopLevelEntity(namespaceInitFunction) + .addTopLevelEntity(namespaceImportFunction); } public static LlvmGlobalDefinition defineGlobal( diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/ir/LlvmIrSerializer.java b/src/main/java/org/shedlang/compiler/backends/llvm/ir/LlvmIrSerializer.java index 82433866..d304ce84 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/ir/LlvmIrSerializer.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/ir/LlvmIrSerializer.java @@ -40,8 +40,11 @@ public class LlvmIrSerializer { serializeOperand(add.right(), builder); } case LlvmCall call -> { - serializeVariable(call.target(), builder); - builder.append(" = call "); + if (call.target().isPresent()) { + serializeVariable(call.target().get(), builder); + builder.append(" = "); + } + builder.append("call "); serializeType(call.returnType(), builder); builder.append(" "); serializeOperand(call.functionPointer(), builder); diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/instructions/LlvmCall.java b/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/instructions/LlvmCall.java index 4851fc5e..aa6d9718 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/instructions/LlvmCall.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/instructions/LlvmCall.java @@ -6,11 +6,25 @@ import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmVariable; import org.shedlang.compiler.backends.llvm.ir.ast.types.LlvmType; import java.util.List; +import java.util.Optional; public record LlvmCall( - LlvmVariable target, + Optional target, LlvmType returnType, LlvmOperand functionPointer, List args ) implements LlvmInstruction { + public LlvmCall( + LlvmVariable target, + LlvmType returnType, + LlvmOperand functionPointer, + List args + ) { + this( + Optional.of(target), + returnType, + functionPointer, + args + ); + } } -- cgit v1.2.3