basic patterns impl (without variables), implementation for most of the nodes (except scopes, closure capture, etc.)

This commit is contained in:
ProgramSnail 2025-06-13 20:34:26 +03:00
parent 07b80ce5cb
commit 41a86c1314
47 changed files with 643 additions and 266 deletions

View file

@ -21,39 +21,4 @@ public final class LamaContext {
public LamaContext() {
this.globalScopeObject = new GlobalScopeObject();
}
// private final FrameDescriptor globalFrameDescriptor;
// private final Namespace globalNamespace;
// private final MaterializedFrame globalFrame;
// private final LamaLanguage language;
//
// public LamaContext() { this(null); }
//
// public LamaContext(LamaLanguage language) {
// this.globalFrameDescriptor = new FrameDescriptor();
// this.globalNamespace = new Namespace(this.globalFrameDescriptor);
// this.globalFrame = this.initGlobalFrame(language);
// this.language = language;
// }
//
// private MaterializedFrame initGlobalFrame(LamaLanguage language) {
// VirtualFrame frame = Truffle.getRuntime().createVirtualFrame(null, this.globalFrameDescriptor);
// addGlobalFunctions(language, frame);
// return frame.materialize();
// }
//
// private static void addGlobalFunctions(LamaLanguage language, VirtualFrame virtualFrame) {
// // TODO
// }
//
// /**
// * @return A {@link MaterializedFrame} on the heap that contains all global
// * values.
// */
// public MaterializedFrame getGlobalFrame() {
// return this.globalFrame;
// }
//
// public Namespace getGlobalNamespace() {
// return this.globalNamespace;
// }
}

View file

@ -26,26 +26,23 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@TruffleLanguage.Registration(id = LamaLanguage.ID, name = "Lama", defaultMimeType = LamaLanguage.MIME_TYPE, characterMimeTypes = LamaLanguage.MIME_TYPE, contextPolicy = TruffleLanguage.ContextPolicy.SHARED, fileTypeDetectors = LamaFileDetector.class)
//@ProvidedTags({StandardTags.CallTag.class, StandardTags.StatementTag.class, StandardTags.RootTag.class, StandardTags.RootBodyTag.class, StandardTags.ExpressionTag.class, DebuggerTags.AlwaysHalt.class,
// StandardTags.ReadVariableTag.class, StandardTags.WriteVariableTag.class})
public class LamaLanguage extends TruffleLanguage<LamaContext> {
// public static volatile int counter; // count class instances
private static final LanguageReference<LamaLanguage> REF = LanguageReference.create(LamaLanguage.class);
public static LamaLanguage get(Node node) {
return REF.get(node);
}
public static final String ID = "lama";
public static final String MIME_TYPE = "application/x-lama";
// private static final Source BUILTIN_SOURCE = Source.newBuilder(ID, "", "LaMa builtin").build();
// private static final LanguageReference<LamaLanguage> REFERENCE = LanguageReference.create(LamaLanguage.class);
// private static final List<NodeFactory<? extends LamaBuiltinNode>> EXTERNAL_BUILTINS = Collections.synchronizedList(new ArrayList<>());
// public static final TruffleString.Encoding STRING_ENCODING = TruffleString.Encoding.UTF_16;
private final Assumption singleContext = Truffle.getRuntime().createAssumption("Single Lama context.");
@Override
protected CallTarget parse(ParsingRequest request) throws Exception {
var exprNode = LamaParser.parseLama(this, request.getSource());
var rootNode = new LamaRootNode(exprNode);
var rootNode = new LamaRootNode(this, exprNode);
return rootNode.getCallTarget();
}
@ -58,153 +55,4 @@ public class LamaLanguage extends TruffleLanguage<LamaContext> {
protected Object getScope(LamaContext context) {
return context.globalScopeObject;
}
//
// //
//
// public LamaLanguage() {
//// counter++;
// }
//
// @Override
// protected LamaContext createContext(Env env) {
// return new LamaContext(this, env, new ArrayList<>(EXTERNAL_BUILTINS));
// }
//
// @Override
// protected boolean patchContext(LamaContext context, Env newEnv) {
// context.patchContext(newEnv);
// return true;
// }
//
// //
//
// public RootCallTarget getOrCreateUndefinedFunction(TruffleString name) {
// RootCallTarget target = undefinedFunctions.get(name);
// if (target == null) {
// target = new LamaUndefinedFunctionRootNode(this, name).getCallTarget();
// RootCallTarget other = undefinedFunctions.putIfAbsent(name, target);
// if (other != null) {
// target = other;
// }
// }
// return target;
// }
//
// public RootCallTarget lookupBuiltin(NodeFactory<? extends LamaBuiltinNode> factory) {
// RootCallTarget target = builtinTargets.get(factory);
// if (target != null) {
// return target;
// }
//
// /*
// * The builtin node factory is a class that is automatically generated by the Truffle DSL.
// * The signature returned by the factory reflects the signature of the @Specialization
// *
// * methods in the builtin classes.
// */
// int argumentCount = factory.getExecutionSignature().size();
// LamaExpressionNode[] argumentNodes = new LamaExpressionNode[argumentCount];
// /*
// * Builtin functions are like normal functions, i.e., the arguments are passed in as an
// * Object[] array encapsulated in SLArguments. A SLReadArgumentNode extracts a parameter
// * from this array.
// */
// for (int i = 0; i < argumentCount; i++) {
// argumentNodes[i] = new LamaReadArgumentNode(i);
// }
// /* Instantiate the builtin node. This node performs the actual functionality. */
// LamaBuiltinNode builtinBodyNode = factory.createNode((Object) argumentNodes);
// builtinBodyNode.addRootTag();
// /* The name of the builtin function is specified via an annotation on the node class. */
// TruffleString name = LamaStrings.fromJavaString(lookupNodeInfo(builtinBodyNode.getClass()).shortName());
// builtinBodyNode.setUnavailableSourceSection();
//
// /* Wrap the builtin in a RootNode. Truffle requires all AST to start with a RootNode. */
// LamaRootNode rootNode = new LamaRootNode(this, new FrameDescriptor(), builtinBodyNode, BUILTIN_SOURCE.createUnavailableSection(), name);
//
// /*
// * Register the builtin function in the builtin registry. Call targets for builtins may be
// * reused across multiple contexts.
// */
// RootCallTarget newTarget = rootNode.getCallTarget();
// RootCallTarget oldTarget = builtinTargets.putIfAbsent(factory, newTarget);
// if (oldTarget != null) {
// return oldTarget;
// }
// return newTarget;
// }
//
// public static NodeInfo lookupNodeInfo(Class<?> c) {
// if (c == null) {
// return null;
// }
// NodeInfo info = c.getAnnotation(NodeInfo.class);
// if (info != null) {
// return info;
// } else {
// return lookupNodeInfo(c.getSuperclass());
// }
// }
//
//
// @Override
// protected void initializeMultipleContexts() {
// singleContext.invalidate();
// }
//
// public boolean isSingleContext() {
// return singleContext.isValid();
// }
//
// @Override
// protected Object getLanguageView(LamaContext context, Object value) {
// return LamaLanguageView.create(value);
// }
//
// @Override
// protected boolean isVisible(LamaContext context, Object value) {
// return !InteropLibrary.getFactory().getUncached(value).isNull(value);
// }
//
// @Override
// protected Object getScope(LamaContext context) {
// return context.getFunctionRegistry().getFunctionsObject();
// }
//
// public Shape getRootShape() {
// return rootShape;
// }
//
// /**
// * Allocate an empty object. All new objects initially have no properties. Properties are added
// * when they are first stored, i.e., the store triggers a shape change of the object.
// */
// public LamaObject createObject(AllocationReporter reporter) {
// reporter.onEnter(null, 0, AllocationReporter.SIZE_UNKNOWN);
// LamaObject object = new LamaObject(rootShape);
// reporter.onReturnValue(object, 0, AllocationReporter.SIZE_UNKNOWN);
// return object;
// }
//
// //
//
// public static LamaLanguage get(Node node) {
// return REFERENCE.get(node);
// }
//
// //
//
// public static void installBuiltin(NodeFactory<? extends LamaBuiltinNode> builtin) {
// EXTERNAL_BUILTINS.add(builtin);
// }
//
// @Override
// protected void exitContext(LamaContext context, ExitMode exitMode, int exitCode) {
// /*
// * Runs shutdown hooks during explicit exit triggered by TruffleContext#closeExit(Node, int)
// * or natural exit triggered during natural context close.
// */
// context.runShutdownHooks();
// }
}

View file

@ -0,0 +1,27 @@
package org.programsnail.truffle_lama.nodes;
import com.oracle.truffle.api.frame.FrameDescriptor;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.RootNode;
import org.programsnail.truffle_lama.LamaLanguage;
public class FunctionRootNode extends RootNode {
@SuppressWarnings("FieldMayBeFinal")
@Child
private LamaExpressionNode exprNode;
public FunctionRootNode(LamaLanguage language, LamaExpressionNode exprNode) {
this(language, null, exprNode);
}
public FunctionRootNode(LamaLanguage language, FrameDescriptor frameDescriptor, LamaExpressionNode exprNode) {
super(language, frameDescriptor);
this.exprNode = exprNode;
}
@Override
public Object execute(VirtualFrame frame) {
return this.exprNode.executeGeneric(frame);
}
}

View file

@ -6,41 +6,23 @@ import com.oracle.truffle.api.instrumentation.*;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.NodeInfo;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.programsnail.truffle_lama.LamaContext;
import org.programsnail.truffle_lama.LamaLanguage;
@TypeSystemReference(LamaTypes.class)
@NodeInfo(description = "The abstract base node for all expressions")
public abstract class LamaExpressionNode extends Node {
protected final LamaLanguage currentTruffleLanguage() {
return LamaLanguage.get(this);
}
protected final LamaContext currentLanguageContext() {
return LamaContext.get(this);
}
private boolean hasExpressionTag;
/**
* The execute method when no specialization is possible. This is the most general case,
* therefore it must be provided by all subclasses.
*/
public abstract Object executeGeneric(VirtualFrame frame) throws UnexpectedResultException;
/**
* The return value is just discarded.
*/
public void executeVoid(VirtualFrame frame) {
executeGeneric(frame);
}
public boolean hasTag(Class<? extends Tag> tag) {
if (tag == StandardTags.ExpressionTag.class) {
return hasExpressionTag;
}
return false; // no super tags
}
/**
* Marks this node as being a {@link StandardTags.ExpressionTag} for instrumentation purposes.
*/
public final void addExpressionTag() {
hasExpressionTag = true;
}
/*
* Execute methods for specialized types. They all follow the same pattern: they call the
* generic execution method and then expect a result of their return type. Type-specialized

View file

@ -2,14 +2,15 @@ package org.programsnail.truffle_lama.nodes;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.RootNode;
import org.programsnail.truffle_lama.LamaLanguage;
public class LamaRootNode extends RootNode {
@SuppressWarnings("FieldMayBeFinal")
@Child
private LamaExpressionNode exprNode;
public LamaRootNode(LamaExpressionNode exprNode) {
super(null);
public LamaRootNode(LamaLanguage language, LamaExpressionNode exprNode) {
super(language);
this.exprNode = exprNode;
}

View file

@ -1,4 +1,40 @@
package org.programsnail.truffle_lama.nodes.controlflow;
public class LamaCaseNode {
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
import org.programsnail.truffle_lama.nodes.pattern.LamaPattern;
import org.programsnail.truffle_lama.runtime.LamaException;
public final class LamaCaseNode extends LamaExpressionNode {
// TODO
@Child
private LamaExpressionNode valueNode;
private LamaPattern[] patterns;
@Children
private LamaExpressionNode[] exprNodes;
// atr ??
// loc ??
public LamaCaseNode(LamaExpressionNode valueNode, LamaPattern[] patterns, LamaExpressionNode[] exprNodes) {
this.valueNode = valueNode;
this.patterns = patterns;
this.exprNodes = exprNodes;
assert (exprNodes.length == patterns.length); // ??
}
@Override
public Object executeGeneric(VirtualFrame frame) throws UnexpectedResultException {
Object value = this.valueNode.executeGeneric(frame);
for (int i = 0; i < this.patterns.length; ++i) {
if (this.patterns[i].match(value)) { // TODO: special case for name binding ??
return this.exprNodes[i].executeGeneric(frame);
}
}
throw new LamaException("Value do not match any cases");
}
}

View file

@ -1,4 +0,0 @@
package org.programsnail.truffle_lama.nodes.controlflow;
public class LamaControlNode {
}

View file

@ -1,4 +1,24 @@
package org.programsnail.truffle_lama.nodes.expression;
public class LamaArrayNode {
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
import org.programsnail.truffle_lama.runtime.LamaArray;
public final class LamaArrayNode extends LamaExpressionNode {
@Children
private LamaExpressionNode[] elementNodes;
public LamaArrayNode(LamaExpressionNode[] elementNodes) {
this.elementNodes = elementNodes;
}
@Override
public Object executeGeneric(VirtualFrame frame) throws UnexpectedResultException {
Object[] elements = new Object[elementNodes.length];
for (int i = 0; i < elements.length; ++i) {
elements[i] = elementNodes[i].executeGeneric(frame);
}
return new LamaArray(elements);
}
}

View file

@ -1,4 +1,25 @@
package org.programsnail.truffle_lama.nodes.expression;
public class LamaAssignNode {
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
import org.programsnail.truffle_lama.runtime.LamaException;
import org.programsnail.truffle_lama.runtime.LamaUnit;
import org.programsnail.truffle_lama.runtime.LamaGlobalVarRef;
@NodeChild("leftNode")
@NodeChild("rightNode")
public abstract class LamaAssignNode extends LamaExpressionNode {
@Specialization
public Object assignValue(Object leftValue, Object rightValue) throws UnexpectedResultException {
if (leftValue instanceof LamaGlobalVarRef) {
if (!((LamaGlobalVarRef) leftValue).assign(rightValue)) {
throw new LamaException("Can't update variable by identifier '" + name + "'");
}
} else {
throw new LamaException("Can't assign not to ref", this);
}
return LamaUnit.INSTANCE;
}
}

View file

@ -11,9 +11,6 @@ import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
@NodeChild("rightNode")
@NodeField(name = "op", type = String.class)
public abstract class LamaBinopNode extends LamaExpressionNode {
@Child
LamaExpressionNode leftNode, rightNode;
@Specialization(rewriteOn = IllegalStateException.class)
protected long numOp(long leftValue, long rightValue) {
return switch (op) {

View file

@ -1,4 +1,35 @@
package org.programsnail.truffle_lama.nodes.expression;
public class LamaCallNode {
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.programsnail.truffle_lama.nodes.FunctionDispatchNode;
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
public final class LamaCallNode extends LamaExpressionNode {
@Child
private LamaExpressionNode functionNode;
@Children
private LamaExpressionNode[] callArgumentNodes;
@Child
private FunctionDispatchNode dispatchNode;
public LamaCallNode(LamaExpressionNode targetFunction, LamaExpressionNode[] callArguments, FunctionDispatchNode dispatchNode) {
this.functionNode = targetFunction;
this.callArgumentNodes = callArguments;
this.dispatchNode = dispatchNode;
}
@Override
public Object executeGeneric(VirtualFrame frame) throws UnexpectedResultException {
Object targetFunction = this.functionNode.executeGeneric(frame);
Object[] callArguments = new Object[callArgumentNodes.length];
for (int i = 0; i < callArgumentNodes.length; ++i) {
callArguments[i] = callArgumentNodes[i].executeGeneric(frame);
}
return this.dispatchNode.executeDispatch(targetFunction, callArguments);
}
}

View file

@ -1,4 +1,22 @@
package org.programsnail.truffle_lama.nodes.expression;
public class LamaElemNode {
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.Specialization;
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
import org.programsnail.truffle_lama.runtime.LamaArrayLike;
import org.programsnail.truffle_lama.runtime.LamaException;
@NodeChild("leftNode")
@NodeChild("rightNode")
public abstract class LamaElemNode extends LamaExpressionNode {
@Specialization
public Object accessAt(LamaArrayLike array, int id) {
return array.readAt(id);
}
@Fallback
public Object accessFailed(Object array, Object id) {
throw new LamaException("Elem: wrong types", this);
}
}

View file

@ -1,4 +1,23 @@
package org.programsnail.truffle_lama.nodes.expression;
public class LamaElemRefNode {
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.Specialization;
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
import org.programsnail.truffle_lama.runtime.LamaArrayLike;
import org.programsnail.truffle_lama.runtime.LamaElemRef;
import org.programsnail.truffle_lama.runtime.LamaException;
@NodeChild("leftNode")
@NodeChild("rightNode")
public abstract class LamaElemRefNode extends LamaExpressionNode {
@Specialization
public Object accessAt(LamaArrayLike array, int id) {
return new LamaElemRef(array, id);
}
@Fallback
public Object accessFailed(Object array, Object id) {
throw new LamaException("ElemRef: wrong types", this);
}
}

View file

@ -0,0 +1,19 @@
package org.programsnail.truffle_lama.nodes.expression;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
import org.programsnail.truffle_lama.runtime.LamaGlobalVarRef;
public final class LamaGlobalRefNode extends LamaExpressionNode {
String name;
public LamaGlobalRefNode(String name) {
this.name = name;
}
@Override
public Object executeGeneric(VirtualFrame frame) throws UnexpectedResultException {
return new LamaGlobalVarRef(this.name, this.currentLanguageContext());
}
}

View file

@ -0,0 +1,16 @@
package org.programsnail.truffle_lama.nodes.expression;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
import org.programsnail.truffle_lama.runtime.LamaUnit;
public final class LamaGlobalVarNode extends LamaExpressionNode {
String name;
@Override
public Object executeGeneric(VirtualFrame frame) throws UnexpectedResultException {
this.currentLanguageContext().globalScopeObject.newVariable(name, LamaUnit.INSTANCE, false);
return LamaUnit.INSTANCE;
}
}

View file

@ -9,8 +9,13 @@ public final class LamaIgnoreNode extends LamaExpressionNode {
@Child
LamaExpressionNode node;
public LamaIgnoreNode(LamaExpressionNode node) {
this.node = node;
}
@Override
public Object executeGeneric(VirtualFrame frame) throws UnexpectedResultException {
node.executeGeneric(frame);
return LamaUnit.INSTANCE;
}
}

View file

@ -1,4 +0,0 @@
package org.programsnail.truffle_lama.nodes.expression;
public class LamaIntrinsicNode {
}

View file

@ -1,4 +1,32 @@
package org.programsnail.truffle_lama.nodes.expression;
public class LamaLambdaNode {
import com.oracle.truffle.api.frame.FrameDescriptor;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.programsnail.truffle_lama.FunctionObject;
import org.programsnail.truffle_lama.LamaLanguage;
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
public final class LamaLambdaNode extends LamaExpressionNode {
@Child
private LamaExpressionNode bodyNode;
private final String name;
private final FrameDescriptor frameDescriptor;
private final int argumentsCount; // local variables are translated to ids
// TODO: captured variables
public LamaLambdaNode(LamaExpressionNode bodyNode, String name, FrameDescriptor frameDescriptor, int argumentsCount) {
this.bodyNode = bodyNode;
this.name = name;
this.frameDescriptor = frameDescriptor;
this.argumentsCount = argumentsCount;
}
@Override
public Object executeGeneric(VirtualFrame frame) throws UnexpectedResultException {
LamaLanguage language = this.currentTruffleLanguage();
FunctionRootNode functionRootNode = new FunctionRootNode(language, this.frameDescriptor, this.bodyNode);
return new FunctionObject(functionRootNode.getCallTarget(), this.argumentsCount);
}
}

View file

@ -0,0 +1,19 @@
package org.programsnail.truffle_lama.nodes.expression;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
import org.programsnail.truffle_lama.runtime.LamaLocalVarRef;
public final class LamaLocalRefNode extends LamaExpressionNode {
int id;
public LamaLocalRefNode(int id) {
this.id = id;
}
@Override
public Object executeGeneric(VirtualFrame frame) throws UnexpectedResultException {
return new LamaLocalVarRef(this.id, frame); // TODO: correct frame ??
}
}

View file

@ -0,0 +1,25 @@
package org.programsnail.truffle_lama.nodes.expression;
import com.oracle.truffle.api.frame.FrameSlotKind;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
import org.programsnail.truffle_lama.runtime.LamaUnit;
public final class LamaLocalVarNode extends LamaExpressionNode {
private final int frameSlot;
public int getFrameSlot() {
return frameSlot;
}
public LamaLocalVarNode(int frameSlot) {
this.frameSlot = frameSlot;
}
@Override
public Object executeGeneric(VirtualFrame frame) throws UnexpectedResultException {
frame.getFrameDescriptor().setSlotKind(this.frameSlot, FrameSlotKind.Object);
return LamaUnit.INSTANCE;
}
}

View file

@ -1,4 +0,0 @@
package org.programsnail.truffle_lama.nodes.expression;
public class LamaRefNode {
}

View file

@ -1,4 +1,21 @@
package org.programsnail.truffle_lama.nodes.expression;
public class LamaSeqNode {
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
public final class LamaSeqNode extends LamaExpressionNode {
@Child
LamaExpressionNode leftNode, rightNode;
public LamaSeqNode(LamaExpressionNode leftNode, LamaExpressionNode rightNode) {
this.leftNode = leftNode;
this.rightNode = rightNode;
}
@Override
public Object executeGeneric(VirtualFrame frame) throws UnexpectedResultException {
leftNode.executeGeneric(frame);
return rightNode.executeGeneric(frame);
}
}

View file

@ -1,4 +1,27 @@
package org.programsnail.truffle_lama.nodes.expression;
public class LamaSexpNode {
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
import org.programsnail.truffle_lama.runtime.LamaSexp;
public final class LamaSexpNode extends LamaExpressionNode {
private String tag;
@Children
private LamaExpressionNode[] elementNodes;
public LamaSexpNode(String tag, LamaExpressionNode[] elementNodes) {
this.tag = tag;
this.elementNodes = elementNodes;
}
@Override
public Object executeGeneric(VirtualFrame frame) throws UnexpectedResultException {
Object[] elements = new Object[elementNodes.length];
for (int i = 0; i < elements.length; ++i) {
elements[i] = elementNodes[i].executeGeneric(frame);
}
return new LamaSexp(tag, elements);
}
}

View file

@ -1,4 +1,16 @@
package org.programsnail.truffle_lama.nodes.expression;
public class LamaSkipNode {
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
import org.programsnail.truffle_lama.runtime.LamaUnit;
public final class LamaSkipNode extends LamaExpressionNode {
public LamaSkipNode() {
}
@Override
public Object executeGeneric(VirtualFrame frame) throws UnexpectedResultException {
return LamaUnit.INSTANCE;
}
}

View file

@ -1,4 +1,19 @@
package org.programsnail.truffle_lama.nodes.expression;
public class LamaStringNode {
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import com.oracle.truffle.api.strings.TruffleString;
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
public final class LamaStringNode extends LamaExpressionNode {
private final TruffleString value;
public LamaStringNode(TruffleString value) {
this.value = value;
}
@Override
public Object executeGeneric(VirtualFrame frame) throws UnexpectedResultException {
return this.value;
}
}

View file

@ -1,4 +0,0 @@
package org.programsnail.truffle_lama.nodes.expression;
public class LamaVarNode {
}

View file

@ -0,0 +1,27 @@
package org.programsnail.truffle_lama.nodes.pattern;
import org.programsnail.truffle_lama.runtime.LamaArray;
public final class LamaArrayPattern extends LamaPattern {
private final LamaPattern[] elements;
public LamaArrayPattern(LamaPattern[] elements) {
this.elements = elements;
}
@Override
public boolean match(Object object) {
if (!(object instanceof LamaArray array)) {
return false;
}
if (elements.length != array.getLength()) {
return false;
}
for (int i = 0; i < elements.length; ++i) {
if (!elements[i].match(array.readAt(i))) {
return false;
}
}
return true;
}
}

View file

@ -0,0 +1,10 @@
package org.programsnail.truffle_lama.nodes.pattern;
import org.programsnail.truffle_lama.runtime.LamaArray;
public final class LamaArrayTagPattern extends LamaPattern {
@Override
public boolean match(Object object) {
return object instanceof LamaArray;
}
}

View file

@ -0,0 +1,12 @@
package org.programsnail.truffle_lama.nodes.pattern;
import com.oracle.truffle.api.strings.TruffleString;
import org.programsnail.truffle_lama.runtime.LamaArrayLike;
import org.programsnail.truffle_lama.runtime.LamaSexp;
public final class LamaBoxedPattern extends LamaPattern {
@Override
public boolean match(Object object) {
return object instanceof TruffleString || object instanceof LamaArrayLike; // includes array and sexp
}
}

View file

@ -0,0 +1,10 @@
package org.programsnail.truffle_lama.nodes.pattern;
import org.programsnail.truffle_lama.FunctionObject;
public final class LamaClosureTagPattern extends LamaPattern {
@Override
public boolean match(Object object) {
return object instanceof FunctionObject; // TODO: check
}
}

View file

@ -0,0 +1,16 @@
package org.programsnail.truffle_lama.nodes.pattern;
import org.programsnail.truffle_lama.runtime.LamaArray;
public final class LamaConstPattern extends LamaPattern {
private final long value;
public LamaConstPattern(long value) {
this.value = value;
}
@Override
public boolean match(Object object) {
return (object instanceof Integer other) && other == value;
}
}

View file

@ -0,0 +1,5 @@
package org.programsnail.truffle_lama.nodes.pattern;
public final class LamaNamedPattern extends LamaPattern {
// TODO: return var assignment in som way
}

View file

@ -0,0 +1,5 @@
package org.programsnail.truffle_lama.nodes.pattern;
public abstract class LamaPattern {
public abstract boolean match(Object object);
}

View file

@ -0,0 +1,4 @@
package org.programsnail.truffle_lama.nodes.pattern;
public final class LamaSexpPattern extends LamaPattern {
}

View file

@ -0,0 +1,10 @@
package org.programsnail.truffle_lama.nodes.pattern;
import org.programsnail.truffle_lama.runtime.LamaSexp;
public final class LamaSexpTagPattern extends LamaPattern {
@Override
public boolean match(Object object) {
return object instanceof LamaSexp;
}
}

View file

@ -0,0 +1,16 @@
package org.programsnail.truffle_lama.nodes.pattern;
import com.oracle.truffle.api.strings.TruffleString;
public final class LamaStringPattern extends LamaPattern {
private final TruffleString value;
public LamaStringPattern(TruffleString value) {
this.value = value;
}
@Override
public boolean match(Object object) {
return (object instanceof TruffleString other) && other == value;
}
}

View file

@ -0,0 +1,10 @@
package org.programsnail.truffle_lama.nodes.pattern;
import com.oracle.truffle.api.strings.TruffleString;
public final class LamaStringTagPattern extends LamaPattern {
@Override
public boolean match(Object object) {
return object instanceof TruffleString;
}
}

View file

@ -0,0 +1,8 @@
package org.programsnail.truffle_lama.nodes.pattern;
public final class LamaUnBoxedPattern extends LamaPattern {
@Override
public boolean match(Object object) {
return object instanceof Integer; // TODO: does work with int ??
}
}

View file

@ -0,0 +1,8 @@
package org.programsnail.truffle_lama.nodes.pattern;
public final class LamaWildcardPattern extends LamaPattern {
@Override
public boolean match(Object object) {
return true;
}
}

View file

@ -0,0 +1,11 @@
package org.programsnail.truffle_lama.runtime;
public final class LamaArray extends LamaArrayLike {
public LamaArray(Object[] elements) {
super(elements);
}
public LamaArray(int length) {
super(length);
}
}

View file

@ -0,0 +1,32 @@
package org.programsnail.truffle_lama.runtime;
public class LamaArrayLike {
private Object[] elements;
public LamaArrayLike(Object[] elements) {
this.elements = elements;
}
public LamaArrayLike(int length) {
this.elements = new Object[length];
}
public int getLength() {
return elements.length;
}
public boolean assignAt(int id, Object object) {
if (id < 0 || id >= elements.length) {
return false;
}
elements[id] = object;
return true;
}
public Object readAt(int id) {
if (id < 0 || id >= elements.length) {
return null;
}
return elements[id];
}
}

View file

@ -0,0 +1,16 @@
package org.programsnail.truffle_lama.runtime;
public class LamaElemRef extends LamaObjRef {
LamaArrayLike array;
int id;
public LamaElemRef(LamaArrayLike array, int id) {
this.array = array;
this.id = id;
}
@Override
public boolean assign(Object object) {
return array.assignAt(id, object);
}
}

View file

@ -0,0 +1,19 @@
package org.programsnail.truffle_lama.runtime;
import org.programsnail.truffle_lama.LamaContext;
public final class LamaGlobalVarRef extends LamaObjRef {
private String name;
private LamaContext context;
public LamaGlobalVarRef(String name, LamaContext context) {
this.name = name;
this.context = context;
}
@Override
public boolean assign(Object object) {
return this.context.globalScopeObject.updateVariable(name, object);
}
}

View file

@ -0,0 +1,19 @@
package org.programsnail.truffle_lama.runtime;
import com.oracle.truffle.api.frame.VirtualFrame;
public final class LamaLocalVarRef extends LamaObjRef {
private int id;
private VirtualFrame frame;
public LamaLocalVarRef(int id, VirtualFrame frame) {
this.id = id;
this.frame = frame;
}
@Override
public boolean assign(Object object) {
this.frame.setObject(id, object);
return true;
}
}

View file

@ -0,0 +1,5 @@
package org.programsnail.truffle_lama.runtime;
public abstract class LamaObjRef {
public abstract boolean assign(Object object);
}

View file

@ -1,13 +0,0 @@
package org.programsnail.truffle_lama.runtime;
import java.util.List;
public final class LamaSExp {
public String name;
public List<Object> elements;
LamaSExp(String name, List<Object> elements) {
this.name = name;
this.elements = elements;
}
}

View file

@ -0,0 +1,19 @@
package org.programsnail.truffle_lama.runtime;
public final class LamaSexp extends LamaArrayLike {
private String tag;
public String getTag() {
return tag;
}
public LamaSexp(String tag, Object[] elements) {
super(elements);
this.tag = tag;
}
LamaSexp(String tag, int length) {
super(length);
this.tag = tag;
}
}