From 07d62885c5150fe6eadfa9372a190dd73fd754cc Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 2 Dec 2023 19:47:35 +0000 Subject: Rename stack IR to Shid --- .../java/org/shedlang/compiler/ShedCompiler.java | 10 +- .../org/shedlang/compiler/backends/Backend.java | 4 +- .../backends/GenerateInstructionsBackend.java | 6 +- .../shedlang/compiler/backends/PatioBackend.java | 4 +- .../compiler/backends/llvm/LlvmBackend.java | 4 +- .../compiler/backends/wasm/WasmBackend.java | 4 +- .../org/shedlang/compiler/patio/PatioCodeGen.java | 204 ++--- .../compiler/patio/PatioCodeGenClosures.java | 22 +- .../compiler/patio/PatioCodeGenContext.java | 102 +-- .../compiler/patio/PatioCodeGenEffects.java | 10 +- .../compiler/patio/PatioCodeGenStructs.java | 10 +- .../compiler/shid/InstructionSerializer.java | 280 +++++++ .../org/shedlang/compiler/shid/ShidCodeGen.java | 848 +++++++++++++++++++++ .../org/shedlang/compiler/shid/ShidNamespace.java | 12 + .../compiler/shid/instructions/ShidCall.java | 25 + .../shid/instructions/ShidDefineEffect.java | 14 + .../shid/instructions/ShidDefineFunction.java | 105 +++ .../shid/instructions/ShidDefineStruct.java | 21 + .../compiler/shid/instructions/ShidDiscard.java | 9 + .../compiler/shid/instructions/ShidDuplicate.java | 9 + .../compiler/shid/instructions/ShidFieldLoad.java | 22 + .../compiler/shid/instructions/ShidIf.java | 22 + .../shid/instructions/ShidInstruction.java | 9 + .../compiler/shid/instructions/ShidIntAdd.java | 10 + .../compiler/shid/instructions/ShidIntEquals.java | 10 + .../shid/instructions/ShidIntNotEqual.java | 10 + .../compiler/shid/instructions/ShidIntSub.java | 11 + .../compiler/shid/instructions/ShidLocalLoad.java | 10 + .../compiler/shid/instructions/ShidLocalStore.java | 10 + .../compiler/shid/instructions/ShidLoop.java | 17 + .../compiler/shid/instructions/ShidLoopBreak.java | 9 + .../shid/instructions/ShidLoopContinue.java | 9 + .../shid/instructions/ShidNamespaceFieldStore.java | 15 + .../shid/instructions/ShidNamespaceImport.java | 13 + .../compiler/shid/instructions/ShidPushBool.java | 12 + .../compiler/shid/instructions/ShidPushInt.java | 11 + .../compiler/shid/instructions/ShidPushString.java | 9 + .../compiler/shid/instructions/ShidPushUnit.java | 9 + .../compiler/shid/instructions/ShidResume.java | 10 + .../compiler/shid/instructions/ShidReturn.java | 10 + .../compiler/shid/instructions/ShidStringAdd.java | 12 + .../compiler/shid/instructions/ShidSwitch.java | 21 + .../compiler/shid/instructions/ShidTry.java | 26 + .../shid/instructions/ShidTupleCreate.java | 14 + .../compiler/shid/instructions/ShidTupleGet.java | 14 + .../compiler/shid/instructions/ShidVarLoad.java | 10 + .../compiler/shid/instructions/ShidVarStore.java | 10 + .../compiler/stackir/InstructionSerializer.java | 280 ------- .../shedlang/compiler/stackir/StackCompiler.java | 848 --------------------- .../compiler/stackir/StackIrNamespace.java | 12 - .../stackir/instructions/CallInstruction.java | 25 - .../instructions/DefineEffectInstruction.java | 14 - .../instructions/DefineFunctionInstruction.java | 105 --- .../instructions/DefineStructInstruction.java | 21 - .../stackir/instructions/DiscardInstruction.java | 9 - .../stackir/instructions/DuplicateInstruction.java | 9 - .../stackir/instructions/FieldLoadInstruction.java | 22 - .../stackir/instructions/IfInstruction.java | 22 - .../compiler/stackir/instructions/Instruction.java | 9 - .../stackir/instructions/IntAddInstruction.java | 10 - .../stackir/instructions/IntEqualsInstruction.java | 10 - .../instructions/IntNotEqualInstruction.java | 10 - .../stackir/instructions/IntSubInstruction.java | 11 - .../stackir/instructions/LocalLoadInstruction.java | 10 - .../instructions/LocalStoreInstruction.java | 10 - .../stackir/instructions/LoopBreakInstruction.java | 9 - .../instructions/LoopContinueInstruction.java | 9 - .../stackir/instructions/LoopInstruction.java | 17 - .../NamespaceFieldStoreInstruction.java | 15 - .../instructions/NamespaceImportInstruction.java | 13 - .../stackir/instructions/PushBoolInstruction.java | 12 - .../stackir/instructions/PushIntInstruction.java | 11 - .../instructions/PushStringInstruction.java | 9 - .../stackir/instructions/PushUnitInstruction.java | 9 - .../stackir/instructions/ResumeInstruction.java | 10 - .../stackir/instructions/ReturnInstruction.java | 10 - .../stackir/instructions/StringAddInstruction.java | 12 - .../stackir/instructions/SwitchInstruction.java | 21 - .../stackir/instructions/TryInstruction.java | 26 - .../instructions/TupleCreateInstruction.java | 14 - .../stackir/instructions/TupleGetInstruction.java | 14 - .../stackir/instructions/VarLoadInstruction.java | 10 - .../stackir/instructions/VarStoreInstruction.java | 10 - 83 files changed, 1858 insertions(+), 1858 deletions(-) create mode 100644 src/main/java/org/shedlang/compiler/shid/InstructionSerializer.java create mode 100644 src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java create mode 100644 src/main/java/org/shedlang/compiler/shid/ShidNamespace.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidCall.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineEffect.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineFunction.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineStruct.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidDiscard.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidDuplicate.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidFieldLoad.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidIf.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidInstruction.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidIntAdd.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidIntEquals.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidIntNotEqual.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidIntSub.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidLocalLoad.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidLocalStore.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidLoop.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidLoopBreak.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidLoopContinue.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidNamespaceFieldStore.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidNamespaceImport.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidPushBool.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidPushInt.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidPushString.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidPushUnit.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidResume.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidReturn.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidStringAdd.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidSwitch.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidTry.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidTupleCreate.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidTupleGet.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidVarLoad.java create mode 100644 src/main/java/org/shedlang/compiler/shid/instructions/ShidVarStore.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/InstructionSerializer.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/StackCompiler.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/StackIrNamespace.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/CallInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/DefineEffectInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/DefineFunctionInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/DefineStructInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/DiscardInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/DuplicateInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/FieldLoadInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/IfInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/IntAddInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/IntEqualsInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/IntNotEqualInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/IntSubInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/LocalLoadInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/LocalStoreInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/LoopBreakInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/LoopContinueInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/LoopInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/NamespaceFieldStoreInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/NamespaceImportInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/PushBoolInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/PushIntInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/PushStringInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/PushUnitInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/ResumeInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/ReturnInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/StringAddInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/SwitchInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/TryInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/TupleCreateInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/TupleGetInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/VarLoadInstruction.java delete mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/VarStoreInstruction.java (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/ShedCompiler.java b/src/main/java/org/shedlang/compiler/ShedCompiler.java index 325383ae..f07ead28 100644 --- a/src/main/java/org/shedlang/compiler/ShedCompiler.java +++ b/src/main/java/org/shedlang/compiler/ShedCompiler.java @@ -6,8 +6,8 @@ import org.shedlang.compiler.config.ConfigChecker; import org.shedlang.compiler.config.ProjectConfig; import org.shedlang.compiler.parser.Parser; import org.shedlang.compiler.sources.Sources; -import org.shedlang.compiler.stackir.StackCompiler; -import org.shedlang.compiler.stackir.StackIrNamespace; +import org.shedlang.compiler.shid.ShidCodeGen; +import org.shedlang.compiler.shid.ShidNamespace; import org.shedlang.compiler.typechecker.TypeChecker; import org.shedlang.compiler.typechecker.TypeCheckerContext; import org.shedlang.compiler.types.*; @@ -36,7 +36,7 @@ public class ShedCompiler { var untypedNamespaceNodes = parseSource(sourceRoot, sourceFilePaths); - var namespaces = new ArrayList(); + var namespaces = new ArrayList(); var typeCheckerContext = TypeCheckerContext.EMPTY .addNamespaceTypeInfo( @@ -59,8 +59,8 @@ public class ShedCompiler { var typeCheckNamespaceResult = TypeChecker.typeCheckNamespace(untypedNamespaceNode, typeCheckerContext); typeCheckerContext = typeCheckNamespaceResult.context(); - var stackIrNamespace = StackCompiler.compileNamespace(typeCheckNamespaceResult.value()); - namespaces.add(stackIrNamespace); + var shidNamespace = ShidCodeGen.compileNamespace(typeCheckNamespaceResult.value()); + namespaces.add(shidNamespace); } var typeInfos = typeCheckerContext.toTypeInfos(); diff --git a/src/main/java/org/shedlang/compiler/backends/Backend.java b/src/main/java/org/shedlang/compiler/backends/Backend.java index 42938d34..40a00fbf 100644 --- a/src/main/java/org/shedlang/compiler/backends/Backend.java +++ b/src/main/java/org/shedlang/compiler/backends/Backend.java @@ -1,7 +1,7 @@ package org.shedlang.compiler.backends; import org.shedlang.compiler.config.ProjectConfig; -import org.shedlang.compiler.stackir.StackIrNamespace; +import org.shedlang.compiler.shid.ShidNamespace; import org.shedlang.compiler.typechecker.TypeInfos; import java.io.IOException; @@ -13,7 +13,7 @@ public interface Backend { void compile( ProjectConfig config, - List namespaces, + List namespaces, TypeInfos typeInfos, Path targetDir ) throws IOException, InterruptedException; diff --git a/src/main/java/org/shedlang/compiler/backends/GenerateInstructionsBackend.java b/src/main/java/org/shedlang/compiler/backends/GenerateInstructionsBackend.java index dd33ae89..c2a6ea23 100644 --- a/src/main/java/org/shedlang/compiler/backends/GenerateInstructionsBackend.java +++ b/src/main/java/org/shedlang/compiler/backends/GenerateInstructionsBackend.java @@ -1,8 +1,8 @@ package org.shedlang.compiler.backends; import org.shedlang.compiler.config.ProjectConfig; -import org.shedlang.compiler.stackir.InstructionSerializer; -import org.shedlang.compiler.stackir.StackIrNamespace; +import org.shedlang.compiler.shid.InstructionSerializer; +import org.shedlang.compiler.shid.ShidNamespace; import org.shedlang.compiler.typechecker.TypeInfos; import java.nio.file.Path; @@ -11,7 +11,7 @@ import java.util.List; public class GenerateInstructionsBackend implements Backend { public void compile( ProjectConfig config, - List namespaces, + List namespaces, TypeInfos typeInfos, Path targetDir ) { diff --git a/src/main/java/org/shedlang/compiler/backends/PatioBackend.java b/src/main/java/org/shedlang/compiler/backends/PatioBackend.java index 9e444cee..f9ae1695 100644 --- a/src/main/java/org/shedlang/compiler/backends/PatioBackend.java +++ b/src/main/java/org/shedlang/compiler/backends/PatioBackend.java @@ -4,7 +4,7 @@ import org.shedlang.compiler.config.ProjectConfig; import org.shedlang.compiler.patio.PatioCodeGen; import org.shedlang.compiler.patio.PatioCodeGenContext; import org.shedlang.compiler.patio.ast.PatioSerializer; -import org.shedlang.compiler.stackir.StackIrNamespace; +import org.shedlang.compiler.shid.ShidNamespace; import org.shedlang.compiler.typechecker.TypeInfos; import java.nio.file.Path; @@ -13,7 +13,7 @@ import java.util.List; public class PatioBackend implements Backend { public void compile( ProjectConfig config, - List namespaces, + List namespaces, TypeInfos typeInfos, Path targetDir ) { diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmBackend.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmBackend.java index c1575a31..97e1917f 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmBackend.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmBackend.java @@ -15,7 +15,7 @@ import org.shedlang.compiler.filesystem.ShedCompilerFiles; import org.shedlang.compiler.patio.PatioCodeGen; import org.shedlang.compiler.patio.PatioCodeGenContext; import org.shedlang.compiler.sources.Sources; -import org.shedlang.compiler.stackir.StackIrNamespace; +import org.shedlang.compiler.shid.ShidNamespace; import org.shedlang.compiler.typechecker.TypeInfos; import org.shedlang.compiler.types.NamespaceName; import org.shedlang.compiler.util.processes.ProcessError; @@ -42,7 +42,7 @@ public class LlvmBackend implements Backend { @Override public void compile( ProjectConfig config, - List namespaces, + List namespaces, TypeInfos typeInfos, Path targetDir ) throws IOException, InterruptedException { diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/WasmBackend.java b/src/main/java/org/shedlang/compiler/backends/wasm/WasmBackend.java index a0074d28..17b5c1ff 100644 --- a/src/main/java/org/shedlang/compiler/backends/wasm/WasmBackend.java +++ b/src/main/java/org/shedlang/compiler/backends/wasm/WasmBackend.java @@ -10,7 +10,7 @@ import org.shedlang.compiler.filesystem.ShedCompilerFiles; import org.shedlang.compiler.patio.PatioCodeGen; import org.shedlang.compiler.patio.PatioCodeGenContext; import org.shedlang.compiler.sources.Sources; -import org.shedlang.compiler.stackir.StackIrNamespace; +import org.shedlang.compiler.shid.ShidNamespace; import org.shedlang.compiler.typechecker.TypeInfos; import org.shedlang.compiler.types.NamespaceName; import org.shedlang.compiler.util.processes.ProcessError; @@ -35,7 +35,7 @@ public class WasmBackend implements Backend { @Override public void compile( ProjectConfig config, - List namespaces, + List namespaces, TypeInfos typeInfos, Path targetDir ) throws IOException, InterruptedException { diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java index e2f1b6ba..b5b3aa0b 100644 --- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java +++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java @@ -13,8 +13,8 @@ import org.shedlang.compiler.patio.ast.types.PatioDataLayouts; import org.shedlang.compiler.patio.ast.types.PatioTypes; import org.shedlang.compiler.sources.Source; import org.shedlang.compiler.sources.Sources; -import org.shedlang.compiler.stackir.StackIrNamespace; -import org.shedlang.compiler.stackir.instructions.*; +import org.shedlang.compiler.shid.ShidNamespace; +import org.shedlang.compiler.shid.instructions.*; import org.shedlang.compiler.types.NamespaceName; import org.shedlang.compiler.util.P; @@ -100,19 +100,19 @@ public class PatioCodeGen { } public static PatioCompilationUnit generateNamespace( - StackIrNamespace stackIrNamespace, + ShidNamespace shidNamespace, PatioCodeGenContext context ) { context = PatioCodeGenNamespaces.define( - stackIrNamespace.namespaceName(), + shidNamespace.namespaceName(), initContext -> { - initContext = declareStackIrLocals( - stackIrNamespace.instructions(), + initContext = declareShidLocals( + shidNamespace.instructions(), FreeVariables.empty(), initContext ); - return generateInstructions(stackIrNamespace.instructions(), initContext); + return generateInstructions(shidNamespace.instructions(), initContext); }, context ); @@ -122,22 +122,22 @@ public class PatioCodeGen { } public static PatioCodeGenContext generateInstructions( - List stackIrInstructions, + List shidInstructions, PatioCodeGenContext context ) { - for (var stackIrInstruction : stackIrInstructions) { - context = generateInstruction(stackIrInstruction, context); + for (var shidInstruction : shidInstructions) { + context = generateInstruction(shidInstruction, context); } return context; } public static PatioCodeGenContext generateInstruction( - Instruction stackIrInstruction, + ShidInstruction shidInstruction, PatioCodeGenContext context ) { - return switch (stackIrInstruction) { - case CallInstruction call -> { + return switch (shidInstruction) { + case ShidCall call -> { var namedArgsByName = new ArrayList>(); for (var argName : call.namedArgNames().reversed()) { var argResult = context.allocateVal( @@ -150,7 +150,7 @@ public class PatioCodeGen { context = context.temporaryPopIntoLocal( arg, - stackIrInstruction.source() + shidInstruction.source() ); namedArgsByName.add(Map.entry(argName, arg)); @@ -168,7 +168,7 @@ public class PatioCodeGen { context = context.temporaryPopIntoLocal( arg, - stackIrInstruction.source() + shidInstruction.source() ); positionalArgs.add(arg); @@ -184,7 +184,7 @@ public class PatioCodeGen { context = context.temporaryPopIntoLocal( receiver, - stackIrInstruction.source() + shidInstruction.source() ); var targetResult = context.allocateVal( @@ -199,12 +199,12 @@ public class PatioCodeGen { receiver, positionalArgs, namedArgsByName, - stackIrInstruction.source(), + shidInstruction.source(), context ).temporaryPush(target); } - case DefineEffectInstruction defineEffect -> { + case ShidDefineEffect defineEffect -> { var targetResult = context.allocateVal( PatioCodeGenLocalSpace.USER_DEFINED_EFFECT, defineEffect.effect().name(), @@ -225,7 +225,7 @@ public class PatioCodeGen { yield context; } - case DefineFunctionInstruction defineFunction -> { + case ShidDefineFunction defineFunction -> { var targetResult = context.allocateVal( PatioCodeGenLocalSpace.CLOSURE, defineFunction.name(), @@ -243,7 +243,7 @@ public class PatioCodeGen { functionContext -> { // TODO: explicitly store locals on a function? - functionContext = declareStackIrLocals( + functionContext = declareShidLocals( defineFunction.body(), defineFunction.freeVariables(), functionContext @@ -260,7 +260,7 @@ public class PatioCodeGen { yield context; } - case DefineStructInstruction defineStruct -> { + case ShidDefineStruct defineStruct -> { var targetResult = context.allocateVal( PatioCodeGenLocalSpace.STRUCT_TYPE, defineStruct.type().name(), @@ -282,10 +282,10 @@ public class PatioCodeGen { yield context; } - case DiscardInstruction discard -> + case ShidDiscard discard -> context.temporaryPop().context(); - case DuplicateInstruction duplicate -> { + case ShidDuplicate duplicate -> { var valueResult = context.temporaryPop(); var value = valueResult.value(); context = valueResult.context(); @@ -293,7 +293,7 @@ public class PatioCodeGen { yield context.temporaryPush(value).temporaryPush(value); } - case FieldLoadInstruction fieldLoad -> { + case ShidFieldLoad fieldLoad -> { var receiverResult = context.temporaryPop(); var receiver = receiverResult.value(); context = receiverResult.context(); @@ -307,7 +307,7 @@ public class PatioCodeGen { context = targetResult.context(); switch (fieldLoad.receiver()) { - case FieldLoadInstruction.Receiver.Effect receiverEffect -> { + case ShidFieldLoad.Receiver.Effect receiverEffect -> { context = PatioCodeGenEffects.fieldLoad( target, receiver, @@ -318,7 +318,7 @@ public class PatioCodeGen { ); } - case FieldLoadInstruction.Receiver.Namespace receiverNamespace -> { + case ShidFieldLoad.Receiver.Namespace receiverNamespace -> { context = PatioCodeGenNamespaces.fieldLoad( target, receiver, @@ -329,7 +329,7 @@ public class PatioCodeGen { ); } - case FieldLoadInstruction.Receiver.Struct receiverStruct -> { + case ShidFieldLoad.Receiver.Struct receiverStruct -> { context = PatioCodeGenStructs.fieldLoad( target, receiver, @@ -346,7 +346,7 @@ public class PatioCodeGen { yield context; } - case IfInstruction if_ -> { + case ShidIf if_ -> { var conditionBoolResult = generateCondition(if_.source(), context); var conditionBool = conditionBoolResult.value(); context = conditionBoolResult.context(); @@ -387,7 +387,7 @@ public class PatioCodeGen { yield context; } - case IntAddInstruction intAdd -> + case ShidIntAdd intAdd -> generateBinaryOperation( (target, left, right, operationContext) -> operationContext.addInstruction(new PatioIntAdd( @@ -399,7 +399,7 @@ public class PatioCodeGen { context ); - case IntEqualsInstruction intEquals -> + case ShidIntEquals intEquals -> generateComparison( (target, left, right, operationContext) -> operationContext.addInstruction(new PatioIntEquals( @@ -412,7 +412,7 @@ public class PatioCodeGen { context ); - case IntNotEqualInstruction intNotEqual -> + case ShidIntNotEqual intNotEqual -> generateComparison( (target, left, right, operationContext) -> operationContext.addInstruction(new PatioIntNotEqual( @@ -425,7 +425,7 @@ public class PatioCodeGen { context ); - case IntSubInstruction intSub -> + case ShidIntSub intSub -> generateBinaryOperation( (target, left, right, operationContext) -> operationContext.addInstruction(new PatioIntSub( @@ -437,30 +437,30 @@ public class PatioCodeGen { context ); - case LocalLoadInstruction localLoad -> { - var local = context.stackIrLocalNameToLocal(localLoad.name()); + case ShidLocalLoad localLoad -> { + var local = context.shidLocalNameToLocal(localLoad.name()); yield context.temporaryPush(local); } - case LocalStoreInstruction localStore -> { + case ShidLocalStore localStore -> { context = context.temporaryPopIntoLocal( - context.stackIrLocalNameToLocal(localStore.name()), + context.shidLocalNameToLocal(localStore.name()), localStore.source() ); - context = context.initStackIrLocal(localStore.name()); + context = context.initShidLocal(localStore.name()); yield context; } - case LoopBreakInstruction loopBreak -> + case ShidLoopBreak loopBreak -> context.addInstruction(new PatioLoopBreak(loopBreak.source())); - case LoopContinueInstruction loopContinue -> + case ShidLoopContinue loopContinue -> context.addInstruction(new PatioLoopContinue(loopContinue.source())); - case LoopInstruction loop -> { + case ShidLoop loop -> { context = context.enterBlock(); context = generateInstructions(loop.body(), context); @@ -473,7 +473,7 @@ public class PatioCodeGen { yield context; } - case NamespaceFieldStoreInstruction namespaceFieldStore -> { + case ShidNamespaceFieldStore namespaceFieldStore -> { var fieldValueResult = context.temporaryPop(); var fieldValue = fieldValueResult.value(); context = fieldValueResult.context(); @@ -489,7 +489,7 @@ public class PatioCodeGen { yield context; } - case NamespaceImportInstruction namespaceImport -> { + case ShidNamespaceImport namespaceImport -> { var namespaceValueResult = context.allocateVal( PatioCodeGenLocalSpace.NAMESPACE_VALUE, PatioCodeGenNamespaces.NAMESPACE_VALUE_TYPE @@ -509,13 +509,13 @@ public class PatioCodeGen { yield context; } - case PushBoolInstruction pushBool -> + case ShidPushBool pushBool -> pushValue(pushBool.value() ? 1 : 0, pushBool.source(), context); - case PushIntInstruction pushInt -> + case ShidPushInt pushInt -> pushValue(pushInt.value().intValueExact(), pushInt.source(), context); - case PushStringInstruction pushString -> { + case ShidPushString pushString -> { var stringPtrOperandResult = PatioCodeGenStrings.define( pushString.value(), pushString.source(), @@ -542,10 +542,10 @@ public class PatioCodeGen { yield context; } - case PushUnitInstruction pushUnit -> + case ShidPushUnit pushUnit -> pushValue(0, pushUnit.source(), context); - case ResumeInstruction resume -> { + case ShidResume resume -> { var valueResult = context.temporaryPop(); var value = valueResult.value(); context = valueResult.context(); @@ -553,7 +553,7 @@ public class PatioCodeGen { yield context.addInstruction(new PatioResume(value, resume.source())); } - case ReturnInstruction return_ -> { + case ShidReturn return_ -> { var valueResult = context.temporaryPop(); var value = valueResult.value(); context = valueResult.context(); @@ -561,7 +561,7 @@ public class PatioCodeGen { yield context.addInstruction(new PatioReturn(value, return_.source())); } - case StringAddInstruction stringAdd -> + case ShidStringAdd stringAdd -> generateBinaryOperation( (target, left, right, operationContext) -> PatioCodeGenStrings.add( @@ -574,7 +574,7 @@ public class PatioCodeGen { context ); - case SwitchInstruction switch_ -> { + case ShidSwitch switch_ -> { var targetResult = context.allocateVal( PatioCodeGenLocalSpace.TEMPORARY, PatioCodeGenTypes.VALUE_TYPE @@ -602,20 +602,20 @@ public class PatioCodeGen { var cases = new ArrayList(); - for (var stackIrCase : switch_.cases()) { + for (var shidCase : switch_.cases()) { var bodyResult = generateBlock( 1, - stackIrCase.body(), - stackIrCase.source(), + shidCase.body(), + shidCase.source(), context ); var body = bodyResult.value(); context = bodyResult.context(); cases.add(new PatioSwitch.Case( - context.structTag(stackIrCase.caseType()), + context.structTag(shidCase.caseType()), body, - stackIrCase.source() + shidCase.source() )); } @@ -638,7 +638,7 @@ public class PatioCodeGen { yield context; } - case TryInstruction try_ -> { + case ShidTry try_ -> { var handlerMethodsByName = new HashMap(); for (var handlerMethodName : try_.handlerMethodNames().reversed()) { @@ -661,7 +661,7 @@ public class PatioCodeGen { yield context; } - case TupleCreateInstruction tupleCreate -> { + case ShidTupleCreate tupleCreate -> { var elements = new ArrayList(); for (var elementIndex = tupleCreate.elementCount(); elementIndex --> 0;) { @@ -687,7 +687,7 @@ public class PatioCodeGen { yield context.temporaryPush(tuple); } - case TupleGetInstruction tupleGet -> { + case ShidTupleGet tupleGet -> { var tupleResult = context.temporaryPop(); var tuple = tupleResult.value(); context = tupleResult.context(); @@ -705,7 +705,7 @@ public class PatioCodeGen { yield context.temporaryPush(target); } - case VarLoadInstruction varLoad -> { + case ShidVarLoad varLoad -> { var varValueResult = context.allocateVal( PatioCodeGenLocalSpace.VAR_VALUE, varLoad.name(), @@ -716,7 +716,7 @@ public class PatioCodeGen { context = context.addInstruction(new PatioMemoryLoad( varValue, - context.stackIrLocalNameToLocal(varLoad.name()), + context.shidLocalNameToLocal(varLoad.name()), PatioDataLayouts.fromType(PatioCodeGenTypes.VALUE_TYPE), List.of(), varLoad.source() @@ -727,13 +727,13 @@ public class PatioCodeGen { yield context; } - case VarStoreInstruction varStore -> { + case ShidVarStore varStore -> { var valueResult = context.temporaryPop(); var value = valueResult.value(); context = valueResult.context(); context = context.addInstruction(new PatioMemoryStore( - context.stackIrLocalNameToLocal(varStore.name()), + context.shidLocalNameToLocal(varStore.name()), PatioDataLayouts.fromType(PatioCodeGenTypes.VALUE_TYPE), List.of(), value, @@ -816,12 +816,12 @@ public class PatioCodeGen { private static PatioCodeGenResult generateBlock( int resultCount, - List stackIrInstructions, + List shidInstructions, Source source, PatioCodeGenContext context ) { context = context.enterBlock(); - context = generateInstructions(stackIrInstructions, context); + context = generateInstructions(shidInstructions, context); var targets = new ArrayList(); for (var i = 0; i < resultCount; i++) { @@ -875,8 +875,8 @@ public class PatioCodeGen { return context.toResult(conditionBool); } - private static PatioCodeGenContext declareStackIrLocals( - List body, + private static PatioCodeGenContext declareShidLocals( + List body, FreeVariables freeVariables, PatioCodeGenContext context ) { @@ -890,7 +890,7 @@ public class PatioCodeGen { if (freeVariableNames.contains(boundVariable.name())) { // This is a terrible hack. Another reason to collect variables up-front. } else if (boundVariable.isMutable()) { - var patioLocalResult = context.declareStackIrVal( + var patioLocalResult = context.declareShidVal( boundVariable.name(), PatioTypes.DATA_POINTER ); @@ -904,9 +904,9 @@ public class PatioCodeGen { Sources.NULL )); - context = context.initStackIrLocal(boundVariable.name()); + context = context.initShidLocal(boundVariable.name()); } else { - context = context.declareStackIrVal( + context = context.declareShidVal( boundVariable.name(), PatioCodeGenTypes.VALUE_TYPE ).context(); @@ -916,82 +916,82 @@ public class PatioCodeGen { } private static OrderedPSet findAssignedVariables( - List body, + List body, OrderedPSet boundVariables ) { for (var bodyInstruction : body) { switch (bodyInstruction) { - case CallInstruction callInstruction -> { + case ShidCall callInstruction -> { } - case DefineEffectInstruction defineEffectInstruction -> { + case ShidDefineEffect defineEffectInstruction -> { } - case DefineFunctionInstruction defineFunctionInstruction -> { + case ShidDefineFunction defineFunctionInstruction -> { } - case DefineStructInstruction defineStructInstruction -> { + case ShidDefineStruct defineStructInstruction -> { } - case DiscardInstruction discardInstruction -> { + case ShidDiscard discardInstruction -> { } - case DuplicateInstruction duplicateInstruction -> { + case ShidDuplicate duplicateInstruction -> { } - case FieldLoadInstruction fieldLoadInstruction -> { + case ShidFieldLoad fieldLoadInstruction -> { } - case IfInstruction ifInstruction -> { + case ShidIf ifInstruction -> { boundVariables = findAssignedVariables(ifInstruction.trueBody(), boundVariables); boundVariables = findAssignedVariables(ifInstruction.falseBody(), boundVariables); } - case IntAddInstruction intAddInstruction -> { + case ShidIntAdd intAddInstruction -> { } - case IntEqualsInstruction intEqualsInstruction -> { + case ShidIntEquals intEqualsInstruction -> { } - case IntNotEqualInstruction intNotEqualInstruction -> { + case ShidIntNotEqual intNotEqualInstruction -> { } - case IntSubInstruction intSubInstruction -> { + case ShidIntSub intSubInstruction -> { } - case LocalLoadInstruction localLoadInstruction -> { + case ShidLocalLoad localLoadInstruction -> { } - case LocalStoreInstruction localStoreInstruction -> { + case ShidLocalStore localStoreInstruction -> { boundVariables = boundVariables.plus(BoundVariable.immutable(localStoreInstruction.name())); } - case LoopBreakInstruction loopBreakInstruction -> { + case ShidLoopBreak loopBreakInstruction -> { } - case LoopContinueInstruction loopContinueInstruction -> { + case ShidLoopContinue loopContinueInstruction -> { } - case LoopInstruction loopInstruction -> { + case ShidLoop loopInstruction -> { boundVariables = findAssignedVariables(loopInstruction.body(), boundVariables); } - case NamespaceFieldStoreInstruction namespaceFieldStoreInstruction -> { + case ShidNamespaceFieldStore namespaceFieldStoreInstruction -> { } - case NamespaceImportInstruction namespaceImportInstruction -> { + case ShidNamespaceImport namespaceImportInstruction -> { } - case PushBoolInstruction pushBoolInstruction -> { + case ShidPushBool pushBoolInstruction -> { } - case PushIntInstruction pushIntInstruction -> { + case ShidPushInt pushIntInstruction -> { } - case PushStringInstruction pushStringInstruction -> { + case ShidPushString pushStringInstruction -> { } - case PushUnitInstruction pushUnitInstruction -> { + case ShidPushUnit pushUnitInstruction -> { } - case ResumeInstruction resumeInstruction -> { + case ShidResume resumeInstruction -> { } - case ReturnInstruction returnInstruction -> { + case ShidReturn returnInstruction -> { } - case StringAddInstruction stringAddInstruction -> { + case ShidStringAdd stringAddInstruction -> { } - case SwitchInstruction switchInstruction -> { + case ShidSwitch switchInstruction -> { for (var switchCase : switchInstruction.cases()) { boundVariables = findAssignedVariables(switchCase.body(), boundVariables); } } - case TryInstruction tryInstruction -> { + case ShidTry tryInstruction -> { boundVariables = findAssignedVariables(tryInstruction.body(), boundVariables); } - case TupleCreateInstruction tupleCreateInstruction -> { + case ShidTupleCreate tupleCreateInstruction -> { } - case TupleGetInstruction tupleGetInstruction -> { + case ShidTupleGet tupleGetInstruction -> { } - case VarLoadInstruction varLoadInstruction -> { + case ShidVarLoad varLoadInstruction -> { } - case VarStoreInstruction varStoreInstruction -> { + case ShidVarStore varStoreInstruction -> { boundVariables = boundVariables.plus(BoundVariable.mutable(varStoreInstruction.name())); } } diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenClosures.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenClosures.java index 961eeef0..abc89e10 100644 --- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenClosures.java +++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenClosures.java @@ -9,7 +9,7 @@ import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; import org.shedlang.compiler.patio.ast.operands.PatioOperand; import org.shedlang.compiler.patio.ast.types.*; import org.shedlang.compiler.sources.Source; -import org.shedlang.compiler.stackir.instructions.DefineFunctionInstruction; +import org.shedlang.compiler.shid.instructions.ShidDefineFunction; import java.util.ArrayList; import java.util.List; @@ -53,7 +53,7 @@ class PatioCodeGenClosures { FreeVariable freeVariable, PatioCodeGenContext context ) { - var local = context.stackIrLocalNameToLocal(freeVariable.name()); + var local = context.shidLocalNameToLocal(freeVariable.name()); return context.localType(local); } @@ -64,8 +64,8 @@ class PatioCodeGenClosures { public static PatioCodeGenContext create( PatioLocalRef target, String name, - List positionalParams, - List namedParams, + List positionalParams, + List namedParams, FreeVariables freeVariables, Function generateBody, Source source, @@ -90,14 +90,14 @@ class PatioCodeGenClosures { bodyContext = closurePointerResult.context(); var orderedNamedParams = sortedBy(namedParams, param -> param.name()); - var stackIrParams = Stream.concat(positionalParams.stream(), orderedNamedParams.stream()).toList(); + var shidParams = Stream.concat(positionalParams.stream(), orderedNamedParams.stream()).toList(); - for (var stackIrParam : stackIrParams) { - bodyContext = bodyContext.defineStackIrParam(stackIrParam.name()); + for (var shidParam : shidParams) { + bodyContext = bodyContext.defineShidParam(shidParam.name()); } for (var freeVariable : freeVariables) { - var freeVariableLocalResult = bodyContext.declareStackIrVal( + var freeVariableLocalResult = bodyContext.declareShidVal( freeVariable.name(), freeVariableType(freeVariable, bodyContextParent) ); @@ -112,7 +112,7 @@ class PatioCodeGenClosures { source )); - bodyContext = bodyContext.initStackIrLocal(freeVariable.name()); + bodyContext = bodyContext.initShidLocal(freeVariable.name()); } bodyContext = generateBody.apply(bodyContext); @@ -145,13 +145,13 @@ class PatioCodeGenClosures { )); for (var freeVariable : freeVariables) { - context = context.onceStackIrLocalDefined( + context = context.onceShidLocalDefined( freeVariable.name(), c -> c.addInstruction(new PatioMemoryStore( closurePointer, layout, freeVariableOffset(freeVariable), - c.stackIrLocalNameToLocal(freeVariable.name()), + c.shidLocalNameToLocal(freeVariable.name()), source )) ); diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenContext.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenContext.java index cfb075c3..545a198f 100644 --- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenContext.java +++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenContext.java @@ -184,8 +184,8 @@ public record PatioCodeGenContext( PStack temporaryStack, PVector instructions, OrderedPMap localsByName, - PMap stackIrNameToLocal, - PMap>> waitingForStackIrLocal + PMap shidNameToLocal, + PMap>> waitingForShidLocal ) { public static final FunctionContext EMPTY = new FunctionContext( P.stack(), @@ -201,8 +201,8 @@ public record PatioCodeGenContext( this.temporaryStack.minus(0), this.instructions, this.localsByName, - this.stackIrNameToLocal, - this.waitingForStackIrLocal + this.shidNameToLocal, + this.waitingForShidLocal ).toResult(this.temporaryStack.get(0)); } @@ -212,8 +212,8 @@ public record PatioCodeGenContext( this.temporaryStack.plus(value), this.instructions, this.localsByName, - this.stackIrNameToLocal, - this.waitingForStackIrLocal + this.shidNameToLocal, + this.waitingForShidLocal ); } @@ -223,8 +223,8 @@ public record PatioCodeGenContext( this.temporaryStack, this.instructions.plus(instruction), this.localsByName, - this.stackIrNameToLocal, - this.waitingForStackIrLocal + this.shidNameToLocal, + this.waitingForShidLocal ); } @@ -244,22 +244,22 @@ public record PatioCodeGenContext( this.temporaryStack, this.instructions, this.localsByName.plus(fullName, createLocal.apply(fullName)), - this.stackIrNameToLocal, - this.waitingForStackIrLocal + this.shidNameToLocal, + this.waitingForShidLocal ).toResult(new PatioLocalRef(fullName)); } @CheckReturnValue - public FunctionContext.Result declareStackIrLocal( + public FunctionContext.Result declareShidLocal( String name, PatioType type, PatioLocalType localType ) { var context = this; - if (this.stackIrNameToLocal.containsKey(name)) { + if (this.shidNameToLocal.containsKey(name)) { // TODO: better error - throw new RuntimeException("Stack IR local already exists: " + name); + throw new RuntimeException("Shid local already exists: " + name); } var fullName = NameAllocator.allocateFixedName( @@ -278,48 +278,48 @@ public record PatioCodeGenContext( new PatioLocal(fullName, type, localType) ), // TODO: the mapping is redundant given we fix the mapping - this.stackIrNameToLocal.plus(name, localRef), - this.waitingForStackIrLocal.plus(name, P.vector()) + this.shidNameToLocal.plus(name, localRef), + this.waitingForShidLocal.plus(name, P.vector()) ); return context.toResult(localRef); } @CheckReturnValue - public FunctionContext.Result>> initStackIrLocal(String name) { + public FunctionContext.Result>> initShidLocal(String name) { var context = new FunctionContext( this.temporaryStack, this.instructions, this.localsByName, - this.stackIrNameToLocal, - this.waitingForStackIrLocal.minus(name) + this.shidNameToLocal, + this.waitingForShidLocal.minus(name) ); - return context.toResult(this.waitingForStackIrLocal.getOrDefault(name, P.vector())); + return context.toResult(this.waitingForShidLocal.getOrDefault(name, P.vector())); } @CheckReturnValue - public PatioLocalRef stackIrLocalNameToLocal(String name) { - var local = this.stackIrNameToLocal.get(name); + public PatioLocalRef shidLocalNameToLocal(String name) { + var local = this.shidNameToLocal.get(name); if (local == null) { // TODO: better error - throw new RuntimeException("Unknown stack IR local: " + name); + throw new RuntimeException("Unknown Shid local: " + name); } return local; } @CheckReturnValue - public Optional stackIrLocalNameToLocalOrNone(String name) { - var local = this.stackIrNameToLocal.get(name); + public Optional shidLocalNameToLocalOrNone(String name) { + var local = this.shidNameToLocal.get(name); return Optional.ofNullable(local); } @CheckReturnValue - public boolean isStackIrLocalDefined(String name) { - return !this.waitingForStackIrLocal.containsKey(name); + public boolean isShidLocalDefined(String name) { + return !this.waitingForShidLocal.containsKey(name); } @CheckReturnValue @@ -329,7 +329,7 @@ public record PatioCodeGenContext( } @CheckReturnValue - public FunctionContext addWaitingForShedLocal( + public FunctionContext addWaitingForShidLocal( String name, Function func ) { @@ -337,10 +337,10 @@ public record PatioCodeGenContext( this.temporaryStack, this.instructions, this.localsByName, - this.stackIrNameToLocal, - this.waitingForStackIrLocal.plus( + this.shidNameToLocal, + this.waitingForShidLocal.plus( name, - this.waitingForStackIrLocal.getOrDefault(name, P.vector()).plus(func) + this.waitingForShidLocal.getOrDefault(name, P.vector()).plus(func) ) ); } @@ -514,13 +514,13 @@ public record PatioCodeGenContext( } @CheckReturnValue - public PatioCodeGenContext defineStackIrParam(String name) { - return declareStackIrParam(name).initStackIrLocal(name); + public PatioCodeGenContext defineShidParam(String name) { + return declareShidParam(name).initShidLocal(name); } @CheckReturnValue - private PatioCodeGenContext declareStackIrParam(String name) { - return declareStackIrLocal( + private PatioCodeGenContext declareShidParam(String name) { + return declareShidLocal( name, PatioCodeGenTypes.VALUE_TYPE, PatioLocalType.PARAM @@ -528,8 +528,8 @@ public record PatioCodeGenContext( } @CheckReturnValue - public PatioCodeGenResult declareStackIrVal(String name, PatioType type) { - return declareStackIrLocal( + public PatioCodeGenResult declareShidVal(String name, PatioType type) { + return declareShidLocal( name, type, PatioLocalType.VAL @@ -537,12 +537,12 @@ public record PatioCodeGenContext( } @CheckReturnValue - public PatioCodeGenResult declareStackIrLocal( + public PatioCodeGenResult declareShidLocal( String name, PatioType type, PatioLocalType patioLocalType ) { - return withFunctionContextResult(this.functionContext.declareStackIrLocal( + return withFunctionContextResult(this.functionContext.declareShidLocal( name, type, patioLocalType @@ -550,8 +550,8 @@ public record PatioCodeGenContext( } @CheckReturnValue - public PatioCodeGenContext initStackIrLocal(String name) { - var result = this.functionContext.initStackIrLocal(name); + public PatioCodeGenContext initShidLocal(String name) { + var result = this.functionContext.initShidLocal(name); var context = withFunctionContext(result.context); for (var func : result.value) { @@ -562,18 +562,18 @@ public record PatioCodeGenContext( } @CheckReturnValue - public PatioCodeGenContext onceStackIrLocalDefined( + public PatioCodeGenContext onceShidLocalDefined( String name, Function func ) { - var local = this.functionContext.stackIrLocalNameToLocalOrNone(name); + var local = this.functionContext.shidLocalNameToLocalOrNone(name); if (local.isEmpty()) { // TODO: better error - throw new RuntimeException("Unknown stack IR local: " + name); - } else if (!this.functionContext.isStackIrLocalDefined(name)) { + throw new RuntimeException("Unknown Shid local: " + name); + } else if (!this.functionContext.isShidLocalDefined(name)) { return withFunctionContext( - this.functionContext.addWaitingForShedLocal(name, func) + this.functionContext.addWaitingForShidLocal(name, func) ); } else { return func.apply(this); @@ -581,8 +581,8 @@ public record PatioCodeGenContext( } @CheckReturnValue - public PatioLocalRef stackIrLocalNameToLocal(String name) { - return this.functionContext.stackIrLocalNameToLocal(name); + public PatioLocalRef shidLocalNameToLocal(String name) { + return this.functionContext.shidLocalNameToLocal(name); } @CheckReturnValue @@ -634,8 +634,8 @@ public record PatioCodeGenContext( P.stack(), P.vector(), this.functionContext.localsByName, - this.functionContext.stackIrNameToLocal, - this.functionContext.waitingForStackIrLocal + this.functionContext.shidNameToLocal, + this.functionContext.waitingForShidLocal ) ); } @@ -654,8 +654,8 @@ public record PatioCodeGenContext( this.blockStack.get(0).temporaryStack, this.blockStack.get(0).instructions, this.functionContext.localsByName, - this.functionContext.stackIrNameToLocal, - this.functionContext.waitingForStackIrLocal + this.functionContext.shidNameToLocal, + this.functionContext.waitingForShidLocal ) ).toResult(this.functionContext.instructions); } diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenEffects.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenEffects.java index 4eb842b2..5f32e90e 100644 --- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenEffects.java +++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenEffects.java @@ -13,7 +13,7 @@ import org.shedlang.compiler.patio.ast.types.PatioType; import org.shedlang.compiler.patio.ast.types.PatioTypes; import org.shedlang.compiler.sources.Source; import org.shedlang.compiler.sources.Sources; -import org.shedlang.compiler.stackir.instructions.DefineFunctionInstruction; +import org.shedlang.compiler.shid.instructions.ShidDefineFunction; import org.shedlang.compiler.types.UserDefinedEffect; import org.shedlang.compiler.util.Lists; @@ -104,7 +104,7 @@ public class PatioCodeGenEffects { var positionalParams = IntStream.range(0, method.type().positionalParams().size()) // TODO: ensure names of positional params doesn't clash with named params - .mapToObj(paramIndex -> new DefineFunctionInstruction.Param("arg" + paramIndex, source)) + .mapToObj(paramIndex -> new ShidDefineFunction.Param("arg" + paramIndex, source)) .toList(); context = PatioCodeGenClosures.create( @@ -112,7 +112,7 @@ public class PatioCodeGenEffects { method.name(), positionalParams, method.type().namedParams().stream() - .map(namedParam -> new DefineFunctionInstruction.Param(namedParam.name(), source)) + .map(namedParam -> new ShidDefineFunction.Param(namedParam.name(), source)) .toList(), FreeVariables.empty(), bodyContext -> { @@ -147,12 +147,12 @@ public class PatioCodeGenEffects { returnValue, handlerMethod, positionalParams.stream() - .map(param -> bodyContextArgs.stackIrLocalNameToLocal(param.name())) + .map(param -> bodyContextArgs.shidLocalNameToLocal(param.name())) .toList(), method.type().namedParams().stream() .map(param -> Map.entry( param.name(), - bodyContextArgs.stackIrLocalNameToLocal(param.name()) + bodyContextArgs.shidLocalNameToLocal(param.name()) )) .toList(), source, diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenStructs.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenStructs.java index 92081325..6ef49080 100644 --- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenStructs.java +++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenStructs.java @@ -8,8 +8,8 @@ import org.shedlang.compiler.patio.ast.types.PatioDataLayout; import org.shedlang.compiler.patio.ast.types.PatioDataLayouts; import org.shedlang.compiler.patio.ast.types.PatioTypes; import org.shedlang.compiler.sources.Source; -import org.shedlang.compiler.stackir.instructions.DefineFunctionInstruction; -import org.shedlang.compiler.stackir.instructions.DefineStructInstruction; +import org.shedlang.compiler.shid.instructions.ShidDefineFunction; +import org.shedlang.compiler.shid.instructions.ShidDefineStruct; import org.shedlang.compiler.types.StructType; import org.shedlang.compiler.util.Lists; @@ -22,7 +22,7 @@ public class PatioCodeGenStructs { public static PatioCodeGenContext createType( PatioLocalRef target, StructType type, - List fields, + List fields, Source source, PatioCodeGenContext context ) { @@ -31,7 +31,7 @@ public class PatioCodeGenStructs { type.name(), List.of(), fields.stream() - .map(field -> new DefineFunctionInstruction.Param(field.name(), field.source())) + .map(field -> new ShidDefineFunction.Param(field.name(), field.source())) .toList(), FreeVariables.empty(), bodyContext -> { @@ -67,7 +67,7 @@ public class PatioCodeGenStructs { valuePointer, structDataLayout, List.of(1, fieldIndex), - bodyContext.stackIrLocalNameToLocal(field.name()), + bodyContext.shidLocalNameToLocal(field.name()), source )); } diff --git a/src/main/java/org/shedlang/compiler/shid/InstructionSerializer.java b/src/main/java/org/shedlang/compiler/shid/InstructionSerializer.java new file mode 100644 index 00000000..afbccf6c --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/InstructionSerializer.java @@ -0,0 +1,280 @@ +package org.shedlang.compiler.shid; + +import org.shedlang.compiler.shid.instructions.*; +import org.shedlang.compiler.treetext.Tree; +import org.shedlang.compiler.types.StructType; +import org.shedlang.compiler.types.UserDefinedEffect; + +import java.util.List; + +import static org.shedlang.compiler.treetext.TreeSerializer.serializeTree; +import static org.shedlang.compiler.treetext.Trees.*; + +public class InstructionSerializer { + private InstructionSerializer() { + } + + public static void serializeInstructions(List instructions, StringBuilder builder) { + var tree = instructionsToTree(instructions); + serializeTree(tree, builder, 0); + } + + public static void serializeInstruction(ShidInstruction instruction, StringBuilder builder) { + var tree = instructionToTree(instruction); + serializeTree(tree, builder, 0); + } + + private static Tree instructionsToTree(List instructions) { + return treeListIndented( + instructions.stream() + .map(instruction -> instructionToTree(instruction)) + .toList() + ); + } + + private static Tree instructionToTree(ShidInstruction instruction) { + return switch (instruction) { + case ShidCall callInstruction -> + treeList( + treeIdentifier("call"), + treeNamed( + "positional-arg-count", + treeInt(callInstruction.positionalArgCount()) + ), + treeNamed( + "named-arg-names", + treeList( + callInstruction.namedArgNames().stream() + .map(arg -> treeString(arg)) + .toList() + ) + ) + ); + + case ShidDefineEffect defineEffectInstruction -> + treeList( + treeIdentifier("define-effect"), + userDefinedEffectToTree(defineEffectInstruction.effect()) + ); + + case ShidDefineFunction defineFunctionInstruction -> + treeListIndented( + treeIdentifier("define-function"), + treeNamed("name", treeString(defineFunctionInstruction.name())), + treeNamed("positional-params", treeList( + defineFunctionInstruction.positionalParams().stream() + .map(param -> treeString(param.name())) + .toList() + )), + treeNamed("named-params", treeList( + defineFunctionInstruction.namedParams().stream() + .map(param -> treeString(param.name())) + .toList() + )), + treeNamed("free-variables", treeList( + defineFunctionInstruction.freeVariables().stream() + .map(freeVariable -> treeString(freeVariable.name())) + .toList() + )), + treeNamed("body", instructionsToTree(defineFunctionInstruction.body())) + ); + + case ShidDefineStruct defineStructInstruction -> + treeListIndented( + treeIdentifier("define-struct"), + treeNamed("type", structTypeToTree(defineStructInstruction.type())), + treeNamed("fields", treeList( + defineStructInstruction.fields().stream() + .map(field -> treeString(field.name())) + .toList() + )) + ); + + case ShidDiscard discardInstruction -> + treeList( + treeIdentifier("discard") + ); + + case ShidDuplicate duplicate -> + treeList( + treeIdentifier("duplicate") + ); + + case ShidFieldLoad fieldLoad -> + treeList( + treeIdentifier("field-load"), + switch (fieldLoad.receiver()) { + case ShidFieldLoad.Receiver.Effect effect -> + treeList( + treeIdentifier("effect"), + userDefinedEffectToTree(effect.effect()) + ); + + case ShidFieldLoad.Receiver.Namespace namespace -> + treeList( + treeIdentifier("namespace"), + treeString(namespace.name().toString()) + ); + + case ShidFieldLoad.Receiver.Struct struct -> + treeList( + treeIdentifier("struct"), + structTypeToTree(struct.type()) + ); + }, + treeString(fieldLoad.fieldName()) + ); + + case ShidIf if_ -> + treeListIndented( + treeIdentifier("if"), + treeNamed("result-count", treeInt(if_.resultCount())), + instructionsToTree(if_.trueBody()), + instructionsToTree(if_.falseBody()) + ); + + case ShidIntAdd intAdd -> + treeList(treeIdentifier("int-add")); + + case ShidIntEquals intEquals -> + treeList(treeIdentifier("int-eq")); + + case ShidIntNotEqual intNotEqual -> + treeList(treeIdentifier("int-ne")); + + case ShidIntSub intSub -> + treeList(treeIdentifier("int-sub")); + + case ShidLocalLoad localLoadInstruction -> + treeList( + treeIdentifier("local-load"), + treeString(localLoadInstruction.name()) + ); + + case ShidLocalStore localStoreInstruction -> + treeList( + treeIdentifier("local-store"), + treeString(localStoreInstruction.name()) + ); + + case ShidLoop loop -> + treeListIndented( + treeIdentifier("loop"), + instructionsToTree(loop.body()) + ); + + case ShidLoopBreak loopBreak -> + treeList(treeIdentifier("break")); + + case ShidLoopContinue loopContinue -> + treeList(treeIdentifier("continue")); + + case ShidNamespaceFieldStore namespaceFieldStore -> + treeList( + treeIdentifier("namespace-field-store"), + treeString(namespaceFieldStore.namespaceName().toString()), + treeString(namespaceFieldStore.fieldName()) + ); + + case ShidNamespaceImport namespaceImport -> + treeList( + treeIdentifier("namespace-import"), + treeString(namespaceImport.namespaceName().toString()) + ); + + case ShidPushBool pushBoolInstruction -> + treeList( + treeIdentifier("push-bool"), + treeIdentifier(Boolean.toString(pushBoolInstruction.value())) + ); + + case ShidPushInt pushIntInstruction -> + treeList( + treeIdentifier("push-int"), + treeIdentifier(pushIntInstruction.value().toString()) + ); + + case ShidPushString pushStringInstruction -> + treeList( + treeIdentifier("push-string"), + treeString(pushStringInstruction.value()) + ); + + case ShidPushUnit pushUnitInstruction -> + treeList( + treeIdentifier("push-unit") + ); + + case ShidResume resumeInstruction -> + treeList( + treeIdentifier("resume") + ); + + case ShidReturn returnInstruction -> + treeList( + treeIdentifier("return") + ); + + case ShidStringAdd stringAddInstruction -> + treeList(treeIdentifier("string-add")); + + case ShidSwitch switchInstruction -> + treeListIndented( + treeIdentifier("switch"), + treeListIndented( + switchInstruction.cases().stream() + .map(switchCase -> treeListIndented( + structTypeToTree(switchCase.caseType()), + instructionsToTree(switchCase.body()) + )) + .toList() + ) + ); + + case ShidTry tryInstruction -> + treeListIndented( + treeIdentifier("try"), + userDefinedEffectToTree(tryInstruction.handledEffect()), + treeListIndented( + tryInstruction.handlerMethodNames().stream() + .map(name -> treeString(name)) + .toList() + ), + instructionsToTree(tryInstruction.body()) + ); + + case ShidTupleCreate tupleCreateInstruction -> + treeList( + treeIdentifier("tuple-create"), + treeInt(tupleCreateInstruction.elementCount()) + ); + + case ShidTupleGet tupleGetInstruction -> + treeList( + treeIdentifier("tuple-get"), + treeInt(tupleGetInstruction.elementIndex()), + treeInt(tupleGetInstruction.elementCount()) + ); + + case ShidVarLoad varLoadInstruction -> + treeList( + treeIdentifier("var-load"), + treeString(varLoadInstruction.name()) + ); + + case ShidVarStore varStoreInstruction -> + treeList( + treeIdentifier("var-store"), + treeString(varStoreInstruction.name()) + ); + }; + } + + private static Tree userDefinedEffectToTree(UserDefinedEffect effect) { + return treeString(effect.describe()); + } + + private static Tree structTypeToTree(StructType type) { + return treeString(type.describe()); + } +} diff --git a/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java b/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java new file mode 100644 index 00000000..47190813 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java @@ -0,0 +1,848 @@ +package org.shedlang.compiler.shid; + +import org.pcollections.*; +import org.shedlang.compiler.ShedBuiltins; +import org.shedlang.compiler.ast.typed.*; +import org.shedlang.compiler.sources.Source; +import org.shedlang.compiler.shid.instructions.*; +import org.shedlang.compiler.types.*; +import org.shedlang.compiler.util.Iterables; +import org.shedlang.compiler.util.P; + +import java.util.ArrayList; +import java.util.List; + +public class ShidCodeGen { + private ShidCodeGen() { + } + + private static Context compileAssign(TypedAssignNode node, Context context) { + context = compileExpression(node.expression(), context); + context = compileTarget(node.target(), context); + return context; + } + + private static Context compileBinaryOperation( + TypedBinaryOperationNode node, + Context context + ) { + context = compileExpression(node.left(), context); + + context = compileExpression(node.right(), context); + + context = context.addInstruction(switch (node.operator()) { + case INT_ADD -> + new ShidIntAdd(node.source()); + case INT_EQUALS -> + new ShidIntEquals(node.source()); + case INT_NOT_EQUAL -> + new ShidIntNotEqual(node.source()); + case INT_SUB -> + new ShidIntSub(node.source()); + case STRING_ADD -> + new ShidStringAdd(node.source()); + }); + + return context; + } + + static Context compileBlockWithYield(TypedBlockNode node, Context context) { + for (var statement : node.statements()) { + context = compileFunctionStatement(statement, context); + } + + switch (node.behaviour()) { + case TypedFunctionStatementBehaviour.BlockReturn blockReturn -> { + } + case TypedFunctionStatementBehaviour.Continue continue_ -> { + context = context.addInstruction(new ShidPushUnit(node.source())); + } + case TypedFunctionStatementBehaviour.Terminate terminate -> { + } + } + + return context; + } + + static Context compileBlockWithoutYield(TypedBlockNode node, Context context) { + for (var statement : node.statements()) { + context = compileFunctionStatement(statement, context); + } + + switch (node.behaviour()) { + case TypedFunctionStatementBehaviour.BlockReturn blockReturn -> { + context = context.addInstruction(new ShidDiscard(node.source())); + } + case TypedFunctionStatementBehaviour.Continue continue_ -> { + } + case TypedFunctionStatementBehaviour.Terminate terminate -> { + } + } + + return context; + } + + private static Context compileBlockReturn(TypedBlockReturnNode blockReturn, Context context) { + return compileExpression(blockReturn.expression(), context); + } + + private static Context compileBoolLiteral(TypedBoolLiteralNode node, Context context) { + return context.addInstruction(new ShidPushBool(node.value(), node.source())); + } + + private static Context compileCall(TypedCallNode node, Context context) { + context = compileExpression(node.receiver(), context); + + for (var arg : node.args().positional()) { + context = compileExpression(arg, context); + } + + for (var arg : node.args().named()) { + context = compileExpression(arg.expression(), context); + } + + var callInstruction = new ShidCall( + node.args().positional().size(), + node.args().named().stream() + .map(arg -> arg.name()) + .toList(), + node.source() + ); + + context = context.addInstruction(callInstruction); + + return context; + } + + private static Context compileEffectDefinition( + TypedEffectDefinitionNode node, + Context context + ) { + var localName = context.shedVariableToLocal(node.effect().name()); + + return context + .addInstruction(new ShidDefineEffect(node.effect(), node.source())) + .addInstruction(new ShidLocalStore(localName, node.source())); + } + + public static Context compileExpression(TypedExpressionNode node, Context context) { + return switch (node) { + case TypedBinaryOperationNode typedBinaryOperationNode -> + compileBinaryOperation(typedBinaryOperationNode, context); + + case TypedBoolLiteralNode typedBoolLiteralNode -> + compileBoolLiteral(typedBoolLiteralNode, context); + + case TypedCallNode typedCallNode -> + compileCall(typedCallNode, context); + + case TypedFieldAccessNode typedFieldAccessNode -> + compileFieldAccess(typedFieldAccessNode, context); + + case TypedFunctionExpressionNode typedFunctionExpressionNode -> + compileFunctionExpression(typedFunctionExpressionNode, context); + + case TypedIfNode typedIfNode -> + compileIf(typedIfNode, context); + + case TypedIntLiteralNode typedIntLiteralNode -> + compileIntLiteral(typedIntLiteralNode, context); + + case TypedReferenceNode typedReferenceNode -> + compileReference(typedReferenceNode, context); + + case TypedStringLiteralNode typedStringLiteralNode -> + compileStringLiteral(typedStringLiteralNode, context); + + case TypedTryNode typedTryNode -> + compileTry(typedTryNode, context); + + case TypedTupleNode typedTupleNode -> + compileTuple(typedTupleNode, context); + + case TypedUnitLiteralNode typedUnitLiteralNode -> + compileUnitLiteral(typedUnitLiteralNode, context); + + case TypedWhenNode typedWhenNode -> + compileWhen(typedWhenNode, context); + }; + } + + private static Context compileExpressionStatement( + TypedExpressionStatementNode node, + Context context + ) { + context = compileExpression(node.expression(), context); + context = context.addInstruction(new ShidDiscard(node.source())); + return context; + } + + private static Context compileFieldAccess( + TypedFieldAccessNode node, + Context context + ) { + context = compileExpression(node.receiver(), context); + // TODO: handle not a type with fields + var receiver = switch (node.receiver().type()) { + case NamespaceType namespaceType -> + new ShidFieldLoad.Receiver.Namespace(namespaceType.namespaceName()); + + case StructType structType -> + new ShidFieldLoad.Receiver.Struct(structType); + + case TypeLevelValueType typeLevelValueType -> { + if (typeLevelValueType.value() instanceof UserDefinedEffect effect) { + yield new ShidFieldLoad.Receiver.Effect(effect); + } else { + throw new RuntimeException("not a type with fields"); + } + } + + default -> + throw new RuntimeException("not a type with fields"); + }; + + context = context.addInstruction(new ShidFieldLoad( + receiver, + node.fieldName(), + node.source() + )); + return context; + } + + private static Context compileFunction( + String name, + TypedParamsNode params, + TypedFunctionBodyNode body, + Source source, + Context context + ) { + context = context.enterBlock(body.boundVariables()); + + var c = context; + + var positionalParams = params.positional().stream() + .map(param -> new ShidDefineFunction.Param( + c.shedVariableToLocal(param.name()), + param.source() + )) + .toList(); + + var namedParams = params.named().stream() + .map(param -> new ShidDefineFunction.Param( + c.shedVariableToLocal(param.name()), + param.source() + )) + .toList(); + + context = compileBlockWithYield(body.block(), context); + + switch (body.behaviour()) { + case TypedFunctionStatementBehaviour.BlockReturn blockReturn -> { + context = context.addInstruction(new ShidReturn(body.source())); + } + case TypedFunctionStatementBehaviour.Continue continue_ -> { + context = context.addInstruction(new ShidReturn(body.source())); + } + case TypedFunctionStatementBehaviour.Terminate terminate -> { + } + } + + var bodyInstructions = context.instructions; + + context = context.exitBlock(); + + var freeVariables = FreeVariables.builder(); + for (var shedFreeVariable : body.freeVariables()) { + var freeVariableLocalName = context.shedVariableToLocal(shedFreeVariable.name()); + for (var freeVariableSource : shedFreeVariable.referenceSources()) { + freeVariables = freeVariables.plus( + freeVariableLocalName, + freeVariableSource + ); + } + } + + var defineFunctionInstruction = new ShidDefineFunction( + name, + positionalParams, + namedParams, + freeVariables.build(), + bodyInstructions, + source + ); + + return context.addInstruction(defineFunctionInstruction); + } + + private static Context compileFunctionDefinition( + TypedFunctionDefinitionNode node, + Context context + ) { + context = compileFunction( + node.name(), + node.signature().params(), + node.body(), + node.source(), + context + ); + + var localName = context.shedVariableToLocal(node.name()); + var storeInstruction = new ShidLocalStore(localName, node.source()); + + return context.addInstruction(storeInstruction); + } + + private static Context compileFunctionExpression( + TypedFunctionExpressionNode node, + Context context + ) { + return compileFunction( + // TODO: include source location? + "anonymous", + node.signature().params(), + node.body(), + node.source(), + context + ); + } + + private static Context compileFunctionReturn( + TypedFunctionReturnNode node, + Context context + ) { + context = compileExpression(node.expression(), context); + context = context.addInstruction(new ShidReturn(node.source())); + return context; + } + + public static Context compileFunctionStatement( + TypedFunctionStatementNode node, + Context context + ) { + return switch (node) { + case TypedAssignNode assign -> + compileAssign(assign, context); + + case TypedBlockReturnNode blockReturn -> + compileBlockReturn(blockReturn, context); + + case TypedExpressionStatementNode expressionStatement -> + compileExpressionStatement(expressionStatement, context); + + case TypedFunctionReturnNode functionReturn -> + compileFunctionReturn(functionReturn, context); + + case TypedResumeNode resume -> + compileResume(resume, context); + + case TypedWhileNode while_ -> + compileWhile(while_, context); + }; + } + + private static Context compileIf(TypedIfNode node, Context context) { + return compileIf( + node.conditionalBranches(), + node.elseBody(), + context + ); + } + + private static Context compileIf( + List conditionalBranches, + TypedBlockNode elseBody, + Context context + ) { + if (conditionalBranches.isEmpty()) { + context = context.enterBlock(elseBody.boundVariables()); + context = compileBlockWithYield(elseBody, context); + var elseInstructions = context.instructions; + context = context.exitBlock(); + for (var instruction : elseInstructions) { + context = context.addInstruction(instruction); + } + } else { + var conditionalBranch = conditionalBranches.get(0); + context = compileExpression(conditionalBranch.condition(), context); + + context = context.enterBlock(conditionalBranch.body().boundVariables()); + context = compileBlockWithYield(conditionalBranch.body(), context); + var ifTrueInstructions = context.instructions; + context = context.exitBlock(); + + context = context.enterBlock(List.of()); + context = compileIf( + conditionalBranches.subList(1, conditionalBranches.size()), + elseBody, + context + ); + var ifFalseInstructions = context.instructions; + context = context.exitBlock(); + + context = context.addInstruction(new ShidIf( + 1, + ifTrueInstructions, + ifFalseInstructions, + conditionalBranch.source() + )); + } + + return context; + } + + private static Context compileIntLiteral(TypedIntLiteralNode node, Context context) { + return context.addInstruction(new ShidPushInt(node.value(), node.source())); + } + + public static ShidNamespace compileNamespace(TypedNamespaceNode node) { + var context = Context.EMPTY; + + context = context.addShedVal(ShedBuiltins.PRINT_NAME); + var printLocalName = context.shedVariableToLocal(ShedBuiltins.PRINT_NAME); + + context = context + .addInstruction(new ShidNamespaceImport(ShedBuiltins.NAMESPACE_NAME, node.source())) + .addInstruction(new ShidFieldLoad( + new ShidFieldLoad.Receiver.Namespace(ShedBuiltins.NAMESPACE_NAME), + ShedBuiltins.PRINT_NAME, + node.source() + )) + .addInstruction(new ShidLocalStore(printLocalName, node.source())); + + for (var boundVariable : node.boundVariables()) { + context = context.addShedVariable(boundVariable); + } + + for (var importNode : node.imports()) { + var localName = context.shedVariableToLocal(importNode.variableName()); + context = context + .addInstruction(new ShidNamespaceImport( + importNode.namespaceName(), + importNode.source() + )) + .addInstruction(new ShidLocalStore( + localName, + importNode.source() + )); + + } + + var statementsAfterHoisting = Iterables.sortedBy(node.body(), statement -> switch (statement) { + case TypedAssignNode assign -> + 1; + + case TypedEffectDefinitionNode effectDefinition -> + 0; + + case TypedFunctionDefinitionNode functionDefinition -> + 1; + + case TypedStructDefinitionNode structDefinition -> + 0; + + case TypedSumTypeDefinitionNode sumTypeDefinition -> + 0; + }); + for (var statement : statementsAfterHoisting) { + context = compileNamespaceStatement(statement, context); + } + + for (var fieldName : node.fieldNames()) { + var localName = context.shedVariableToLocal(fieldName); + + context = context + .addInstruction(new ShidLocalLoad(localName, node.source())) + .addInstruction(new ShidNamespaceFieldStore( + node.namespaceName(), + fieldName, + node.source() + )); + } + + return new ShidNamespace(node.namespaceName(), context.instructions); + } + + public static Context compileNamespaceStatement(TypedNamespaceStatementNode node, Context context) { + return switch (node) { + case TypedAssignNode assign -> + compileAssign(assign, context); + + case TypedEffectDefinitionNode effectDefinition -> + compileEffectDefinition(effectDefinition, context); + + case TypedFunctionDefinitionNode functionDefinition -> + compileFunctionDefinition(functionDefinition, context); + + case TypedStructDefinitionNode structDefinition -> + compileStructDefinition(structDefinition, context); + + case TypedSumTypeDefinitionNode sumDefinition -> + compileSumTypeDefinition(sumDefinition, context); + }; + } + + private static Context compileReference(TypedReferenceNode node, Context context) { + var shedVariable = context.shedVariable(node.name()); + + if (shedVariable.isVar) { + return context.addInstruction(new ShidVarLoad( + shedVariable.shidLocalName, + node.source() + )); + } else { + return context.addInstruction(new ShidLocalLoad( + shedVariable.shidLocalName, + node.source() + )); + } + } + + private static Context compileResume(TypedResumeNode node, Context context) { + context = compileExpression(node.expression(), context); + context = context.addInstruction(new ShidResume(node.source())); + return context; + } + + private static Context compileStringLiteral( + TypedStringLiteralNode node, + Context context + ) { + var instruction = new ShidPushString(node.value(), node.source()); + return context.addInstruction(instruction); + } + + private static Context compileStructDefinition( + TypedStructDefinitionNode node, + Context context + ) { + var defineStructInstruction = new ShidDefineStruct( + node.type(), + node.fields().stream() + .map(field -> new ShidDefineStruct.Field(field.name(), field.source())) + .toList(), + node.source() + ); + + var localName = context.shedVariableToLocal(node.type().name()); + var storeInstruction = new ShidLocalStore(localName, node.source()); + + return context + .addInstruction(defineStructInstruction) + .addInstruction(storeInstruction); + } + + private static Context compileSumTypeDefinition( + TypedSumTypeDefinitionNode node, + Context context + ) { + var defineSumTypeInstruction = new ShidPushUnit(node.source()); + + var localName = context.shedVariableToLocal(node.type().name()); + var storeInstruction = new ShidLocalStore(localName, node.source()); + + return context + .addInstruction(defineSumTypeInstruction) + .addInstruction(storeInstruction); + } + + private static Context compileTarget( + TypedTargetNode target, + Context context + ) { + return switch (target) { + case TypedTargetNode.Ignore ignore -> { + yield context.addInstruction(new ShidDiscard(ignore.source())); + } + + case TypedTargetNode.Reassign reassign -> { + context = context.addInstruction( + new ShidVarStore( + context.shedVariableToLocal(reassign.name()), + reassign.source() + ) + ); + + yield context; + } + + case TypedTargetNode.Tuple tuple -> { + if (tuple.elements().size() == 0) { + context = context.addInstruction(new ShidDiscard(tuple.source())); + } + + for (var elementIndex = 0; elementIndex < tuple.elements().size(); elementIndex++) { + if (elementIndex < tuple.elements().size() - 1) { + context = context + .addInstruction(new ShidDuplicate(tuple.source())); + } + + context = context + .addInstruction(new ShidTupleGet( + elementIndex, + tuple.elements().size(), + tuple.source() + )); + + context = compileTarget(tuple.elements().get(elementIndex), context); + } + + yield context; + } + + case TypedTargetNode.Val val -> { + context = context.addInstruction( + new ShidLocalStore( + context.shedVariableToLocal(val.name()), + val.source() + ) + ); + + yield context; + } + + case TypedTargetNode.Var var -> { + context = context.addInstruction( + new ShidVarStore( + context.shedVariableToLocal(var.name()), + var.source() + ) + ); + + yield context; + } + }; + } + + private static Context compileTry(TypedTryNode node, Context context) { + for (var handlerMethod : node.handlerMethods()) { + context = compileTryHandlerMethod(handlerMethod, context); + } + + context = context.enterBlock(node.body().boundVariables()); + context = compileBlockWithYield(node.body(), context); + var bodyInstructions = context.instructions; + context = context.exitBlock(); + + var instruction = new ShidTry( + node.handledEffect().value(), + node.handlerMethods().stream() + .map(methodNode -> methodNode.name()) + .toList(), + bodyInstructions, + node.source() + ); + + return context.addInstruction(instruction); + } + + private static Context compileTryHandlerMethod( + TypedTryHandlerMethodNode node, + Context context + ) { + return compileFunction( + node.name(), + node.params(), + node.body(), + node.source(), + context + ); + } + + private static Context compileTuple(TypedTupleNode node, Context context) { + for (var elementNode : node.elements()) { + context = compileExpression(elementNode, context); + } + + var instruction = new ShidTupleCreate(node.elements().size(), node.source()); + return context.addInstruction(instruction); + } + + private static Context compileUnitLiteral( + TypedUnitLiteralNode node, + Context context + ) { + return context.addInstruction(new ShidPushUnit(node.source())); + } + + private static Context compileWhen(TypedWhenNode node, Context context) { + context = compileExpression(node.expression(), context); + + var switchCases = new ArrayList(); + + for (var whenCase : node.cases()) { + context = context.enterBlock(whenCase.body().boundVariables()); + context = compileBlockWithYield(whenCase.body(), context); + var caseBodyInstructions = context.instructions; + context = context.exitBlock(); + + var switchCase = new ShidSwitch.Case( + whenCase.caseType().value(), + caseBodyInstructions, + whenCase.source() + ); + switchCases.add(switchCase); + } + + context = context.addInstruction(new ShidSwitch( + switchCases, + node.source() + )); + + return context; + } + + private static Context compileWhile(TypedWhileNode node, Context context) { + context = context.enterBlock(node.body().boundVariables()); + context = compileBlockWithoutYield(node.body(), context); + var ifTrueInstructions = context.instructions; + context = context.exitBlock(); + + context = context.enterBlock(List.of()); + + context = compileExpression(node.condition(), context); + context = context.addInstruction(new ShidIf( + 0, + List.of(), + List.of( + new ShidLoopBreak(node.source()) + ), + node.source() + )); + + context = context.addInstructions(ifTrueInstructions); + + context = context.addInstruction(new ShidLoopContinue(node.source())); + + var bodyInstructions = context.instructions; + context = context.exitBlock(); + + context = context.addInstruction(new ShidLoop(bodyInstructions, node.source())); + + return context; + } + + public static class Context { + public static final Context EMPTY = new Context( + P.stack(), + P.vector(), + Empty.set(), + P.stack(), + P.map() + ); + + private final PStack> instructionsStack; + private final PVector instructions; + private final PSet localNames; + private final PStack> shedVariablesByNameStack; + private final PMap shedVariablesByName; + + private Context( + PStack> instructionsStack, + PVector instructions, + PSet localNames, + PStack> shedVariablesByNameStack, + PMap shedVariablesByName + ) { + this.instructionsStack = instructionsStack; + this.instructions = instructions; + this.localNames = localNames; + this.shedVariablesByNameStack = shedVariablesByNameStack; + this.shedVariablesByName = shedVariablesByName; + } + + public Context enterBlock(List shedVariables) { + var context = new Context( + this.instructionsStack.plus(this.instructions), + P.vector(), + this.localNames, + this.shedVariablesByNameStack.plus(this.shedVariablesByName), + this.shedVariablesByName + ); + + for (var shedVariable : shedVariables) { + context = context.addShedVariable(shedVariable); + } + + return context; + } + + public Context exitBlock() { + return new Context( + this.instructionsStack.minus(0), + this.instructionsStack.get(0), + this.localNames, + this.shedVariablesByNameStack.minus(0), + this.shedVariablesByNameStack.get(0) + ); + } + + private Context addInstruction(ShidInstruction instruction) { + return new Context( + this.instructionsStack, + this.instructions.plus(instruction), + this.localNames, + this.shedVariablesByNameStack, + this.shedVariablesByName + ); + } + + public Context addInstructions(PVector instructions) { + return new Context( + this.instructionsStack, + this.instructions.plusAll(instructions), + this.localNames, + this.shedVariablesByNameStack, + this.shedVariablesByName + ); + } + + public String shedVariableToLocal(String variableName) { + return shedVariable(variableName).shidLocalName; + } + + public ShedVariable shedVariable(String variableName) { + var shedVariable = this.shedVariablesByName.get(variableName); + + if (shedVariable == null) { + throw new RuntimeException("Unknown Shed variable: " + variableName); + } + + return shedVariable; + } + + public Context addShedVal(String variableName) { + return addShedVariable(BoundVariable.immutable(variableName)); + } + + public Context addShedVariable(BoundVariable boundVariable) { + var localName = generateLocalNameForVariable(boundVariable.name()); + + return new Context( + this.instructionsStack, + this.instructions, + this.localNames.plus(localName), + this.shedVariablesByNameStack, + this.shedVariablesByName.plus(boundVariable.name(), new ShedVariable(localName, boundVariable.isMutable())) + ); + } + + private String generateLocalNameForVariable(String variableName) { + var index = 0; + while (true) { + var localName = variableName + "__" + index; + if (this.localNames.contains(localName)) { + index++; + } else { + return localName; + } + } + } + + public List instructions() { + return this.instructions; + } + } + + private record ShedVariable(String shidLocalName, boolean isVar) {} +} diff --git a/src/main/java/org/shedlang/compiler/shid/ShidNamespace.java b/src/main/java/org/shedlang/compiler/shid/ShidNamespace.java new file mode 100644 index 00000000..4c5f134f --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/ShidNamespace.java @@ -0,0 +1,12 @@ +package org.shedlang.compiler.shid; + +import org.shedlang.compiler.shid.instructions.ShidInstruction; +import org.shedlang.compiler.types.NamespaceName; + +import java.util.List; + +public record ShidNamespace( + NamespaceName namespaceName, + List instructions +) { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidCall.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidCall.java new file mode 100644 index 00000000..bb720696 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidCall.java @@ -0,0 +1,25 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; + +import java.util.List; + +/** + * Pop a receiver and arguments from the temporary value stack and call the + * receiver with those arguments. + * + *

Specifically, the values should have been pushed onto the temporary value + * stack in the following order:

+ * + *
    + *
  • The receiver i.e. the function to be called.
  • + *
  • The positional arguments, from left to right.
  • + *
  • The named arguments, in the same order as namedArgNames.
  • + *
+ */ +public record ShidCall( + int positionalArgCount, + List namedArgNames, + Source source +) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineEffect.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineEffect.java new file mode 100644 index 00000000..cbd24307 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineEffect.java @@ -0,0 +1,14 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; +import org.shedlang.compiler.types.UserDefinedEffect; + +/** + * Push an effect value onto the temporary value stack with the given + * definition. + */ +public record ShidDefineEffect( + UserDefinedEffect effect, + Source source +) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineFunction.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineFunction.java new file mode 100644 index 00000000..16561049 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineFunction.java @@ -0,0 +1,105 @@ +package org.shedlang.compiler.shid.instructions; + +import org.pcollections.PVector; +import org.shedlang.compiler.ast.typed.FreeVariables; +import org.shedlang.compiler.sources.Source; +import org.shedlang.compiler.sources.Sources; +import org.shedlang.compiler.util.P; + +import java.util.List; + +/** + * Push a function value onto the temporary value stack with the given + * definition. + */ +public record ShidDefineFunction( + String name, + List positionalParams, + List namedParams, + FreeVariables freeVariables, + List body, + Source source +) implements ShidInstruction { + public record Param(String name, Source source) { + + } + + public static Builder builder() { + return new Builder( + "f", + P.vector(), + P.vector(), + FreeVariables.builder(), + P.vector() + ); + } + + public record Builder( + String name, + PVector positionalParams, + PVector namedParams, + FreeVariables.Builder freeVariables, + PVector body + ) { + public ShidDefineFunction build() { + return new ShidDefineFunction( + name, + positionalParams, + namedParams, + freeVariables.build(), + body, + Sources.NULL + ); + } + + public Builder withName(String name) { + return new Builder( + name, + this.positionalParams, + this.namedParams, + this.freeVariables, + this.body + ); + } + + public Builder addPositionalParam(String name) { + return new Builder( + this.name, + this.positionalParams.plus(new Param(name, Sources.NULL)), + this.namedParams, + this.freeVariables, + this.body + ); + } + + public Builder addNamedParam(String name) { + return new Builder( + this.name, + this.positionalParams, + this.namedParams.plus(new Param(name, Sources.NULL)), + this.freeVariables, + this.body + ); + } + + public Builder addFreeVariable(String name) { + return new Builder( + this.name, + this.positionalParams, + this.namedParams, + this.freeVariables.plus(name, Sources.NULL), + this.body + ); + } + + public Builder addBodyInstruction(ShidInstruction instruction) { + return new Builder( + this.name, + this.positionalParams, + this.namedParams, + this.freeVariables, + this.body.plus(instruction) + ); + } + } +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineStruct.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineStruct.java new file mode 100644 index 00000000..82d165e6 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineStruct.java @@ -0,0 +1,21 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; +import org.shedlang.compiler.types.StructType; + +import java.util.List; + +/** + * Push a struct type value onto the temporary value stack with the given + * definition. + */ +public record ShidDefineStruct( + StructType type, + // TODO: remove fields? We should have fields from the type info. + List fields, + Source source +) implements ShidInstruction { + public record Field(String name, Source source) { + + } +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidDiscard.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidDiscard.java new file mode 100644 index 00000000..ac5940d2 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidDiscard.java @@ -0,0 +1,9 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; + +/** + * Pop a value from the temporary value stack and discard it. + */ +public record ShidDiscard(Source source) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidDuplicate.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidDuplicate.java new file mode 100644 index 00000000..29714cd3 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidDuplicate.java @@ -0,0 +1,9 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; + +/** + * Duplicates the value on top of the temporary value stack. + */ +public record ShidDuplicate(Source source) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidFieldLoad.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidFieldLoad.java new file mode 100644 index 00000000..0df10550 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidFieldLoad.java @@ -0,0 +1,22 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; +import org.shedlang.compiler.types.NamespaceName; +import org.shedlang.compiler.types.StructType; +import org.shedlang.compiler.types.UserDefinedEffect; + +/** + * Pop a value from the temporary value stack, get the given field from the + * popped value, and push the field's value onto the temporary value stack. + */ +public record ShidFieldLoad( + Receiver receiver, + String fieldName, + Source source +) implements ShidInstruction { + public sealed interface Receiver { + record Effect(UserDefinedEffect effect) implements Receiver {} + record Namespace(NamespaceName name) implements Receiver {} + record Struct(StructType type) implements Receiver {} + } +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidIf.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidIf.java new file mode 100644 index 00000000..408ccbef --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidIf.java @@ -0,0 +1,22 @@ +package org.shedlang.compiler.shid.instructions; + + +import org.shedlang.compiler.sources.Source; + +import java.util.List; + +/** + * Pop a value from the temporary value stack, and assume it is a Bool. If it is + * true, execute the instructions in the "true" body, otherwise execute the + * instructions in the "false" body. + *

+ * Each branch body should push resultCount values onto the + * temporary value stack. + */ +public record ShidIf( + int resultCount, + List trueBody, + List falseBody, + Source source +) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidInstruction.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidInstruction.java new file mode 100644 index 00000000..308fe739 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidInstruction.java @@ -0,0 +1,9 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; + +public sealed interface ShidInstruction + permits ShidCall, ShidDefineEffect, ShidDefineFunction, ShidDefineStruct, ShidDiscard, ShidDuplicate, ShidFieldLoad, ShidIf, ShidIntAdd, ShidIntEquals, ShidIntNotEqual, ShidIntSub, ShidLocalLoad, ShidLocalStore, ShidLoop, ShidLoopBreak, ShidLoopContinue, ShidNamespaceFieldStore, ShidNamespaceImport, ShidPushBool, ShidPushInt, ShidPushString, ShidPushUnit, ShidResume, ShidReturn, ShidStringAdd, ShidSwitch, ShidTry, ShidTupleCreate, ShidTupleGet, ShidVarLoad, ShidVarStore { + + Source source(); +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidIntAdd.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidIntAdd.java new file mode 100644 index 00000000..ed570cef --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidIntAdd.java @@ -0,0 +1,10 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; + +/** + * Pop two values from the temporary value stack, assumed to be Ints, add them + * together, and push the result onto the temporary value stack. + */ +public record ShidIntAdd(Source source) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidIntEquals.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidIntEquals.java new file mode 100644 index 00000000..f5543143 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidIntEquals.java @@ -0,0 +1,10 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; + +/** + * Pop two values from the temporary value stack, compare them as Ints, and push + * a Bool onto the temporary value stack: true if equal, false if not equal. + */ +public record ShidIntEquals(Source source) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidIntNotEqual.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidIntNotEqual.java new file mode 100644 index 00000000..60eea7c5 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidIntNotEqual.java @@ -0,0 +1,10 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; + +/** + * Pop two values from the temporary value stack, compare them as Ints, and push + * a Bool onto the temporary value stack: true if not equal, false if equal. + */ +public record ShidIntNotEqual(Source source) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidIntSub.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidIntSub.java new file mode 100644 index 00000000..3fbd3e09 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidIntSub.java @@ -0,0 +1,11 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; + +/** + * Pop the right operand from the temporary value stack, then the left operand + * from the temporary value stack, calculate the left operand minus the right + * operand, then push the result onto the temporary value stack. + */ +public record ShidIntSub(Source source) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidLocalLoad.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidLocalLoad.java new file mode 100644 index 00000000..a1de23fe --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidLocalLoad.java @@ -0,0 +1,10 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; + +/** + * Load the local with the given name and push it onto the temporary value + * stack. + */ +public record ShidLocalLoad(String name, Source source) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidLocalStore.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidLocalStore.java new file mode 100644 index 00000000..003aaf40 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidLocalStore.java @@ -0,0 +1,10 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; + +/** + * Pop a value from the temporary value stack and store it as the local with the + * given name. + */ +public record ShidLocalStore(String name, Source source) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidLoop.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidLoop.java new file mode 100644 index 00000000..bfa7a1fa --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidLoop.java @@ -0,0 +1,17 @@ +package org.shedlang.compiler.shid.instructions; + + +import org.shedlang.compiler.sources.Source; + +import java.util.List; + +/** + * Execute the body. The continue instruction can jump back to the + * start of the body. The break instruction can jump to the end of + * the body. + */ +public record ShidLoop( + List body, + Source source +) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidLoopBreak.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidLoopBreak.java new file mode 100644 index 00000000..6e2e70d7 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidLoopBreak.java @@ -0,0 +1,9 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; + +/** + * Jump to the end of the enclosing loop instruction's body. + */ +public record ShidLoopBreak(Source source) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidLoopContinue.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidLoopContinue.java new file mode 100644 index 00000000..d6ee6c3d --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidLoopContinue.java @@ -0,0 +1,9 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; + +/** + * Jump to the start of the enclosing loop instruction's body. + */ +public record ShidLoopContinue(Source source) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidNamespaceFieldStore.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidNamespaceFieldStore.java new file mode 100644 index 00000000..583dbb5f --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidNamespaceFieldStore.java @@ -0,0 +1,15 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; +import org.shedlang.compiler.types.NamespaceName; + +/** + * Pop a value from the temporary value stack and store it as the field with the + * given name on the given namespace. + */ +public record ShidNamespaceFieldStore( + NamespaceName namespaceName, + String fieldName, + Source source +) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidNamespaceImport.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidNamespaceImport.java new file mode 100644 index 00000000..9e93a95f --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidNamespaceImport.java @@ -0,0 +1,13 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; +import org.shedlang.compiler.types.NamespaceName; + +/** + * Import the given namespace and push it onto the temporary value stack. + */ +public record ShidNamespaceImport( + NamespaceName namespaceName, + Source source +) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidPushBool.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidPushBool.java new file mode 100644 index 00000000..c92e8959 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidPushBool.java @@ -0,0 +1,12 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; + +/** + * Push a boolean onto the temporary value stack. + */ +public record ShidPushBool( + boolean value, + Source source +) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidPushInt.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidPushInt.java new file mode 100644 index 00000000..e4673e9b --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidPushInt.java @@ -0,0 +1,11 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; + +import java.math.BigInteger; + +/** + * Push an integer onto the temporary value stack. + */ +public record ShidPushInt(BigInteger value, Source source) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidPushString.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidPushString.java new file mode 100644 index 00000000..b0fa0183 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidPushString.java @@ -0,0 +1,9 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; + +/** + * Push a string onto the temporary value stack. + */ +public record ShidPushString(String value, Source source) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidPushUnit.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidPushUnit.java new file mode 100644 index 00000000..85e5363e --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidPushUnit.java @@ -0,0 +1,9 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; + +/** + * Push the unit value onto the temporary value stack. + */ +public record ShidPushUnit(Source source) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidResume.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidResume.java new file mode 100644 index 00000000..12eaac48 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidResume.java @@ -0,0 +1,10 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; + +/** + * Pop a value from the temporary value stack and return with that value from + * the current effect handler method back to the effect call. + */ +public record ShidResume(Source source) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidReturn.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidReturn.java new file mode 100644 index 00000000..fd0228fe --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidReturn.java @@ -0,0 +1,10 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; + +/** + * Pop a value from the temporary value stack and return with that value from + * the current function. + */ +public record ShidReturn(Source source) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidStringAdd.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidStringAdd.java new file mode 100644 index 00000000..fea26d1e --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidStringAdd.java @@ -0,0 +1,12 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; + +/** + * Pop the right operand from the temporary value stack, then the left operand + * from the temporary value stack, assume both operands are Strings, concatenate + * the left and right operands, then push the result onto the temporary value + * stack. + */ +public record ShidStringAdd(Source source) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidSwitch.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidSwitch.java new file mode 100644 index 00000000..00126f3c --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidSwitch.java @@ -0,0 +1,21 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; +import org.shedlang.compiler.types.StructType; + +import java.util.List; + +/** + * Pop a value from the temporary value stack, find the case corresponding to + * that value's type, and execute the instructions in the case's body. If there + * is no such case, the behaviour of this instruction is not defined. + *

+ * Each case body should push exactly one value onto the temporary value stack. + */ +public record ShidSwitch( + List cases, + Source source +) implements ShidInstruction { + public record Case(StructType caseType, List body, Source source) { + } +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidTry.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidTry.java new file mode 100644 index 00000000..ef763eda --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidTry.java @@ -0,0 +1,26 @@ +package org.shedlang.compiler.shid.instructions; + + +import org.shedlang.compiler.sources.Source; +import org.shedlang.compiler.types.UserDefinedEffect; + +import java.util.List; + +/** + * For each handler method name, pop a value off the temporary value stack. The + * first value (that is, the first pushed / last popped) corresponds to the + * first handler method name, and so on. Push an effect handler for the given + * effect with the popped handler methods onto the effect handler stack, and + * execute the body. Once the body has exited, pop the effect handler from the + * effect handler stack. + *

+ * If the body runs to completion, it should leave a single value on the + * temporary value stack. + */ +public record ShidTry( + UserDefinedEffect handledEffect, + List handlerMethodNames, + List body, + Source source +) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidTupleCreate.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidTupleCreate.java new file mode 100644 index 00000000..3559be91 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidTupleCreate.java @@ -0,0 +1,14 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; + +/** + * Pop {@code elementCount} values from the temporary value stack, create a + * tuple from those elements, and push the tuple onto the temporary value stack. + * Elements should have been pushed onto the stack in index order. + */ +public record ShidTupleCreate( + int elementCount, + Source source +) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidTupleGet.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidTupleGet.java new file mode 100644 index 00000000..a8a12b1d --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidTupleGet.java @@ -0,0 +1,14 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; + +/** + * Pop a tuple from the temporary value stack, get the element at the given + * index, and push it onto the temporary value stack. + */ +public record ShidTupleGet( + int elementIndex, + int elementCount, + Source source +) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidVarLoad.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidVarLoad.java new file mode 100644 index 00000000..ad0ae2ca --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidVarLoad.java @@ -0,0 +1,10 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; + +/** + * Load the value stored in the var with the given name and push it onto the + * temporary value stack. + */ +public record ShidVarLoad(String name, Source source) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidVarStore.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidVarStore.java new file mode 100644 index 00000000..f9d2fb51 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidVarStore.java @@ -0,0 +1,10 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Source; + +/** + * Pop a value from the temporary value stack and store it in the var with the + * given name. + */ +public record ShidVarStore(String name, Source source) implements ShidInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/stackir/InstructionSerializer.java b/src/main/java/org/shedlang/compiler/stackir/InstructionSerializer.java deleted file mode 100644 index 2cf812c4..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/InstructionSerializer.java +++ /dev/null @@ -1,280 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.shedlang.compiler.stackir.instructions.*; -import org.shedlang.compiler.treetext.Tree; -import org.shedlang.compiler.types.StructType; -import org.shedlang.compiler.types.UserDefinedEffect; - -import java.util.List; - -import static org.shedlang.compiler.treetext.TreeSerializer.serializeTree; -import static org.shedlang.compiler.treetext.Trees.*; - -public class InstructionSerializer { - private InstructionSerializer() { - } - - public static void serializeInstructions(List instructions, StringBuilder builder) { - var tree = instructionsToTree(instructions); - serializeTree(tree, builder, 0); - } - - public static void serializeInstruction(Instruction instruction, StringBuilder builder) { - var tree = instructionToTree(instruction); - serializeTree(tree, builder, 0); - } - - private static Tree instructionsToTree(List instructions) { - return treeListIndented( - instructions.stream() - .map(instruction -> instructionToTree(instruction)) - .toList() - ); - } - - private static Tree instructionToTree(Instruction instruction) { - return switch (instruction) { - case CallInstruction callInstruction -> - treeList( - treeIdentifier("call"), - treeNamed( - "positional-arg-count", - treeInt(callInstruction.positionalArgCount()) - ), - treeNamed( - "named-arg-names", - treeList( - callInstruction.namedArgNames().stream() - .map(arg -> treeString(arg)) - .toList() - ) - ) - ); - - case DefineEffectInstruction defineEffectInstruction -> - treeList( - treeIdentifier("define-effect"), - userDefinedEffectToTree(defineEffectInstruction.effect()) - ); - - case DefineFunctionInstruction defineFunctionInstruction -> - treeListIndented( - treeIdentifier("define-function"), - treeNamed("name", treeString(defineFunctionInstruction.name())), - treeNamed("positional-params", treeList( - defineFunctionInstruction.positionalParams().stream() - .map(param -> treeString(param.name())) - .toList() - )), - treeNamed("named-params", treeList( - defineFunctionInstruction.namedParams().stream() - .map(param -> treeString(param.name())) - .toList() - )), - treeNamed("free-variables", treeList( - defineFunctionInstruction.freeVariables().stream() - .map(freeVariable -> treeString(freeVariable.name())) - .toList() - )), - treeNamed("body", instructionsToTree(defineFunctionInstruction.body())) - ); - - case DefineStructInstruction defineStructInstruction -> - treeListIndented( - treeIdentifier("define-struct"), - treeNamed("type", structTypeToTree(defineStructInstruction.type())), - treeNamed("fields", treeList( - defineStructInstruction.fields().stream() - .map(field -> treeString(field.name())) - .toList() - )) - ); - - case DiscardInstruction discardInstruction -> - treeList( - treeIdentifier("discard") - ); - - case DuplicateInstruction duplicate -> - treeList( - treeIdentifier("duplicate") - ); - - case FieldLoadInstruction fieldLoad -> - treeList( - treeIdentifier("field-load"), - switch (fieldLoad.receiver()) { - case FieldLoadInstruction.Receiver.Effect effect -> - treeList( - treeIdentifier("effect"), - userDefinedEffectToTree(effect.effect()) - ); - - case FieldLoadInstruction.Receiver.Namespace namespace -> - treeList( - treeIdentifier("namespace"), - treeString(namespace.name().toString()) - ); - - case FieldLoadInstruction.Receiver.Struct struct -> - treeList( - treeIdentifier("struct"), - structTypeToTree(struct.type()) - ); - }, - treeString(fieldLoad.fieldName()) - ); - - case IfInstruction if_ -> - treeListIndented( - treeIdentifier("if"), - treeNamed("result-count", treeInt(if_.resultCount())), - instructionsToTree(if_.trueBody()), - instructionsToTree(if_.falseBody()) - ); - - case IntAddInstruction intAdd -> - treeList(treeIdentifier("int-add")); - - case IntEqualsInstruction intEquals -> - treeList(treeIdentifier("int-eq")); - - case IntNotEqualInstruction intNotEqual -> - treeList(treeIdentifier("int-ne")); - - case IntSubInstruction intSub -> - treeList(treeIdentifier("int-sub")); - - case LocalLoadInstruction localLoadInstruction -> - treeList( - treeIdentifier("local-load"), - treeString(localLoadInstruction.name()) - ); - - case LocalStoreInstruction localStoreInstruction -> - treeList( - treeIdentifier("local-store"), - treeString(localStoreInstruction.name()) - ); - - case LoopInstruction loop -> - treeListIndented( - treeIdentifier("loop"), - instructionsToTree(loop.body()) - ); - - case LoopBreakInstruction loopBreak -> - treeList(treeIdentifier("break")); - - case LoopContinueInstruction loopContinue -> - treeList(treeIdentifier("continue")); - - case NamespaceFieldStoreInstruction namespaceFieldStore -> - treeList( - treeIdentifier("namespace-field-store"), - treeString(namespaceFieldStore.namespaceName().toString()), - treeString(namespaceFieldStore.fieldName()) - ); - - case NamespaceImportInstruction namespaceImport -> - treeList( - treeIdentifier("namespace-import"), - treeString(namespaceImport.namespaceName().toString()) - ); - - case PushBoolInstruction pushBoolInstruction -> - treeList( - treeIdentifier("push-bool"), - treeIdentifier(Boolean.toString(pushBoolInstruction.value())) - ); - - case PushIntInstruction pushIntInstruction -> - treeList( - treeIdentifier("push-int"), - treeIdentifier(pushIntInstruction.value().toString()) - ); - - case PushStringInstruction pushStringInstruction -> - treeList( - treeIdentifier("push-string"), - treeString(pushStringInstruction.value()) - ); - - case PushUnitInstruction pushUnitInstruction -> - treeList( - treeIdentifier("push-unit") - ); - - case ResumeInstruction resumeInstruction -> - treeList( - treeIdentifier("resume") - ); - - case ReturnInstruction returnInstruction -> - treeList( - treeIdentifier("return") - ); - - case StringAddInstruction stringAddInstruction -> - treeList(treeIdentifier("string-add")); - - case SwitchInstruction switchInstruction -> - treeListIndented( - treeIdentifier("switch"), - treeListIndented( - switchInstruction.cases().stream() - .map(switchCase -> treeListIndented( - structTypeToTree(switchCase.caseType()), - instructionsToTree(switchCase.body()) - )) - .toList() - ) - ); - - case TryInstruction tryInstruction -> - treeListIndented( - treeIdentifier("try"), - userDefinedEffectToTree(tryInstruction.handledEffect()), - treeListIndented( - tryInstruction.handlerMethodNames().stream() - .map(name -> treeString(name)) - .toList() - ), - instructionsToTree(tryInstruction.body()) - ); - - case TupleCreateInstruction tupleCreateInstruction -> - treeList( - treeIdentifier("tuple-create"), - treeInt(tupleCreateInstruction.elementCount()) - ); - - case TupleGetInstruction tupleGetInstruction -> - treeList( - treeIdentifier("tuple-get"), - treeInt(tupleGetInstruction.elementIndex()), - treeInt(tupleGetInstruction.elementCount()) - ); - - case VarLoadInstruction varLoadInstruction -> - treeList( - treeIdentifier("var-load"), - treeString(varLoadInstruction.name()) - ); - - case VarStoreInstruction varStoreInstruction -> - treeList( - treeIdentifier("var-store"), - treeString(varStoreInstruction.name()) - ); - }; - } - - private static Tree userDefinedEffectToTree(UserDefinedEffect effect) { - return treeString(effect.describe()); - } - - private static Tree structTypeToTree(StructType type) { - return treeString(type.describe()); - } -} diff --git a/src/main/java/org/shedlang/compiler/stackir/StackCompiler.java b/src/main/java/org/shedlang/compiler/stackir/StackCompiler.java deleted file mode 100644 index 2e2b43b7..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/StackCompiler.java +++ /dev/null @@ -1,848 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.pcollections.*; -import org.shedlang.compiler.ShedBuiltins; -import org.shedlang.compiler.ast.typed.*; -import org.shedlang.compiler.sources.Source; -import org.shedlang.compiler.stackir.instructions.*; -import org.shedlang.compiler.types.*; -import org.shedlang.compiler.util.Iterables; -import org.shedlang.compiler.util.P; - -import java.util.ArrayList; -import java.util.List; - -public class StackCompiler { - private StackCompiler() { - } - - private static Context compileAssign(TypedAssignNode node, Context context) { - context = compileExpression(node.expression(), context); - context = compileTarget(node.target(), context); - return context; - } - - private static Context compileBinaryOperation( - TypedBinaryOperationNode node, - Context context - ) { - context = compileExpression(node.left(), context); - - context = compileExpression(node.right(), context); - - context = context.addInstruction(switch (node.operator()) { - case INT_ADD -> - new IntAddInstruction(node.source()); - case INT_EQUALS -> - new IntEqualsInstruction(node.source()); - case INT_NOT_EQUAL -> - new IntNotEqualInstruction(node.source()); - case INT_SUB -> - new IntSubInstruction(node.source()); - case STRING_ADD -> - new StringAddInstruction(node.source()); - }); - - return context; - } - - static Context compileBlockWithYield(TypedBlockNode node, Context context) { - for (var statement : node.statements()) { - context = compileFunctionStatement(statement, context); - } - - switch (node.behaviour()) { - case TypedFunctionStatementBehaviour.BlockReturn blockReturn -> { - } - case TypedFunctionStatementBehaviour.Continue continue_ -> { - context = context.addInstruction(new PushUnitInstruction(node.source())); - } - case TypedFunctionStatementBehaviour.Terminate terminate -> { - } - } - - return context; - } - - static Context compileBlockWithoutYield(TypedBlockNode node, Context context) { - for (var statement : node.statements()) { - context = compileFunctionStatement(statement, context); - } - - switch (node.behaviour()) { - case TypedFunctionStatementBehaviour.BlockReturn blockReturn -> { - context = context.addInstruction(new DiscardInstruction(node.source())); - } - case TypedFunctionStatementBehaviour.Continue continue_ -> { - } - case TypedFunctionStatementBehaviour.Terminate terminate -> { - } - } - - return context; - } - - private static Context compileBlockReturn(TypedBlockReturnNode blockReturn, Context context) { - return compileExpression(blockReturn.expression(), context); - } - - private static Context compileBoolLiteral(TypedBoolLiteralNode node, Context context) { - return context.addInstruction(new PushBoolInstruction(node.value(), node.source())); - } - - private static Context compileCall(TypedCallNode node, Context context) { - context = compileExpression(node.receiver(), context); - - for (var arg : node.args().positional()) { - context = compileExpression(arg, context); - } - - for (var arg : node.args().named()) { - context = compileExpression(arg.expression(), context); - } - - var callInstruction = new CallInstruction( - node.args().positional().size(), - node.args().named().stream() - .map(arg -> arg.name()) - .toList(), - node.source() - ); - - context = context.addInstruction(callInstruction); - - return context; - } - - private static Context compileEffectDefinition( - TypedEffectDefinitionNode node, - Context context - ) { - var localName = context.shedVariableToLocal(node.effect().name()); - - return context - .addInstruction(new DefineEffectInstruction(node.effect(), node.source())) - .addInstruction(new LocalStoreInstruction(localName, node.source())); - } - - public static Context compileExpression(TypedExpressionNode node, Context context) { - return switch (node) { - case TypedBinaryOperationNode typedBinaryOperationNode -> - compileBinaryOperation(typedBinaryOperationNode, context); - - case TypedBoolLiteralNode typedBoolLiteralNode -> - compileBoolLiteral(typedBoolLiteralNode, context); - - case TypedCallNode typedCallNode -> - compileCall(typedCallNode, context); - - case TypedFieldAccessNode typedFieldAccessNode -> - compileFieldAccess(typedFieldAccessNode, context); - - case TypedFunctionExpressionNode typedFunctionExpressionNode -> - compileFunctionExpression(typedFunctionExpressionNode, context); - - case TypedIfNode typedIfNode -> - compileIf(typedIfNode, context); - - case TypedIntLiteralNode typedIntLiteralNode -> - compileIntLiteral(typedIntLiteralNode, context); - - case TypedReferenceNode typedReferenceNode -> - compileReference(typedReferenceNode, context); - - case TypedStringLiteralNode typedStringLiteralNode -> - compileStringLiteral(typedStringLiteralNode, context); - - case TypedTryNode typedTryNode -> - compileTry(typedTryNode, context); - - case TypedTupleNode typedTupleNode -> - compileTuple(typedTupleNode, context); - - case TypedUnitLiteralNode typedUnitLiteralNode -> - compileUnitLiteral(typedUnitLiteralNode, context); - - case TypedWhenNode typedWhenNode -> - compileWhen(typedWhenNode, context); - }; - } - - private static Context compileExpressionStatement( - TypedExpressionStatementNode node, - Context context - ) { - context = compileExpression(node.expression(), context); - context = context.addInstruction(new DiscardInstruction(node.source())); - return context; - } - - private static Context compileFieldAccess( - TypedFieldAccessNode node, - Context context - ) { - context = compileExpression(node.receiver(), context); - // TODO: handle not a type with fields - var receiver = switch (node.receiver().type()) { - case NamespaceType namespaceType -> - new FieldLoadInstruction.Receiver.Namespace(namespaceType.namespaceName()); - - case StructType structType -> - new FieldLoadInstruction.Receiver.Struct(structType); - - case TypeLevelValueType typeLevelValueType -> { - if (typeLevelValueType.value() instanceof UserDefinedEffect effect) { - yield new FieldLoadInstruction.Receiver.Effect(effect); - } else { - throw new RuntimeException("not a type with fields"); - } - } - - default -> - throw new RuntimeException("not a type with fields"); - }; - - context = context.addInstruction(new FieldLoadInstruction( - receiver, - node.fieldName(), - node.source() - )); - return context; - } - - private static Context compileFunction( - String name, - TypedParamsNode params, - TypedFunctionBodyNode body, - Source source, - Context context - ) { - context = context.enterBlock(body.boundVariables()); - - var c = context; - - var positionalParams = params.positional().stream() - .map(param -> new DefineFunctionInstruction.Param( - c.shedVariableToLocal(param.name()), - param.source() - )) - .toList(); - - var namedParams = params.named().stream() - .map(param -> new DefineFunctionInstruction.Param( - c.shedVariableToLocal(param.name()), - param.source() - )) - .toList(); - - context = compileBlockWithYield(body.block(), context); - - switch (body.behaviour()) { - case TypedFunctionStatementBehaviour.BlockReturn blockReturn -> { - context = context.addInstruction(new ReturnInstruction(body.source())); - } - case TypedFunctionStatementBehaviour.Continue continue_ -> { - context = context.addInstruction(new ReturnInstruction(body.source())); - } - case TypedFunctionStatementBehaviour.Terminate terminate -> { - } - } - - var bodyInstructions = context.instructions; - - context = context.exitBlock(); - - var freeVariables = FreeVariables.builder(); - for (var shedFreeVariable : body.freeVariables()) { - var freeVariableLocalName = context.shedVariableToLocal(shedFreeVariable.name()); - for (var freeVariableSource : shedFreeVariable.referenceSources()) { - freeVariables = freeVariables.plus( - freeVariableLocalName, - freeVariableSource - ); - } - } - - var defineFunctionInstruction = new DefineFunctionInstruction( - name, - positionalParams, - namedParams, - freeVariables.build(), - bodyInstructions, - source - ); - - return context.addInstruction(defineFunctionInstruction); - } - - private static Context compileFunctionDefinition( - TypedFunctionDefinitionNode node, - Context context - ) { - context = compileFunction( - node.name(), - node.signature().params(), - node.body(), - node.source(), - context - ); - - var localName = context.shedVariableToLocal(node.name()); - var storeInstruction = new LocalStoreInstruction(localName, node.source()); - - return context.addInstruction(storeInstruction); - } - - private static Context compileFunctionExpression( - TypedFunctionExpressionNode node, - Context context - ) { - return compileFunction( - // TODO: include source location? - "anonymous", - node.signature().params(), - node.body(), - node.source(), - context - ); - } - - private static Context compileFunctionReturn( - TypedFunctionReturnNode node, - Context context - ) { - context = compileExpression(node.expression(), context); - context = context.addInstruction(new ReturnInstruction(node.source())); - return context; - } - - public static Context compileFunctionStatement( - TypedFunctionStatementNode node, - Context context - ) { - return switch (node) { - case TypedAssignNode assign -> - compileAssign(assign, context); - - case TypedBlockReturnNode blockReturn -> - compileBlockReturn(blockReturn, context); - - case TypedExpressionStatementNode expressionStatement -> - compileExpressionStatement(expressionStatement, context); - - case TypedFunctionReturnNode functionReturn -> - compileFunctionReturn(functionReturn, context); - - case TypedResumeNode resume -> - compileResume(resume, context); - - case TypedWhileNode while_ -> - compileWhile(while_, context); - }; - } - - private static Context compileIf(TypedIfNode node, Context context) { - return compileIf( - node.conditionalBranches(), - node.elseBody(), - context - ); - } - - private static Context compileIf( - List conditionalBranches, - TypedBlockNode elseBody, - Context context - ) { - if (conditionalBranches.isEmpty()) { - context = context.enterBlock(elseBody.boundVariables()); - context = compileBlockWithYield(elseBody, context); - var elseInstructions = context.instructions; - context = context.exitBlock(); - for (var instruction : elseInstructions) { - context = context.addInstruction(instruction); - } - } else { - var conditionalBranch = conditionalBranches.get(0); - context = compileExpression(conditionalBranch.condition(), context); - - context = context.enterBlock(conditionalBranch.body().boundVariables()); - context = compileBlockWithYield(conditionalBranch.body(), context); - var ifTrueInstructions = context.instructions; - context = context.exitBlock(); - - context = context.enterBlock(List.of()); - context = compileIf( - conditionalBranches.subList(1, conditionalBranches.size()), - elseBody, - context - ); - var ifFalseInstructions = context.instructions; - context = context.exitBlock(); - - context = context.addInstruction(new IfInstruction( - 1, - ifTrueInstructions, - ifFalseInstructions, - conditionalBranch.source() - )); - } - - return context; - } - - private static Context compileIntLiteral(TypedIntLiteralNode node, Context context) { - return context.addInstruction(new PushIntInstruction(node.value(), node.source())); - } - - public static StackIrNamespace compileNamespace(TypedNamespaceNode node) { - var context = Context.EMPTY; - - context = context.addShedVal(ShedBuiltins.PRINT_NAME); - var printLocalName = context.shedVariableToLocal(ShedBuiltins.PRINT_NAME); - - context = context - .addInstruction(new NamespaceImportInstruction(ShedBuiltins.NAMESPACE_NAME, node.source())) - .addInstruction(new FieldLoadInstruction( - new FieldLoadInstruction.Receiver.Namespace(ShedBuiltins.NAMESPACE_NAME), - ShedBuiltins.PRINT_NAME, - node.source() - )) - .addInstruction(new LocalStoreInstruction(printLocalName, node.source())); - - for (var boundVariable : node.boundVariables()) { - context = context.addShedVariable(boundVariable); - } - - for (var importNode : node.imports()) { - var localName = context.shedVariableToLocal(importNode.variableName()); - context = context - .addInstruction(new NamespaceImportInstruction( - importNode.namespaceName(), - importNode.source() - )) - .addInstruction(new LocalStoreInstruction( - localName, - importNode.source() - )); - - } - - var statementsAfterHoisting = Iterables.sortedBy(node.body(), statement -> switch (statement) { - case TypedAssignNode assign -> - 1; - - case TypedEffectDefinitionNode effectDefinition -> - 0; - - case TypedFunctionDefinitionNode functionDefinition -> - 1; - - case TypedStructDefinitionNode structDefinition -> - 0; - - case TypedSumTypeDefinitionNode sumTypeDefinition -> - 0; - }); - for (var statement : statementsAfterHoisting) { - context = compileNamespaceStatement(statement, context); - } - - for (var fieldName : node.fieldNames()) { - var localName = context.shedVariableToLocal(fieldName); - - context = context - .addInstruction(new LocalLoadInstruction(localName, node.source())) - .addInstruction(new NamespaceFieldStoreInstruction( - node.namespaceName(), - fieldName, - node.source() - )); - } - - return new StackIrNamespace(node.namespaceName(), context.instructions); - } - - public static Context compileNamespaceStatement(TypedNamespaceStatementNode node, Context context) { - return switch (node) { - case TypedAssignNode assign -> - compileAssign(assign, context); - - case TypedEffectDefinitionNode effectDefinition -> - compileEffectDefinition(effectDefinition, context); - - case TypedFunctionDefinitionNode functionDefinition -> - compileFunctionDefinition(functionDefinition, context); - - case TypedStructDefinitionNode structDefinition -> - compileStructDefinition(structDefinition, context); - - case TypedSumTypeDefinitionNode sumDefinition -> - compileSumTypeDefinition(sumDefinition, context); - }; - } - - private static Context compileReference(TypedReferenceNode node, Context context) { - var shedVariable = context.shedVariable(node.name()); - - if (shedVariable.isVar) { - return context.addInstruction(new VarLoadInstruction( - shedVariable.stackIrLocalName, - node.source() - )); - } else { - return context.addInstruction(new LocalLoadInstruction( - shedVariable.stackIrLocalName, - node.source() - )); - } - } - - private static Context compileResume(TypedResumeNode node, Context context) { - context = compileExpression(node.expression(), context); - context = context.addInstruction(new ResumeInstruction(node.source())); - return context; - } - - private static Context compileStringLiteral( - TypedStringLiteralNode node, - Context context - ) { - var instruction = new PushStringInstruction(node.value(), node.source()); - return context.addInstruction(instruction); - } - - private static Context compileStructDefinition( - TypedStructDefinitionNode node, - Context context - ) { - var defineStructInstruction = new DefineStructInstruction( - node.type(), - node.fields().stream() - .map(field -> new DefineStructInstruction.Field(field.name(), field.source())) - .toList(), - node.source() - ); - - var localName = context.shedVariableToLocal(node.type().name()); - var storeInstruction = new LocalStoreInstruction(localName, node.source()); - - return context - .addInstruction(defineStructInstruction) - .addInstruction(storeInstruction); - } - - private static Context compileSumTypeDefinition( - TypedSumTypeDefinitionNode node, - Context context - ) { - var defineSumTypeInstruction = new PushUnitInstruction(node.source()); - - var localName = context.shedVariableToLocal(node.type().name()); - var storeInstruction = new LocalStoreInstruction(localName, node.source()); - - return context - .addInstruction(defineSumTypeInstruction) - .addInstruction(storeInstruction); - } - - private static Context compileTarget( - TypedTargetNode target, - Context context - ) { - return switch (target) { - case TypedTargetNode.Ignore ignore -> { - yield context.addInstruction(new DiscardInstruction(ignore.source())); - } - - case TypedTargetNode.Reassign reassign -> { - context = context.addInstruction( - new VarStoreInstruction( - context.shedVariableToLocal(reassign.name()), - reassign.source() - ) - ); - - yield context; - } - - case TypedTargetNode.Tuple tuple -> { - if (tuple.elements().size() == 0) { - context = context.addInstruction(new DiscardInstruction(tuple.source())); - } - - for (var elementIndex = 0; elementIndex < tuple.elements().size(); elementIndex++) { - if (elementIndex < tuple.elements().size() - 1) { - context = context - .addInstruction(new DuplicateInstruction(tuple.source())); - } - - context = context - .addInstruction(new TupleGetInstruction( - elementIndex, - tuple.elements().size(), - tuple.source() - )); - - context = compileTarget(tuple.elements().get(elementIndex), context); - } - - yield context; - } - - case TypedTargetNode.Val val -> { - context = context.addInstruction( - new LocalStoreInstruction( - context.shedVariableToLocal(val.name()), - val.source() - ) - ); - - yield context; - } - - case TypedTargetNode.Var var -> { - context = context.addInstruction( - new VarStoreInstruction( - context.shedVariableToLocal(var.name()), - var.source() - ) - ); - - yield context; - } - }; - } - - private static Context compileTry(TypedTryNode node, Context context) { - for (var handlerMethod : node.handlerMethods()) { - context = compileTryHandlerMethod(handlerMethod, context); - } - - context = context.enterBlock(node.body().boundVariables()); - context = compileBlockWithYield(node.body(), context); - var bodyInstructions = context.instructions; - context = context.exitBlock(); - - var instruction = new TryInstruction( - node.handledEffect().value(), - node.handlerMethods().stream() - .map(methodNode -> methodNode.name()) - .toList(), - bodyInstructions, - node.source() - ); - - return context.addInstruction(instruction); - } - - private static Context compileTryHandlerMethod( - TypedTryHandlerMethodNode node, - Context context - ) { - return compileFunction( - node.name(), - node.params(), - node.body(), - node.source(), - context - ); - } - - private static Context compileTuple(TypedTupleNode node, Context context) { - for (var elementNode : node.elements()) { - context = compileExpression(elementNode, context); - } - - var instruction = new TupleCreateInstruction(node.elements().size(), node.source()); - return context.addInstruction(instruction); - } - - private static Context compileUnitLiteral( - TypedUnitLiteralNode node, - Context context - ) { - return context.addInstruction(new PushUnitInstruction(node.source())); - } - - private static Context compileWhen(TypedWhenNode node, Context context) { - context = compileExpression(node.expression(), context); - - var switchCases = new ArrayList(); - - for (var whenCase : node.cases()) { - context = context.enterBlock(whenCase.body().boundVariables()); - context = compileBlockWithYield(whenCase.body(), context); - var caseBodyInstructions = context.instructions; - context = context.exitBlock(); - - var switchCase = new SwitchInstruction.Case( - whenCase.caseType().value(), - caseBodyInstructions, - whenCase.source() - ); - switchCases.add(switchCase); - } - - context = context.addInstruction(new SwitchInstruction( - switchCases, - node.source() - )); - - return context; - } - - private static Context compileWhile(TypedWhileNode node, Context context) { - context = context.enterBlock(node.body().boundVariables()); - context = compileBlockWithoutYield(node.body(), context); - var ifTrueInstructions = context.instructions; - context = context.exitBlock(); - - context = context.enterBlock(List.of()); - - context = compileExpression(node.condition(), context); - context = context.addInstruction(new IfInstruction( - 0, - List.of(), - List.of( - new LoopBreakInstruction(node.source()) - ), - node.source() - )); - - context = context.addInstructions(ifTrueInstructions); - - context = context.addInstruction(new LoopContinueInstruction(node.source())); - - var bodyInstructions = context.instructions; - context = context.exitBlock(); - - context = context.addInstruction(new LoopInstruction(bodyInstructions, node.source())); - - return context; - } - - public static class Context { - public static final Context EMPTY = new Context( - P.stack(), - P.vector(), - Empty.set(), - P.stack(), - P.map() - ); - - private final PStack> instructionsStack; - private final PVector instructions; - private final PSet localNames; - private final PStack> shedVariablesByNameStack; - private final PMap shedVariablesByName; - - private Context( - PStack> instructionsStack, - PVector instructions, - PSet localNames, - PStack> shedVariablesByNameStack, - PMap shedVariablesByName - ) { - this.instructionsStack = instructionsStack; - this.instructions = instructions; - this.localNames = localNames; - this.shedVariablesByNameStack = shedVariablesByNameStack; - this.shedVariablesByName = shedVariablesByName; - } - - public Context enterBlock(List shedVariables) { - var context = new Context( - this.instructionsStack.plus(this.instructions), - P.vector(), - this.localNames, - this.shedVariablesByNameStack.plus(this.shedVariablesByName), - this.shedVariablesByName - ); - - for (var shedVariable : shedVariables) { - context = context.addShedVariable(shedVariable); - } - - return context; - } - - public Context exitBlock() { - return new Context( - this.instructionsStack.minus(0), - this.instructionsStack.get(0), - this.localNames, - this.shedVariablesByNameStack.minus(0), - this.shedVariablesByNameStack.get(0) - ); - } - - private Context addInstruction(Instruction instruction) { - return new Context( - this.instructionsStack, - this.instructions.plus(instruction), - this.localNames, - this.shedVariablesByNameStack, - this.shedVariablesByName - ); - } - - public Context addInstructions(PVector instructions) { - return new Context( - this.instructionsStack, - this.instructions.plusAll(instructions), - this.localNames, - this.shedVariablesByNameStack, - this.shedVariablesByName - ); - } - - public String shedVariableToLocal(String variableName) { - return shedVariable(variableName).stackIrLocalName; - } - - public ShedVariable shedVariable(String variableName) { - var shedVariable = this.shedVariablesByName.get(variableName); - - if (shedVariable == null) { - throw new RuntimeException("Unknown Shed variable: " + variableName); - } - - return shedVariable; - } - - public Context addShedVal(String variableName) { - return addShedVariable(BoundVariable.immutable(variableName)); - } - - public Context addShedVariable(BoundVariable boundVariable) { - var localName = generateLocalNameForVariable(boundVariable.name()); - - return new Context( - this.instructionsStack, - this.instructions, - this.localNames.plus(localName), - this.shedVariablesByNameStack, - this.shedVariablesByName.plus(boundVariable.name(), new ShedVariable(localName, boundVariable.isMutable())) - ); - } - - private String generateLocalNameForVariable(String variableName) { - var index = 0; - while (true) { - var localName = variableName + "__" + index; - if (this.localNames.contains(localName)) { - index++; - } else { - return localName; - } - } - } - - public List instructions() { - return this.instructions; - } - } - - private record ShedVariable(String stackIrLocalName, boolean isVar) {} -} diff --git a/src/main/java/org/shedlang/compiler/stackir/StackIrNamespace.java b/src/main/java/org/shedlang/compiler/stackir/StackIrNamespace.java deleted file mode 100644 index 65fd41d3..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/StackIrNamespace.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.shedlang.compiler.stackir.instructions.Instruction; -import org.shedlang.compiler.types.NamespaceName; - -import java.util.List; - -public record StackIrNamespace( - NamespaceName namespaceName, - List instructions -) { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/CallInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/CallInstruction.java deleted file mode 100644 index a84c4af1..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/CallInstruction.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; - -import java.util.List; - -/** - * Pop a receiver and arguments from the temporary value stack and call the - * receiver with those arguments. - * - *

Specifically, the values should have been pushed onto the temporary value - * stack in the following order:

- * - *
    - *
  • The receiver i.e. the function to be called.
  • - *
  • The positional arguments, from left to right.
  • - *
  • The named arguments, in the same order as namedArgNames.
  • - *
- */ -public record CallInstruction( - int positionalArgCount, - List namedArgNames, - Source source -) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/DefineEffectInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/DefineEffectInstruction.java deleted file mode 100644 index d87a6412..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/DefineEffectInstruction.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; -import org.shedlang.compiler.types.UserDefinedEffect; - -/** - * Push an effect value onto the temporary value stack with the given - * definition. - */ -public record DefineEffectInstruction( - UserDefinedEffect effect, - Source source -) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/DefineFunctionInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/DefineFunctionInstruction.java deleted file mode 100644 index 6ca40775..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/DefineFunctionInstruction.java +++ /dev/null @@ -1,105 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.pcollections.PVector; -import org.shedlang.compiler.ast.typed.FreeVariables; -import org.shedlang.compiler.sources.Source; -import org.shedlang.compiler.sources.Sources; -import org.shedlang.compiler.util.P; - -import java.util.List; - -/** - * Push a function value onto the temporary value stack with the given - * definition. - */ -public record DefineFunctionInstruction( - String name, - List positionalParams, - List namedParams, - FreeVariables freeVariables, - List body, - Source source -) implements Instruction { - public record Param(String name, Source source) { - - } - - public static Builder builder() { - return new Builder( - "f", - P.vector(), - P.vector(), - FreeVariables.builder(), - P.vector() - ); - } - - public record Builder( - String name, - PVector positionalParams, - PVector namedParams, - FreeVariables.Builder freeVariables, - PVector body - ) { - public DefineFunctionInstruction build() { - return new DefineFunctionInstruction( - name, - positionalParams, - namedParams, - freeVariables.build(), - body, - Sources.NULL - ); - } - - public Builder withName(String name) { - return new Builder( - name, - this.positionalParams, - this.namedParams, - this.freeVariables, - this.body - ); - } - - public Builder addPositionalParam(String name) { - return new Builder( - this.name, - this.positionalParams.plus(new Param(name, Sources.NULL)), - this.namedParams, - this.freeVariables, - this.body - ); - } - - public Builder addNamedParam(String name) { - return new Builder( - this.name, - this.positionalParams, - this.namedParams.plus(new Param(name, Sources.NULL)), - this.freeVariables, - this.body - ); - } - - public Builder addFreeVariable(String name) { - return new Builder( - this.name, - this.positionalParams, - this.namedParams, - this.freeVariables.plus(name, Sources.NULL), - this.body - ); - } - - public Builder addBodyInstruction(Instruction instruction) { - return new Builder( - this.name, - this.positionalParams, - this.namedParams, - this.freeVariables, - this.body.plus(instruction) - ); - } - } -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/DefineStructInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/DefineStructInstruction.java deleted file mode 100644 index 098c9245..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/DefineStructInstruction.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; -import org.shedlang.compiler.types.StructType; - -import java.util.List; - -/** - * Push a struct type value onto the temporary value stack with the given - * definition. - */ -public record DefineStructInstruction( - StructType type, - // TODO: remove fields? We should have fields from the type info. - List fields, - Source source -) implements Instruction { - public record Field(String name, Source source) { - - } -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/DiscardInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/DiscardInstruction.java deleted file mode 100644 index 503ecc53..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/DiscardInstruction.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; - -/** - * Pop a value from the temporary value stack and discard it. - */ -public record DiscardInstruction(Source source) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/DuplicateInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/DuplicateInstruction.java deleted file mode 100644 index 03685e54..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/DuplicateInstruction.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; - -/** - * Duplicates the value on top of the temporary value stack. - */ -public record DuplicateInstruction(Source source) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/FieldLoadInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/FieldLoadInstruction.java deleted file mode 100644 index 53dc1ee8..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/FieldLoadInstruction.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; -import org.shedlang.compiler.types.NamespaceName; -import org.shedlang.compiler.types.StructType; -import org.shedlang.compiler.types.UserDefinedEffect; - -/** - * Pop a value from the temporary value stack, get the given field from the - * popped value, and push the field's value onto the temporary value stack. - */ -public record FieldLoadInstruction( - Receiver receiver, - String fieldName, - Source source -) implements Instruction { - public sealed interface Receiver { - record Effect(UserDefinedEffect effect) implements Receiver {} - record Namespace(NamespaceName name) implements Receiver {} - record Struct(StructType type) implements Receiver {} - } -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/IfInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/IfInstruction.java deleted file mode 100644 index a6636b91..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/IfInstruction.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - - -import org.shedlang.compiler.sources.Source; - -import java.util.List; - -/** - * Pop a value from the temporary value stack, and assume it is a Bool. If it is - * true, execute the instructions in the "true" body, otherwise execute the - * instructions in the "false" body. - *

- * Each branch body should push resultCount values onto the - * temporary value stack. - */ -public record IfInstruction( - int resultCount, - List trueBody, - List falseBody, - Source source -) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java deleted file mode 100644 index f84de210..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; - -public sealed interface Instruction - permits CallInstruction, DefineEffectInstruction, DefineFunctionInstruction, DefineStructInstruction, DiscardInstruction, DuplicateInstruction, FieldLoadInstruction, IfInstruction, IntAddInstruction, IntEqualsInstruction, IntNotEqualInstruction, IntSubInstruction, LocalLoadInstruction, LocalStoreInstruction, LoopBreakInstruction, LoopContinueInstruction, LoopInstruction, NamespaceFieldStoreInstruction, NamespaceImportInstruction, PushBoolInstruction, PushIntInstruction, PushStringInstruction, PushUnitInstruction, ResumeInstruction, ReturnInstruction, StringAddInstruction, SwitchInstruction, TryInstruction, TupleCreateInstruction, TupleGetInstruction, VarLoadInstruction, VarStoreInstruction { - - Source source(); -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/IntAddInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/IntAddInstruction.java deleted file mode 100644 index 55a4fb1c..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/IntAddInstruction.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; - -/** - * Pop two values from the temporary value stack, assumed to be Ints, add them - * together, and push the result onto the temporary value stack. - */ -public record IntAddInstruction(Source source) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/IntEqualsInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/IntEqualsInstruction.java deleted file mode 100644 index 7f0c97cf..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/IntEqualsInstruction.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; - -/** - * Pop two values from the temporary value stack, compare them as Ints, and push - * a Bool onto the temporary value stack: true if equal, false if not equal. - */ -public record IntEqualsInstruction(Source source) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/IntNotEqualInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/IntNotEqualInstruction.java deleted file mode 100644 index 6b155f67..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/IntNotEqualInstruction.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; - -/** - * Pop two values from the temporary value stack, compare them as Ints, and push - * a Bool onto the temporary value stack: true if not equal, false if equal. - */ -public record IntNotEqualInstruction(Source source) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/IntSubInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/IntSubInstruction.java deleted file mode 100644 index e2fa09b6..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/IntSubInstruction.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; - -/** - * Pop the right operand from the temporary value stack, then the left operand - * from the temporary value stack, calculate the left operand minus the right - * operand, then push the result onto the temporary value stack. - */ -public record IntSubInstruction(Source source) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/LocalLoadInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/LocalLoadInstruction.java deleted file mode 100644 index d0753609..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/LocalLoadInstruction.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; - -/** - * Load the local with the given name and push it onto the temporary value - * stack. - */ -public record LocalLoadInstruction(String name, Source source) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/LocalStoreInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/LocalStoreInstruction.java deleted file mode 100644 index 880c91f8..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/LocalStoreInstruction.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; - -/** - * Pop a value from the temporary value stack and store it as the local with the - * given name. - */ -public record LocalStoreInstruction(String name, Source source) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/LoopBreakInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/LoopBreakInstruction.java deleted file mode 100644 index 60a1d056..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/LoopBreakInstruction.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; - -/** - * Jump to the end of the enclosing loop instruction's body. - */ -public record LoopBreakInstruction(Source source) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/LoopContinueInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/LoopContinueInstruction.java deleted file mode 100644 index d7111ea9..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/LoopContinueInstruction.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; - -/** - * Jump to the start of the enclosing loop instruction's body. - */ -public record LoopContinueInstruction(Source source) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/LoopInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/LoopInstruction.java deleted file mode 100644 index 119d9a52..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/LoopInstruction.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - - -import org.shedlang.compiler.sources.Source; - -import java.util.List; - -/** - * Execute the body. The continue instruction can jump back to the - * start of the body. The break instruction can jump to the end of - * the body. - */ -public record LoopInstruction( - List body, - Source source -) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/NamespaceFieldStoreInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/NamespaceFieldStoreInstruction.java deleted file mode 100644 index b83964a1..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/NamespaceFieldStoreInstruction.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; -import org.shedlang.compiler.types.NamespaceName; - -/** - * Pop a value from the temporary value stack and store it as the field with the - * given name on the given namespace. - */ -public record NamespaceFieldStoreInstruction( - NamespaceName namespaceName, - String fieldName, - Source source -) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/NamespaceImportInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/NamespaceImportInstruction.java deleted file mode 100644 index cc600d5b..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/NamespaceImportInstruction.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; -import org.shedlang.compiler.types.NamespaceName; - -/** - * Import the given namespace and push it onto the temporary value stack. - */ -public record NamespaceImportInstruction( - NamespaceName namespaceName, - Source source -) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/PushBoolInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/PushBoolInstruction.java deleted file mode 100644 index c732a390..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/PushBoolInstruction.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; - -/** - * Push a boolean onto the temporary value stack. - */ -public record PushBoolInstruction( - boolean value, - Source source -) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/PushIntInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/PushIntInstruction.java deleted file mode 100644 index cba3f217..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/PushIntInstruction.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; - -import java.math.BigInteger; - -/** - * Push an integer onto the temporary value stack. - */ -public record PushIntInstruction(BigInteger value, Source source) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/PushStringInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/PushStringInstruction.java deleted file mode 100644 index e33051e5..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/PushStringInstruction.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; - -/** - * Push a string onto the temporary value stack. - */ -public record PushStringInstruction(String value, Source source) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/PushUnitInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/PushUnitInstruction.java deleted file mode 100644 index 998624e1..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/PushUnitInstruction.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; - -/** - * Push the unit value onto the temporary value stack. - */ -public record PushUnitInstruction(Source source) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/ResumeInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/ResumeInstruction.java deleted file mode 100644 index 836b5bac..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/ResumeInstruction.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; - -/** - * Pop a value from the temporary value stack and return with that value from - * the current effect handler method back to the effect call. - */ -public record ResumeInstruction(Source source) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/ReturnInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/ReturnInstruction.java deleted file mode 100644 index 1b9e4213..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/ReturnInstruction.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; - -/** - * Pop a value from the temporary value stack and return with that value from - * the current function. - */ -public record ReturnInstruction(Source source) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/StringAddInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/StringAddInstruction.java deleted file mode 100644 index 5114beff..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/StringAddInstruction.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; - -/** - * Pop the right operand from the temporary value stack, then the left operand - * from the temporary value stack, assume both operands are Strings, concatenate - * the left and right operands, then push the result onto the temporary value - * stack. - */ -public record StringAddInstruction(Source source) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/SwitchInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/SwitchInstruction.java deleted file mode 100644 index 880349de..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/SwitchInstruction.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; -import org.shedlang.compiler.types.StructType; - -import java.util.List; - -/** - * Pop a value from the temporary value stack, find the case corresponding to - * that value's type, and execute the instructions in the case's body. If there - * is no such case, the behaviour of this instruction is not defined. - *

- * Each case body should push exactly one value onto the temporary value stack. - */ -public record SwitchInstruction( - List cases, - Source source -) implements Instruction { - public record Case(StructType caseType, List body, Source source) { - } -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/TryInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/TryInstruction.java deleted file mode 100644 index 0b5051df..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/TryInstruction.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - - -import org.shedlang.compiler.sources.Source; -import org.shedlang.compiler.types.UserDefinedEffect; - -import java.util.List; - -/** - * For each handler method name, pop a value off the temporary value stack. The - * first value (that is, the first pushed / last popped) corresponds to the - * first handler method name, and so on. Push an effect handler for the given - * effect with the popped handler methods onto the effect handler stack, and - * execute the body. Once the body has exited, pop the effect handler from the - * effect handler stack. - *

- * If the body runs to completion, it should leave a single value on the - * temporary value stack. - */ -public record TryInstruction( - UserDefinedEffect handledEffect, - List handlerMethodNames, - List body, - Source source -) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/TupleCreateInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/TupleCreateInstruction.java deleted file mode 100644 index fa331d1c..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/TupleCreateInstruction.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; - -/** - * Pop {@code elementCount} values from the temporary value stack, create a - * tuple from those elements, and push the tuple onto the temporary value stack. - * Elements should have been pushed onto the stack in index order. - */ -public record TupleCreateInstruction( - int elementCount, - Source source -) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/TupleGetInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/TupleGetInstruction.java deleted file mode 100644 index ed52cc29..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/TupleGetInstruction.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; - -/** - * Pop a tuple from the temporary value stack, get the element at the given - * index, and push it onto the temporary value stack. - */ -public record TupleGetInstruction( - int elementIndex, - int elementCount, - Source source -) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/VarLoadInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/VarLoadInstruction.java deleted file mode 100644 index fe35db14..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/VarLoadInstruction.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; - -/** - * Load the value stored in the var with the given name and push it onto the - * temporary value stack. - */ -public record VarLoadInstruction(String name, Source source) implements Instruction { -} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/VarStoreInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/VarStoreInstruction.java deleted file mode 100644 index 33a3ab45..00000000 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/VarStoreInstruction.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Source; - -/** - * Pop a value from the temporary value stack and store it in the var with the - * given name. - */ -public record VarStoreInstruction(String name, Source source) implements Instruction { -} -- cgit v1.2.3