From 400e05ae86949488a49d9dcbb49463b2a17b8fc4 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Thu, 20 Jul 2023 10:59:42 +0100 Subject: Add stubbed function definitions for Patio --- .../org/shedlang/compiler/patio/PatioCodeGen.java | 28 ++++++- .../compiler/patio/PatioCodeGenClosures.java | 30 ++++++- .../PatioCodeGenCompilationUnitElementSpace.java | 16 ++++ .../compiler/patio/PatioCodeGenContext.java | 92 +++++++++++++++++++--- .../compiler/patio/PatioInstructionSerializer.java | 18 +++++ .../patio/instructions/PatioCompilationUnit.java | 11 +++ .../instructions/PatioCompilationUnitElement.java | 8 ++ .../instructions/PatioFunctionDefinition.java | 23 ++++++ 8 files changed, 212 insertions(+), 14 deletions(-) create mode 100644 src/main/java/org/shedlang/compiler/patio/PatioCodeGenCompilationUnitElementSpace.java create mode 100644 src/main/java/org/shedlang/compiler/patio/instructions/PatioCompilationUnit.java create mode 100644 src/main/java/org/shedlang/compiler/patio/instructions/PatioCompilationUnitElement.java create mode 100644 src/main/java/org/shedlang/compiler/patio/instructions/PatioFunctionDefinition.java (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java index 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 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 positionalParams, + List namedParams, + FreeVariables freeVariables, + Function 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 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 Result toResult(T value) { + return new Result<>(value, this); + } + + public Result allocateCompilationUnitName( + PatioCodeGenCompilationUnitElementSpace space, + Optional name + ) { + var fullName = NameAllocator.allocateName( + elementsByName::containsKey, + "shed__" + space, + name + ); + + return toResult(fullName); + } + + public record Result(T value, CompilationUnitContext context) {} + } + public record FunctionContext( PStack temporaryStack, PVector instructions, @@ -91,50 +125,84 @@ public record PatioCodeGenContext( } public static final PatioCodeGenContext EMPTY = new PatioCodeGenContext( + CompilationUnitContext.EMPTY, FunctionContext.EMPTY ); + public PatioCodeGenResult allocateCompilationUnitElementName( + PatioCodeGenCompilationUnitElementSpace space, + String name + ) { + return withCompilationUnitContextResult( + this.compilationUnitContext.allocateCompilationUnitName( + space, + Optional.of(name) + ) + ); + } + public PatioCodeGenResult 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 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 allocateLocal(PatioCodeGenLocalSpace space) { var result = this.functionContext.allocateLocal(space, Optional.empty()); - return new PatioCodeGenContext(result.context).toResult(result.value); + return withFunctionContextResult(result); } public PatioCodeGenResult 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 createBody + ) { + return new PatioCodeGenContext( + this.compilationUnitContext.addElement(new PatioFunctionDefinition(name, source)), + this.functionContext + ); + } + + private PatioCodeGenResult withCompilationUnitContextResult(CompilationUnitContext.Result result) { + return new PatioCodeGenContext(result.context, this.functionContext).toResult(result.value); + } + + private PatioCodeGenContext withFunctionContext(FunctionContext functionContext) { + return new PatioCodeGenContext(this.compilationUnitContext, functionContext); + } + + private PatioCodeGenResult withFunctionContextResult(FunctionContext.Result result) { + return new PatioCodeGenContext(this.compilationUnitContext, result.context).toResult(result.value); } private PatioCodeGenResult 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 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 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 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); + } + } +} -- cgit v1.2.3