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 - .../compiler/patio/PatioCodeGenCallTests.java | 6 +- .../patio/PatioCodeGenDefineEffectTests.java | 4 +- .../patio/PatioCodeGenDefineFunctionTests.java | 70 +- .../patio/PatioCodeGenDefineStructTests.java | 12 +- .../compiler/patio/PatioCodeGenDiscardTests.java | 6 +- .../compiler/patio/PatioCodeGenFieldLoadTests.java | 14 +- .../compiler/patio/PatioCodeGenIfTests.java | 36 +- .../compiler/patio/PatioCodeGenIntAddTests.java | 6 +- .../compiler/patio/PatioCodeGenIntEqualsTests.java | 6 +- .../patio/PatioCodeGenIntNotEqualTests.java | 6 +- .../compiler/patio/PatioCodeGenIntSubTests.java | 6 +- .../compiler/patio/PatioCodeGenLocalLoadTests.java | 8 +- .../patio/PatioCodeGenLocalStoreTests.java | 8 +- .../compiler/patio/PatioCodeGenLoopBreakTests.java | 4 +- .../patio/PatioCodeGenLoopContinueTests.java | 4 +- .../compiler/patio/PatioCodeGenLoopTests.java | 8 +- .../PatioCodeGenNamespaceFieldStoreTests.java | 6 +- .../patio/PatioCodeGenNamespaceImportTests.java | 4 +- .../compiler/patio/PatioCodeGenNamespaceTests.java | 20 +- .../compiler/patio/PatioCodeGenPushBoolTests.java | 10 +- .../compiler/patio/PatioCodeGenPushIntTests.java | 6 +- .../patio/PatioCodeGenPushStringTests.java | 10 +- .../compiler/patio/PatioCodeGenPushUnitTests.java | 6 +- .../compiler/patio/PatioCodeGenResumeTests.java | 6 +- .../compiler/patio/PatioCodeGenReturnTests.java | 6 +- .../compiler/patio/PatioCodeGenStringAddTests.java | 6 +- .../compiler/patio/PatioCodeGenSwitchTests.java | 20 +- .../compiler/patio/PatioCodeGenTryTests.java | 8 +- .../patio/PatioCodeGenTupleCreateTests.java | 10 +- .../compiler/patio/PatioCodeGenTupleGetTests.java | 6 +- .../compiler/patio/PatioCodeGenVarLoadTests.java | 8 +- .../compiler/patio/PatioCodeGenVarStoreTests.java | 16 +- .../compiler/shid/InstructionSerializerTests.java | 469 ++++++++++++ .../compiler/shid/ShidCodeGenAssignTests.java | 94 +++ .../compiler/shid/ShidCodeGenBlockReturnTests.java | 22 + .../compiler/shid/ShidCodeGenBoolLiteralTests.java | 22 + .../compiler/shid/ShidCodeGenCallTests.java | 41 + .../shid/ShidCodeGenEffectDefinitionTests.java | 31 + .../shid/ShidCodeGenExpressionStatementTests.java | 24 + .../compiler/shid/ShidCodeGenFieldAccessTests.java | 78 ++ .../shid/ShidCodeGenFunctionDefinitionTests.java | 75 ++ .../shid/ShidCodeGenFunctionExpressionTests.java | 71 ++ .../shid/ShidCodeGenFunctionReturnTests.java | 23 + .../shedlang/compiler/shid/ShidCodeGenIfTests.java | 98 +++ .../compiler/shid/ShidCodeGenIntAddTests.java | 28 + .../compiler/shid/ShidCodeGenIntEqualsTests.java | 27 + .../compiler/shid/ShidCodeGenIntLiteralTests.java | 22 + .../compiler/shid/ShidCodeGenIntNotEqualTests.java | 27 + .../compiler/shid/ShidCodeGenIntSubTests.java | 27 + .../compiler/shid/ShidCodeGenNamespaceTests.java | 118 +++ .../compiler/shid/ShidCodeGenReferenceTests.java | 43 ++ .../compiler/shid/ShidCodeGenResumeTests.java | 23 + .../compiler/shid/ShidCodeGenStringAddTests.java | 27 + .../shid/ShidCodeGenStringLiteralTests.java | 22 + .../shid/ShidCodeGenStructDefinitionTests.java | 40 + .../shid/ShidCodeGenSumTypeDefinitionTests.java | 30 + .../compiler/shid/ShidCodeGenTryTests.java | 63 ++ .../compiler/shid/ShidCodeGenTupleTests.java | 31 + .../compiler/shid/ShidCodeGenUnitLiteralTests.java | 22 + .../compiler/shid/ShidCodeGenValTests.java | 106 +++ .../compiler/shid/ShidCodeGenVarTests.java | 24 + .../compiler/shid/ShidCodeGenWhenTests.java | 62 ++ .../compiler/shid/ShidCodeGenWhileTests.java | 76 ++ .../shid/instructions/InstructionMatchers.java | 229 ++++++ .../shedlang/compiler/shid/instructions/Shid.java | 193 +++++ .../stackir/InstructionSerializerTests.java | 469 ------------ .../compiler/stackir/StackCompilerAssignTests.java | 94 --- .../stackir/StackCompilerBlockReturnTests.java | 22 - .../stackir/StackCompilerBoolLiteralTests.java | 22 - .../compiler/stackir/StackCompilerCallTests.java | 41 - .../StackCompilerEffectDefinitionTests.java | 31 - .../StackCompilerExpressionStatementTests.java | 24 - .../stackir/StackCompilerFieldAccessTests.java | 78 -- .../StackCompilerFunctionDefinitionTests.java | 75 -- .../StackCompilerFunctionExpressionTests.java | 71 -- .../stackir/StackCompilerFunctionReturnTests.java | 23 - .../compiler/stackir/StackCompilerIfTests.java | 98 --- .../compiler/stackir/StackCompilerIntAddTests.java | 28 - .../stackir/StackCompilerIntEqualsTests.java | 27 - .../stackir/StackCompilerIntLiteralTests.java | 22 - .../stackir/StackCompilerIntNotEqualTests.java | 27 - .../compiler/stackir/StackCompilerIntSubTests.java | 27 - .../stackir/StackCompilerNamespaceTests.java | 118 --- .../stackir/StackCompilerReferenceTests.java | 43 -- .../compiler/stackir/StackCompilerResumeTests.java | 23 - .../stackir/StackCompilerStringAddTests.java | 27 - .../stackir/StackCompilerStringLiteralTests.java | 22 - .../StackCompilerStructDefinitionTests.java | 40 - .../StackCompilerSumTypeDefinitionTests.java | 30 - .../compiler/stackir/StackCompilerTryTests.java | 63 -- .../compiler/stackir/StackCompilerTupleTests.java | 31 - .../stackir/StackCompilerUnitLiteralTests.java | 22 - .../compiler/stackir/StackCompilerValTests.java | 106 --- .../compiler/stackir/StackCompilerVarTests.java | 24 - .../compiler/stackir/StackCompilerWhenTests.java | 62 -- .../compiler/stackir/StackCompilerWhileTests.java | 76 -- .../stackir/instructions/InstructionMatchers.java | 229 ------ .../stackir/instructions/Instructions.java | 193 ----- 181 files changed, 4322 insertions(+), 4322 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 create mode 100644 src/test/java/org/shedlang/compiler/shid/InstructionSerializerTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenAssignTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenBlockReturnTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenBoolLiteralTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenCallTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenEffectDefinitionTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenExpressionStatementTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenFieldAccessTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenFunctionDefinitionTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenFunctionExpressionTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenFunctionReturnTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenIfTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenIntAddTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenIntEqualsTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenIntLiteralTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenIntNotEqualTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenIntSubTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenNamespaceTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenReferenceTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenResumeTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenStringAddTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenStringLiteralTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenStructDefinitionTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenSumTypeDefinitionTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenTryTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenTupleTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenUnitLiteralTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenValTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenVarTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenWhenTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/ShidCodeGenWhileTests.java create mode 100644 src/test/java/org/shedlang/compiler/shid/instructions/InstructionMatchers.java create mode 100644 src/test/java/org/shedlang/compiler/shid/instructions/Shid.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/InstructionSerializerTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerAssignTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerBlockReturnTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerBoolLiteralTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerCallTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerEffectDefinitionTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerExpressionStatementTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerFieldAccessTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerFunctionDefinitionTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerFunctionExpressionTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerFunctionReturnTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerIfTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerIntAddTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerIntEqualsTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerIntLiteralTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerIntNotEqualTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerIntSubTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerNamespaceTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerReferenceTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerResumeTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerStringAddTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerStringLiteralTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerStructDefinitionTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerSumTypeDefinitionTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerTryTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerTupleTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerUnitLiteralTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerValTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerVarTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerWhenTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerWhileTests.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/instructions/InstructionMatchers.java delete mode 100644 src/test/java/org/shedlang/compiler/stackir/instructions/Instructions.java (limited to 'src') 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 { -} diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenCallTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenCallTests.java index a802351e..a4ed029f 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenCallTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenCallTests.java @@ -3,7 +3,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; @@ -16,7 +16,7 @@ import static org.shedlang.compiler.patio.PatioTesting.serialize; public class PatioCodeGenCallTests { @Test public void canCallFunctionWithNoArgs(Snapshotter snapshotter) throws IOException { - var instruction = Instructions.call(0, List.of()); + var instruction = Shid.call(0, List.of()); var context = PatioCodeGenContext.EMPTY .temporaryPush(new PatioLocalRef("other")) .temporaryPush(new PatioLocalRef("receiver")); @@ -28,7 +28,7 @@ public class PatioCodeGenCallTests { @Test public void canCallFunctionWithArgs(Snapshotter snapshotter) throws IOException { - var instruction = Instructions.call(2, List.of("b", "a")); + var instruction = Shid.call(2, List.of("b", "a")); var context = PatioCodeGenContext.EMPTY .temporaryPush(new PatioLocalRef("other")) .temporaryPush(new PatioLocalRef("receiver")) diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenDefineEffectTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenDefineEffectTests.java index a6135d0a..7137affe 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenDefineEffectTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenDefineEffectTests.java @@ -2,7 +2,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; import org.shedlang.compiler.typechecker.TypeInfos; @@ -17,7 +17,7 @@ public class PatioCodeGenDefineEffectTests { @Test public void canGenerateCodeForDefineEffect(Snapshotter snapshotter) throws IOException { var effect = Effects.userDefined(NamespaceName.of("Example", "Project"), "State"); - var instruction = Instructions.defineEffect(effect); + var instruction = Shid.defineEffect(effect); var typeInfos = TypeInfos.EMPTY .addUserDefinedEffectInfo( effect, diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenDefineFunctionTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenDefineFunctionTests.java index 696876b9..b5b9d0b5 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenDefineFunctionTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenDefineFunctionTests.java @@ -6,8 +6,8 @@ import org.shedlang.compiler.ast.typed.FreeVariables; import org.shedlang.compiler.patio.ast.types.PatioTypes; import org.shedlang.compiler.patio.instructions.Patio; import org.shedlang.compiler.sources.Sources; -import org.shedlang.compiler.stackir.instructions.DefineFunctionInstruction; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.ShidDefineFunction; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; @@ -20,14 +20,14 @@ import static org.shedlang.compiler.patio.PatioTesting.serialize; public class PatioCodeGenDefineFunctionTests { @Test public void canDefineMinimalFunction(Snapshotter snapshotter) throws IOException { - var instruction = new DefineFunctionInstruction( + var instruction = new ShidDefineFunction( "f", List.of(), List.of(), FreeVariables.empty(), List.of( - Instructions.pushUnit(), - Instructions.return_() + Shid.pushUnit(), + Shid.return_() ), Sources.NULL ); @@ -40,20 +40,20 @@ public class PatioCodeGenDefineFunctionTests { @Test public void immutableFreeVariablesAreStoredInAndLoadedFromEnvironment(Snapshotter snapshotter) throws IOException { - var instruction = new DefineFunctionInstruction( + var instruction = new ShidDefineFunction( "f", List.of(), List.of(), FreeVariables.builder().plus("a", Sources.NULL).plus("b", Sources.NULL).build(), List.of( - Instructions.localLoad("a"), - Instructions.return_() + Shid.localLoad("a"), + Shid.return_() ), Sources.NULL ); var context = PatioCodeGenContext.EMPTY - .defineStackIrParam("a") - .defineStackIrParam("b"); + .defineShidParam("a") + .defineShidParam("b"); var result = PatioCodeGen.generateInstruction(instruction, context); @@ -62,20 +62,20 @@ public class PatioCodeGenDefineFunctionTests { @Test public void canCaptureFreeVariablesThatAreSetAfterDefinition(Snapshotter snapshotter) throws IOException { - var instruction = new DefineFunctionInstruction( + var instruction = new ShidDefineFunction( "f", List.of(), List.of(), FreeVariables.builder().plus("a", Sources.NULL).plus("b", Sources.NULL).build(), List.of( - Instructions.localLoad("a"), - Instructions.return_() + Shid.localLoad("a"), + Shid.return_() ), Sources.NULL ); var context = PatioCodeGenContext.EMPTY - .declareStackIrVal("a", PatioCodeGenTypes.VALUE_TYPE).context() - .declareStackIrVal("b", PatioCodeGenTypes.VALUE_TYPE).context(); + .declareShidVal("a", PatioCodeGenTypes.VALUE_TYPE).context() + .declareShidVal("b", PatioCodeGenTypes.VALUE_TYPE).context(); context = PatioCodeGen.generateInstruction(instruction, context); @@ -84,16 +84,16 @@ public class PatioCodeGenDefineFunctionTests { // into the closure upon closure creation (i.e. too soon) versus after // the free variable is set. context = context.addInstruction(Patio.localStore(Patio.localRef("a"), Patio.int_(42))); - context = context.initStackIrLocal("a"); + context = context.initShidLocal("a"); context = context.addInstruction(Patio.localStore(Patio.localRef("b"), Patio.int_(47))); - context = context.initStackIrLocal("b"); + context = context.initShidLocal("b"); snapshotter.assertSnapshot(serialize(context)); } @Test public void pointersToFreeMutableVariablesAreStoredInAndLoadedFromEnvironment(Snapshotter snapshotter) throws IOException { - var instruction = new DefineFunctionInstruction( + var instruction = new ShidDefineFunction( "f", List.of(), List.of(), @@ -102,16 +102,16 @@ public class PatioCodeGenDefineFunctionTests { .plus("b", Sources.NULL) .build(), List.of( - Instructions.localLoad("a"), - Instructions.return_() + Shid.localLoad("a"), + Shid.return_() ), Sources.NULL ); var context = PatioCodeGenContext.EMPTY - .declareStackIrVal("a", PatioTypes.DATA_POINTER).context() - .initStackIrLocal("a") - .declareStackIrVal("b", PatioTypes.DATA_POINTER).context() - .initStackIrLocal("b"); + .declareShidVal("a", PatioTypes.DATA_POINTER).context() + .initShidLocal("a") + .declareShidVal("b", PatioTypes.DATA_POINTER).context() + .initShidLocal("b"); var result = PatioCodeGen.generateInstruction(instruction, context); @@ -120,25 +120,25 @@ public class PatioCodeGenDefineFunctionTests { @Test public void positionalAndNamedParamsAreDefined(Snapshotter snapshotter) throws IOException { - var instruction = new DefineFunctionInstruction( + var instruction = new ShidDefineFunction( "f", - List.of(Instructions.param("param1"), Instructions.param("param2")), + List.of(Shid.param("param1"), Shid.param("param2")), // Define named params in non-lexical order - List.of(Instructions.param("paramB"), Instructions.param("paramC"), Instructions.param("paramA")), + List.of(Shid.param("paramB"), Shid.param("paramC"), Shid.param("paramA")), FreeVariables.builder().plus("a", Sources.NULL).plus("b", Sources.NULL).build(), List.of( - Instructions.localLoad("a"), - Instructions.localLoad("param1"), - Instructions.intAdd(), - Instructions.localLoad("paramA"), - Instructions.intAdd(), - Instructions.return_() + Shid.localLoad("a"), + Shid.localLoad("param1"), + Shid.intAdd(), + Shid.localLoad("paramA"), + Shid.intAdd(), + Shid.return_() ), Sources.NULL ); var context = PatioCodeGenContext.EMPTY - .defineStackIrParam("a") - .defineStackIrParam("b"); + .defineShidParam("a") + .defineShidParam("b"); var result = PatioCodeGen.generateInstruction(instruction, context); diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenDefineStructTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenDefineStructTests.java index d79a33fd..450dcba2 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenDefineStructTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenDefineStructTests.java @@ -2,7 +2,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; import org.shedlang.compiler.typechecker.TypeInfos; @@ -22,11 +22,11 @@ public class PatioCodeGenDefineStructTests { @Test public void canGenerateCodeForDefineStruct(Snapshotter snapshotter) throws IOException { var structType = Types.struct(NamespaceName.of("Example", "Project"), "User"); - var instruction = Instructions.defineStruct( + var instruction = Shid.defineStruct( structType, List.of( - Instructions.defineStructField("name"), - Instructions.defineStructField("isActive") + Shid.defineStructField("name"), + Shid.defineStructField("isActive") ) ); var typeInfos = TypeInfos.EMPTY @@ -51,8 +51,8 @@ public class PatioCodeGenDefineStructTests { // will suffice for now var structType1 = Types.struct(NamespaceName.of("Example", "Project"), "User"); var structType2 = Types.struct(NamespaceName.of("Example", "Project"), "Id"); - var instruction1 = Instructions.defineStruct(structType1, List.of()); - var instruction2 = Instructions.defineStruct(structType1, List.of()); + var instruction1 = Shid.defineStruct(structType1, List.of()); + var instruction2 = Shid.defineStruct(structType1, List.of()); var typeInfos = TypeInfos.EMPTY .addStructTypeInfo(structType1, StructTypeInfo.builder().build()) .addStructTypeInfo(structType2, StructTypeInfo.builder().build()); diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenDiscardTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenDiscardTests.java index da7e55de..ff66e6bb 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenDiscardTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenDiscardTests.java @@ -3,7 +3,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; @@ -15,12 +15,12 @@ import static org.shedlang.compiler.patio.PatioTesting.serialize; public class PatioCodeGenDiscardTests { @Test public void discardInstructionPopsFromTemporaryStack(Snapshotter snapshotter) throws IOException { - var stackIr = Instructions.discard(); + var shid = Shid.discard(); var context = PatioCodeGenContext.EMPTY .temporaryPush(new PatioLocalRef("a")) .temporaryPush(new PatioLocalRef("b")); - var result = PatioCodeGen.generateInstruction(stackIr, context); + var result = PatioCodeGen.generateInstruction(shid, context); snapshotter.assertSnapshot(serialize(result)); } diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenFieldLoadTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenFieldLoadTests.java index 1b313b84..24ec9c18 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenFieldLoadTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenFieldLoadTests.java @@ -3,7 +3,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; import org.shedlang.compiler.typechecker.TypeCheckerContext; @@ -20,7 +20,7 @@ public class PatioCodeGenFieldLoadTests { @Test public void canGenerateCodeForNamespaceFieldLoad(Snapshotter snapshotter) throws IOException { var namespaceName = new NamespaceName(List.of("Example", "Project")); - var stackIrInstruction = Instructions.fieldLoad(namespaceName, "y"); + var shidInstruction = Shid.fieldLoad(namespaceName, "y"); var typeInfos = TypeCheckerContext.EMPTY .addNamespaceTypeInfo( namespaceName, @@ -35,7 +35,7 @@ public class PatioCodeGenFieldLoadTests { .temporaryPush(new PatioLocalRef("a")) .temporaryPush(new PatioLocalRef("b")); - var result = PatioCodeGen.generateInstruction(stackIrInstruction, context); + var result = PatioCodeGen.generateInstruction(shidInstruction, context); snapshotter.assertSnapshot(serialize(result)); } @@ -44,7 +44,7 @@ public class PatioCodeGenFieldLoadTests { public void canGenerateCodeForStructFieldLoad(Snapshotter snapshotter) throws IOException { var namespaceName = NamespaceName.of("Example", "Project"); var structType = Types.struct(namespaceName, "User"); - var stackIrInstruction = Instructions.fieldLoad(structType, "id"); + var shidInstruction = Shid.fieldLoad(structType, "id"); var typeInfos = TypeInfos.EMPTY .addStructTypeInfo( structType, @@ -58,7 +58,7 @@ public class PatioCodeGenFieldLoadTests { .temporaryPush(new PatioLocalRef("a")) .temporaryPush(new PatioLocalRef("b")); - var result = PatioCodeGen.generateInstruction(stackIrInstruction, context); + var result = PatioCodeGen.generateInstruction(shidInstruction, context); snapshotter.assertSnapshot(serialize(result)); } @@ -67,7 +67,7 @@ public class PatioCodeGenFieldLoadTests { public void canGenerateCodeForUserDefinedEffectFieldLoad(Snapshotter snapshotter) throws IOException { var namespaceName = NamespaceName.of("Example", "Project"); var effect = Effects.userDefined(namespaceName, "State"); - var stackIrInstruction = Instructions.fieldLoad(effect, "fence"); + var shidInstruction = Shid.fieldLoad(effect, "fence"); var typeInfos = TypeInfos.EMPTY .addUserDefinedEffectInfo( effect, @@ -81,7 +81,7 @@ public class PatioCodeGenFieldLoadTests { .temporaryPush(new PatioLocalRef("a")) .temporaryPush(new PatioLocalRef("b")); - var result = PatioCodeGen.generateInstruction(stackIrInstruction, context); + var result = PatioCodeGen.generateInstruction(shidInstruction, context); snapshotter.assertSnapshot(serialize(result)); } diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenIfTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenIfTests.java index c06f0c5e..34edd733 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenIfTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenIfTests.java @@ -3,7 +3,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; @@ -16,15 +16,15 @@ import static org.shedlang.compiler.patio.PatioTesting.serialize; public class PatioCodeGenIfTests { @Test public void canGenerateCodeForIfWithNoResults(Snapshotter snapshotter) throws IOException { - var instruction = Instructions.if_( + var instruction = Shid.if_( 0, List.of( - Instructions.pushInt(1), - Instructions.discard() + Shid.pushInt(1), + Shid.discard() ), List.of( - Instructions.pushInt(101), - Instructions.discard() + Shid.pushInt(101), + Shid.discard() ) ); var context = PatioCodeGenContext.EMPTY @@ -38,17 +38,17 @@ public class PatioCodeGenIfTests { @Test public void canGenerateCodeForIfWithSingleResult(Snapshotter snapshotter) throws IOException { - var instruction = Instructions.if_( + var instruction = Shid.if_( 1, List.of( - Instructions.pushInt(1), - Instructions.pushInt(2), - Instructions.intAdd() + Shid.pushInt(1), + Shid.pushInt(2), + Shid.intAdd() ), List.of( - Instructions.pushInt(101), - Instructions.pushInt(102), - Instructions.intAdd() + Shid.pushInt(101), + Shid.pushInt(102), + Shid.intAdd() ) ); var context = PatioCodeGenContext.EMPTY @@ -62,15 +62,15 @@ public class PatioCodeGenIfTests { @Test public void canGenerateCodeForIfWithMultipleResults(Snapshotter snapshotter) throws IOException { - var instruction = Instructions.if_( + var instruction = Shid.if_( 2, List.of( - Instructions.pushInt(1), - Instructions.pushInt(2) + Shid.pushInt(1), + Shid.pushInt(2) ), List.of( - Instructions.pushInt(101), - Instructions.pushInt(102) + Shid.pushInt(101), + Shid.pushInt(102) ) ); var context = PatioCodeGenContext.EMPTY diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenIntAddTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenIntAddTests.java index 12016446..53158d0d 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenIntAddTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenIntAddTests.java @@ -3,7 +3,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; @@ -15,13 +15,13 @@ import static org.shedlang.compiler.patio.PatioTesting.serialize; public class PatioCodeGenIntAddTests { @Test public void canGenerateCodeForIntAdd(Snapshotter snapshotter) throws IOException { - var stackIr = Instructions.intAdd(); + var shid = Shid.intAdd(); var context = PatioCodeGenContext.EMPTY .temporaryPush(new PatioLocalRef("a")) .temporaryPush(new PatioLocalRef("b")) .temporaryPush(new PatioLocalRef("c")); - var result = PatioCodeGen.generateInstruction(stackIr, context); + var result = PatioCodeGen.generateInstruction(shid, context); snapshotter.assertSnapshot(serialize(result)); } diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenIntEqualsTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenIntEqualsTests.java index cc1eaf2d..8b9fe35f 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenIntEqualsTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenIntEqualsTests.java @@ -3,7 +3,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; @@ -15,13 +15,13 @@ import static org.shedlang.compiler.patio.PatioTesting.serialize; public class PatioCodeGenIntEqualsTests { @Test public void canGenerateCodeForIntEquals(Snapshotter snapshotter) throws IOException { - var stackIr = Instructions.intEquals(); + var shid = Shid.intEquals(); var context = PatioCodeGenContext.EMPTY .temporaryPush(new PatioLocalRef("a")) .temporaryPush(new PatioLocalRef("b")) .temporaryPush(new PatioLocalRef("c")); - var result = PatioCodeGen.generateInstruction(stackIr, context); + var result = PatioCodeGen.generateInstruction(shid, context); snapshotter.assertSnapshot(serialize(result)); } diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenIntNotEqualTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenIntNotEqualTests.java index 253781d3..5715f0d4 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenIntNotEqualTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenIntNotEqualTests.java @@ -3,7 +3,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; @@ -15,13 +15,13 @@ import static org.shedlang.compiler.patio.PatioTesting.serialize; public class PatioCodeGenIntNotEqualTests { @Test public void canGenerateCodeForIntNotEqual(Snapshotter snapshotter) throws IOException { - var stackIr = Instructions.intNotEqual(); + var shid = Shid.intNotEqual(); var context = PatioCodeGenContext.EMPTY .temporaryPush(new PatioLocalRef("a")) .temporaryPush(new PatioLocalRef("b")) .temporaryPush(new PatioLocalRef("c")); - var result = PatioCodeGen.generateInstruction(stackIr, context); + var result = PatioCodeGen.generateInstruction(shid, context); snapshotter.assertSnapshot(serialize(result)); } diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenIntSubTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenIntSubTests.java index 9c0ccae9..e2036764 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenIntSubTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenIntSubTests.java @@ -3,7 +3,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; @@ -15,13 +15,13 @@ import static org.shedlang.compiler.patio.PatioTesting.serialize; public class PatioCodeGenIntSubTests { @Test public void canGenerateCodeForIntSub(Snapshotter snapshotter) throws IOException { - var stackIr = Instructions.intSub(); + var shid = Shid.intSub(); var context = PatioCodeGenContext.EMPTY .temporaryPush(new PatioLocalRef("a")) .temporaryPush(new PatioLocalRef("b")) .temporaryPush(new PatioLocalRef("c")); - var result = PatioCodeGen.generateInstruction(stackIr, context); + var result = PatioCodeGen.generateInstruction(shid, context); snapshotter.assertSnapshot(serialize(result)); } diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenLocalLoadTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenLocalLoadTests.java index 7e6b5705..f452583b 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenLocalLoadTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenLocalLoadTests.java @@ -2,7 +2,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; @@ -14,11 +14,11 @@ import static org.shedlang.compiler.patio.PatioTesting.serialize; public class PatioCodeGenLocalLoadTests { @Test public void localLoadPushesLocalOntoStack(Snapshotter snapshotter) throws IOException { - var stackIr = Instructions.localLoad("x"); + var shid = Shid.localLoad("x"); var context = PatioCodeGenContext.EMPTY - .defineStackIrParam("x"); + .defineShidParam("x"); - var result = PatioCodeGen.generateInstruction(stackIr, context); + var result = PatioCodeGen.generateInstruction(shid, context); snapshotter.assertSnapshot(serialize(result)); } diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenLocalStoreTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenLocalStoreTests.java index dd37b35f..00b50c44 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenLocalStoreTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenLocalStoreTests.java @@ -3,7 +3,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; @@ -15,13 +15,13 @@ import static org.shedlang.compiler.patio.PatioTesting.serialize; public class PatioCodeGenLocalStoreTests { @Test public void localStorePopsTemporaryIntoLocal(Snapshotter snapshotter) throws IOException { - var stackIr = Instructions.localStore("x"); + var shid = Shid.localStore("x"); var context = PatioCodeGenContext.EMPTY - .declareStackIrVal("x", PatioCodeGenTypes.VALUE_TYPE).context() + .declareShidVal("x", PatioCodeGenTypes.VALUE_TYPE).context() .temporaryPush(new PatioLocalRef("a")) .temporaryPush(new PatioLocalRef("b")); - var result = PatioCodeGen.generateInstruction(stackIr, context); + var result = PatioCodeGen.generateInstruction(shid, context); snapshotter.assertSnapshot(serialize(result)); } diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenLoopBreakTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenLoopBreakTests.java index 76a3799c..16ab525d 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenLoopBreakTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenLoopBreakTests.java @@ -2,7 +2,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; @@ -14,7 +14,7 @@ import static org.shedlang.compiler.patio.PatioTesting.serialize; public class PatioCodeGenLoopBreakTests { @Test public void canGenerateCodeForLoopBreak(Snapshotter snapshotter) throws IOException { - var instruction = Instructions.loopBreak(); + var instruction = Shid.loopBreak(); var context = PatioCodeGenContext.EMPTY; var result = PatioCodeGen.generateInstruction(instruction, context); diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenLoopContinueTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenLoopContinueTests.java index 281f6dcd..0e9372fc 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenLoopContinueTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenLoopContinueTests.java @@ -2,7 +2,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; @@ -14,7 +14,7 @@ import static org.shedlang.compiler.patio.PatioTesting.serialize; public class PatioCodeGenLoopContinueTests { @Test public void canGenerateCodeForLoopContinue(Snapshotter snapshotter) throws IOException { - var instruction = Instructions.loopContinue(); + var instruction = Shid.loopContinue(); var context = PatioCodeGenContext.EMPTY; var result = PatioCodeGen.generateInstruction(instruction, context); diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenLoopTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenLoopTests.java index ff74a17b..6a9648db 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenLoopTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenLoopTests.java @@ -2,7 +2,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; @@ -15,10 +15,10 @@ import static org.shedlang.compiler.patio.PatioTesting.serialize; public class PatioCodeGenLoopTests { @Test public void canGenerateCodeForLoop(Snapshotter snapshotter) throws IOException { - var instruction = Instructions.loop( + var instruction = Shid.loop( List.of( - Instructions.pushInt(1), - Instructions.discard() + Shid.pushInt(1), + Shid.discard() ) ); var context = PatioCodeGenContext.EMPTY; diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenNamespaceFieldStoreTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenNamespaceFieldStoreTests.java index c905d0ce..254249e0 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenNamespaceFieldStoreTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenNamespaceFieldStoreTests.java @@ -3,7 +3,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; import org.shedlang.compiler.typechecker.TypeCheckerContext; @@ -21,7 +21,7 @@ public class PatioCodeGenNamespaceFieldStoreTests { @Test public void canGenerateCodeForNamespaceFieldStore(Snapshotter snapshotter) throws IOException { var namespaceName = new NamespaceName(List.of("Example", "Project")); - var stackIrInstruction = Instructions.namespaceFieldStore(namespaceName, "y"); + var shidInstruction = Shid.namespaceFieldStore(namespaceName, "y"); var typeInfo = TypeCheckerContext.EMPTY .addNamespaceTypeInfo( namespaceName, @@ -36,7 +36,7 @@ public class PatioCodeGenNamespaceFieldStoreTests { .temporaryPush(new PatioLocalRef("a")) .temporaryPush(new PatioLocalRef("b")); - var result = PatioCodeGen.generateInstruction(stackIrInstruction, context); + var result = PatioCodeGen.generateInstruction(shidInstruction, context); snapshotter.assertSnapshot(serialize(result)); } diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenNamespaceImportTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenNamespaceImportTests.java index 705e90dc..f86388cb 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenNamespaceImportTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenNamespaceImportTests.java @@ -2,7 +2,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; import org.shedlang.compiler.types.NamespaceName; @@ -17,7 +17,7 @@ public class PatioCodeGenNamespaceImportTests { @Test public void canGenerateCodeForNamespaceImport(Snapshotter snapshotter) throws IOException { var namespaceName = new NamespaceName(List.of("Example", "Project")); - var instruction = Instructions.namespaceImport(namespaceName); + var instruction = Shid.namespaceImport(namespaceName); var context = PatioCodeGenContext.EMPTY; var result = PatioCodeGen.generateInstruction(instruction, context); diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenNamespaceTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenNamespaceTests.java index 2a3154ef..852eda6f 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenNamespaceTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenNamespaceTests.java @@ -4,10 +4,10 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.shedlang.compiler.ast.typed.FreeVariables; import org.shedlang.compiler.sources.Sources; -import org.shedlang.compiler.stackir.StackIrNamespace; -import org.shedlang.compiler.stackir.instructions.DefineFunctionInstruction; -import org.shedlang.compiler.stackir.instructions.Instruction; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.ShidNamespace; +import org.shedlang.compiler.shid.instructions.ShidDefineFunction; +import org.shedlang.compiler.shid.instructions.ShidInstruction; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; import org.shedlang.compiler.typechecker.TypeInfos; @@ -24,18 +24,18 @@ import static org.shedlang.compiler.patio.PatioTesting.serializeCompilationUnit; public class PatioCodeGenNamespaceTests { @Test public void canDefineNamespace(Snapshotter snapshotter) throws IOException { - var instruction = new DefineFunctionInstruction( + var instruction = new ShidDefineFunction( "f", List.of(), List.of(), FreeVariables.empty(), List.of( - Instructions.pushUnit(), - Instructions.return_() + Shid.pushUnit(), + Shid.return_() ), Sources.NULL ); - var instructions = List.of(instruction); + var instructions = List.of(instruction); var namespaceName = NamespaceName.of("An","Example"); var typeInfos = TypeInfos.EMPTY .addNamespaceTypeInfo( @@ -46,9 +46,9 @@ public class PatioCodeGenNamespaceTests { .build() ); var context = PatioCodeGenContext.forTypeInfos(typeInfos); - var stackIrNamespace = new StackIrNamespace(namespaceName, instructions); + var shidNamespace = new ShidNamespace(namespaceName, instructions); - var result = PatioCodeGen.generateNamespace(stackIrNamespace, context); + var result = PatioCodeGen.generateNamespace(shidNamespace, context); snapshotter.assertSnapshot(serializeCompilationUnit(result)); } diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenPushBoolTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenPushBoolTests.java index 8045decf..4b3c869c 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenPushBoolTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenPushBoolTests.java @@ -2,7 +2,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; @@ -14,20 +14,20 @@ import static org.shedlang.compiler.patio.PatioTesting.serialize; public class PatioCodeGenPushBoolTests { @Test public void pushBoolFalseInstructionGeneratesIntGetZeroInstruction(Snapshotter snapshotter) throws IOException { - var stackIr = Instructions.pushBool(false); + var shid = Shid.pushBool(false); var context = PatioCodeGenContext.EMPTY; - var result = PatioCodeGen.generateInstruction(stackIr, context); + var result = PatioCodeGen.generateInstruction(shid, context); snapshotter.assertSnapshot(serialize(result)); } @Test public void pushBoolTrueInstructionGeneratesIntGetOneInstruction(Snapshotter snapshotter) throws IOException { - var stackIr = Instructions.pushBool(true); + var shid = Shid.pushBool(true); var context = PatioCodeGenContext.EMPTY; - var result = PatioCodeGen.generateInstruction(stackIr, context); + var result = PatioCodeGen.generateInstruction(shid, context); snapshotter.assertSnapshot(serialize(result)); } diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenPushIntTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenPushIntTests.java index b1790fda..0996f981 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenPushIntTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenPushIntTests.java @@ -2,7 +2,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; @@ -14,10 +14,10 @@ import static org.shedlang.compiler.patio.PatioTesting.serialize; public class PatioCodeGenPushIntTests { @Test public void pushIntInstructionGeneratesIntGetInstruction(Snapshotter snapshotter) throws IOException { - var stackIr = Instructions.pushInt(42); + var shid = Shid.pushInt(42); var context = PatioCodeGenContext.EMPTY; - var result = PatioCodeGen.generateInstruction(stackIr, context); + var result = PatioCodeGen.generateInstruction(shid, context); snapshotter.assertSnapshot(serialize(result)); } diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenPushStringTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenPushStringTests.java index 28989deb..3a878afe 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenPushStringTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenPushStringTests.java @@ -2,7 +2,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; @@ -14,10 +14,10 @@ import static org.shedlang.compiler.patio.PatioTesting.serialize; public class PatioCodeGenPushStringTests { @Test public void pushStringIsCompiledToDataAndIndexToData(Snapshotter snapshotter) throws IOException { - var stackIrInstruction = Instructions.pushString("hello"); + var shidInstruction = Shid.pushString("hello"); var context = PatioCodeGenContext.EMPTY; - var result = PatioCodeGen.generateInstruction(stackIrInstruction, context); + var result = PatioCodeGen.generateInstruction(shidInstruction, context); snapshotter.assertSnapshot(serialize(result)); } @@ -26,8 +26,8 @@ public class PatioCodeGenPushStringTests { public void canHaveMultipleStrings(Snapshotter snapshotter) throws IOException { var context = PatioCodeGenContext.EMPTY; - var result = PatioCodeGen.generateInstruction(Instructions.pushString("hello"), context); - result = PatioCodeGen.generateInstruction(Instructions.pushString("world"), result); + var result = PatioCodeGen.generateInstruction(Shid.pushString("hello"), context); + result = PatioCodeGen.generateInstruction(Shid.pushString("world"), result); snapshotter.assertSnapshot(serialize(result)); } diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenPushUnitTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenPushUnitTests.java index 3aec3619..d1aa4bd8 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenPushUnitTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenPushUnitTests.java @@ -2,7 +2,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; @@ -14,10 +14,10 @@ import static org.shedlang.compiler.patio.PatioTesting.serialize; public class PatioCodeGenPushUnitTests { @Test public void pushUnitInstructionGeneratesIntGetInstruction(Snapshotter snapshotter) throws IOException { - var stackIr = Instructions.pushUnit(); + var shid = Shid.pushUnit(); var context = PatioCodeGenContext.EMPTY; - var result = PatioCodeGen.generateInstruction(stackIr, context); + var result = PatioCodeGen.generateInstruction(shid, context); snapshotter.assertSnapshot(serialize(result)); } diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenResumeTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenResumeTests.java index 5f23b926..57d16015 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenResumeTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenResumeTests.java @@ -3,7 +3,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; @@ -15,12 +15,12 @@ import static org.shedlang.compiler.patio.PatioTesting.serialize; public class PatioCodeGenResumeTests { @Test public void resumeInstructionGeneratesResumeInstruction(Snapshotter snapshotter) throws IOException { - var stackIr = Instructions.resume(); + var shid = Shid.resume(); var context = PatioCodeGenContext.EMPTY .temporaryPush(new PatioLocalRef("a")) .temporaryPush(new PatioLocalRef("b")); - var result = PatioCodeGen.generateInstruction(stackIr, context); + var result = PatioCodeGen.generateInstruction(shid, context); snapshotter.assertSnapshot(serialize(result)); } diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenReturnTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenReturnTests.java index 760f23e8..9a7166c5 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenReturnTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenReturnTests.java @@ -3,7 +3,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; @@ -15,12 +15,12 @@ import static org.shedlang.compiler.patio.PatioTesting.serialize; public class PatioCodeGenReturnTests { @Test public void returnInstructionGeneratesReturnInstruction(Snapshotter snapshotter) throws IOException { - var stackIr = Instructions.return_(); + var shid = Shid.return_(); var context = PatioCodeGenContext.EMPTY .temporaryPush(new PatioLocalRef("a")) .temporaryPush(new PatioLocalRef("b")); - var result = PatioCodeGen.generateInstruction(stackIr, context); + var result = PatioCodeGen.generateInstruction(shid, context); snapshotter.assertSnapshot(serialize(result)); } diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenStringAddTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenStringAddTests.java index 0ff8dade..8eb09cb7 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenStringAddTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenStringAddTests.java @@ -3,7 +3,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; @@ -15,13 +15,13 @@ import static org.shedlang.compiler.patio.PatioTesting.serialize; public class PatioCodeGenStringAddTests { @Test public void canGenerateCodeForStringAdd(Snapshotter snapshotter) throws IOException { - var stackIr = Instructions.stringAdd(); + var shid = Shid.stringAdd(); var context = PatioCodeGenContext.EMPTY .temporaryPush(new PatioLocalRef("a")) .temporaryPush(new PatioLocalRef("b")) .temporaryPush(new PatioLocalRef("c")); - var result = PatioCodeGen.generateInstruction(stackIr, context); + var result = PatioCodeGen.generateInstruction(shid, context); snapshotter.assertSnapshot(serialize(result)); } diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenSwitchTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenSwitchTests.java index 979743e3..58463cb4 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenSwitchTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenSwitchTests.java @@ -3,7 +3,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; import org.shedlang.compiler.typechecker.TypeInfos; @@ -23,22 +23,22 @@ public class PatioCodeGenSwitchTests { var namespaceName = NamespaceName.of("Example", "Project"); var structType1 = Types.struct(namespaceName, "A"); var structType2 = Types.struct(namespaceName, "B"); - var instruction = Instructions.switch_( + var instruction = Shid.switch_( List.of( - Instructions.switchCase( + Shid.switchCase( structType1, List.of( - Instructions.pushInt(1), - Instructions.pushInt(2), - Instructions.intAdd() + Shid.pushInt(1), + Shid.pushInt(2), + Shid.intAdd() ) ), - Instructions.switchCase( + Shid.switchCase( structType2, List.of( - Instructions.pushInt(101), - Instructions.pushInt(102), - Instructions.intAdd() + Shid.pushInt(101), + Shid.pushInt(102), + Shid.intAdd() ) ) ) diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenTryTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenTryTests.java index 1a9535d1..f534534c 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenTryTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenTryTests.java @@ -3,7 +3,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; import org.shedlang.compiler.typechecker.TypeCheckerContext; @@ -20,11 +20,11 @@ public class PatioCodeGenTryTests { public void canGenerateCodeForTry(Snapshotter snapshotter) throws IOException { var namespaceName = new NamespaceName(List.of("Example", "Project")); var effect = Effects.userDefined(namespaceName, "State"); - var stackIrInstruction = Instructions.try_( + var shidInstruction = Shid.try_( effect, List.of("a", "c", "b"), List.of( - Instructions.pushInt(42) + Shid.pushInt(42) ) ); var typeInfos = TypeCheckerContext.EMPTY @@ -43,7 +43,7 @@ public class PatioCodeGenTryTests { .temporaryPush(new PatioLocalRef("handlerC")) .temporaryPush(new PatioLocalRef("handlerB")); - var result = PatioCodeGen.generateInstruction(stackIrInstruction, context); + var result = PatioCodeGen.generateInstruction(shidInstruction, context); snapshotter.assertSnapshot(serialize(result)); } diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenTupleCreateTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenTupleCreateTests.java index e489fb37..d5cb6ef1 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenTupleCreateTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenTupleCreateTests.java @@ -3,7 +3,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; @@ -15,24 +15,24 @@ import static org.shedlang.compiler.patio.PatioTesting.serialize; public class PatioCodeGenTupleCreateTests { @Test public void canGenerateCodeForTupleCreate(Snapshotter snapshotter) throws IOException { - var stackIr = Instructions.tupleCreate(3); + var shid = Shid.tupleCreate(3); var context = PatioCodeGenContext.EMPTY .temporaryPush(new PatioLocalRef("a")) .temporaryPush(new PatioLocalRef("b")) .temporaryPush(new PatioLocalRef("c")) .temporaryPush(new PatioLocalRef("d")); - var result = PatioCodeGen.generateInstruction(stackIr, context); + var result = PatioCodeGen.generateInstruction(shid, context); snapshotter.assertSnapshot(serialize(result)); } @Test public void zeroElementTupleIsCreatedWithoutAlloc(Snapshotter snapshotter) throws IOException { - var stackIr = Instructions.tupleCreate(0); + var shid = Shid.tupleCreate(0); var context = PatioCodeGenContext.EMPTY; - var result = PatioCodeGen.generateInstruction(stackIr, context); + var result = PatioCodeGen.generateInstruction(shid, context); snapshotter.assertSnapshot(serialize(result)); } diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenTupleGetTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenTupleGetTests.java index fc1cf272..41a037b0 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenTupleGetTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenTupleGetTests.java @@ -3,7 +3,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; @@ -15,12 +15,12 @@ import static org.shedlang.compiler.patio.PatioTesting.serialize; public class PatioCodeGenTupleGetTests { @Test public void canGenerateCodeForTupleGet(Snapshotter snapshotter) throws IOException { - var stackIr = Instructions.tupleGet(2, 3); + var shid = Shid.tupleGet(2, 3); var context = PatioCodeGenContext.EMPTY .temporaryPush(new PatioLocalRef("a")) .temporaryPush(new PatioLocalRef("b")); - var result = PatioCodeGen.generateInstruction(stackIr, context); + var result = PatioCodeGen.generateInstruction(shid, context); snapshotter.assertSnapshot(serialize(result)); } diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenVarLoadTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenVarLoadTests.java index 4cff0dd4..3eae5cf9 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenVarLoadTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenVarLoadTests.java @@ -3,7 +3,7 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.shedlang.compiler.patio.ast.types.PatioTypes; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; @@ -15,11 +15,11 @@ import static org.shedlang.compiler.patio.PatioTesting.serialize; public class PatioCodeGenVarLoadTests { @Test public void canGenerateCodeForVarLoad(Snapshotter snapshotter) throws IOException { - var stackIr = Instructions.varLoad("x"); + var shid = Shid.varLoad("x"); var context = PatioCodeGenContext.EMPTY - .declareStackIrVal("x", PatioTypes.DATA_POINTER).context(); + .declareShidVal("x", PatioTypes.DATA_POINTER).context(); - var result = PatioCodeGen.generateInstruction(stackIr, context); + var result = PatioCodeGen.generateInstruction(shid, context); snapshotter.assertSnapshot(serialize(result)); } diff --git a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenVarStoreTests.java b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenVarStoreTests.java index 66038785..4f9d4430 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioCodeGenVarStoreTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioCodeGenVarStoreTests.java @@ -4,7 +4,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; import org.shedlang.compiler.patio.ast.types.PatioTypes; -import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.shid.instructions.Shid; import org.shedlang.compiler.testing.snapshots.SnapshotResolver; import org.shedlang.compiler.testing.snapshots.Snapshotter; @@ -16,27 +16,27 @@ import static org.shedlang.compiler.patio.PatioTesting.serialize; public class PatioCodeGenVarStoreTests { @Test public void canGenerateCodeForVarStore(Snapshotter snapshotter) throws IOException { - var stackIr = Instructions.varStore("x"); + var shid = Shid.varStore("x"); var context = PatioCodeGenContext.EMPTY - .declareStackIrVal("x", PatioTypes.DATA_POINTER).context() + .declareShidVal("x", PatioTypes.DATA_POINTER).context() .temporaryPush(new PatioLocalRef("a")) .temporaryPush(new PatioLocalRef("b")); - var result = PatioCodeGen.generateInstruction(stackIr, context); + var result = PatioCodeGen.generateInstruction(shid, context); snapshotter.assertSnapshot(serialize(result)); } @Test public void canStoreIntoVarMultipleTimes(Snapshotter snapshotter) throws IOException { - var stackIr = Instructions.varStore("x"); + var shid = Shid.varStore("x"); var context = PatioCodeGenContext.EMPTY - .declareStackIrVal("x", PatioTypes.DATA_POINTER).context() + .declareShidVal("x", PatioTypes.DATA_POINTER).context() .temporaryPush(new PatioLocalRef("a")) .temporaryPush(new PatioLocalRef("b")); - var result = PatioCodeGen.generateInstruction(stackIr, context); - result = PatioCodeGen.generateInstruction(stackIr, result); + var result = PatioCodeGen.generateInstruction(shid, context); + result = PatioCodeGen.generateInstruction(shid, result); snapshotter.assertSnapshot(serialize(result)); } diff --git a/src/test/java/org/shedlang/compiler/shid/InstructionSerializerTests.java b/src/test/java/org/shedlang/compiler/shid/InstructionSerializerTests.java new file mode 100644 index 00000000..9f6bdcf1 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/InstructionSerializerTests.java @@ -0,0 +1,469 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.shid.instructions.ShidDefineFunction; +import org.shedlang.compiler.shid.instructions.ShidInstruction; +import org.shedlang.compiler.shid.instructions.Shid; +import org.shedlang.compiler.types.Effects; +import org.shedlang.compiler.types.NamespaceName; +import org.shedlang.compiler.types.Types; + +import java.util.List; + +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.equalTo; + +public class InstructionSerializerTests { + @Test + public void canSerializeCall() { + var instruction = Shid.call(1, List.of("x", "y")); + + var string = serialize(instruction); + + assertThat(string, equalTo("(call positional-arg-count=1 named-arg-names=(\"x\" \"y\"))")); + } + + @Test + public void canSerializeDefineEffect() { + var instruction = Shid.defineEffect( + Effects.userDefined(NamespaceName.of("Example", "Project"), "State") + ); + + var string = serialize(instruction); + + assertThat(string, equalTo(""" + (define-effect "Example/Project.State")""" + )); + } + + @Test + public void canSerializeDefineFunction() { + var instruction = ShidDefineFunction.builder() + .withName("f") + .addPositionalParam("p1") + .addPositionalParam("p2") + .addNamedParam("n1") + .addNamedParam("n2") + .addFreeVariable("fv1") + .addFreeVariable("fv2") + .addBodyInstruction(Shid.pushBool(true)) + .addBodyInstruction(Shid.pushBool(false)) + .build(); + + var string = serialize(instruction); + + assertThat(string, equalTo(""" + ( + define-function + name="f" + positional-params=("p1" "p2") + named-params=("n1" "n2") + free-variables=("fv1" "fv2") + body=( + (push-bool true) + (push-bool false) + ) + )""")); + } + + @Test + public void canSerializeDefineStruct() { + var instruction = Shid.defineStruct( + Types.struct(NamespaceName.of("Example", "Project"), "User"), + List.of( + Shid.defineStructField("name"), + Shid.defineStructField("id") + ) + ); + + var string = serialize(instruction); + + assertThat(string, equalTo(""" + ( + define-struct + type="Example/Project.User" + fields=("name" "id") + )""")); + } + + @Test + public void canSerializeDiscard() { + var instruction = Shid.discard(); + + var string = serialize(instruction); + + assertThat(string, equalTo("(discard)")); + } + + @Test + public void canSerializeDuplicate() { + var instruction = Shid.duplicate(); + + var string = serialize(instruction); + + assertThat(string, equalTo("(duplicate)")); + } + + @Test + public void canSerializeNamespaceFieldLoad() { + var instruction = Shid.fieldLoad( + new NamespaceName(List.of("Example", "Lib")), + "x" + ); + + var string = serialize(instruction); + + assertThat(string, equalTo("(field-load (namespace \"Example/Lib\") \"x\")")); + } + + @Test + public void canSerializeStructFieldLoad() { + var instruction = Shid.fieldLoad( + Types.struct(NamespaceName.of("Example", "Project"), "User"), + "name" + ); + + var string = serialize(instruction); + + assertThat(string, equalTo("(field-load (struct \"Example/Project.User\") \"name\")")); + } + + @Test + public void canSerializeUserDefinedEffectFieldLoad() { + var instruction = Shid.fieldLoad( + Effects.userDefined(NamespaceName.of("Example", "Project"), "State"), + "read" + ); + + var string = serialize(instruction); + + assertThat(string, equalTo("(field-load (effect \"Example/Project.State\") \"read\")")); + } + + @Test + public void canSerializeIf() { + var instruction = Shid.if_( + 1, + List.of( + Shid.pushUnit() + ), + List.of( + Shid.localLoad("x"), + Shid.discard(), + Shid.pushBool(true) + ) + ); + + var string = serialize(instruction); + + assertThat(string, equalTo(""" + ( + if + result-count=1 + ( + (push-unit) + ) + ( + (local-load "x") + (discard) + (push-bool true) + ) + )""")); + } + + @Test + public void canSerializeIntAdd() { + var instruction = Shid.intAdd(); + + var string = serialize(instruction); + + assertThat(string, equalTo("(int-add)")); + } + + @Test + public void canSerializeIntEquals() { + var instruction = Shid.intEquals(); + + var string = serialize(instruction); + + assertThat(string, equalTo("(int-eq)")); + } + + @Test + public void canSerializeIntNotEqual() { + var instruction = Shid.intNotEqual(); + + var string = serialize(instruction); + + assertThat(string, equalTo("(int-ne)")); + } + + @Test + public void canSerializeIntSub() { + var instruction = Shid.intSub(); + + var string = serialize(instruction); + + assertThat(string, equalTo("(int-sub)")); + } + + @Test + public void canSerializeLocalLoad() { + var instruction = Shid.localLoad("x"); + + var string = serialize(instruction); + + assertThat(string, equalTo("(local-load \"x\")")); + } + + @Test + public void canSerializeLocalStore() { + var instruction = Shid.localStore("x"); + + var string = serialize(instruction); + + assertThat(string, equalTo("(local-store \"x\")")); + } + + @Test + public void canSerializeLoop() { + var instruction = Shid.loop( + List.of( + Shid.localLoad("x"), + Shid.discard() + ) + ); + + var string = serialize(instruction); + + assertThat(string, equalTo(""" + ( + loop + ( + (local-load "x") + (discard) + ) + )""")); + } + + @Test + public void canSerializeLoopBreak() { + var instruction = Shid.loopBreak(); + + var string = serialize(instruction); + + assertThat(string, equalTo("(break)")); + } + + @Test + public void canSerializeLoopContinue() { + var instruction = Shid.loopContinue(); + + var string = serialize(instruction); + + assertThat(string, equalTo("(continue)")); + } + + @Test + public void canSerializeNamespaceFieldStore() { + var instruction = Shid.namespaceFieldStore( + new NamespaceName(List.of("Example", "Lib")), + "x" + ); + + var string = serialize(instruction); + + assertThat(string, equalTo("(namespace-field-store \"Example/Lib\" \"x\")")); + } + + @Test + public void canSerializeNamespaceImport() { + var instruction = Shid.namespaceImport( + new NamespaceName(List.of("Example", "Lib")) + ); + + var string = serialize(instruction); + + assertThat(string, equalTo("(namespace-import \"Example/Lib\")")); + } + + @Test + public void canSerializePushBool() { + var instruction = Shid.pushBool(true); + + var string = serialize(instruction); + + assertThat(string, equalTo("(push-bool true)")); + } + + @Test + public void canSerializePushInt() { + var instruction = Shid.pushInt(42); + + var string = serialize(instruction); + + assertThat(string, equalTo("(push-int 42)")); + } + + @Test + public void canSerializePushString() { + var instruction = Shid.pushString("hello"); + + var string = serialize(instruction); + + assertThat(string, equalTo("(push-string \"hello\")")); + } + + @Test + public void specialCharactersInStringAreEscaped() { + var instruction = Shid.pushString("\b\t\n\f\r\"\\"); + + var string = serialize(instruction); + + assertThat(string, equalTo("(push-string \"\\b\\t\\n\\f\\r\\\"\\\\\")")); + } + + @Test + public void canSerializePushUnit() { + var instruction = Shid.pushUnit(); + + var string = serialize(instruction); + + assertThat(string, equalTo("(push-unit)")); + } + + @Test + public void canSerializeResume() { + var instruction = Shid.resume(); + + var string = serialize(instruction); + + assertThat(string, equalTo("(resume)")); + } + + @Test + public void canSerializeReturn() { + var instruction = Shid.return_(); + + var string = serialize(instruction); + + assertThat(string, equalTo("(return)")); + } + + @Test + public void canSerializeStringAdd() { + var instruction = Shid.stringAdd(); + + var string = serialize(instruction); + + assertThat(string, equalTo("(string-add)")); + } + + @Test + public void canSerializeSwitch() { + var instruction = Shid.switch_(List.of( + Shid.switchCase( + Types.struct(NamespaceName.of("Example", "Project"), "A"), + List.of( + Shid.return_() + ) + ), + Shid.switchCase( + Types.struct(NamespaceName.of("Example", "Project"), "B"), + List.of( + Shid.discard() + ) + ) + )); + + var string = serialize(instruction); + + assertThat(string, equalTo(""" + ( + switch + ( + ( + "Example/Project.A" + ( + (return) + ) + ) + ( + "Example/Project.B" + ( + (discard) + ) + ) + ) + )""" + )); + } + @Test + public void canSerializeTry() { + var effect = Effects.userDefined(NamespaceName.of("Example", "Project"), "State"); + var instruction = Shid.try_( + effect, + List.of("read", "write"), + List.of( + Shid.pushUnit() + ) + ); + + var string = serialize(instruction); + + assertThat(string, equalTo(""" + ( + try + "Example/Project.State" + ( + "read" + "write" + ) + ( + (push-unit) + ) + )""")); + } + + @Test + public void canSerializeTupleCreate() { + var instruction = Shid.tupleCreate(2); + + var string = serialize(instruction); + + assertThat(string, equalTo("(tuple-create 2)")); + } + + @Test + public void canSerializeTupleGet() { + var instruction = Shid.tupleGet(2, 3); + + var string = serialize(instruction); + + assertThat(string, equalTo("(tuple-get 2 3)")); + } + + @Test + public void canSerializeVarLoad() { + var instruction = Shid.varLoad("x"); + + var string = serialize(instruction); + + assertThat(string, equalTo("(var-load \"x\")")); + } + + @Test + public void canSerializeVarStore() { + var instruction = Shid.varStore("x"); + + var string = serialize(instruction); + + assertThat(string, equalTo("(var-store \"x\")")); + } + + private String serialize(ShidInstruction instruction) { + var builder = new StringBuilder(); + InstructionSerializer.serializeInstruction(instruction, builder); + return builder.toString(); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenAssignTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenAssignTests.java new file mode 100644 index 00000000..65e30e5a --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenAssignTests.java @@ -0,0 +1,94 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; + +import java.util.List; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.*; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ShidCodeGenAssignTests { + @Test + public void targetIgnoreIsCompiledToDiscard() { + var node = Typed.assign( + Typed.targetIgnore(), + Typed.reference("x") + ); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("x"); + + var result = ShidCodeGen.compileFunctionStatement(node, context); + + assertThat(result.instructions(), isSequence( + isLocalLoadInstruction("x__0"), + isDiscardInstruction() + )); + } + + @Test + public void whenTargetIsReassignThenExpressionIsEvaluatedAndStoredAsVar() { + var node = Typed.assign( + Typed.targetReassign("x"), + Typed.stringLiteral("hello") + ); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("x"); + + var result = ShidCodeGen.compileFunctionStatement(node, context); + + assertThat(result.instructions(), isSequence( + isPushStringInstruction("hello"), + isVarStoreInstruction("x__0") + )); + } + + @Test + public void whenTargetIsTupleThenExpressionIsDeconstructed() { + var node = Typed.assign( + Typed.targetTuple(List.of( + Typed.targetVal("a"), + Typed.targetVal("b"), + Typed.targetVal("c") + )), + Typed.reference("x") + ); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("x") + .addShedVal("a") + .addShedVal("b") + .addShedVal("c"); + + var result = ShidCodeGen.compileFunctionStatement(node, context); + + assertThat(result.instructions(), isSequence( + isLocalLoadInstruction("x__0"), + isDuplicateInstruction(), + isTupleGetInstruction(0), + isLocalStoreInstruction("a__0"), + isDuplicateInstruction(), + isTupleGetInstruction(1), + isLocalStoreInstruction("b__0"), + isTupleGetInstruction(2), + isLocalStoreInstruction("c__0") + )); + } + + @Test + public void deconstructingEmptyTupleDiscardsExpression() { + var node = Typed.assign( + Typed.targetTuple(List.of()), + Typed.reference("x") + ); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("x"); + + var result = ShidCodeGen.compileFunctionStatement(node, context); + + assertThat(result.instructions(), isSequence( + isLocalLoadInstruction("x__0"), + isDiscardInstruction() + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenBlockReturnTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenBlockReturnTests.java new file mode 100644 index 00000000..082560b7 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenBlockReturnTests.java @@ -0,0 +1,22 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.isPushStringInstruction; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ShidCodeGenBlockReturnTests { + @Test + public void expressionIsEvaluated() { + var node = Typed.blockReturn(Typed.stringLiteral("hello")); + var context = ShidCodeGen.Context.EMPTY; + + var result = ShidCodeGen.compileFunctionStatement(node, context); + + assertThat(result.instructions(), isSequence( + isPushStringInstruction("hello") + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenBoolLiteralTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenBoolLiteralTests.java new file mode 100644 index 00000000..965f9b3c --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenBoolLiteralTests.java @@ -0,0 +1,22 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.isPushBoolInstruction; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ShidCodeGenBoolLiteralTests { + @Test + public void boolLiteralIsCompiledToPushBoolInstruction() { + var node = Typed.boolLiteral(true); + var context = ShidCodeGen.Context.EMPTY; + + var result = ShidCodeGen.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + isPushBoolInstruction(true) + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenCallTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenCallTests.java new file mode 100644 index 00000000..5d14cc31 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenCallTests.java @@ -0,0 +1,41 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; + +import java.util.List; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.*; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ShidCodeGenCallTests { + @Test + public void callIsCompiledToInstructionsForOperandThenCall() { + var node = Typed.call( + Typed.reference("f"), + List.of( + Typed.stringLiteral("p1"), + Typed.stringLiteral("p2") + + ), + List.of( + Typed.namedArg("x2", Typed.stringLiteral("n2")), + Typed.namedArg("x1", Typed.stringLiteral("n1")) + ) + ); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("f"); + + var result = ShidCodeGen.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + isLocalLoadInstruction("f__0"), + isPushStringInstruction("p1"), + isPushStringInstruction("p2"), + isPushStringInstruction("n2"), + isPushStringInstruction("n1"), + isCallInstruction(2, List.of("x2", "x1")) + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenEffectDefinitionTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenEffectDefinitionTests.java new file mode 100644 index 00000000..4777f5a7 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenEffectDefinitionTests.java @@ -0,0 +1,31 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; +import org.shedlang.compiler.shid.instructions.ShidDefineEffect; +import org.shedlang.compiler.types.Effects; +import org.shedlang.compiler.types.NamespaceName; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.isLocalStoreInstruction; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.*; + +public class ShidCodeGenEffectDefinitionTests { + @Test + public void effectDefinitionIsCompiledToDefineEffectInstruction() { + var effect = Effects.userDefined(NamespaceName.of("Example", "Project"), "State"); + var node = Typed.effectDefinition(effect); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("State"); + + var result = ShidCodeGen.compileNamespaceStatement(node, context); + + assertThat(result.instructions(), isSequence( + instanceOf( + ShidDefineEffect.class, + has("effect", x -> x.effect(), equalTo(effect)) + ), + isLocalStoreInstruction("State__0") + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenExpressionStatementTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenExpressionStatementTests.java new file mode 100644 index 00000000..05a47d39 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenExpressionStatementTests.java @@ -0,0 +1,24 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.isDiscardInstruction; +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.isPushStringInstruction; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ShidCodeGenExpressionStatementTests { + @Test + public void expressionIsEvaluatedAndTheResultDiscarded() { + var node = Typed.expressionStatement(Typed.stringLiteral("hello")); + var context = ShidCodeGen.Context.EMPTY; + + var result = ShidCodeGen.compileFunctionStatement(node, context); + + assertThat(result.instructions(), isSequence( + isPushStringInstruction("hello"), + isDiscardInstruction() + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenFieldAccessTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenFieldAccessTests.java new file mode 100644 index 00000000..0e869445 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenFieldAccessTests.java @@ -0,0 +1,78 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; +import org.shedlang.compiler.shid.instructions.ShidFieldLoad; +import org.shedlang.compiler.types.Effects; +import org.shedlang.compiler.types.NamespaceName; +import org.shedlang.compiler.types.Types; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.isFieldLoadInstruction; +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.isLocalLoadInstruction; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ShidCodeGenFieldAccessTests { + @Test + public void namespaceFieldAccessIsCompiledToFieldLoad() { + var namespaceType = Types.namespace(NamespaceName.of("Example", "Project")); + var node = Typed.fieldAccess( + Typed.reference("Project", namespaceType), + "name", + Types.STRING + ); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("Project"); + + var result = ShidCodeGen.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + isLocalLoadInstruction("Project__0"), + isFieldLoadInstruction( + new ShidFieldLoad.Receiver.Namespace(namespaceType.namespaceName()), + "name" + ) + )); + } + + @Test + public void structFieldAccessIsCompiledToFieldLoad() { + var structType = Types.struct(NamespaceName.of("Example", "Project"), "User"); + var node = Typed.fieldAccess( + Typed.reference("user", structType), + "name", + Types.STRING + ); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("user"); + + var result = ShidCodeGen.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + isLocalLoadInstruction("user__0"), + isFieldLoadInstruction(structType, "name") + )); + } + + @Test + public void userDefinedEffectFieldAccessIsCompiledToFieldLoad() { + var effect = Effects.userDefined(NamespaceName.of("Example", "Project"), "State"); + var node = Typed.fieldAccess( + Typed.reference("State", Types.effectType(effect)), + "read", + Types.STRING + ); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("State"); + + var result = ShidCodeGen.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + isLocalLoadInstruction("State__0"), + isFieldLoadInstruction( + new ShidFieldLoad.Receiver.Effect(effect), + "read" + ) + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenFunctionDefinitionTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenFunctionDefinitionTests.java new file mode 100644 index 00000000..0f6a3835 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenFunctionDefinitionTests.java @@ -0,0 +1,75 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; +import org.shedlang.compiler.ast.typed.TypedFunctionDefinitionNode; +import org.shedlang.compiler.shid.instructions.ShidDefineFunction; +import org.shedlang.compiler.types.Types; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.*; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.*; + +public class ShidCodeGenFunctionDefinitionTests { + @Test + public void functionIsCompiledToDefineFunctionInstruction() { + var node = TypedFunctionDefinitionNode.builder() + .withName("f") + .addPositionalParam("x", Typed.typeLevelReference("String", Types.STRING)) + .addNamedParam("y", Typed.typeLevelReference("Int", Types.INT)) + .addFreeVariable("z") + .addStatement(Typed.expressionStatement(Typed.stringLiteral("hello"))) + .build(); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("f") + .addShedVal("z"); + + var result = ShidCodeGen.compileNamespaceStatement(node, context); + + assertThat(result.instructions(), isSequence( + instanceOf( + ShidDefineFunction.class, + has("name", x -> x.name(), equalTo("f")), + has("positionalParams", x -> x.positionalParams(), isSequence( + isDefineFunctionInstructionParam("x__0") + )), + has("namedParams", x -> x.namedParams(), isSequence( + isDefineFunctionInstructionParam("y__0") + )), + has("freeVariables", x -> x.freeVariables(), containsExactly( + has("name", x -> x.name(), equalTo("z__0")) + )), + has("body", x -> x.body(), isSequence( + isPushStringInstruction("hello"), + isDiscardInstruction(), + isPushUnitInstruction(), + isReturnInstruction() + )) + ), + isLocalStoreInstruction("f__0") + )); + } + + @Test + public void whenLastStatementIsBlockReturnThenThatValueIsReturned() { + var node = TypedFunctionDefinitionNode.builder() + .withName("f") + .addStatement(Typed.blockReturn(Typed.stringLiteral("hello"))) + .build(); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("f"); + + var result = ShidCodeGen.compileNamespaceStatement(node, context); + + assertThat(result.instructions(), isSequence( + instanceOf( + ShidDefineFunction.class, + has("body", x -> x.body(), isSequence( + isPushStringInstruction("hello"), + isReturnInstruction() + )) + ), + isLocalStoreInstruction("f__0") + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenFunctionExpressionTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenFunctionExpressionTests.java new file mode 100644 index 00000000..c5f78340 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenFunctionExpressionTests.java @@ -0,0 +1,71 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; +import org.shedlang.compiler.ast.typed.TypedFunctionExpressionNode; +import org.shedlang.compiler.shid.instructions.ShidDefineFunction; +import org.shedlang.compiler.types.Types; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.*; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.*; + +public class ShidCodeGenFunctionExpressionTests { + @Test + public void functionIsCompiledToDefineFunctionInstruction() { + var node = TypedFunctionExpressionNode.builder() + .addPositionalParam("x", Typed.typeLevelReference("String", Types.STRING)) + .addNamedParam("y", Typed.typeLevelReference("Int", Types.INT)) + .addFreeVariable("z") + .addStatement(Typed.expressionStatement(Typed.stringLiteral("hello"))) + .build(); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("f") + .addShedVal("z"); + + var result = ShidCodeGen.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + instanceOf( + ShidDefineFunction.class, + has("name", x -> x.name(), equalTo("anonymous")), + has("positionalParams", x -> x.positionalParams(), isSequence( + isDefineFunctionInstructionParam("x__0") + )), + has("namedParams", x -> x.namedParams(), isSequence( + isDefineFunctionInstructionParam("y__0") + )), + has("freeVariables", x -> x.freeVariables(), containsExactly( + has("name", x -> x.name(), equalTo("z__0")) + )), + has("body", x -> x.body(), isSequence( + isPushStringInstruction("hello"), + isDiscardInstruction(), + isPushUnitInstruction(), + isReturnInstruction() + )) + ) + )); + } + + @Test + public void whenLastStatementIsBlockReturnThenThatValueIsReturned() { + var node = TypedFunctionExpressionNode.builder() + .addStatement(Typed.blockReturn(Typed.stringLiteral("hello"))) + .build(); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("f"); + + var result = ShidCodeGen.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + instanceOf( + ShidDefineFunction.class, + has("body", x -> x.body(), isSequence( + isPushStringInstruction("hello"), + isReturnInstruction() + )) + ) + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenFunctionReturnTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenFunctionReturnTests.java new file mode 100644 index 00000000..d6a63c1f --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenFunctionReturnTests.java @@ -0,0 +1,23 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.*; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ShidCodeGenFunctionReturnTests { + @Test + public void expressionIsEvaluatedAndReturned() { + var node = Typed.functionReturn(Typed.stringLiteral("hello")); + var context = ShidCodeGen.Context.EMPTY; + + var result = ShidCodeGen.compileFunctionStatement(node, context); + + assertThat(result.instructions(), isSequence( + isPushStringInstruction("hello"), + isReturnInstruction() + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenIfTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenIfTests.java new file mode 100644 index 00000000..f1f81e95 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenIfTests.java @@ -0,0 +1,98 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; +import org.shedlang.compiler.types.Types; + +import java.util.List; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.*; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ShidCodeGenIfTests { + @Test + public void ifWithSingleConditionalBranchIsCompiledToSingleIfInstruction() { + var node = Typed.if_( + List.of( + Typed.conditionalBranch( + Typed.reference("c"), + Typed.block(List.of( + Typed.blockReturn(Typed.intLiteral(42)) + )) + ) + ), + Typed.block(List.of( + Typed.functionReturn(Typed.stringLiteral("x")) + )), + Types.INT + ); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("c"); + + var result = ShidCodeGen.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + isLocalLoadInstruction("c__0"), + isIfInstruction( + isSequence( + isPushIntInstruction(42) + ), + isSequence( + isPushStringInstruction("x"), + isReturnInstruction() + ) + ) + )); + } + + @Test + public void ifWithMultipleConditionalBranchesIsCompiledToNestedIfInstructions() { + var node = Typed.if_( + List.of( + Typed.conditionalBranch( + Typed.reference("c"), + Typed.block(List.of( + Typed.blockReturn(Typed.intLiteral(42)) + )) + ), + Typed.conditionalBranch( + Typed.reference("d"), + Typed.block(List.of( + Typed.blockReturn(Typed.intLiteral(1)) + )) + ) + ), + Typed.block(List.of( + Typed.functionReturn(Typed.stringLiteral("x")) + )), + Types.INT + ); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("c") + .addShedVal("d"); + + var result = ShidCodeGen.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + isLocalLoadInstruction("c__0"), + isIfInstruction( + isSequence( + isPushIntInstruction(42) + ), + isSequence( + isLocalLoadInstruction("d__0"), + isIfInstruction( + isSequence( + isPushIntInstruction(1) + ), + isSequence( + isPushStringInstruction("x"), + isReturnInstruction() + ) + ) + ) + ) + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenIntAddTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenIntAddTests.java new file mode 100644 index 00000000..4ff0e6eb --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenIntAddTests.java @@ -0,0 +1,28 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.isIntAddInstruction; +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.isPushIntInstruction; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ShidCodeGenIntAddTests { + @Test + public void intAddIsCompiledToIntAddInstruction() { + var node = Typed.intAdd( + Typed.intLiteral(42), + Typed.intLiteral(47) + ); + var context = ShidCodeGen.Context.EMPTY; + + var result = ShidCodeGen.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + isPushIntInstruction(42), + isPushIntInstruction(47), + isIntAddInstruction() + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenIntEqualsTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenIntEqualsTests.java new file mode 100644 index 00000000..464e73f4 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenIntEqualsTests.java @@ -0,0 +1,27 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.*; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ShidCodeGenIntEqualsTests { + @Test + public void intEqualsIsCompiledToIntEqualsInstruction() { + var node = Typed.intEquals( + Typed.intLiteral(42), + Typed.intLiteral(47) + ); + var context = ShidCodeGen.Context.EMPTY; + + var result = ShidCodeGen.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + isPushIntInstruction(42), + isPushIntInstruction(47), + isIntEqualsInstruction() + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenIntLiteralTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenIntLiteralTests.java new file mode 100644 index 00000000..ed95e765 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenIntLiteralTests.java @@ -0,0 +1,22 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.isPushIntInstruction; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ShidCodeGenIntLiteralTests { + @Test + public void intLiteralIsCompiledToPushIntInstruction() { + var node = Typed.intLiteral(42); + var context = ShidCodeGen.Context.EMPTY; + + var result = ShidCodeGen.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + isPushIntInstruction(42) + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenIntNotEqualTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenIntNotEqualTests.java new file mode 100644 index 00000000..9c55f222 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenIntNotEqualTests.java @@ -0,0 +1,27 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.*; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ShidCodeGenIntNotEqualTests { + @Test + public void intNotEqualsIsCompiledToIntNotEqualInstruction() { + var node = Typed.intNotEqual( + Typed.intLiteral(42), + Typed.intLiteral(47) + ); + var context = ShidCodeGen.Context.EMPTY; + + var result = ShidCodeGen.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + isPushIntInstruction(42), + isPushIntInstruction(47), + isIntNotEqualInstruction() + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenIntSubTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenIntSubTests.java new file mode 100644 index 00000000..df3e9791 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenIntSubTests.java @@ -0,0 +1,27 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.*; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ShidCodeGenIntSubTests { + @Test + public void intSubIsCompiledToIntSubInstruction() { + var node = Typed.intSub( + Typed.intLiteral(42), + Typed.intLiteral(47) + ); + var context = ShidCodeGen.Context.EMPTY; + + var result = ShidCodeGen.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + isPushIntInstruction(42), + isPushIntInstruction(47), + isIntSubInstruction() + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenNamespaceTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenNamespaceTests.java new file mode 100644 index 00000000..f56ba972 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenNamespaceTests.java @@ -0,0 +1,118 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.*; +import org.shedlang.compiler.shid.instructions.*; +import org.shedlang.compiler.types.NamespaceName; +import org.shedlang.compiler.types.Types; + +import java.util.List; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.*; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.*; + +public class ShidCodeGenNamespaceTests { + @Test + public void bodyOfNamespaceIsCompiledWithNamesBeingExported() { + var namespaceName = new NamespaceName(List.of("Example")); + + var node = Typed.namespace( + namespaceName, + List.of( + TypedFunctionDefinitionNode.builder() + .withName("f") + .addPositionalParam("x", Typed.typeLevelReference("String", Types.STRING)) + .addNamedParam("y", Typed.typeLevelReference("Int", Types.INT)) + .addStatement(Typed.expressionStatement(Typed.stringLiteral("hello"))) + .build() + ), + List.of(BoundVariable.immutable("f")), + List.of("f") + ); + + var shidNamespace = ShidCodeGen.compileNamespace(node); + + assertThat(shidNamespace.instructions(), isSequence( + // TODO: test the builtin loading properly + instanceOf(ShidNamespaceImport.class), + instanceOf(ShidFieldLoad.class), + instanceOf(ShidLocalStore.class), + + instanceOf( + ShidDefineFunction.class, + has("name", x -> x.name(), equalTo("f")) + ), + isLocalStoreInstruction("f__0"), + isLocalLoadInstruction("f__0"), + isNamespaceFieldStoreInstruction(namespaceName, "f") + )); + } + + @Test + public void importsAreLoaded() { + var node = TypedNamespaceNode.builder() + .addImport(Typed.import_(NamespaceName.of("A"))) + .addBoundVariable(BoundVariable.immutable("A")) + .addImport(Typed.import_(NamespaceName.of("B"))) + .addBoundVariable(BoundVariable.immutable("B")) + .build(); + + var shidNamespace = ShidCodeGen.compileNamespace(node); + + assertThat(shidNamespace.instructions(), isSequence( + // TODO: test the builtin loading properly + instanceOf(ShidNamespaceImport.class), + instanceOf(ShidFieldLoad.class), + instanceOf(ShidLocalStore.class), + + isNamespaceImportInstruction(NamespaceName.of("A")), + isLocalStoreInstruction("A__0"), + isNamespaceImportInstruction(NamespaceName.of("B")), + isLocalStoreInstruction("B__0") + )); + } + + @Test + public void structsAreHoisted() { + var namespaceName = new NamespaceName(List.of("Example")); + var structType = Types.struct(namespaceName, "None"); + var node = Typed.namespace( + namespaceName, + List.of( + TypedFunctionDefinitionNode.builder() + .withName("f") + .build(), + TypedStructDefinitionNode.builder() + .withType(structType) + .build() + ), + List.of(BoundVariable.immutable("f"), BoundVariable.immutable("None")), + List.of("f", "None") + ); + + var shidNamespace = ShidCodeGen.compileNamespace(node); + + assertThat(shidNamespace.instructions(), isSequence( + // TODO: test the builtin loading properly + instanceOf(ShidNamespaceImport.class), + instanceOf(ShidFieldLoad.class), + instanceOf(ShidLocalStore.class), + + instanceOf( + ShidDefineStruct.class, + has("type", x -> x.type(), equalTo(structType)) + ), + isLocalStoreInstruction("None__0"), + instanceOf( + ShidDefineFunction.class, + has("name", x -> x.name(), equalTo("f")) + ), + isLocalStoreInstruction("f__0"), + isLocalLoadInstruction("f__0"), + isNamespaceFieldStoreInstruction(namespaceName, "f"), + isLocalLoadInstruction("None__0"), + isNamespaceFieldStoreInstruction(namespaceName, "None") + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenReferenceTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenReferenceTests.java new file mode 100644 index 00000000..2a30266b --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenReferenceTests.java @@ -0,0 +1,43 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.BoundVariable; +import org.shedlang.compiler.ast.typed.Typed; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.*; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ShidCodeGenReferenceTests { + @Test + public void referenceIsCompiledToLocalLoad() { + var node = Typed.reference("x"); + var context = ShidCodeGen.Context.EMPTY + .addShedVariable(BoundVariable.immutable("x")); + + var result = ShidCodeGen.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + isLocalLoadInstruction("x__0") + )); + } + + @Test + public void whenLocalIsVarThenReferenceIsCompiledToVarLoad() { + var node = Typed.reference("x"); + var context = ShidCodeGen.Context.EMPTY + .addShedVariable(BoundVariable.mutable("x")); + context = ShidCodeGen.compileFunctionStatement( + Typed.var("x", Typed.intLiteral(0)), + context + ); + + var result = ShidCodeGen.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + isPushIntInstruction(0), + isVarStoreInstruction("x__0"), + isVarLoadInstruction("x__0") + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenResumeTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenResumeTests.java new file mode 100644 index 00000000..6992783d --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenResumeTests.java @@ -0,0 +1,23 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.*; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ShidCodeGenResumeTests { + @Test + public void expressionIsEvaluatedAndReturned() { + var node = Typed.resume(Typed.stringLiteral("hello")); + var context = ShidCodeGen.Context.EMPTY; + + var result = ShidCodeGen.compileFunctionStatement(node, context); + + assertThat(result.instructions(), isSequence( + isPushStringInstruction("hello"), + isResumeInstruction() + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenStringAddTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenStringAddTests.java new file mode 100644 index 00000000..56b2750e --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenStringAddTests.java @@ -0,0 +1,27 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.*; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ShidCodeGenStringAddTests { + @Test + public void stringAddIsCompiledToStringAddInstruction() { + var node = Typed.stringAdd( + Typed.stringLiteral("a"), + Typed.stringLiteral("b") + ); + var context = ShidCodeGen.Context.EMPTY; + + var result = ShidCodeGen.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + isPushStringInstruction("a"), + isPushStringInstruction("b"), + isStringAddInstruction() + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenStringLiteralTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenStringLiteralTests.java new file mode 100644 index 00000000..b308c300 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenStringLiteralTests.java @@ -0,0 +1,22 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.isPushStringInstruction; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ShidCodeGenStringLiteralTests { + @Test + public void stringLiteralIsCompiledToPushStringInstruction() { + var node = Typed.stringLiteral("hello"); + var context = ShidCodeGen.Context.EMPTY; + + var result = ShidCodeGen.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + isPushStringInstruction("hello") + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenStructDefinitionTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenStructDefinitionTests.java new file mode 100644 index 00000000..4e989e9b --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenStructDefinitionTests.java @@ -0,0 +1,40 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; +import org.shedlang.compiler.ast.typed.TypedStructDefinitionNode; +import org.shedlang.compiler.shid.instructions.ShidDefineStruct; +import org.shedlang.compiler.types.NamespaceName; +import org.shedlang.compiler.types.Types; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.isLocalStoreInstruction; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.*; + +public class ShidCodeGenStructDefinitionTests { + @Test + public void structDefinitionIsCompiledToDefineStructInstruction() { + var structType = Types.struct(NamespaceName.of("Example", "Project"), "User"); + var node = TypedStructDefinitionNode.builder() + .withType(structType) + .addField(Typed.structFieldDefinition("name", Typed.typeLevelReference("String", Types.STRING))) + .addField(Typed.structFieldDefinition("isActive", Typed.typeLevelReference("Bool", Types.BOOL))) + .build(); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("User"); + + var result = ShidCodeGen.compileNamespaceStatement(node, context); + + assertThat(result.instructions(), isSequence( + instanceOf( + ShidDefineStruct.class, + has("type", x -> x.type(), equalTo(structType)), + has("fields", x -> x.fields(), isSequence( + has("name", x -> x.name(), equalTo("name")), + has("name", x -> x.name(), equalTo("isActive")) + )) + ), + isLocalStoreInstruction("User__0") + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenSumTypeDefinitionTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenSumTypeDefinitionTests.java new file mode 100644 index 00000000..74521d29 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenSumTypeDefinitionTests.java @@ -0,0 +1,30 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; +import org.shedlang.compiler.types.NamespaceName; +import org.shedlang.compiler.types.Types; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.isLocalStoreInstruction; +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.isPushUnitInstruction; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ShidCodeGenSumTypeDefinitionTests { + @Test + public void sumTypeDefinitionIsCompiledToUnit() { + // TODO: this is a bit of a hack, we probably want to be able to have + // sum types in some potential backends (e.g. the JVM) + var sumType = Types.sum(NamespaceName.of("Example", "Project"), "Option"); + var node = Typed.sumTypeDefinition(sumType); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("Option"); + + var result = ShidCodeGen.compileNamespaceStatement(node, context); + + assertThat(result.instructions(), isSequence( + isPushUnitInstruction(), + isLocalStoreInstruction("Option__0") + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenTryTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenTryTests.java new file mode 100644 index 00000000..daff19b0 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenTryTests.java @@ -0,0 +1,63 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; +import org.shedlang.compiler.ast.typed.TypedTryHandlerMethodNode; +import org.shedlang.compiler.ast.typed.TypedTryNode; +import org.shedlang.compiler.shid.instructions.ShidDefineFunction; +import org.shedlang.compiler.shid.instructions.ShidTry; +import org.shedlang.compiler.types.Effects; +import org.shedlang.compiler.types.NamespaceName; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.isPushIntInstruction; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.*; + +public class ShidCodeGenTryTests { + @Test + public void tryNodeIsCompiledToTryInstruction() { + var effect = Effects.userDefined(NamespaceName.of("Example"), "State"); + var node = TypedTryNode.builder() + .addBodyStatement( + Typed.blockReturn(Typed.intLiteral(42)) + ) + .withHandledEffect(Typed.typeLevelReference("State", effect)) + .addHandlerMethod( + TypedTryHandlerMethodNode.builder() + .withName("read") + .build() + ) + .addHandlerMethod( + TypedTryHandlerMethodNode.builder() + .withName("write") + .build() + ) + .build(); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("c"); + + var result = ShidCodeGen.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + instanceOf( + ShidDefineFunction.class, + has("name", x -> x.name(), equalTo("read")) + ), + instanceOf( + ShidDefineFunction.class, + has("name", x -> x.name(), equalTo("write")) + ), + instanceOf( + ShidTry.class, + has("handledEffect", x -> x.handledEffect(), equalTo(effect)), + has("handlerMethodNames", x -> x.handlerMethodNames(), isSequence( + equalTo("read"), + equalTo("write") + )), + has("body", x -> x.body(), isSequence( + isPushIntInstruction(42) + )) + ) + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenTupleTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenTupleTests.java new file mode 100644 index 00000000..c3194182 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenTupleTests.java @@ -0,0 +1,31 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; + +import java.util.List; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.*; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ShidCodeGenTupleTests { + @Test + public void stringAddIsCompiledToStringAddInstruction() { + var node = Typed.tuple(List.of( + Typed.stringLiteral("a"), + Typed.boolLiteral(true), + Typed.intLiteral(4) + )); + var context = ShidCodeGen.Context.EMPTY; + + var result = ShidCodeGen.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + isPushStringInstruction("a"), + isPushBoolInstruction(true), + isPushIntInstruction(4), + isTupleCreateInstruction(3) + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenUnitLiteralTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenUnitLiteralTests.java new file mode 100644 index 00000000..27b7ed6c --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenUnitLiteralTests.java @@ -0,0 +1,22 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.isPushUnitInstruction; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ShidCodeGenUnitLiteralTests { + @Test + public void unitLiteralIsCompiledToPushUnitInstruction() { + var node = Typed.unitLiteral(); + var context = ShidCodeGen.Context.EMPTY; + + var result = ShidCodeGen.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + isPushUnitInstruction() + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenValTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenValTests.java new file mode 100644 index 00000000..5007e1e8 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenValTests.java @@ -0,0 +1,106 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.BoundVariable; +import org.shedlang.compiler.ast.typed.Typed; +import org.shedlang.compiler.types.Types; + +import java.util.List; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.*; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ShidCodeGenValTests { + @Test + public void whenValIsFunctionStatementThenExpressionIsEvaluatedAndStoredAsLocal() { + var node = Typed.val("x", Typed.stringLiteral("hello")); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("x"); + + var result = ShidCodeGen.compileFunctionStatement(node, context); + + assertThat(result.instructions(), isSequence( + isPushStringInstruction("hello"), + isLocalStoreInstruction("x__0") + )); + } + + @Test + public void whenValIsNamespaceStatementThenExpressionIsEvaluatedAndStoredAsLocal() { + var node = Typed.val("x", Typed.stringLiteral("hello")); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("x"); + + var result = ShidCodeGen.compileNamespaceStatement(node, context); + + assertThat(result.instructions(), isSequence( + isPushStringInstruction("hello"), + isLocalStoreInstruction("x__0") + )); + } + + @Test + public void valsInDifferentBlocksAssignToDifferentLocals() { + var nodes = List.of( + Typed.val("x", Typed.intLiteral(10)), + Typed.expressionStatement(Typed.reference("x")), + Typed.expressionStatement(Typed.if_( + List.of( + Typed.conditionalBranch( + Typed.boolLiteral(true), + Typed.block( + List.of( + Typed.val("x", Typed.intLiteral(11)), + Typed.expressionStatement(Typed.reference("x")) + ), + List.of(BoundVariable.immutable("x")) + ) + ) + ), + Typed.block( + List.of( + Typed.val("x", Typed.intLiteral(12)), + Typed.expressionStatement(Typed.reference("x")) + ), + List.of(BoundVariable.immutable("x")) + ), + Types.INT + )), + Typed.expressionStatement(Typed.reference("x")) + ); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("x"); + + for (var node : nodes) { + context = ShidCodeGen.compileFunctionStatement(node, context); + } + + assertThat(context.instructions(), isSequence( + isPushIntInstruction(10), + isLocalStoreInstruction("x__0"), + isLocalLoadInstruction("x__0"), + isDiscardInstruction(), + isPushBoolInstruction(true), + isIfInstruction( + isSequence( + isPushIntInstruction(11), + isLocalStoreInstruction("x__1"), + isLocalLoadInstruction("x__1"), + isDiscardInstruction(), + isPushUnitInstruction() + ), + isSequence( + isPushIntInstruction(12), + isLocalStoreInstruction("x__2"), + isLocalLoadInstruction("x__2"), + isDiscardInstruction(), + isPushUnitInstruction() + ) + ), + isDiscardInstruction(), + isLocalLoadInstruction("x__0"), + isDiscardInstruction() + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenVarTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenVarTests.java new file mode 100644 index 00000000..a1e264ad --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenVarTests.java @@ -0,0 +1,24 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.*; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ShidCodeGenVarTests { + @Test + public void expressionIsEvaluatedAndStoredAsVar() { + var node = Typed.var("x", Typed.stringLiteral("hello")); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("x"); + + var result = ShidCodeGen.compileFunctionStatement(node, context); + + assertThat(result.instructions(), isSequence( + isPushStringInstruction("hello"), + isVarStoreInstruction("x__0") + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenWhenTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenWhenTests.java new file mode 100644 index 00000000..f3e2880c --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenWhenTests.java @@ -0,0 +1,62 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; +import org.shedlang.compiler.types.NamespaceName; +import org.shedlang.compiler.types.Types; + +import java.util.List; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.*; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ShidCodeGenWhenTests { + private final static NamespaceName NAMESPACE_NAME = NamespaceName.of("Example", "Project"); + + @Test + public void whenIsCompiledToSwitchInstruction() { + var node = Typed.when( + Typed.reference("x"), + List.of( + Typed.whenCase( + Typed.typeLevelReference("A", Types.struct(NAMESPACE_NAME, "A")), + Typed.block(List.of( + Typed.blockReturn(Typed.stringLiteral("a")) + )) + ), + Typed.whenCase( + Typed.typeLevelReference("B", Types.struct(NAMESPACE_NAME, "B")), + Typed.block(List.of( + Typed.blockReturn(Typed.stringLiteral("b")) + )) + ) + ), + Types.STRING + ); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("x"); + + var result = ShidCodeGen.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + isLocalLoadInstruction("x__0"), + isSwitchInstruction( + isSequence( + isSwitchInstructionCase( + Types.struct(NAMESPACE_NAME, "A"), + isSequence( + isPushStringInstruction("a") + ) + ), + isSwitchInstructionCase( + Types.struct(NAMESPACE_NAME, "B"), + isSequence( + isPushStringInstruction("b") + ) + ) + ) + ) + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/ShidCodeGenWhileTests.java b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenWhileTests.java new file mode 100644 index 00000000..1ab5240a --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/ShidCodeGenWhileTests.java @@ -0,0 +1,76 @@ +package org.shedlang.compiler.shid; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; + +import java.util.List; + +import static org.shedlang.compiler.shid.instructions.InstructionMatchers.*; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ShidCodeGenWhileTests { + @Test + public void whileIsCompiledToLoop() { + var node = Typed.while_( + Typed.reference("c"), + Typed.block(List.of( + Typed.expressionStatement(Typed.intLiteral(42)) + )) + ); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("c"); + + var result = ShidCodeGen.compileFunctionStatement(node, context); + + assertThat(result.instructions(), isSequence( + isLoopInstruction( + isSequence( + isLocalLoadInstruction("c__0"), + isIfInstruction( + isSequence(), + isSequence( + isLoopBreakInstruction() + ) + ), + isPushIntInstruction(42), + isDiscardInstruction(), + isLoopContinueInstruction() + ) + ) + )); + } + + @Test + public void whenBodyYieldsValueThenValueIsDiscarded() { + // In principle, the type checker should prevent the body from yielding + // a value, but we check we handle this case anyway. + var node = Typed.while_( + Typed.reference("c"), + Typed.block(List.of( + Typed.blockReturn(Typed.intLiteral(42)) + )) + ); + var context = ShidCodeGen.Context.EMPTY + .addShedVal("c"); + + var result = ShidCodeGen.compileFunctionStatement(node, context); + + assertThat(result.instructions(), isSequence( + isLoopInstruction( + isSequence( + isLocalLoadInstruction("c__0"), + isIfInstruction( + isSequence(), + isSequence( + isLoopBreakInstruction() + ) + ), + isPushIntInstruction(42), + isDiscardInstruction(), + isLoopContinueInstruction() + ) + ) + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/instructions/InstructionMatchers.java b/src/test/java/org/shedlang/compiler/shid/instructions/InstructionMatchers.java new file mode 100644 index 00000000..c7c89825 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/instructions/InstructionMatchers.java @@ -0,0 +1,229 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.types.NamespaceName; +import org.shedlang.compiler.types.StructType; +import org.zwobble.precisely.Matcher; + +import java.math.BigInteger; +import java.util.List; + +import static org.zwobble.precisely.Matchers.*; + +public class InstructionMatchers { + private InstructionMatchers() { + } + + public static Matcher isCallInstruction( + int positionalArgCount, + List namedArgNames + ) { + return instanceOf( + ShidCall.class, + has("positionalArgCount", x -> x.positionalArgCount(), equalTo(positionalArgCount)), + has("namedArgNames", x -> x.namedArgNames(), equalTo(namedArgNames)) + ); + } + + public static Matcher isDefineFunctionInstructionParam(String name) { + return has("name", x -> x.name(), equalTo(name)); + } + + public static Matcher isDiscardInstruction() { + return instanceOf( + ShidDiscard.class + ); + } + + public static Matcher isDuplicateInstruction() { + return instanceOf(ShidDuplicate.class); + } + + public static Matcher isFieldLoadInstruction( + ShidFieldLoad.Receiver receiver, + String fieldName + ) { + return instanceOf( + ShidFieldLoad.class, + has("receiver", x -> x.receiver(), equalTo(receiver)), + has("fieldName", x -> x.fieldName(), equalTo(fieldName)) + ); + } + + public static Matcher isFieldLoadInstruction( + StructType receiverType, + String fieldName + ) { + return isFieldLoadInstruction( + new ShidFieldLoad.Receiver.Struct(receiverType), + fieldName + ); + } + + public static Matcher isIfInstruction( + Matcher> trueBody, + Matcher> falseBody + ) { + return instanceOf( + ShidIf.class, + has("trueBody", x -> x.trueBody(), trueBody), + has("falseBody", x -> x.falseBody(), falseBody) + ); + } + + public static Matcher isIntAddInstruction() { + return instanceOf(ShidIntAdd.class); + } + + public static Matcher isIntEqualsInstruction() { + return instanceOf(ShidIntEquals.class); + } + + public static Matcher isIntNotEqualInstruction() { + return instanceOf(ShidIntNotEqual.class); + } + + public static Matcher isIntSubInstruction() { + return instanceOf(ShidIntSub.class); + } + + public static Matcher isLocalLoadInstruction(String name) { + return instanceOf( + ShidLocalLoad.class, + has("name", x -> x.name(), equalTo(name)) + ); + } + + public static Matcher isLocalStoreInstruction(String name) { + return instanceOf( + ShidLocalStore.class, + has("name", x -> x.name(), equalTo(name)) + ); + } + + public static Matcher isLoopInstruction( + Matcher> body + ) { + return instanceOf( + ShidLoop.class, + has("body", x -> x.body(), body) + ); + } + + public static Matcher isLoopBreakInstruction() { + return instanceOf(ShidLoopBreak.class); + } + + public static Matcher isLoopContinueInstruction() { + return instanceOf(ShidLoopContinue.class); + } + + public static Matcher isNamespaceFieldStoreInstruction( + NamespaceName namespaceName, + String fieldName + ) { + return instanceOf( + ShidNamespaceFieldStore.class, + has("namespaceName", x -> x.namespaceName(), equalTo(namespaceName)), + has("fieldName", x -> x.fieldName(), equalTo(fieldName)) + ); + } + + public static Matcher isNamespaceImportInstruction( + NamespaceName namespaceName + ) { + return instanceOf( + ShidNamespaceImport.class, + has("namespaceName", x -> x.namespaceName(), equalTo(namespaceName)) + ); + } + + public static Matcher isPushBoolInstruction(boolean value) { + return instanceOf( + ShidPushBool.class, + has("value", x -> x.value(), equalTo(value)) + ); + } + + public static Matcher isPushIntInstruction(int value) { + return instanceOf( + ShidPushInt.class, + has("value", x -> x.value(), equalTo(BigInteger.valueOf(value))) + ); + } + + public static Matcher isPushStringInstruction(String value) { + return instanceOf( + ShidPushString.class, + has("value", x -> x.value(), equalTo(value)) + ); + } + + public static Matcher isPushUnitInstruction() { + return instanceOf( + ShidPushUnit.class + ); + } + + public static Matcher isResumeInstruction() { + return instanceOf( + ShidResume.class + ); + } + + public static Matcher isReturnInstruction() { + return instanceOf( + ShidReturn.class + ); + } + + public static Matcher isStringAddInstruction() { + return instanceOf(ShidStringAdd.class); + } + + public static Matcher isSwitchInstruction( + Matcher> cases + ) { + return instanceOf( + ShidSwitch.class, + has("cases", x -> x.cases(), cases) + ); + } + + public static Matcher isSwitchInstructionCase( + StructType caseType, + Matcher> body + ) { + return allOf( + has("caseType", x -> x.caseType(), equalTo(caseType)), + has("body", x -> x.body(), body) + ); + } + + public static Matcher isTupleCreateInstruction(int elementCount) { + return instanceOf( + ShidTupleCreate.class, + has("elementCount", x -> x.elementCount(), equalTo(elementCount)) + ); + } + + public static Matcher isTupleGetInstruction(int elementIndex) { + return instanceOf( + ShidTupleGet.class, + has("elementIndex", x -> x.elementIndex(), equalTo(elementIndex)) + ); + } + + public static Matcher isVarLoadInstruction(String name) { + return instanceOf( + ShidVarLoad.class, + has("name", x -> x.name(), equalTo(name)) + ); + } + + public static Matcher isVarStoreInstruction(String name) { + return instanceOf( + ShidVarStore.class, + has("name", x -> x.name(), equalTo(name)) + ); + } +} diff --git a/src/test/java/org/shedlang/compiler/shid/instructions/Shid.java b/src/test/java/org/shedlang/compiler/shid/instructions/Shid.java new file mode 100644 index 00000000..cd8e41fd --- /dev/null +++ b/src/test/java/org/shedlang/compiler/shid/instructions/Shid.java @@ -0,0 +1,193 @@ +package org.shedlang.compiler.shid.instructions; + +import org.shedlang.compiler.sources.Sources; +import org.shedlang.compiler.types.NamespaceName; +import org.shedlang.compiler.types.StructType; +import org.shedlang.compiler.types.UserDefinedEffect; + +import java.math.BigInteger; +import java.util.List; + +public class Shid { + private Shid() { + } + + public static ShidInstruction call(int positionalArgCount, List namedArgNames) { + return new ShidCall(positionalArgCount, namedArgNames, Sources.NULL); + } + + public static ShidInstruction defineEffect(UserDefinedEffect effect) { + return new ShidDefineEffect(effect, Sources.NULL); + } + + public static ShidInstruction defineStruct( + StructType type, + List fields + ) { + return new ShidDefineStruct( + type, + fields, + Sources.NULL + ); + } + + public static ShidDefineStruct.Field defineStructField(String name) { + return new ShidDefineStruct.Field(name, Sources.NULL); + } + + public static ShidInstruction discard() { + return new ShidDiscard(Sources.NULL); + } + + public static ShidInstruction duplicate() { + return new ShidDuplicate(Sources.NULL); + } + + public static ShidInstruction fieldLoad(NamespaceName namespaceName, String fieldName) { + return new ShidFieldLoad( + new ShidFieldLoad.Receiver.Namespace(namespaceName), + fieldName, + Sources.NULL + ); + } + + public static ShidInstruction fieldLoad(StructType type, String fieldName) { + return new ShidFieldLoad( + new ShidFieldLoad.Receiver.Struct(type), + fieldName, + Sources.NULL + ); + } + + public static ShidInstruction fieldLoad(UserDefinedEffect effect, String fieldName) { + return new ShidFieldLoad( + new ShidFieldLoad.Receiver.Effect(effect), + fieldName, + Sources.NULL + ); + } + + public static ShidInstruction if_( + int resultCount, + List trueBody, + List falseBody + ) { + return new ShidIf(resultCount, trueBody, falseBody, Sources.NULL); + } + + public static ShidInstruction intAdd() { + return new ShidIntAdd(Sources.NULL); + } + + public static ShidInstruction intEquals() { + return new ShidIntEquals(Sources.NULL); + } + + public static ShidInstruction intNotEqual() { + return new ShidIntNotEqual(Sources.NULL); + } + + public static ShidInstruction intSub() { + return new ShidIntSub(Sources.NULL); + } + + public static ShidInstruction localLoad(String name) { + return new ShidLocalLoad(name, Sources.NULL); + } + + public static ShidInstruction localStore(String name) { + return new ShidLocalStore(name, Sources.NULL); + } + + public static ShidInstruction loop(List body) { + return new ShidLoop(body, Sources.NULL); + } + + public static ShidInstruction loopBreak() { + return new ShidLoopBreak(Sources.NULL); + } + + public static ShidInstruction loopContinue() { + return new ShidLoopContinue(Sources.NULL); + } + + public static ShidInstruction namespaceFieldStore(NamespaceName namespaceName, String fieldName) { + return new ShidNamespaceFieldStore(namespaceName, fieldName, Sources.NULL); + } + + public static ShidInstruction namespaceImport(NamespaceName namespaceName) { + return new ShidNamespaceImport(namespaceName, Sources.NULL); + } + + public static ShidDefineFunction.Param param(String name) { + return new ShidDefineFunction.Param(name, Sources.NULL); + } + + public static ShidInstruction pushBool(boolean value) { + return new ShidPushBool(value, Sources.NULL); + } + + public static ShidInstruction pushInt(int value) { + return new ShidPushInt(BigInteger.valueOf(value), Sources.NULL); + } + + public static ShidInstruction pushString(String value) { + return new ShidPushString(value, Sources.NULL); + } + + public static ShidInstruction pushUnit() { + return new ShidPushUnit(Sources.NULL); + } + + public static ShidInstruction resume() { + return new ShidResume(Sources.NULL); + } + + public static ShidInstruction return_() { + return new ShidReturn(Sources.NULL); + } + + public static ShidInstruction stringAdd() { + return new ShidStringAdd(Sources.NULL); + } + + public static ShidInstruction switch_(List cases) { + return new ShidSwitch(cases, Sources.NULL); + } + + public static ShidSwitch.Case switchCase( + StructType type, + List body + ) { + return new ShidSwitch.Case(type, body, Sources.NULL); + } + + public static ShidInstruction try_( + UserDefinedEffect handledEffect, + List handlerMethodNames, + List body + ) { + return new ShidTry( + handledEffect, + handlerMethodNames, + body, + Sources.NULL + ); + } + + public static ShidInstruction tupleCreate(int elementCount) { + return new ShidTupleCreate(elementCount, Sources.NULL); + } + + public static ShidInstruction tupleGet(int elementIndex, int elementCount) { + return new ShidTupleGet(elementIndex, elementCount, Sources.NULL); + } + + public static ShidInstruction varLoad(String name) { + return new ShidVarLoad(name, Sources.NULL); + } + + public static ShidInstruction varStore(String name) { + return new ShidVarStore(name, Sources.NULL); + } +} diff --git a/src/test/java/org/shedlang/compiler/stackir/InstructionSerializerTests.java b/src/test/java/org/shedlang/compiler/stackir/InstructionSerializerTests.java deleted file mode 100644 index c36977cf..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/InstructionSerializerTests.java +++ /dev/null @@ -1,469 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.stackir.instructions.DefineFunctionInstruction; -import org.shedlang.compiler.stackir.instructions.Instruction; -import org.shedlang.compiler.stackir.instructions.Instructions; -import org.shedlang.compiler.types.Effects; -import org.shedlang.compiler.types.NamespaceName; -import org.shedlang.compiler.types.Types; - -import java.util.List; - -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.equalTo; - -public class InstructionSerializerTests { - @Test - public void canSerializeCall() { - var instruction = Instructions.call(1, List.of("x", "y")); - - var string = serialize(instruction); - - assertThat(string, equalTo("(call positional-arg-count=1 named-arg-names=(\"x\" \"y\"))")); - } - - @Test - public void canSerializeDefineEffect() { - var instruction = Instructions.defineEffect( - Effects.userDefined(NamespaceName.of("Example", "Project"), "State") - ); - - var string = serialize(instruction); - - assertThat(string, equalTo(""" - (define-effect "Example/Project.State")""" - )); - } - - @Test - public void canSerializeDefineFunction() { - var instruction = DefineFunctionInstruction.builder() - .withName("f") - .addPositionalParam("p1") - .addPositionalParam("p2") - .addNamedParam("n1") - .addNamedParam("n2") - .addFreeVariable("fv1") - .addFreeVariable("fv2") - .addBodyInstruction(Instructions.pushBool(true)) - .addBodyInstruction(Instructions.pushBool(false)) - .build(); - - var string = serialize(instruction); - - assertThat(string, equalTo(""" - ( - define-function - name="f" - positional-params=("p1" "p2") - named-params=("n1" "n2") - free-variables=("fv1" "fv2") - body=( - (push-bool true) - (push-bool false) - ) - )""")); - } - - @Test - public void canSerializeDefineStruct() { - var instruction = Instructions.defineStruct( - Types.struct(NamespaceName.of("Example", "Project"), "User"), - List.of( - Instructions.defineStructField("name"), - Instructions.defineStructField("id") - ) - ); - - var string = serialize(instruction); - - assertThat(string, equalTo(""" - ( - define-struct - type="Example/Project.User" - fields=("name" "id") - )""")); - } - - @Test - public void canSerializeDiscard() { - var instruction = Instructions.discard(); - - var string = serialize(instruction); - - assertThat(string, equalTo("(discard)")); - } - - @Test - public void canSerializeDuplicate() { - var instruction = Instructions.duplicate(); - - var string = serialize(instruction); - - assertThat(string, equalTo("(duplicate)")); - } - - @Test - public void canSerializeNamespaceFieldLoad() { - var instruction = Instructions.fieldLoad( - new NamespaceName(List.of("Example", "Lib")), - "x" - ); - - var string = serialize(instruction); - - assertThat(string, equalTo("(field-load (namespace \"Example/Lib\") \"x\")")); - } - - @Test - public void canSerializeStructFieldLoad() { - var instruction = Instructions.fieldLoad( - Types.struct(NamespaceName.of("Example", "Project"), "User"), - "name" - ); - - var string = serialize(instruction); - - assertThat(string, equalTo("(field-load (struct \"Example/Project.User\") \"name\")")); - } - - @Test - public void canSerializeUserDefinedEffectFieldLoad() { - var instruction = Instructions.fieldLoad( - Effects.userDefined(NamespaceName.of("Example", "Project"), "State"), - "read" - ); - - var string = serialize(instruction); - - assertThat(string, equalTo("(field-load (effect \"Example/Project.State\") \"read\")")); - } - - @Test - public void canSerializeIf() { - var instruction = Instructions.if_( - 1, - List.of( - Instructions.pushUnit() - ), - List.of( - Instructions.localLoad("x"), - Instructions.discard(), - Instructions.pushBool(true) - ) - ); - - var string = serialize(instruction); - - assertThat(string, equalTo(""" - ( - if - result-count=1 - ( - (push-unit) - ) - ( - (local-load "x") - (discard) - (push-bool true) - ) - )""")); - } - - @Test - public void canSerializeIntAdd() { - var instruction = Instructions.intAdd(); - - var string = serialize(instruction); - - assertThat(string, equalTo("(int-add)")); - } - - @Test - public void canSerializeIntEquals() { - var instruction = Instructions.intEquals(); - - var string = serialize(instruction); - - assertThat(string, equalTo("(int-eq)")); - } - - @Test - public void canSerializeIntNotEqual() { - var instruction = Instructions.intNotEqual(); - - var string = serialize(instruction); - - assertThat(string, equalTo("(int-ne)")); - } - - @Test - public void canSerializeIntSub() { - var instruction = Instructions.intSub(); - - var string = serialize(instruction); - - assertThat(string, equalTo("(int-sub)")); - } - - @Test - public void canSerializeLocalLoad() { - var instruction = Instructions.localLoad("x"); - - var string = serialize(instruction); - - assertThat(string, equalTo("(local-load \"x\")")); - } - - @Test - public void canSerializeLocalStore() { - var instruction = Instructions.localStore("x"); - - var string = serialize(instruction); - - assertThat(string, equalTo("(local-store \"x\")")); - } - - @Test - public void canSerializeLoop() { - var instruction = Instructions.loop( - List.of( - Instructions.localLoad("x"), - Instructions.discard() - ) - ); - - var string = serialize(instruction); - - assertThat(string, equalTo(""" - ( - loop - ( - (local-load "x") - (discard) - ) - )""")); - } - - @Test - public void canSerializeLoopBreak() { - var instruction = Instructions.loopBreak(); - - var string = serialize(instruction); - - assertThat(string, equalTo("(break)")); - } - - @Test - public void canSerializeLoopContinue() { - var instruction = Instructions.loopContinue(); - - var string = serialize(instruction); - - assertThat(string, equalTo("(continue)")); - } - - @Test - public void canSerializeNamespaceFieldStore() { - var instruction = Instructions.namespaceFieldStore( - new NamespaceName(List.of("Example", "Lib")), - "x" - ); - - var string = serialize(instruction); - - assertThat(string, equalTo("(namespace-field-store \"Example/Lib\" \"x\")")); - } - - @Test - public void canSerializeNamespaceImport() { - var instruction = Instructions.namespaceImport( - new NamespaceName(List.of("Example", "Lib")) - ); - - var string = serialize(instruction); - - assertThat(string, equalTo("(namespace-import \"Example/Lib\")")); - } - - @Test - public void canSerializePushBool() { - var instruction = Instructions.pushBool(true); - - var string = serialize(instruction); - - assertThat(string, equalTo("(push-bool true)")); - } - - @Test - public void canSerializePushInt() { - var instruction = Instructions.pushInt(42); - - var string = serialize(instruction); - - assertThat(string, equalTo("(push-int 42)")); - } - - @Test - public void canSerializePushString() { - var instruction = Instructions.pushString("hello"); - - var string = serialize(instruction); - - assertThat(string, equalTo("(push-string \"hello\")")); - } - - @Test - public void specialCharactersInStringAreEscaped() { - var instruction = Instructions.pushString("\b\t\n\f\r\"\\"); - - var string = serialize(instruction); - - assertThat(string, equalTo("(push-string \"\\b\\t\\n\\f\\r\\\"\\\\\")")); - } - - @Test - public void canSerializePushUnit() { - var instruction = Instructions.pushUnit(); - - var string = serialize(instruction); - - assertThat(string, equalTo("(push-unit)")); - } - - @Test - public void canSerializeResume() { - var instruction = Instructions.resume(); - - var string = serialize(instruction); - - assertThat(string, equalTo("(resume)")); - } - - @Test - public void canSerializeReturn() { - var instruction = Instructions.return_(); - - var string = serialize(instruction); - - assertThat(string, equalTo("(return)")); - } - - @Test - public void canSerializeStringAdd() { - var instruction = Instructions.stringAdd(); - - var string = serialize(instruction); - - assertThat(string, equalTo("(string-add)")); - } - - @Test - public void canSerializeSwitch() { - var instruction = Instructions.switch_(List.of( - Instructions.switchCase( - Types.struct(NamespaceName.of("Example", "Project"), "A"), - List.of( - Instructions.return_() - ) - ), - Instructions.switchCase( - Types.struct(NamespaceName.of("Example", "Project"), "B"), - List.of( - Instructions.discard() - ) - ) - )); - - var string = serialize(instruction); - - assertThat(string, equalTo(""" - ( - switch - ( - ( - "Example/Project.A" - ( - (return) - ) - ) - ( - "Example/Project.B" - ( - (discard) - ) - ) - ) - )""" - )); - } - @Test - public void canSerializeTry() { - var effect = Effects.userDefined(NamespaceName.of("Example", "Project"), "State"); - var instruction = Instructions.try_( - effect, - List.of("read", "write"), - List.of( - Instructions.pushUnit() - ) - ); - - var string = serialize(instruction); - - assertThat(string, equalTo(""" - ( - try - "Example/Project.State" - ( - "read" - "write" - ) - ( - (push-unit) - ) - )""")); - } - - @Test - public void canSerializeTupleCreate() { - var instruction = Instructions.tupleCreate(2); - - var string = serialize(instruction); - - assertThat(string, equalTo("(tuple-create 2)")); - } - - @Test - public void canSerializeTupleGet() { - var instruction = Instructions.tupleGet(2, 3); - - var string = serialize(instruction); - - assertThat(string, equalTo("(tuple-get 2 3)")); - } - - @Test - public void canSerializeVarLoad() { - var instruction = Instructions.varLoad("x"); - - var string = serialize(instruction); - - assertThat(string, equalTo("(var-load \"x\")")); - } - - @Test - public void canSerializeVarStore() { - var instruction = Instructions.varStore("x"); - - var string = serialize(instruction); - - assertThat(string, equalTo("(var-store \"x\")")); - } - - private String serialize(Instruction instruction) { - var builder = new StringBuilder(); - InstructionSerializer.serializeInstruction(instruction, builder); - return builder.toString(); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerAssignTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerAssignTests.java deleted file mode 100644 index 431556a0..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerAssignTests.java +++ /dev/null @@ -1,94 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; - -import java.util.List; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.*; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; - -public class StackCompilerAssignTests { - @Test - public void targetIgnoreIsCompiledToDiscard() { - var node = Typed.assign( - Typed.targetIgnore(), - Typed.reference("x") - ); - var context = StackCompiler.Context.EMPTY - .addShedVal("x"); - - var result = StackCompiler.compileFunctionStatement(node, context); - - assertThat(result.instructions(), isSequence( - isLocalLoadInstruction("x__0"), - isDiscardInstruction() - )); - } - - @Test - public void whenTargetIsReassignThenExpressionIsEvaluatedAndStoredAsVar() { - var node = Typed.assign( - Typed.targetReassign("x"), - Typed.stringLiteral("hello") - ); - var context = StackCompiler.Context.EMPTY - .addShedVal("x"); - - var result = StackCompiler.compileFunctionStatement(node, context); - - assertThat(result.instructions(), isSequence( - isPushStringInstruction("hello"), - isVarStoreInstruction("x__0") - )); - } - - @Test - public void whenTargetIsTupleThenExpressionIsDeconstructed() { - var node = Typed.assign( - Typed.targetTuple(List.of( - Typed.targetVal("a"), - Typed.targetVal("b"), - Typed.targetVal("c") - )), - Typed.reference("x") - ); - var context = StackCompiler.Context.EMPTY - .addShedVal("x") - .addShedVal("a") - .addShedVal("b") - .addShedVal("c"); - - var result = StackCompiler.compileFunctionStatement(node, context); - - assertThat(result.instructions(), isSequence( - isLocalLoadInstruction("x__0"), - isDuplicateInstruction(), - isTupleGetInstruction(0), - isLocalStoreInstruction("a__0"), - isDuplicateInstruction(), - isTupleGetInstruction(1), - isLocalStoreInstruction("b__0"), - isTupleGetInstruction(2), - isLocalStoreInstruction("c__0") - )); - } - - @Test - public void deconstructingEmptyTupleDiscardsExpression() { - var node = Typed.assign( - Typed.targetTuple(List.of()), - Typed.reference("x") - ); - var context = StackCompiler.Context.EMPTY - .addShedVal("x"); - - var result = StackCompiler.compileFunctionStatement(node, context); - - assertThat(result.instructions(), isSequence( - isLocalLoadInstruction("x__0"), - isDiscardInstruction() - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerBlockReturnTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerBlockReturnTests.java deleted file mode 100644 index df738405..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerBlockReturnTests.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.isPushStringInstruction; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; - -public class StackCompilerBlockReturnTests { - @Test - public void expressionIsEvaluated() { - var node = Typed.blockReturn(Typed.stringLiteral("hello")); - var context = StackCompiler.Context.EMPTY; - - var result = StackCompiler.compileFunctionStatement(node, context); - - assertThat(result.instructions(), isSequence( - isPushStringInstruction("hello") - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerBoolLiteralTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerBoolLiteralTests.java deleted file mode 100644 index ac96c48e..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerBoolLiteralTests.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.isPushBoolInstruction; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; - -public class StackCompilerBoolLiteralTests { - @Test - public void boolLiteralIsCompiledToPushBoolInstruction() { - var node = Typed.boolLiteral(true); - var context = StackCompiler.Context.EMPTY; - - var result = StackCompiler.compileExpression(node, context); - - assertThat(result.instructions(), isSequence( - isPushBoolInstruction(true) - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerCallTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerCallTests.java deleted file mode 100644 index 2cf25bb1..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerCallTests.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; - -import java.util.List; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.*; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; - -public class StackCompilerCallTests { - @Test - public void callIsCompiledToInstructionsForOperandThenCall() { - var node = Typed.call( - Typed.reference("f"), - List.of( - Typed.stringLiteral("p1"), - Typed.stringLiteral("p2") - - ), - List.of( - Typed.namedArg("x2", Typed.stringLiteral("n2")), - Typed.namedArg("x1", Typed.stringLiteral("n1")) - ) - ); - var context = StackCompiler.Context.EMPTY - .addShedVal("f"); - - var result = StackCompiler.compileExpression(node, context); - - assertThat(result.instructions(), isSequence( - isLocalLoadInstruction("f__0"), - isPushStringInstruction("p1"), - isPushStringInstruction("p2"), - isPushStringInstruction("n2"), - isPushStringInstruction("n1"), - isCallInstruction(2, List.of("x2", "x1")) - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerEffectDefinitionTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerEffectDefinitionTests.java deleted file mode 100644 index 051c03e4..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerEffectDefinitionTests.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; -import org.shedlang.compiler.stackir.instructions.DefineEffectInstruction; -import org.shedlang.compiler.types.Effects; -import org.shedlang.compiler.types.NamespaceName; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.isLocalStoreInstruction; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.*; - -public class StackCompilerEffectDefinitionTests { - @Test - public void effectDefinitionIsCompiledToDefineEffectInstruction() { - var effect = Effects.userDefined(NamespaceName.of("Example", "Project"), "State"); - var node = Typed.effectDefinition(effect); - var context = StackCompiler.Context.EMPTY - .addShedVal("State"); - - var result = StackCompiler.compileNamespaceStatement(node, context); - - assertThat(result.instructions(), isSequence( - instanceOf( - DefineEffectInstruction.class, - has("effect", x -> x.effect(), equalTo(effect)) - ), - isLocalStoreInstruction("State__0") - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerExpressionStatementTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerExpressionStatementTests.java deleted file mode 100644 index f644408b..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerExpressionStatementTests.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.isDiscardInstruction; -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.isPushStringInstruction; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; - -public class StackCompilerExpressionStatementTests { - @Test - public void expressionIsEvaluatedAndTheResultDiscarded() { - var node = Typed.expressionStatement(Typed.stringLiteral("hello")); - var context = StackCompiler.Context.EMPTY; - - var result = StackCompiler.compileFunctionStatement(node, context); - - assertThat(result.instructions(), isSequence( - isPushStringInstruction("hello"), - isDiscardInstruction() - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerFieldAccessTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerFieldAccessTests.java deleted file mode 100644 index 4c0821a6..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerFieldAccessTests.java +++ /dev/null @@ -1,78 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; -import org.shedlang.compiler.stackir.instructions.FieldLoadInstruction; -import org.shedlang.compiler.types.Effects; -import org.shedlang.compiler.types.NamespaceName; -import org.shedlang.compiler.types.Types; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.isFieldLoadInstruction; -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.isLocalLoadInstruction; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; - -public class StackCompilerFieldAccessTests { - @Test - public void namespaceFieldAccessIsCompiledToFieldLoad() { - var namespaceType = Types.namespace(NamespaceName.of("Example", "Project")); - var node = Typed.fieldAccess( - Typed.reference("Project", namespaceType), - "name", - Types.STRING - ); - var context = StackCompiler.Context.EMPTY - .addShedVal("Project"); - - var result = StackCompiler.compileExpression(node, context); - - assertThat(result.instructions(), isSequence( - isLocalLoadInstruction("Project__0"), - isFieldLoadInstruction( - new FieldLoadInstruction.Receiver.Namespace(namespaceType.namespaceName()), - "name" - ) - )); - } - - @Test - public void structFieldAccessIsCompiledToFieldLoad() { - var structType = Types.struct(NamespaceName.of("Example", "Project"), "User"); - var node = Typed.fieldAccess( - Typed.reference("user", structType), - "name", - Types.STRING - ); - var context = StackCompiler.Context.EMPTY - .addShedVal("user"); - - var result = StackCompiler.compileExpression(node, context); - - assertThat(result.instructions(), isSequence( - isLocalLoadInstruction("user__0"), - isFieldLoadInstruction(structType, "name") - )); - } - - @Test - public void userDefinedEffectFieldAccessIsCompiledToFieldLoad() { - var effect = Effects.userDefined(NamespaceName.of("Example", "Project"), "State"); - var node = Typed.fieldAccess( - Typed.reference("State", Types.effectType(effect)), - "read", - Types.STRING - ); - var context = StackCompiler.Context.EMPTY - .addShedVal("State"); - - var result = StackCompiler.compileExpression(node, context); - - assertThat(result.instructions(), isSequence( - isLocalLoadInstruction("State__0"), - isFieldLoadInstruction( - new FieldLoadInstruction.Receiver.Effect(effect), - "read" - ) - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerFunctionDefinitionTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerFunctionDefinitionTests.java deleted file mode 100644 index d28a3eb5..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerFunctionDefinitionTests.java +++ /dev/null @@ -1,75 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; -import org.shedlang.compiler.ast.typed.TypedFunctionDefinitionNode; -import org.shedlang.compiler.stackir.instructions.DefineFunctionInstruction; -import org.shedlang.compiler.types.Types; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.*; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.*; - -public class StackCompilerFunctionDefinitionTests { - @Test - public void functionIsCompiledToDefineFunctionInstruction() { - var node = TypedFunctionDefinitionNode.builder() - .withName("f") - .addPositionalParam("x", Typed.typeLevelReference("String", Types.STRING)) - .addNamedParam("y", Typed.typeLevelReference("Int", Types.INT)) - .addFreeVariable("z") - .addStatement(Typed.expressionStatement(Typed.stringLiteral("hello"))) - .build(); - var context = StackCompiler.Context.EMPTY - .addShedVal("f") - .addShedVal("z"); - - var result = StackCompiler.compileNamespaceStatement(node, context); - - assertThat(result.instructions(), isSequence( - instanceOf( - DefineFunctionInstruction.class, - has("name", x -> x.name(), equalTo("f")), - has("positionalParams", x -> x.positionalParams(), isSequence( - isDefineFunctionInstructionParam("x__0") - )), - has("namedParams", x -> x.namedParams(), isSequence( - isDefineFunctionInstructionParam("y__0") - )), - has("freeVariables", x -> x.freeVariables(), containsExactly( - has("name", x -> x.name(), equalTo("z__0")) - )), - has("body", x -> x.body(), isSequence( - isPushStringInstruction("hello"), - isDiscardInstruction(), - isPushUnitInstruction(), - isReturnInstruction() - )) - ), - isLocalStoreInstruction("f__0") - )); - } - - @Test - public void whenLastStatementIsBlockReturnThenThatValueIsReturned() { - var node = TypedFunctionDefinitionNode.builder() - .withName("f") - .addStatement(Typed.blockReturn(Typed.stringLiteral("hello"))) - .build(); - var context = StackCompiler.Context.EMPTY - .addShedVal("f"); - - var result = StackCompiler.compileNamespaceStatement(node, context); - - assertThat(result.instructions(), isSequence( - instanceOf( - DefineFunctionInstruction.class, - has("body", x -> x.body(), isSequence( - isPushStringInstruction("hello"), - isReturnInstruction() - )) - ), - isLocalStoreInstruction("f__0") - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerFunctionExpressionTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerFunctionExpressionTests.java deleted file mode 100644 index d14356f7..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerFunctionExpressionTests.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; -import org.shedlang.compiler.ast.typed.TypedFunctionExpressionNode; -import org.shedlang.compiler.stackir.instructions.DefineFunctionInstruction; -import org.shedlang.compiler.types.Types; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.*; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.*; - -public class StackCompilerFunctionExpressionTests { - @Test - public void functionIsCompiledToDefineFunctionInstruction() { - var node = TypedFunctionExpressionNode.builder() - .addPositionalParam("x", Typed.typeLevelReference("String", Types.STRING)) - .addNamedParam("y", Typed.typeLevelReference("Int", Types.INT)) - .addFreeVariable("z") - .addStatement(Typed.expressionStatement(Typed.stringLiteral("hello"))) - .build(); - var context = StackCompiler.Context.EMPTY - .addShedVal("f") - .addShedVal("z"); - - var result = StackCompiler.compileExpression(node, context); - - assertThat(result.instructions(), isSequence( - instanceOf( - DefineFunctionInstruction.class, - has("name", x -> x.name(), equalTo("anonymous")), - has("positionalParams", x -> x.positionalParams(), isSequence( - isDefineFunctionInstructionParam("x__0") - )), - has("namedParams", x -> x.namedParams(), isSequence( - isDefineFunctionInstructionParam("y__0") - )), - has("freeVariables", x -> x.freeVariables(), containsExactly( - has("name", x -> x.name(), equalTo("z__0")) - )), - has("body", x -> x.body(), isSequence( - isPushStringInstruction("hello"), - isDiscardInstruction(), - isPushUnitInstruction(), - isReturnInstruction() - )) - ) - )); - } - - @Test - public void whenLastStatementIsBlockReturnThenThatValueIsReturned() { - var node = TypedFunctionExpressionNode.builder() - .addStatement(Typed.blockReturn(Typed.stringLiteral("hello"))) - .build(); - var context = StackCompiler.Context.EMPTY - .addShedVal("f"); - - var result = StackCompiler.compileExpression(node, context); - - assertThat(result.instructions(), isSequence( - instanceOf( - DefineFunctionInstruction.class, - has("body", x -> x.body(), isSequence( - isPushStringInstruction("hello"), - isReturnInstruction() - )) - ) - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerFunctionReturnTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerFunctionReturnTests.java deleted file mode 100644 index 8bd5c64d..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerFunctionReturnTests.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.*; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; - -public class StackCompilerFunctionReturnTests { - @Test - public void expressionIsEvaluatedAndReturned() { - var node = Typed.functionReturn(Typed.stringLiteral("hello")); - var context = StackCompiler.Context.EMPTY; - - var result = StackCompiler.compileFunctionStatement(node, context); - - assertThat(result.instructions(), isSequence( - isPushStringInstruction("hello"), - isReturnInstruction() - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerIfTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerIfTests.java deleted file mode 100644 index dca0be02..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerIfTests.java +++ /dev/null @@ -1,98 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; -import org.shedlang.compiler.types.Types; - -import java.util.List; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.*; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; - -public class StackCompilerIfTests { - @Test - public void ifWithSingleConditionalBranchIsCompiledToSingleIfInstruction() { - var node = Typed.if_( - List.of( - Typed.conditionalBranch( - Typed.reference("c"), - Typed.block(List.of( - Typed.blockReturn(Typed.intLiteral(42)) - )) - ) - ), - Typed.block(List.of( - Typed.functionReturn(Typed.stringLiteral("x")) - )), - Types.INT - ); - var context = StackCompiler.Context.EMPTY - .addShedVal("c"); - - var result = StackCompiler.compileExpression(node, context); - - assertThat(result.instructions(), isSequence( - isLocalLoadInstruction("c__0"), - isIfInstruction( - isSequence( - isPushIntInstruction(42) - ), - isSequence( - isPushStringInstruction("x"), - isReturnInstruction() - ) - ) - )); - } - - @Test - public void ifWithMultipleConditionalBranchesIsCompiledToNestedIfInstructions() { - var node = Typed.if_( - List.of( - Typed.conditionalBranch( - Typed.reference("c"), - Typed.block(List.of( - Typed.blockReturn(Typed.intLiteral(42)) - )) - ), - Typed.conditionalBranch( - Typed.reference("d"), - Typed.block(List.of( - Typed.blockReturn(Typed.intLiteral(1)) - )) - ) - ), - Typed.block(List.of( - Typed.functionReturn(Typed.stringLiteral("x")) - )), - Types.INT - ); - var context = StackCompiler.Context.EMPTY - .addShedVal("c") - .addShedVal("d"); - - var result = StackCompiler.compileExpression(node, context); - - assertThat(result.instructions(), isSequence( - isLocalLoadInstruction("c__0"), - isIfInstruction( - isSequence( - isPushIntInstruction(42) - ), - isSequence( - isLocalLoadInstruction("d__0"), - isIfInstruction( - isSequence( - isPushIntInstruction(1) - ), - isSequence( - isPushStringInstruction("x"), - isReturnInstruction() - ) - ) - ) - ) - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerIntAddTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerIntAddTests.java deleted file mode 100644 index 4724b867..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerIntAddTests.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.isIntAddInstruction; -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.isPushIntInstruction; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; - -public class StackCompilerIntAddTests { - @Test - public void intAddIsCompiledToIntAddInstruction() { - var node = Typed.intAdd( - Typed.intLiteral(42), - Typed.intLiteral(47) - ); - var context = StackCompiler.Context.EMPTY; - - var result = StackCompiler.compileExpression(node, context); - - assertThat(result.instructions(), isSequence( - isPushIntInstruction(42), - isPushIntInstruction(47), - isIntAddInstruction() - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerIntEqualsTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerIntEqualsTests.java deleted file mode 100644 index 61eb93f9..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerIntEqualsTests.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.*; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; - -public class StackCompilerIntEqualsTests { - @Test - public void intEqualsIsCompiledToIntEqualsInstruction() { - var node = Typed.intEquals( - Typed.intLiteral(42), - Typed.intLiteral(47) - ); - var context = StackCompiler.Context.EMPTY; - - var result = StackCompiler.compileExpression(node, context); - - assertThat(result.instructions(), isSequence( - isPushIntInstruction(42), - isPushIntInstruction(47), - isIntEqualsInstruction() - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerIntLiteralTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerIntLiteralTests.java deleted file mode 100644 index 402c6dac..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerIntLiteralTests.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.isPushIntInstruction; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; - -public class StackCompilerIntLiteralTests { - @Test - public void intLiteralIsCompiledToPushIntInstruction() { - var node = Typed.intLiteral(42); - var context = StackCompiler.Context.EMPTY; - - var result = StackCompiler.compileExpression(node, context); - - assertThat(result.instructions(), isSequence( - isPushIntInstruction(42) - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerIntNotEqualTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerIntNotEqualTests.java deleted file mode 100644 index 8364bc81..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerIntNotEqualTests.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.*; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; - -public class StackCompilerIntNotEqualTests { - @Test - public void intNotEqualsIsCompiledToIntNotEqualInstruction() { - var node = Typed.intNotEqual( - Typed.intLiteral(42), - Typed.intLiteral(47) - ); - var context = StackCompiler.Context.EMPTY; - - var result = StackCompiler.compileExpression(node, context); - - assertThat(result.instructions(), isSequence( - isPushIntInstruction(42), - isPushIntInstruction(47), - isIntNotEqualInstruction() - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerIntSubTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerIntSubTests.java deleted file mode 100644 index 110be63a..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerIntSubTests.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.*; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; - -public class StackCompilerIntSubTests { - @Test - public void intSubIsCompiledToIntSubInstruction() { - var node = Typed.intSub( - Typed.intLiteral(42), - Typed.intLiteral(47) - ); - var context = StackCompiler.Context.EMPTY; - - var result = StackCompiler.compileExpression(node, context); - - assertThat(result.instructions(), isSequence( - isPushIntInstruction(42), - isPushIntInstruction(47), - isIntSubInstruction() - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerNamespaceTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerNamespaceTests.java deleted file mode 100644 index 322bf49f..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerNamespaceTests.java +++ /dev/null @@ -1,118 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.*; -import org.shedlang.compiler.stackir.instructions.*; -import org.shedlang.compiler.types.NamespaceName; -import org.shedlang.compiler.types.Types; - -import java.util.List; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.*; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.*; - -public class StackCompilerNamespaceTests { - @Test - public void bodyOfNamespaceIsCompiledWithNamesBeingExported() { - var namespaceName = new NamespaceName(List.of("Example")); - - var node = Typed.namespace( - namespaceName, - List.of( - TypedFunctionDefinitionNode.builder() - .withName("f") - .addPositionalParam("x", Typed.typeLevelReference("String", Types.STRING)) - .addNamedParam("y", Typed.typeLevelReference("Int", Types.INT)) - .addStatement(Typed.expressionStatement(Typed.stringLiteral("hello"))) - .build() - ), - List.of(BoundVariable.immutable("f")), - List.of("f") - ); - - var stackIrNamespace = StackCompiler.compileNamespace(node); - - assertThat(stackIrNamespace.instructions(), isSequence( - // TODO: test the builtin loading properly - instanceOf(NamespaceImportInstruction.class), - instanceOf(FieldLoadInstruction.class), - instanceOf(LocalStoreInstruction.class), - - instanceOf( - DefineFunctionInstruction.class, - has("name", x -> x.name(), equalTo("f")) - ), - isLocalStoreInstruction("f__0"), - isLocalLoadInstruction("f__0"), - isNamespaceFieldStoreInstruction(namespaceName, "f") - )); - } - - @Test - public void importsAreLoaded() { - var node = TypedNamespaceNode.builder() - .addImport(Typed.import_(NamespaceName.of("A"))) - .addBoundVariable(BoundVariable.immutable("A")) - .addImport(Typed.import_(NamespaceName.of("B"))) - .addBoundVariable(BoundVariable.immutable("B")) - .build(); - - var stackIrNamespace = StackCompiler.compileNamespace(node); - - assertThat(stackIrNamespace.instructions(), isSequence( - // TODO: test the builtin loading properly - instanceOf(NamespaceImportInstruction.class), - instanceOf(FieldLoadInstruction.class), - instanceOf(LocalStoreInstruction.class), - - isNamespaceImportInstruction(NamespaceName.of("A")), - isLocalStoreInstruction("A__0"), - isNamespaceImportInstruction(NamespaceName.of("B")), - isLocalStoreInstruction("B__0") - )); - } - - @Test - public void structsAreHoisted() { - var namespaceName = new NamespaceName(List.of("Example")); - var structType = Types.struct(namespaceName, "None"); - var node = Typed.namespace( - namespaceName, - List.of( - TypedFunctionDefinitionNode.builder() - .withName("f") - .build(), - TypedStructDefinitionNode.builder() - .withType(structType) - .build() - ), - List.of(BoundVariable.immutable("f"), BoundVariable.immutable("None")), - List.of("f", "None") - ); - - var stackIrNamespace = StackCompiler.compileNamespace(node); - - assertThat(stackIrNamespace.instructions(), isSequence( - // TODO: test the builtin loading properly - instanceOf(NamespaceImportInstruction.class), - instanceOf(FieldLoadInstruction.class), - instanceOf(LocalStoreInstruction.class), - - instanceOf( - DefineStructInstruction.class, - has("type", x -> x.type(), equalTo(structType)) - ), - isLocalStoreInstruction("None__0"), - instanceOf( - DefineFunctionInstruction.class, - has("name", x -> x.name(), equalTo("f")) - ), - isLocalStoreInstruction("f__0"), - isLocalLoadInstruction("f__0"), - isNamespaceFieldStoreInstruction(namespaceName, "f"), - isLocalLoadInstruction("None__0"), - isNamespaceFieldStoreInstruction(namespaceName, "None") - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerReferenceTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerReferenceTests.java deleted file mode 100644 index 038351c4..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerReferenceTests.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.BoundVariable; -import org.shedlang.compiler.ast.typed.Typed; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.*; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; - -public class StackCompilerReferenceTests { - @Test - public void referenceIsCompiledToLocalLoad() { - var node = Typed.reference("x"); - var context = StackCompiler.Context.EMPTY - .addShedVariable(BoundVariable.immutable("x")); - - var result = StackCompiler.compileExpression(node, context); - - assertThat(result.instructions(), isSequence( - isLocalLoadInstruction("x__0") - )); - } - - @Test - public void whenLocalIsVarThenReferenceIsCompiledToVarLoad() { - var node = Typed.reference("x"); - var context = StackCompiler.Context.EMPTY - .addShedVariable(BoundVariable.mutable("x")); - context = StackCompiler.compileFunctionStatement( - Typed.var("x", Typed.intLiteral(0)), - context - ); - - var result = StackCompiler.compileExpression(node, context); - - assertThat(result.instructions(), isSequence( - isPushIntInstruction(0), - isVarStoreInstruction("x__0"), - isVarLoadInstruction("x__0") - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerResumeTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerResumeTests.java deleted file mode 100644 index 8ee1f909..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerResumeTests.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.*; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; - -public class StackCompilerResumeTests { - @Test - public void expressionIsEvaluatedAndReturned() { - var node = Typed.resume(Typed.stringLiteral("hello")); - var context = StackCompiler.Context.EMPTY; - - var result = StackCompiler.compileFunctionStatement(node, context); - - assertThat(result.instructions(), isSequence( - isPushStringInstruction("hello"), - isResumeInstruction() - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerStringAddTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerStringAddTests.java deleted file mode 100644 index 42557970..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerStringAddTests.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.*; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; - -public class StackCompilerStringAddTests { - @Test - public void stringAddIsCompiledToStringAddInstruction() { - var node = Typed.stringAdd( - Typed.stringLiteral("a"), - Typed.stringLiteral("b") - ); - var context = StackCompiler.Context.EMPTY; - - var result = StackCompiler.compileExpression(node, context); - - assertThat(result.instructions(), isSequence( - isPushStringInstruction("a"), - isPushStringInstruction("b"), - isStringAddInstruction() - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerStringLiteralTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerStringLiteralTests.java deleted file mode 100644 index 44133713..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerStringLiteralTests.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.isPushStringInstruction; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; - -public class StackCompilerStringLiteralTests { - @Test - public void stringLiteralIsCompiledToPushStringInstruction() { - var node = Typed.stringLiteral("hello"); - var context = StackCompiler.Context.EMPTY; - - var result = StackCompiler.compileExpression(node, context); - - assertThat(result.instructions(), isSequence( - isPushStringInstruction("hello") - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerStructDefinitionTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerStructDefinitionTests.java deleted file mode 100644 index 6dc845bd..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerStructDefinitionTests.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; -import org.shedlang.compiler.ast.typed.TypedStructDefinitionNode; -import org.shedlang.compiler.stackir.instructions.DefineStructInstruction; -import org.shedlang.compiler.types.NamespaceName; -import org.shedlang.compiler.types.Types; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.isLocalStoreInstruction; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.*; - -public class StackCompilerStructDefinitionTests { - @Test - public void structDefinitionIsCompiledToDefineStructInstruction() { - var structType = Types.struct(NamespaceName.of("Example", "Project"), "User"); - var node = TypedStructDefinitionNode.builder() - .withType(structType) - .addField(Typed.structFieldDefinition("name", Typed.typeLevelReference("String", Types.STRING))) - .addField(Typed.structFieldDefinition("isActive", Typed.typeLevelReference("Bool", Types.BOOL))) - .build(); - var context = StackCompiler.Context.EMPTY - .addShedVal("User"); - - var result = StackCompiler.compileNamespaceStatement(node, context); - - assertThat(result.instructions(), isSequence( - instanceOf( - DefineStructInstruction.class, - has("type", x -> x.type(), equalTo(structType)), - has("fields", x -> x.fields(), isSequence( - has("name", x -> x.name(), equalTo("name")), - has("name", x -> x.name(), equalTo("isActive")) - )) - ), - isLocalStoreInstruction("User__0") - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerSumTypeDefinitionTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerSumTypeDefinitionTests.java deleted file mode 100644 index 849e2df7..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerSumTypeDefinitionTests.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; -import org.shedlang.compiler.types.NamespaceName; -import org.shedlang.compiler.types.Types; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.isLocalStoreInstruction; -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.isPushUnitInstruction; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; - -public class StackCompilerSumTypeDefinitionTests { - @Test - public void sumTypeDefinitionIsCompiledToUnit() { - // TODO: this is a bit of a hack, we probably want to be able to have - // sum types in some potential backends (e.g. the JVM) - var sumType = Types.sum(NamespaceName.of("Example", "Project"), "Option"); - var node = Typed.sumTypeDefinition(sumType); - var context = StackCompiler.Context.EMPTY - .addShedVal("Option"); - - var result = StackCompiler.compileNamespaceStatement(node, context); - - assertThat(result.instructions(), isSequence( - isPushUnitInstruction(), - isLocalStoreInstruction("Option__0") - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerTryTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerTryTests.java deleted file mode 100644 index f4e87f8f..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerTryTests.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; -import org.shedlang.compiler.ast.typed.TypedTryHandlerMethodNode; -import org.shedlang.compiler.ast.typed.TypedTryNode; -import org.shedlang.compiler.stackir.instructions.DefineFunctionInstruction; -import org.shedlang.compiler.stackir.instructions.TryInstruction; -import org.shedlang.compiler.types.Effects; -import org.shedlang.compiler.types.NamespaceName; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.isPushIntInstruction; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.*; - -public class StackCompilerTryTests { - @Test - public void tryNodeIsCompiledToTryInstruction() { - var effect = Effects.userDefined(NamespaceName.of("Example"), "State"); - var node = TypedTryNode.builder() - .addBodyStatement( - Typed.blockReturn(Typed.intLiteral(42)) - ) - .withHandledEffect(Typed.typeLevelReference("State", effect)) - .addHandlerMethod( - TypedTryHandlerMethodNode.builder() - .withName("read") - .build() - ) - .addHandlerMethod( - TypedTryHandlerMethodNode.builder() - .withName("write") - .build() - ) - .build(); - var context = StackCompiler.Context.EMPTY - .addShedVal("c"); - - var result = StackCompiler.compileExpression(node, context); - - assertThat(result.instructions(), isSequence( - instanceOf( - DefineFunctionInstruction.class, - has("name", x -> x.name(), equalTo("read")) - ), - instanceOf( - DefineFunctionInstruction.class, - has("name", x -> x.name(), equalTo("write")) - ), - instanceOf( - TryInstruction.class, - has("handledEffect", x -> x.handledEffect(), equalTo(effect)), - has("handlerMethodNames", x -> x.handlerMethodNames(), isSequence( - equalTo("read"), - equalTo("write") - )), - has("body", x -> x.body(), isSequence( - isPushIntInstruction(42) - )) - ) - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerTupleTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerTupleTests.java deleted file mode 100644 index f05e9257..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerTupleTests.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; - -import java.util.List; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.*; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; - -public class StackCompilerTupleTests { - @Test - public void stringAddIsCompiledToStringAddInstruction() { - var node = Typed.tuple(List.of( - Typed.stringLiteral("a"), - Typed.boolLiteral(true), - Typed.intLiteral(4) - )); - var context = StackCompiler.Context.EMPTY; - - var result = StackCompiler.compileExpression(node, context); - - assertThat(result.instructions(), isSequence( - isPushStringInstruction("a"), - isPushBoolInstruction(true), - isPushIntInstruction(4), - isTupleCreateInstruction(3) - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerUnitLiteralTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerUnitLiteralTests.java deleted file mode 100644 index 024b9561..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerUnitLiteralTests.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.isPushUnitInstruction; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; - -public class StackCompilerUnitLiteralTests { - @Test - public void unitLiteralIsCompiledToPushUnitInstruction() { - var node = Typed.unitLiteral(); - var context = StackCompiler.Context.EMPTY; - - var result = StackCompiler.compileExpression(node, context); - - assertThat(result.instructions(), isSequence( - isPushUnitInstruction() - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerValTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerValTests.java deleted file mode 100644 index 2e6194ca..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerValTests.java +++ /dev/null @@ -1,106 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.BoundVariable; -import org.shedlang.compiler.ast.typed.Typed; -import org.shedlang.compiler.types.Types; - -import java.util.List; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.*; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; - -public class StackCompilerValTests { - @Test - public void whenValIsFunctionStatementThenExpressionIsEvaluatedAndStoredAsLocal() { - var node = Typed.val("x", Typed.stringLiteral("hello")); - var context = StackCompiler.Context.EMPTY - .addShedVal("x"); - - var result = StackCompiler.compileFunctionStatement(node, context); - - assertThat(result.instructions(), isSequence( - isPushStringInstruction("hello"), - isLocalStoreInstruction("x__0") - )); - } - - @Test - public void whenValIsNamespaceStatementThenExpressionIsEvaluatedAndStoredAsLocal() { - var node = Typed.val("x", Typed.stringLiteral("hello")); - var context = StackCompiler.Context.EMPTY - .addShedVal("x"); - - var result = StackCompiler.compileNamespaceStatement(node, context); - - assertThat(result.instructions(), isSequence( - isPushStringInstruction("hello"), - isLocalStoreInstruction("x__0") - )); - } - - @Test - public void valsInDifferentBlocksAssignToDifferentLocals() { - var nodes = List.of( - Typed.val("x", Typed.intLiteral(10)), - Typed.expressionStatement(Typed.reference("x")), - Typed.expressionStatement(Typed.if_( - List.of( - Typed.conditionalBranch( - Typed.boolLiteral(true), - Typed.block( - List.of( - Typed.val("x", Typed.intLiteral(11)), - Typed.expressionStatement(Typed.reference("x")) - ), - List.of(BoundVariable.immutable("x")) - ) - ) - ), - Typed.block( - List.of( - Typed.val("x", Typed.intLiteral(12)), - Typed.expressionStatement(Typed.reference("x")) - ), - List.of(BoundVariable.immutable("x")) - ), - Types.INT - )), - Typed.expressionStatement(Typed.reference("x")) - ); - var context = StackCompiler.Context.EMPTY - .addShedVal("x"); - - for (var node : nodes) { - context = StackCompiler.compileFunctionStatement(node, context); - } - - assertThat(context.instructions(), isSequence( - isPushIntInstruction(10), - isLocalStoreInstruction("x__0"), - isLocalLoadInstruction("x__0"), - isDiscardInstruction(), - isPushBoolInstruction(true), - isIfInstruction( - isSequence( - isPushIntInstruction(11), - isLocalStoreInstruction("x__1"), - isLocalLoadInstruction("x__1"), - isDiscardInstruction(), - isPushUnitInstruction() - ), - isSequence( - isPushIntInstruction(12), - isLocalStoreInstruction("x__2"), - isLocalLoadInstruction("x__2"), - isDiscardInstruction(), - isPushUnitInstruction() - ) - ), - isDiscardInstruction(), - isLocalLoadInstruction("x__0"), - isDiscardInstruction() - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerVarTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerVarTests.java deleted file mode 100644 index 7df00442..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerVarTests.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.*; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; - -public class StackCompilerVarTests { - @Test - public void expressionIsEvaluatedAndStoredAsVar() { - var node = Typed.var("x", Typed.stringLiteral("hello")); - var context = StackCompiler.Context.EMPTY - .addShedVal("x"); - - var result = StackCompiler.compileFunctionStatement(node, context); - - assertThat(result.instructions(), isSequence( - isPushStringInstruction("hello"), - isVarStoreInstruction("x__0") - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerWhenTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerWhenTests.java deleted file mode 100644 index d19eb525..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerWhenTests.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; -import org.shedlang.compiler.types.NamespaceName; -import org.shedlang.compiler.types.Types; - -import java.util.List; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.*; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; - -public class StackCompilerWhenTests { - private final static NamespaceName NAMESPACE_NAME = NamespaceName.of("Example", "Project"); - - @Test - public void whenIsCompiledToSwitchInstruction() { - var node = Typed.when( - Typed.reference("x"), - List.of( - Typed.whenCase( - Typed.typeLevelReference("A", Types.struct(NAMESPACE_NAME, "A")), - Typed.block(List.of( - Typed.blockReturn(Typed.stringLiteral("a")) - )) - ), - Typed.whenCase( - Typed.typeLevelReference("B", Types.struct(NAMESPACE_NAME, "B")), - Typed.block(List.of( - Typed.blockReturn(Typed.stringLiteral("b")) - )) - ) - ), - Types.STRING - ); - var context = StackCompiler.Context.EMPTY - .addShedVal("x"); - - var result = StackCompiler.compileExpression(node, context); - - assertThat(result.instructions(), isSequence( - isLocalLoadInstruction("x__0"), - isSwitchInstruction( - isSequence( - isSwitchInstructionCase( - Types.struct(NAMESPACE_NAME, "A"), - isSequence( - isPushStringInstruction("a") - ) - ), - isSwitchInstructionCase( - Types.struct(NAMESPACE_NAME, "B"), - isSequence( - isPushStringInstruction("b") - ) - ) - ) - ) - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerWhileTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerWhileTests.java deleted file mode 100644 index 006c0b4c..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerWhileTests.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.shedlang.compiler.stackir; - -import org.junit.jupiter.api.Test; -import org.shedlang.compiler.ast.typed.Typed; - -import java.util.List; - -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.*; -import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; - -public class StackCompilerWhileTests { - @Test - public void whileIsCompiledToLoop() { - var node = Typed.while_( - Typed.reference("c"), - Typed.block(List.of( - Typed.expressionStatement(Typed.intLiteral(42)) - )) - ); - var context = StackCompiler.Context.EMPTY - .addShedVal("c"); - - var result = StackCompiler.compileFunctionStatement(node, context); - - assertThat(result.instructions(), isSequence( - isLoopInstruction( - isSequence( - isLocalLoadInstruction("c__0"), - isIfInstruction( - isSequence(), - isSequence( - isLoopBreakInstruction() - ) - ), - isPushIntInstruction(42), - isDiscardInstruction(), - isLoopContinueInstruction() - ) - ) - )); - } - - @Test - public void whenBodyYieldsValueThenValueIsDiscarded() { - // In principle, the type checker should prevent the body from yielding - // a value, but we check we handle this case anyway. - var node = Typed.while_( - Typed.reference("c"), - Typed.block(List.of( - Typed.blockReturn(Typed.intLiteral(42)) - )) - ); - var context = StackCompiler.Context.EMPTY - .addShedVal("c"); - - var result = StackCompiler.compileFunctionStatement(node, context); - - assertThat(result.instructions(), isSequence( - isLoopInstruction( - isSequence( - isLocalLoadInstruction("c__0"), - isIfInstruction( - isSequence(), - isSequence( - isLoopBreakInstruction() - ) - ), - isPushIntInstruction(42), - isDiscardInstruction(), - isLoopContinueInstruction() - ) - ) - )); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/instructions/InstructionMatchers.java b/src/test/java/org/shedlang/compiler/stackir/instructions/InstructionMatchers.java deleted file mode 100644 index 34c94f0e..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/instructions/InstructionMatchers.java +++ /dev/null @@ -1,229 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.types.NamespaceName; -import org.shedlang.compiler.types.StructType; -import org.zwobble.precisely.Matcher; - -import java.math.BigInteger; -import java.util.List; - -import static org.zwobble.precisely.Matchers.*; - -public class InstructionMatchers { - private InstructionMatchers() { - } - - public static Matcher isCallInstruction( - int positionalArgCount, - List namedArgNames - ) { - return instanceOf( - CallInstruction.class, - has("positionalArgCount", x -> x.positionalArgCount(), equalTo(positionalArgCount)), - has("namedArgNames", x -> x.namedArgNames(), equalTo(namedArgNames)) - ); - } - - public static Matcher isDefineFunctionInstructionParam(String name) { - return has("name", x -> x.name(), equalTo(name)); - } - - public static Matcher isDiscardInstruction() { - return instanceOf( - DiscardInstruction.class - ); - } - - public static Matcher isDuplicateInstruction() { - return instanceOf(DuplicateInstruction.class); - } - - public static Matcher isFieldLoadInstruction( - FieldLoadInstruction.Receiver receiver, - String fieldName - ) { - return instanceOf( - FieldLoadInstruction.class, - has("receiver", x -> x.receiver(), equalTo(receiver)), - has("fieldName", x -> x.fieldName(), equalTo(fieldName)) - ); - } - - public static Matcher isFieldLoadInstruction( - StructType receiverType, - String fieldName - ) { - return isFieldLoadInstruction( - new FieldLoadInstruction.Receiver.Struct(receiverType), - fieldName - ); - } - - public static Matcher isIfInstruction( - Matcher> trueBody, - Matcher> falseBody - ) { - return instanceOf( - IfInstruction.class, - has("trueBody", x -> x.trueBody(), trueBody), - has("falseBody", x -> x.falseBody(), falseBody) - ); - } - - public static Matcher isIntAddInstruction() { - return instanceOf(IntAddInstruction.class); - } - - public static Matcher isIntEqualsInstruction() { - return instanceOf(IntEqualsInstruction.class); - } - - public static Matcher isIntNotEqualInstruction() { - return instanceOf(IntNotEqualInstruction.class); - } - - public static Matcher isIntSubInstruction() { - return instanceOf(IntSubInstruction.class); - } - - public static Matcher isLocalLoadInstruction(String name) { - return instanceOf( - LocalLoadInstruction.class, - has("name", x -> x.name(), equalTo(name)) - ); - } - - public static Matcher isLocalStoreInstruction(String name) { - return instanceOf( - LocalStoreInstruction.class, - has("name", x -> x.name(), equalTo(name)) - ); - } - - public static Matcher isLoopInstruction( - Matcher> body - ) { - return instanceOf( - LoopInstruction.class, - has("body", x -> x.body(), body) - ); - } - - public static Matcher isLoopBreakInstruction() { - return instanceOf(LoopBreakInstruction.class); - } - - public static Matcher isLoopContinueInstruction() { - return instanceOf(LoopContinueInstruction.class); - } - - public static Matcher isNamespaceFieldStoreInstruction( - NamespaceName namespaceName, - String fieldName - ) { - return instanceOf( - NamespaceFieldStoreInstruction.class, - has("namespaceName", x -> x.namespaceName(), equalTo(namespaceName)), - has("fieldName", x -> x.fieldName(), equalTo(fieldName)) - ); - } - - public static Matcher isNamespaceImportInstruction( - NamespaceName namespaceName - ) { - return instanceOf( - NamespaceImportInstruction.class, - has("namespaceName", x -> x.namespaceName(), equalTo(namespaceName)) - ); - } - - public static Matcher isPushBoolInstruction(boolean value) { - return instanceOf( - PushBoolInstruction.class, - has("value", x -> x.value(), equalTo(value)) - ); - } - - public static Matcher isPushIntInstruction(int value) { - return instanceOf( - PushIntInstruction.class, - has("value", x -> x.value(), equalTo(BigInteger.valueOf(value))) - ); - } - - public static Matcher isPushStringInstruction(String value) { - return instanceOf( - PushStringInstruction.class, - has("value", x -> x.value(), equalTo(value)) - ); - } - - public static Matcher isPushUnitInstruction() { - return instanceOf( - PushUnitInstruction.class - ); - } - - public static Matcher isResumeInstruction() { - return instanceOf( - ResumeInstruction.class - ); - } - - public static Matcher isReturnInstruction() { - return instanceOf( - ReturnInstruction.class - ); - } - - public static Matcher isStringAddInstruction() { - return instanceOf(StringAddInstruction.class); - } - - public static Matcher isSwitchInstruction( - Matcher> cases - ) { - return instanceOf( - SwitchInstruction.class, - has("cases", x -> x.cases(), cases) - ); - } - - public static Matcher isSwitchInstructionCase( - StructType caseType, - Matcher> body - ) { - return allOf( - has("caseType", x -> x.caseType(), equalTo(caseType)), - has("body", x -> x.body(), body) - ); - } - - public static Matcher isTupleCreateInstruction(int elementCount) { - return instanceOf( - TupleCreateInstruction.class, - has("elementCount", x -> x.elementCount(), equalTo(elementCount)) - ); - } - - public static Matcher isTupleGetInstruction(int elementIndex) { - return instanceOf( - TupleGetInstruction.class, - has("elementIndex", x -> x.elementIndex(), equalTo(elementIndex)) - ); - } - - public static Matcher isVarLoadInstruction(String name) { - return instanceOf( - VarLoadInstruction.class, - has("name", x -> x.name(), equalTo(name)) - ); - } - - public static Matcher isVarStoreInstruction(String name) { - return instanceOf( - VarStoreInstruction.class, - has("name", x -> x.name(), equalTo(name)) - ); - } -} diff --git a/src/test/java/org/shedlang/compiler/stackir/instructions/Instructions.java b/src/test/java/org/shedlang/compiler/stackir/instructions/Instructions.java deleted file mode 100644 index ce6ebf37..00000000 --- a/src/test/java/org/shedlang/compiler/stackir/instructions/Instructions.java +++ /dev/null @@ -1,193 +0,0 @@ -package org.shedlang.compiler.stackir.instructions; - -import org.shedlang.compiler.sources.Sources; -import org.shedlang.compiler.types.NamespaceName; -import org.shedlang.compiler.types.StructType; -import org.shedlang.compiler.types.UserDefinedEffect; - -import java.math.BigInteger; -import java.util.List; - -public class Instructions { - private Instructions() { - } - - public static Instruction call(int positionalArgCount, List namedArgNames) { - return new CallInstruction(positionalArgCount, namedArgNames, Sources.NULL); - } - - public static Instruction defineEffect(UserDefinedEffect effect) { - return new DefineEffectInstruction(effect, Sources.NULL); - } - - public static Instruction defineStruct( - StructType type, - List fields - ) { - return new DefineStructInstruction( - type, - fields, - Sources.NULL - ); - } - - public static DefineStructInstruction.Field defineStructField(String name) { - return new DefineStructInstruction.Field(name, Sources.NULL); - } - - public static Instruction discard() { - return new DiscardInstruction(Sources.NULL); - } - - public static Instruction duplicate() { - return new DuplicateInstruction(Sources.NULL); - } - - public static Instruction fieldLoad(NamespaceName namespaceName, String fieldName) { - return new FieldLoadInstruction( - new FieldLoadInstruction.Receiver.Namespace(namespaceName), - fieldName, - Sources.NULL - ); - } - - public static Instruction fieldLoad(StructType type, String fieldName) { - return new FieldLoadInstruction( - new FieldLoadInstruction.Receiver.Struct(type), - fieldName, - Sources.NULL - ); - } - - public static Instruction fieldLoad(UserDefinedEffect effect, String fieldName) { - return new FieldLoadInstruction( - new FieldLoadInstruction.Receiver.Effect(effect), - fieldName, - Sources.NULL - ); - } - - public static Instruction if_( - int resultCount, - List trueBody, - List falseBody - ) { - return new IfInstruction(resultCount, trueBody, falseBody, Sources.NULL); - } - - public static Instruction intAdd() { - return new IntAddInstruction(Sources.NULL); - } - - public static Instruction intEquals() { - return new IntEqualsInstruction(Sources.NULL); - } - - public static Instruction intNotEqual() { - return new IntNotEqualInstruction(Sources.NULL); - } - - public static Instruction intSub() { - return new IntSubInstruction(Sources.NULL); - } - - public static Instruction localLoad(String name) { - return new LocalLoadInstruction(name, Sources.NULL); - } - - public static Instruction localStore(String name) { - return new LocalStoreInstruction(name, Sources.NULL); - } - - public static Instruction loop(List body) { - return new LoopInstruction(body, Sources.NULL); - } - - public static Instruction loopBreak() { - return new LoopBreakInstruction(Sources.NULL); - } - - public static Instruction loopContinue() { - return new LoopContinueInstruction(Sources.NULL); - } - - public static Instruction namespaceFieldStore(NamespaceName namespaceName, String fieldName) { - return new NamespaceFieldStoreInstruction(namespaceName, fieldName, Sources.NULL); - } - - public static Instruction namespaceImport(NamespaceName namespaceName) { - return new NamespaceImportInstruction(namespaceName, Sources.NULL); - } - - public static DefineFunctionInstruction.Param param(String name) { - return new DefineFunctionInstruction.Param(name, Sources.NULL); - } - - public static Instruction pushBool(boolean value) { - return new PushBoolInstruction(value, Sources.NULL); - } - - public static Instruction pushInt(int value) { - return new PushIntInstruction(BigInteger.valueOf(value), Sources.NULL); - } - - public static Instruction pushString(String value) { - return new PushStringInstruction(value, Sources.NULL); - } - - public static Instruction pushUnit() { - return new PushUnitInstruction(Sources.NULL); - } - - public static Instruction resume() { - return new ResumeInstruction(Sources.NULL); - } - - public static Instruction return_() { - return new ReturnInstruction(Sources.NULL); - } - - public static Instruction stringAdd() { - return new StringAddInstruction(Sources.NULL); - } - - public static Instruction switch_(List cases) { - return new SwitchInstruction(cases, Sources.NULL); - } - - public static SwitchInstruction.Case switchCase( - StructType type, - List body - ) { - return new SwitchInstruction.Case(type, body, Sources.NULL); - } - - public static Instruction try_( - UserDefinedEffect handledEffect, - List handlerMethodNames, - List body - ) { - return new TryInstruction( - handledEffect, - handlerMethodNames, - body, - Sources.NULL - ); - } - - public static Instruction tupleCreate(int elementCount) { - return new TupleCreateInstruction(elementCount, Sources.NULL); - } - - public static Instruction tupleGet(int elementIndex, int elementCount) { - return new TupleGetInstruction(elementIndex, elementCount, Sources.NULL); - } - - public static Instruction varLoad(String name) { - return new VarLoadInstruction(name, Sources.NULL); - } - - public static Instruction varStore(String name) { - return new VarStoreInstruction(name, Sources.NULL); - } -} -- cgit v1.2.3