From 96a5e5d7fe6af05163de84b522effb6f1893dbaf Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 22 Jul 2023 17:02:51 +0100 Subject: Support string addition in Patio code gen --- .../org/shedlang/compiler/patio/PatioCodeGen.java | 84 +++++++++++++++------- .../compiler/patio/PatioCodeGenStrings.java | 34 +++++++++ 2 files changed, 93 insertions(+), 25 deletions(-) (limited to 'src/main/java') 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; + } } -- cgit v1.2.3