aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2025-01-17 23:32:18 +0000
committerMichael Williamson <mike@zwobble.org>2025-01-17 23:32:18 +0000
commit436f43fa2667c77ef8a7d05bb5b8001c17c7822b (patch)
tree364fece3c5f4833713b1fd7d6e9f1a99dc8dd0a0 /src/main/java/org
parent7c5489a16401738969f87bd1a5d89d0e1e736f99 (diff)
Add support for native functions
Diffstat (limited to 'src/main/java/org')
-rw-r--r--src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionSignatureNode.java9
-rw-r--r--src/main/java/org/shedlang/compiler/ast/typed/TypedNativeFunctionDeclarationNode.java11
-rw-r--r--src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java6
-rw-r--r--src/main/java/org/shedlang/compiler/shid/ShidSerializer.java16
-rw-r--r--src/main/java/org/shedlang/compiler/shid/instructions/ShidDeclareNativeFunction.java42
-rw-r--r--src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatio.java27
-rw-r--r--src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioClosures.java54
-rw-r--r--src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioFunctions.java24
8 files changed, 175 insertions, 14 deletions
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 2e535a7d..839cbcf0 100644
--- a/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionSignatureNode.java
+++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionSignatureNode.java
@@ -63,9 +63,16 @@ public record TypedFunctionSignatureNode(
}
public Builder addNamedParam(String name, TypedTypeLevelExpressionNode<Type> type) {
+ return addNamedParam(name, Optional.of(type));
+ }
+
+ public Builder addNamedParam(
+ String name,
+ Optional<TypedTypeLevelExpressionNode<Type>> type
+ ) {
return new Builder(
this.positionalParams,
- this.namedParams.plus(new TypedParamNode(name, Optional.of(type), Sources.NULL)),
+ this.namedParams.plus(new TypedParamNode(name, type, Sources.NULL)),
this.effect,
this.returnType
);
diff --git a/src/main/java/org/shedlang/compiler/ast/typed/TypedNativeFunctionDeclarationNode.java b/src/main/java/org/shedlang/compiler/ast/typed/TypedNativeFunctionDeclarationNode.java
index e22bc311..f94ef1fc 100644
--- a/src/main/java/org/shedlang/compiler/ast/typed/TypedNativeFunctionDeclarationNode.java
+++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedNativeFunctionDeclarationNode.java
@@ -69,6 +69,17 @@ public record TypedNativeFunctionDeclarationNode(
);
}
+ public TypedNativeFunctionDeclarationNode.Builder addNamedParam(
+ String name,
+ Optional<TypedTypeLevelExpressionNode<Type>> type
+ ) {
+ return new TypedNativeFunctionDeclarationNode.Builder(
+ this.name,
+ this.signature.addNamedParam(name, type),
+ this.type
+ );
+ }
+
public TypedNativeFunctionDeclarationNode.Builder withEffect(TypedTypeLevelExpressionNode<Effect> effect) {
return new TypedNativeFunctionDeclarationNode.Builder(
this.name,
diff --git a/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java b/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java
index f6830ae5..350ed118 100644
--- a/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java
+++ b/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java
@@ -631,6 +631,12 @@ public class ShidCodeGen {
context = context.addInstruction(new ShidDeclareNativeFunction(
context.namespaceName(),
node.name(),
+ node.signature().params().positional().stream()
+ .map(param -> new ShidParam(param.name(), param.source()))
+ .toList(),
+ node.signature().params().named().stream()
+ .map(param -> new ShidParam(param.name(), param.source()))
+ .toList(),
node.source()
));
diff --git a/src/main/java/org/shedlang/compiler/shid/ShidSerializer.java b/src/main/java/org/shedlang/compiler/shid/ShidSerializer.java
index 54cd53e5..590c3d39 100644
--- a/src/main/java/org/shedlang/compiler/shid/ShidSerializer.java
+++ b/src/main/java/org/shedlang/compiler/shid/ShidSerializer.java
@@ -2,6 +2,7 @@ package org.shedlang.compiler.shid;
import org.shedlang.compiler.shid.instructions.*;
import org.shedlang.compiler.treetext.Tree;
+import org.shedlang.compiler.types.NamespaceName;
import org.shedlang.compiler.types.SimpleStructType;
import org.shedlang.compiler.types.UserDefinedEffect;
@@ -76,7 +77,10 @@ public class ShidSerializer {
case ShidDeclareNativeFunction declareNativeFunction ->
treeListIndented(
treeIdentifier("declare-native-function"),
- treeNamed("name", treeString(declareNativeFunction.name()))
+ treeNamed("namespace-name", namespaceNameToTree(declareNativeFunction.namespaceName())),
+ treeNamed("name", treeString(declareNativeFunction.name())),
+ positionalParamsToTree(declareNativeFunction.positionalParams()),
+ namedParamsToTree(declareNativeFunction.namedParams())
);
case ShidDefineEffect defineEffectInstruction ->
@@ -143,7 +147,7 @@ public class ShidSerializer {
case ShidFieldLoad.Receiver.Namespace namespace ->
treeList(
treeIdentifier("namespace"),
- treeString(namespace.name().toString())
+ namespaceNameToTree(namespace.name())
);
case ShidFieldLoad.Receiver.Struct struct ->
@@ -222,14 +226,14 @@ public class ShidSerializer {
case ShidNamespaceFieldStore namespaceFieldStore ->
treeList(
treeIdentifier("namespace-field-store"),
- treeString(namespaceFieldStore.namespaceName().toString()),
+ namespaceNameToTree(namespaceFieldStore.namespaceName()),
treeString(namespaceFieldStore.fieldName())
);
case ShidNamespaceImport namespaceImport ->
treeList(
treeIdentifier("namespace-import"),
- treeString(namespaceImport.namespaceName().toString())
+ namespaceNameToTree(namespaceImport.namespaceName())
);
case ShidPushBool pushBoolInstruction ->
@@ -320,6 +324,10 @@ public class ShidSerializer {
};
}
+ private static Tree namespaceNameToTree(NamespaceName namespaceName) {
+ return treeString(namespaceName.toString());
+ }
+
private static Tree positionalParamsToTree(List<ShidParam> positionalParams) {
return treeNamed("positional-params", treeList(
positionalParams.stream()
diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidDeclareNativeFunction.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidDeclareNativeFunction.java
index 9f88ca5f..56b7e287 100644
--- a/src/main/java/org/shedlang/compiler/shid/instructions/ShidDeclareNativeFunction.java
+++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidDeclareNativeFunction.java
@@ -1,8 +1,12 @@
package org.shedlang.compiler.shid.instructions;
+import org.pcollections.PVector;
import org.shedlang.compiler.sources.Source;
import org.shedlang.compiler.sources.Sources;
import org.shedlang.compiler.types.NamespaceName;
+import org.shedlang.compiler.util.P;
+
+import java.util.List;
/**
* Push a native function value onto the temporary value stack with the given
@@ -11,6 +15,8 @@ import org.shedlang.compiler.types.NamespaceName;
public record ShidDeclareNativeFunction(
NamespaceName namespaceName,
String name,
+ List<ShidParam> positionalParams,
+ List<ShidParam> namedParams,
Source source
) implements ShidInstruction {
@Override
@@ -21,18 +27,24 @@ public record ShidDeclareNativeFunction(
public static Builder builder() {
return new Builder(
NamespaceName.of(),
- "f"
+ "f",
+ P.vector(),
+ P.vector()
);
}
public record Builder(
NamespaceName namespaceName,
- String name
+ String name,
+ PVector<ShidParam> positionalParams,
+ PVector<ShidParam> namedParams
) {
public ShidDeclareNativeFunction build() {
return new ShidDeclareNativeFunction(
this.namespaceName,
this.name,
+ this.positionalParams,
+ this.namedParams,
Sources.NULL
);
}
@@ -40,14 +52,36 @@ public record ShidDeclareNativeFunction(
public Builder withNamespaceName(NamespaceName namespaceName) {
return new Builder(
namespaceName,
- this.name
+ this.name,
+ this.positionalParams,
+ this.namedParams
);
}
public Builder withName(String name) {
return new Builder(
this.namespaceName,
- name
+ name,
+ this.positionalParams,
+ this.namedParams
+ );
+ }
+
+ public Builder addPositionalParam(String name) {
+ return new Builder(
+ this.namespaceName,
+ this.name,
+ this.positionalParams.plus(new ShidParam(name, Sources.NULL)),
+ this.namedParams
+ );
+ }
+
+ public Builder addNamedParam(String name) {
+ return new Builder(
+ this.namespaceName,
+ this.name,
+ this.positionalParams,
+ this.namedParams.plus(new ShidParam(name, Sources.NULL))
);
}
}
diff --git a/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatio.java b/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatio.java
index 11fcdee8..b039789a 100644
--- a/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatio.java
+++ b/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatio.java
@@ -244,6 +244,30 @@ public class ShidToPatio {
yield context;
}
+ case ShidDeclareNativeFunction declareNativeFunction -> {
+ var destinationResult = context.allocateVal(
+ ShidToPatioLocalSpace.CLOSURE,
+ declareNativeFunction.name(),
+ ShidToPatioTypes.VALUE_TYPE
+ );
+ var destination = destinationResult.value();
+ context = destinationResult.context();
+
+ context = ShidToPatioFunctions.createNative(
+ destination,
+ declareNativeFunction.namespaceName(),
+ declareNativeFunction.name(),
+ declareNativeFunction.positionalParams(),
+ declareNativeFunction.namedParams(),
+ declareNativeFunction.source(),
+ context
+ );
+
+ context = context.temporaryPush(destination);
+
+ yield context;
+ }
+
case ShidDefineFunction defineFunction -> {
var destinationResult = context.allocateVal(
ShidToPatioLocalSpace.CLOSURE,
@@ -595,9 +619,6 @@ public class ShidToPatio {
yield context;
}
- case ShidDeclareNativeFunction declareNativeFunction ->
- throw new UnsupportedOperationException("TODO");
-
case ShidPushBool pushBool ->
pushValue(pushBool.value() ? 1 : 0, pushBool.source(), context);
diff --git a/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioClosures.java b/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioClosures.java
index 624a2787..f93b2844 100644
--- a/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioClosures.java
+++ b/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioClosures.java
@@ -2,6 +2,8 @@ package org.shedlang.compiler.shidtopatio;
import org.shedlang.compiler.ast.typed.FreeVariable;
import org.shedlang.compiler.ast.typed.FreeVariables;
+import org.shedlang.compiler.patio.PatioFunctionDeclaration;
+import org.shedlang.compiler.patio.PatioLocal;
import org.shedlang.compiler.patio.PatioVisibility;
import org.shedlang.compiler.patio.instructions.*;
import org.shedlang.compiler.patio.operands.PatioFunctionPtrConst;
@@ -13,6 +15,7 @@ import org.shedlang.compiler.patio.types.PatioType;
import org.shedlang.compiler.patio.types.PatioTypes;
import org.shedlang.compiler.shid.instructions.ShidParam;
import org.shedlang.compiler.sources.Source;
+import org.shedlang.compiler.types.NamespaceName;
import org.shedlang.compiler.util.P;
import java.util.ArrayList;
@@ -99,8 +102,7 @@ class ShidToPatioClosures {
List<ShidParam> namedParams,
ShidToPatioContext bodyContext
) {
- var orderedNamedParams = sortedBy(namedParams, param -> param.name());
- var shidParams = Stream.concat(positionalParams.stream(), orderedNamedParams.stream()).toList();
+ var shidParams = generateShidParamList(positionalParams, namedParams);
for (var shidParam : shidParams) {
bodyContext = bodyContext.defineShidParam(shidParam.name());
@@ -109,6 +111,14 @@ class ShidToPatioClosures {
return bodyContext;
}
+ private static List<ShidParam> generateShidParamList(
+ List<ShidParam> positionalParams,
+ List<ShidParam> namedParams
+ ) {
+ var orderedNamedParams = sortedBy(namedParams, param -> param.name());
+ return Stream.concat(positionalParams.stream(), orderedNamedParams.stream()).toList();
+ }
+
static ShidToPatioContext create(
PatioLocalRef destination,
ShidToPatioCompilationUnitElementSpace functionElementSpace,
@@ -170,6 +180,46 @@ class ShidToPatioClosures {
return context;
}
+ public static ShidToPatioContext createNative(
+ PatioLocalRef destination,
+ NamespaceName namespaceName,
+ String name,
+ List<ShidParam> positionalParams,
+ List<ShidParam> namedParams,
+ ClosureRuntimeType closureRuntimeType,
+ Source source,
+ ShidToPatioContext context
+ ) {
+ var fullName = String.format(
+ "shed__runtime__namespace__%s__%s",
+ String.join("__", namespaceName.parts()),
+ name
+ );
+
+ context = context.addCompilationUnitElement(new PatioFunctionDeclaration(
+ fullName,
+ generateShidParamList(positionalParams, namedParams).stream()
+ .map(param -> PatioLocal.param(param.name(), ShidToPatioTypes.VALUE_TYPE))
+ .toList(),
+ ShidToPatioTypes.VALUE_TYPE,
+ source
+ ));
+
+ context = alloc(
+ destination,
+ name,
+ fullName,
+ closureRuntimeType,
+ (closurePointer, storeContext) -> storeContext,
+ FreeVariables.empty(),
+ source,
+ context
+ );
+
+ return context;
+ }
+
+
static ShidToPatioContext alloc(
PatioLocalRef destination,
String name,
diff --git a/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioFunctions.java b/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioFunctions.java
index c4edd762..105ca4e9 100644
--- a/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioFunctions.java
+++ b/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioFunctions.java
@@ -6,6 +6,7 @@ import org.shedlang.compiler.patio.types.PatioDataLayout;
import org.shedlang.compiler.patio.types.PatioDataLayouts;
import org.shedlang.compiler.shid.instructions.ShidParam;
import org.shedlang.compiler.sources.Source;
+import org.shedlang.compiler.types.NamespaceName;
import java.util.List;
import java.util.function.Function;
@@ -53,4 +54,27 @@ public class ShidToPatioFunctions {
context
);
}
+
+ public static ShidToPatioContext createNative(
+ PatioLocalRef destination,
+ NamespaceName namespaceName,
+ String name,
+ List<ShidParam> positionalParams,
+ List<ShidParam> namedParams,
+ Source source,
+ ShidToPatioContext context
+ ) {
+ var functionRuntimeType = functionRuntimeType(FreeVariables.empty(), context);
+
+ return ShidToPatioClosures.createNative(
+ destination,
+ namespaceName,
+ name,
+ positionalParams,
+ namedParams,
+ functionRuntimeType,
+ source,
+ context
+ );
+ }
}