From f570b54bd3e0fe6ebc134101e3c54be5bc49253d Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Fri, 20 Dec 2024 14:21:22 +0000 Subject: Add Shid code gen for methods on structs --- .../ast/typed/TypedFunctionDefinitionNode.java | 12 +++++++++++- .../ast/typed/TypedFunctionSignatureNode.java | 14 ++++++++++++-- .../ast/typed/TypedStructDefinitionNode.java | 9 +++++++++ .../org/shedlang/compiler/shid/ShidCodeGen.java | 22 +++++++++++++++++++++- .../shid/instructions/ShidDefineStruct.java | 3 +++ 5 files changed, 56 insertions(+), 4 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionDefinitionNode.java b/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionDefinitionNode.java index 3d1089b0..b802f255 100644 --- a/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionDefinitionNode.java +++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionDefinitionNode.java @@ -62,7 +62,17 @@ public record TypedFunctionDefinitionNode( ); } - public TypedFunctionDefinitionNode.Builder addPositionalParam(String name, TypedTypeLevelExpressionNode type) { + public TypedFunctionDefinitionNode.Builder addPositionalParam( + String name, + TypedTypeLevelExpressionNode type + ) { + return addPositionalParam(name, Optional.of(type)); + } + + public TypedFunctionDefinitionNode.Builder addPositionalParam( + String name, + Optional> type + ) { return new TypedFunctionDefinitionNode.Builder( this.name, this.signature.addPositionalParam(name, type), diff --git a/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionSignatureNode.java b/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionSignatureNode.java index 4e66b819..2e535a7d 100644 --- a/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionSignatureNode.java +++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionSignatureNode.java @@ -43,9 +43,19 @@ public record TypedFunctionSignatureNode( ); } - public Builder addPositionalParam(String name, TypedTypeLevelExpressionNode type) { + public Builder addPositionalParam( + String name, + TypedTypeLevelExpressionNode type + ) { + return addPositionalParam(name, Optional.of(type)); + } + + public Builder addPositionalParam( + String name, + Optional> type + ) { return new Builder( - this.positionalParams.plus(new TypedParamNode(name, Optional.of(type), Sources.NULL)), + this.positionalParams.plus(new TypedParamNode(name, type, Sources.NULL)), this.namedParams, this.effect, this.returnType diff --git a/src/main/java/org/shedlang/compiler/ast/typed/TypedStructDefinitionNode.java b/src/main/java/org/shedlang/compiler/ast/typed/TypedStructDefinitionNode.java index 5d36e05a..0d63e34b 100644 --- a/src/main/java/org/shedlang/compiler/ast/typed/TypedStructDefinitionNode.java +++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedStructDefinitionNode.java @@ -61,5 +61,14 @@ public record TypedStructDefinitionNode( this.methods ); } + + public Builder addMethod(TypedFunctionDefinitionNode method) { + return new Builder( + this.type, + this.fields, + this.fieldsArePositional, + this.methods.plus(method) + ); + } } } diff --git a/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java b/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java index 48dbbf3c..b0c33578 100644 --- a/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java +++ b/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java @@ -3,8 +3,8 @@ 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.sources.Source; import org.shedlang.compiler.sources.Sources; import org.shedlang.compiler.types.*; import org.shedlang.compiler.util.Iterables; @@ -549,11 +549,31 @@ public class ShidCodeGen { ) { var structType = node.typeOrConstructor().toType(); + var methods = new ArrayList(); + for (var methodNode : node.methods()) { + var shidFunctionName = context.generateLocalNameForVariable( + structType.name() + "__" + methodNode.name() + ); + context = compileFunction( + shidFunctionName, + methodNode.signature().params(), + methodNode.body(), + ShidDefineFunction.Variant.FUNCTION, + methodNode.source(), + context + ); + methods.add(new ShidDefineStruct.Method( + methodNode.name(), + shidFunctionName + )); + } + var defineStructInstruction = new ShidDefineStruct( structType, node.fields().stream() .map(field -> new ShidDefineStruct.Field(field.name(), field.source())) .toList(), + methods, node.source() ); diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineStruct.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineStruct.java index b52c9e74..c76b4f20 100644 --- a/src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineStruct.java +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineStruct.java @@ -13,10 +13,13 @@ public record ShidDefineStruct( SimpleStructType type, // TODO: remove fields? We should have fields from the type info. List fields, + List methods, Source source ) implements ShidInstruction { public record Field(String name, Source source) { + } + public record Method(String methodName, String shidFunctionName) { } @Override -- cgit v1.2.3