aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-07-22 17:02:51 +0100
committerMichael Williamson <mike@zwobble.org>2023-07-22 17:02:51 +0100
commit96a5e5d7fe6af05163de84b522effb6f1893dbaf (patch)
treef7ca6477a93292e28fc46b02541a1a4790e7f1a3 /src/main/java
parentabccf06f978217831e0eedd7182ab356dd20659e (diff)
Support string addition in Patio code gen
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java84
-rw-r--r--src/main/java/org/shedlang/compiler/patio/PatioCodeGenStrings.java34
2 files changed, 93 insertions, 25 deletions
diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java
index 120a78af..e6a12214 100644
--- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java
+++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java
@@ -176,31 +176,17 @@ public class PatioCodeGen {
yield context;
}
- case IntAddInstruction intAdd -> {
- var rightResult = context.temporaryPop();
- var right = rightResult.value();
- context = rightResult.context();
-
- var leftResult = context.temporaryPop();
- var left = leftResult.value();
- context = leftResult.context();
-
- var targetResult = context.allocateLocal(
- PatioCodeGenLocalSpace.TEMPORARY,
- PatioCodeGenTypes.VALUE_TYPE
+ case IntAddInstruction intAdd ->
+ generateBinaryOperation(
+ (target, left, right, operationContext) ->
+ operationContext.addInstruction(new PatioIntAdd(
+ target,
+ left,
+ right,
+ intAdd.source()
+ )),
+ context
);
- var target = targetResult.value();
- context = targetResult.context();
-
- yield context
- .addInstruction(new PatioIntAdd(
- target,
- left,
- right,
- intAdd.source()
- ))
- .temporaryPush(target);
- }
case LocalLoadInstruction localLoad -> {
var local = context.stackIrLocalNameToLocal(localLoad.name());
@@ -285,7 +271,6 @@ public class PatioCodeGen {
yield context;
}
-
case PushUnitInstruction pushUnit ->
pushValue(0, pushUnit.source(), context);
@@ -297,11 +282,60 @@ public class PatioCodeGen {
yield context.addInstruction(new PatioReturn(value, return_.source()));
}
+ case StringAddInstruction stringAdd ->
+ generateBinaryOperation(
+ (target, left, right, operationContext) ->
+ PatioCodeGenStrings.add(
+ target,
+ left,
+ right,
+ stringAdd.source(),
+ operationContext
+ ),
+ context
+ );
+
default ->
throw new IllegalStateException("Unexpected value: " + stackIrInstruction);
};
}
+ interface BinaryOperationCodeGen {
+ PatioCodeGenContext generate(
+ PatioLocalRef target,
+ PatioLocalRef left,
+ PatioLocalRef right,
+ PatioCodeGenContext context
+ );
+ }
+
+ private static PatioCodeGenContext generateBinaryOperation(
+ BinaryOperationCodeGen binaryOperationCodeGen,
+ PatioCodeGenContext context
+ ) {
+ var rightResult = context.temporaryPop();
+ var right = rightResult.value();
+ context = rightResult.context();
+
+ var leftResult = context.temporaryPop();
+ var left = leftResult.value();
+ context = leftResult.context();
+
+ var targetResult = context.allocateLocal(
+ PatioCodeGenLocalSpace.TEMPORARY,
+ PatioCodeGenTypes.VALUE_TYPE
+ );
+ var target = targetResult.value();
+ context = targetResult.context();
+
+ return binaryOperationCodeGen.generate(
+ target,
+ left,
+ right,
+ context
+ ).temporaryPush(target);
+ }
+
private static PatioCodeGenContext pushValue(int value, Source source, PatioCodeGenContext context) {
var localResult = context.allocateLocal(PatioCodeGenLocalSpace.TEMPORARY, PatioCodeGenTypes.VALUE_TYPE);
var local = localResult.value();
diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenStrings.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenStrings.java
index e45a43e9..098d0296 100644
--- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenStrings.java
+++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenStrings.java
@@ -1,7 +1,11 @@
package org.shedlang.compiler.patio;
import org.shedlang.compiler.patio.ast.PatioDataElementImmutable;
+import org.shedlang.compiler.patio.ast.PatioFunctionDeclaration;
+import org.shedlang.compiler.patio.ast.PatioLocal;
+import org.shedlang.compiler.patio.ast.instructions.PatioCall;
import org.shedlang.compiler.patio.ast.operands.PatioDataPtr;
+import org.shedlang.compiler.patio.ast.operands.PatioLocalRef;
import org.shedlang.compiler.patio.ast.types.PatioDataLayouts;
import org.shedlang.compiler.patio.ast.types.PatioDataValue;
import org.shedlang.compiler.patio.ast.types.PatioDataValues;
@@ -10,6 +14,7 @@ import org.shedlang.compiler.sources.Source;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
public class PatioCodeGenStrings {
private PatioCodeGenStrings() {}
@@ -45,4 +50,33 @@ public class PatioCodeGenStrings {
return context.toResult(new PatioDataPtr(elementName));
}
+
+ public static PatioCodeGenContext add(
+ PatioLocalRef target,
+ PatioLocalRef left,
+ PatioLocalRef right,
+ Source source,
+ PatioCodeGenContext context
+ ) {
+ var runtimeAddName = "shed__runtime__string_add";
+
+ context = context.addCompilationUnitElement(new PatioFunctionDeclaration(
+ runtimeAddName,
+ List.of(
+ new PatioLocal("left", PatioCodeGenTypes.VALUE_TYPE),
+ new PatioLocal("right", PatioCodeGenTypes.VALUE_TYPE)
+ ),
+ PatioCodeGenTypes.VALUE_TYPE,
+ source
+ ));
+
+ context = context.addInstruction(new PatioCall(
+ Optional.of(target),
+ runtimeAddName,
+ List.of(left, right),
+ source
+ ));
+
+ return context;
+ }
}