diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-07-20 10:59:42 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-07-20 11:00:00 +0100 |
| commit | 400e05ae86949488a49d9dcbb49463b2a17b8fc4 (patch) | |
| tree | 34e9fefd29f9f33dbcd64de4434b36a63ee3bcf7 /src/main/java | |
| parent | 492a56b70d5956a956052f37fd77081554cdb837 (diff) | |
Add stubbed function definitions for Patio
Diffstat (limited to 'src/main/java')
8 files changed, 212 insertions, 14 deletions
diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java index 5fdcd30f..13e77b53 100644 --- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java +++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java @@ -1,11 +1,14 @@ package org.shedlang.compiler.patio; -import org.shedlang.compiler.patio.instructions.*; +import org.shedlang.compiler.patio.instructions.PatioIntGet; +import org.shedlang.compiler.patio.instructions.PatioLocal; +import org.shedlang.compiler.patio.instructions.PatioReturn; import org.shedlang.compiler.sources.Source; import org.shedlang.compiler.stackir.instructions.*; import java.util.ArrayList; import java.util.Collections; +import java.util.List; import java.util.Map; import static org.shedlang.compiler.util.Lists.reversed; @@ -13,6 +16,17 @@ import static org.shedlang.compiler.util.Lists.reversed; public class PatioCodeGen { private PatioCodeGen() {} + public static PatioCodeGenContext generateInstructions( + List<Instruction> stackIrInstructions, + PatioCodeGenContext context + ) { + for (var stackIrInstruction : stackIrInstructions) { + context = generateInstruction(stackIrInstruction, context); + } + + return context; + } + public static PatioCodeGenContext generateInstruction( Instruction stackIrInstruction, PatioCodeGenContext context @@ -77,6 +91,18 @@ public class PatioCodeGen { ).temporaryPush(target); } + case DefineFunctionInstruction defineFunction -> + PatioCodeGenClosures.create( + defineFunction.name(), + defineFunction.positionalParams(), + defineFunction.namedParams(), + defineFunction.freeVariables(), + functionContext -> + generateInstructions(defineFunction.body(), functionContext), + defineFunction.source(), + context + ); + case DiscardInstruction discard -> context.temporaryPop().context(); diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenClosures.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenClosures.java index b2bf66f7..e662c053 100644 --- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenClosures.java +++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenClosures.java @@ -1,11 +1,16 @@ package org.shedlang.compiler.patio; -import org.shedlang.compiler.patio.instructions.*; +import org.shedlang.compiler.ast.typed.FreeVariables; +import org.shedlang.compiler.patio.instructions.PatioCallPointer; +import org.shedlang.compiler.patio.instructions.PatioLocal; +import org.shedlang.compiler.patio.instructions.PatioMemoryLoad; import org.shedlang.compiler.sources.Source; +import org.shedlang.compiler.stackir.instructions.DefineFunctionInstruction; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.function.Function; import static org.shedlang.compiler.util.Iterables.sortedBy; @@ -14,6 +19,29 @@ class PatioCodeGenClosures { private static final int FUNCTION_POINTER_OFFSET = 0; + public static PatioCodeGenContext create( + String name, + List<DefineFunctionInstruction.Param> positionalParams, + List<DefineFunctionInstruction.Param> namedParams, + FreeVariables freeVariables, + Function<PatioCodeGenContext, PatioCodeGenContext> compileBody, + Source source, + PatioCodeGenContext context + ) { + var fullNameResult = context.allocateCompilationUnitElementName( + PatioCodeGenCompilationUnitElementSpace.FUNCTION, + name + ); + var fullName = fullNameResult.value(); + context = fullNameResult.context(); + + context = context.createFunction(fullName, source, bodyContext -> { + return bodyContext; + }); + + return context; + } + static PatioCodeGenContext call( PatioLocal target, PatioLocal closure, diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenCompilationUnitElementSpace.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenCompilationUnitElementSpace.java new file mode 100644 index 00000000..0db4e4de --- /dev/null +++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenCompilationUnitElementSpace.java @@ -0,0 +1,16 @@ +package org.shedlang.compiler.patio; + +public enum PatioCodeGenCompilationUnitElementSpace { + FUNCTION("function"); + + private final String name; + + PatioCodeGenCompilationUnitElementSpace(String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } +} diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenContext.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenContext.java index 1c7a6a77..6818d157 100644 --- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenContext.java +++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenContext.java @@ -1,20 +1,54 @@ package org.shedlang.compiler.patio; +import org.pcollections.OrderedPMap; import org.pcollections.PMap; import org.pcollections.PStack; import org.pcollections.PVector; import org.shedlang.compiler.backends.llvm.NameAllocator; -import org.shedlang.compiler.patio.instructions.PatioInstruction; -import org.shedlang.compiler.patio.instructions.PatioLocal; -import org.shedlang.compiler.patio.instructions.PatioLocalCopy; +import org.shedlang.compiler.patio.instructions.*; import org.shedlang.compiler.sources.Source; import org.shedlang.compiler.util.P; import java.util.Optional; +import java.util.function.Function; public record PatioCodeGenContext( + CompilationUnitContext compilationUnitContext, FunctionContext functionContext ) { + public record CompilationUnitContext( + OrderedPMap<String, PatioCompilationUnitElement> elementsByName + ) { + public static final CompilationUnitContext EMPTY = new CompilationUnitContext( + OrderedPMap.empty() + ); + + public CompilationUnitContext addElement(PatioCompilationUnitElement element) { + return new CompilationUnitContext( + this.elementsByName.plus(element.name(), element) + ); + } + + private <T> Result<T> toResult(T value) { + return new Result<>(value, this); + } + + public Result<String> allocateCompilationUnitName( + PatioCodeGenCompilationUnitElementSpace space, + Optional<String> name + ) { + var fullName = NameAllocator.allocateName( + elementsByName::containsKey, + "shed__" + space, + name + ); + + return toResult(fullName); + } + + public record Result<T>(T value, CompilationUnitContext context) {} + } + public record FunctionContext( PStack<PatioLocal> temporaryStack, PVector<PatioInstruction> instructions, @@ -91,50 +125,84 @@ public record PatioCodeGenContext( } public static final PatioCodeGenContext EMPTY = new PatioCodeGenContext( + CompilationUnitContext.EMPTY, FunctionContext.EMPTY ); + public PatioCodeGenResult<String> allocateCompilationUnitElementName( + PatioCodeGenCompilationUnitElementSpace space, + String name + ) { + return withCompilationUnitContextResult( + this.compilationUnitContext.allocateCompilationUnitName( + space, + Optional.of(name) + ) + ); + } + public PatioCodeGenResult<PatioLocal> temporaryPop() { var result = this.functionContext.temporaryPop(); - return new PatioCodeGenContext(result.context).toResult(result.value); + return withFunctionContextResult(result); } public PatioCodeGenContext temporaryPopIntoLocal(PatioLocal target, Source source) { var result = this.functionContext.temporaryPop(); - return new PatioCodeGenContext(result.context) + return new PatioCodeGenContext(this.compilationUnitContext, result.context) .addInstruction(new PatioLocalCopy(target, result.value, source)); } public PatioCodeGenContext temporaryPush(PatioLocal value) { var result = this.functionContext.temporaryPush(value); - return new PatioCodeGenContext(result); + return withFunctionContext(result); } public PatioCodeGenContext addInstruction(PatioInstruction instruction) { - return new PatioCodeGenContext( - this.functionContext.addInstruction(instruction) - ); + return withFunctionContext(this.functionContext.addInstruction(instruction)); } public PatioCodeGenResult<PatioLocal> allocateLocal(PatioCodeGenLocalSpace space, String name) { var result = this.functionContext.allocateLocal(space, Optional.of(name)); - return new PatioCodeGenContext(result.context).toResult(result.value); + return withFunctionContextResult(result); } public PatioCodeGenResult<PatioLocal> allocateLocal(PatioCodeGenLocalSpace space) { var result = this.functionContext.allocateLocal(space, Optional.empty()); - return new PatioCodeGenContext(result.context).toResult(result.value); + return withFunctionContextResult(result); } public PatioCodeGenResult<PatioLocal> stackIrLocalNameToLocal(String name) { var result = this.functionContext.stackIrLocalNameToLocal(name); - return new PatioCodeGenContext(result.context).toResult(result.value); + return withFunctionContextResult(result); + } + + public PatioCodeGenContext createFunction( + String name, + Source source, + Function<PatioCodeGenContext, PatioCodeGenContext> createBody + ) { + return new PatioCodeGenContext( + this.compilationUnitContext.addElement(new PatioFunctionDefinition(name, source)), + this.functionContext + ); + } + + private <T> PatioCodeGenResult<T> withCompilationUnitContextResult(CompilationUnitContext.Result<T> result) { + return new PatioCodeGenContext(result.context, this.functionContext).toResult(result.value); + } + + private <T> PatioCodeGenContext withFunctionContext(FunctionContext functionContext) { + return new PatioCodeGenContext(this.compilationUnitContext, functionContext); + } + + private <T> PatioCodeGenResult<T> withFunctionContextResult(FunctionContext.Result<T> result) { + return new PatioCodeGenContext(this.compilationUnitContext, result.context).toResult(result.value); } private <T> PatioCodeGenResult<T> toResult(T value) { diff --git a/src/main/java/org/shedlang/compiler/patio/PatioInstructionSerializer.java b/src/main/java/org/shedlang/compiler/patio/PatioInstructionSerializer.java index 132803fe..393b4734 100644 --- a/src/main/java/org/shedlang/compiler/patio/PatioInstructionSerializer.java +++ b/src/main/java/org/shedlang/compiler/patio/PatioInstructionSerializer.java @@ -11,6 +11,14 @@ import static org.shedlang.compiler.treetext.Trees.*; public class PatioInstructionSerializer { private PatioInstructionSerializer() {} + public static void serializeCompilationUnitElement( + PatioCompilationUnitElement element, + StringBuilder builder + ) { + var tree = compilationUnitElementToTree(element); + serializeTree(tree, builder, 0); + } + public static void serializeInstructions(List<PatioInstruction> instructions, StringBuilder builder) { var tree = instructionsToTree(instructions); serializeTree(tree, builder, 0); @@ -21,6 +29,16 @@ public class PatioInstructionSerializer { serializeTree(tree, builder, 0); } + private static Tree compilationUnitElementToTree(PatioCompilationUnitElement element) { + return switch (element) { + case PatioFunctionDefinition functionDefinition -> + treeListIndented( + treeIdentifier("function"), + treeString(element.name()) + ); + }; + } + private static Tree instructionsToTree(List<PatioInstruction> instructions) { return treeListIndented( instructions.stream() diff --git a/src/main/java/org/shedlang/compiler/patio/instructions/PatioCompilationUnit.java b/src/main/java/org/shedlang/compiler/patio/instructions/PatioCompilationUnit.java new file mode 100644 index 00000000..6c4f4a1a --- /dev/null +++ b/src/main/java/org/shedlang/compiler/patio/instructions/PatioCompilationUnit.java @@ -0,0 +1,11 @@ +package org.shedlang.compiler.patio.instructions; + +import org.shedlang.compiler.sources.Source; + +import java.util.List; + +public record PatioCompilationUnit( + List<PatioCompilationUnitElement> elements, + Source source +) { +} diff --git a/src/main/java/org/shedlang/compiler/patio/instructions/PatioCompilationUnitElement.java b/src/main/java/org/shedlang/compiler/patio/instructions/PatioCompilationUnitElement.java new file mode 100644 index 00000000..7d29e082 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/patio/instructions/PatioCompilationUnitElement.java @@ -0,0 +1,8 @@ +package org.shedlang.compiler.patio.instructions; + +import org.shedlang.compiler.sources.Source; + +public sealed interface PatioCompilationUnitElement permits PatioFunctionDefinition { + String name(); + Source source(); +} diff --git a/src/main/java/org/shedlang/compiler/patio/instructions/PatioFunctionDefinition.java b/src/main/java/org/shedlang/compiler/patio/instructions/PatioFunctionDefinition.java new file mode 100644 index 00000000..57ee63e3 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/patio/instructions/PatioFunctionDefinition.java @@ -0,0 +1,23 @@ +package org.shedlang.compiler.patio.instructions; + +import org.shedlang.compiler.sources.Source; +import org.shedlang.compiler.sources.Sources; + +public record PatioFunctionDefinition( + String name, + Source source +) implements PatioCompilationUnitElement { + public static Builder builder() { + return new Builder("f"); + } + + public record Builder(String name) { + public Builder withName(String name) { + return new Builder(name); + } + + public PatioFunctionDefinition build() { + return new PatioFunctionDefinition(name, Sources.NULL); + } + } +} |
