aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-06-13 23:10:45 +0100
committerMichael Williamson <mike@zwobble.org>2023-06-13 23:10:45 +0100
commitedff0de2d08ed5a4bab9c1f3f748d7478fc0de1d (patch)
tree12ff3d1d30be8f252d1d68e92574abbe96b45793 /src/main/java/org
parent855a6dbfa164b737fc752831b19fef468255aab5 (diff)
Compile namespace-field-store to LLVM IR
Diffstat (limited to 'src/main/java/org')
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompiler.java28
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerContext.java24
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerNamespaces.java34
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/operands/LlvmTypedOperand.java8
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java4
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeInfo.java24
-rw-r--r--src/main/java/org/shedlang/compiler/util/POrderedMap.java4
7 files changed, 119 insertions, 7 deletions
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 322c9a4f..8b933bad 100644
--- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompiler.java
+++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompiler.java
@@ -1,6 +1,10 @@
package org.shedlang.compiler.backends.llvm;
+import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmGetElementPtr;
+import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmStore;
import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmOperandInt;
+import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmTypedOperand;
+import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmVariableLocal;
import org.shedlang.compiler.stackir.instructions.*;
import org.shedlang.compiler.types.NamespaceName;
@@ -34,8 +38,29 @@ public class LlvmCompiler {
}
case NamespaceFieldStoreInstruction namespaceFieldStore -> {
- throw new UnsupportedOperationException("TODO");
+ var popResult = context.pop();
+ var fieldValue = popResult.value();
+ context = popResult.context();
+
+ var namespaceFields = context.typeInfo().namespaceFields(
+ namespaceFieldStore.namespaceName()
+ );
+ var fieldPointerName = "fieldPointer__" + namespaceFieldStore.fieldName();
+ yield context.addInstruction(new LlvmGetElementPtr(
+ new LlvmVariableLocal(fieldPointerName),
+ LlvmCompilerNamespaces.typeNamespacePointer(namespaceFields),
+ LlvmCompilerNamespaces.operandNamespaceValue(namespaceFieldStore.namespaceName()),
+ List.of(
+ LlvmTypedOperand.arrayIndex(0),
+ LlvmTypedOperand.structureIndex(namespaceFields.keys().indexOf(namespaceFieldStore.fieldName()))
+ )
+ )).addInstruction(new LlvmStore(
+ LlvmCompilerTypes.VALUE_TYPE,
+ fieldValue,
+ new LlvmVariableLocal(fieldPointerName)
+ ));
}
+
case PushBoolInstruction pushBool ->
context.push(new LlvmOperandInt(pushBool.value() ? 1 : 0));
@@ -49,6 +74,7 @@ public class LlvmCompiler {
yield context.push(LlvmCompilerStrings.operandAsShedObject(globalDefinition));
}
+
case PushUnitInstruction pushUnit ->
context.push(new LlvmOperandInt(0));
};
diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerContext.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerContext.java
index b24025b6..144575c0 100644
--- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerContext.java
+++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerContext.java
@@ -8,25 +8,33 @@ import org.shedlang.compiler.backends.llvm.ir.ast.LlvmGlobalDefinition;
import org.shedlang.compiler.backends.llvm.ir.ast.LlvmTopLevelEntity;
import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmInstruction;
import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmOperand;
+import org.shedlang.compiler.typechecker.TypeInfo;
import org.shedlang.compiler.util.POrderedMap;
import java.util.Collection;
public record LlvmCompilerContext(
+ TypeInfo typeInfo,
PStack<LlvmOperand> stack,
PMap<String, LlvmOperand> locals,
PVector<LlvmInstruction> instructions,
POrderedMap<String, LlvmTopLevelEntity> topLevelEntitiesByName
) {
- public static LlvmCompilerContext EMPTY = new LlvmCompilerContext(
- Empty.stack(),
- Empty.map(),
- Empty.vector(),
- POrderedMap.empty()
- );
+ public static LlvmCompilerContext EMPTY = fromTypeInfo(TypeInfo.EMPTY);
+
+ public static LlvmCompilerContext fromTypeInfo(TypeInfo typeInfo) {
+ return new LlvmCompilerContext(
+ typeInfo,
+ Empty.stack(),
+ Empty.map(),
+ Empty.vector(),
+ POrderedMap.empty()
+ );
+ }
public LlvmCompilerContext push(LlvmOperand operand) {
return new LlvmCompilerContext(
+ typeInfo,
stack.plus(operand),
locals,
instructions,
@@ -36,6 +44,7 @@ public record LlvmCompilerContext(
public LlvmCompilerResult<LlvmOperand> pop() {
return new LlvmCompilerContext(
+ typeInfo,
stack.minus(0),
locals,
instructions,
@@ -45,6 +54,7 @@ public record LlvmCompilerContext(
public LlvmCompilerContext addLocal(String name, LlvmOperand value) {
return new LlvmCompilerContext(
+ typeInfo,
stack,
locals.plus(name, value),
instructions,
@@ -58,6 +68,7 @@ public record LlvmCompilerContext(
public LlvmCompilerContext addInstruction(LlvmInstruction instruction) {
return new LlvmCompilerContext(
+ typeInfo,
stack,
locals,
instructions.plus(instruction),
@@ -78,6 +89,7 @@ public record LlvmCompilerContext(
);
return new LlvmCompilerContext(
+ typeInfo,
stack,
locals,
instructions,
diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerNamespaces.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerNamespaces.java
new file mode 100644
index 00000000..85caf95e
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerNamespaces.java
@@ -0,0 +1,34 @@
+package org.shedlang.compiler.backends.llvm;
+
+import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmVariableGlobal;
+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.types.NamespaceName;
+import org.shedlang.compiler.types.Type;
+import org.shedlang.compiler.util.POrderedMap;
+
+public class LlvmCompilerNamespaces {
+ private LlvmCompilerNamespaces() {
+ }
+
+ public static LlvmTypePointer typeNamespacePointer(POrderedMap<String, Type> namespaceFields) {
+ return new LlvmTypePointer(typeNamespaceStruct(namespaceFields));
+ }
+
+ public static LlvmType typeNamespaceStruct(POrderedMap<String, Type> namespaceFields) {
+ return new LlvmTypeStructure(
+ namespaceFields.values().stream()
+ .map(x -> LlvmCompilerTypes.VALUE_TYPE)
+ .toList()
+ );
+ }
+
+ public static LlvmVariableGlobal operandNamespaceValue(NamespaceName namespaceName) {
+ return new LlvmVariableGlobal(globalNameNamespaceValue(namespaceName));
+ }
+
+ private static String globalNameNamespaceValue(NamespaceName namespaceName) {
+ return "shed__namespace__" + String.join("_", namespaceName.parts());
+ }
+}
diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/operands/LlvmTypedOperand.java b/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/operands/LlvmTypedOperand.java
index 91be449f..85e39cad 100644
--- a/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/operands/LlvmTypedOperand.java
+++ b/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/operands/LlvmTypedOperand.java
@@ -1,9 +1,17 @@
package 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.LlvmTypes;
public record LlvmTypedOperand(
LlvmType type,
LlvmOperand operand
) {
+ public static LlvmTypedOperand arrayIndex(long index) {
+ return new LlvmTypedOperand(LlvmTypes.INT_64, new LlvmOperandInt(index));
+ }
+
+ public static LlvmTypedOperand structureIndex(long index) {
+ return new LlvmTypedOperand(LlvmTypes.INT_32, new LlvmOperandInt(index));
+ }
}
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java
index 3429be63..93207cd3 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java
@@ -113,4 +113,8 @@ public class TypeCheckerContext {
return new TypeCheckerResult<>(mappedValues, context);
}
+
+ public TypeInfo toTypeInfo() {
+ return new TypeInfo(namespaceFields);
+ }
}
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeInfo.java b/src/main/java/org/shedlang/compiler/typechecker/TypeInfo.java
new file mode 100644
index 00000000..cfce56ef
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeInfo.java
@@ -0,0 +1,24 @@
+package org.shedlang.compiler.typechecker;
+
+import org.pcollections.Empty;
+import org.pcollections.PMap;
+import org.shedlang.compiler.types.NamespaceName;
+import org.shedlang.compiler.types.Type;
+import org.shedlang.compiler.util.POrderedMap;
+
+public class TypeInfo {
+ public static final TypeInfo EMPTY = new TypeInfo(Empty.map());
+
+ private final PMap<NamespaceName, POrderedMap<String, Type>> namespaceFields;
+
+ public TypeInfo(
+ PMap<NamespaceName, POrderedMap<String, Type>> namespaceFields
+ ) {
+ this.namespaceFields = namespaceFields;
+ }
+
+ public POrderedMap<String, Type> namespaceFields(NamespaceName namespaceName) {
+ // TODO: handle missing key
+ return namespaceFields.get(namespaceName);
+ }
+}
diff --git a/src/main/java/org/shedlang/compiler/util/POrderedMap.java b/src/main/java/org/shedlang/compiler/util/POrderedMap.java
index aabec1d7..6d273cdc 100644
--- a/src/main/java/org/shedlang/compiler/util/POrderedMap.java
+++ b/src/main/java/org/shedlang/compiler/util/POrderedMap.java
@@ -30,6 +30,10 @@ public class POrderedMap<K, V> {
return map.containsKey(key);
}
+ public PVector<K> keys() {
+ return keys;
+ }
+
public Collection<V> values() {
return map.values();
}