mirror of
https://codeberg.org/ProgramSnail/truffle-lama.git
synced 2025-12-06 06:48:47 +00:00
init nodes, some basic nodes implementations
This commit is contained in:
parent
a149766007
commit
07b80ce5cb
46 changed files with 906 additions and 256 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -36,3 +36,5 @@ build/
|
||||||
|
|
||||||
### Mac OS ###
|
### Mac OS ###
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
gen/
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,9 @@
|
||||||
This is an attempt to implement the LaMa language (https://github.com/PLTools/Lama) with GraalVM and Truffle.
|
This is an attempt to implement the LaMa language (https://github.com/PLTools/Lama) with GraalVM and Truffle.
|
||||||
|
|
||||||
Code is based on:
|
Code is based on:
|
||||||
|
|
||||||
- https://github.com/graalvm/simplelanguage
|
- https://github.com/graalvm/simplelanguage
|
||||||
- https://github.com/cesquivias/mumbler
|
- https://github.com/cesquivias/mumbler
|
||||||
|
- https://github.com/skinny85/graalvm-truffle-tutorial
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
package org.programsnail.truffle_lama;
|
||||||
|
|
||||||
|
import com.oracle.truffle.api.CallTarget;
|
||||||
|
import com.oracle.truffle.api.interop.InteropLibrary;
|
||||||
|
import com.oracle.truffle.api.interop.TruffleObject;
|
||||||
|
import com.oracle.truffle.api.library.ExportLibrary;
|
||||||
|
import com.oracle.truffle.api.library.ExportMessage;
|
||||||
|
import org.programsnail.truffle_lama.nodes.FunctionDispatchNode;
|
||||||
|
import org.programsnail.truffle_lama.runtime.LamaException;
|
||||||
|
|
||||||
|
@ExportLibrary(InteropLibrary.class)
|
||||||
|
public final class FunctionObject implements TruffleObject {
|
||||||
|
public final CallTarget callTarget;
|
||||||
|
public final int argumentCount;
|
||||||
|
public final FunctionDispatchNode functionDispatchNode;
|
||||||
|
|
||||||
|
public FunctionObject(CallTarget callTarget, int argumentCount, FunctionDispatchNode functionDispatchNode) {
|
||||||
|
this.callTarget = callTarget;
|
||||||
|
this.argumentCount = argumentCount;
|
||||||
|
this.functionDispatchNode = functionDispatchNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportMessage
|
||||||
|
boolean isExecutable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportMessage
|
||||||
|
Object execute(Object[] arguments) {
|
||||||
|
if (arguments.length != argumentCount) {
|
||||||
|
throw new LamaException("Wrong amount of function arguments: " + arguments.length + " instead of " + argumentCount);
|
||||||
|
}
|
||||||
|
// TODO: check values of arguments ??
|
||||||
|
return this.functionDispatchNode.executeDispatch(this, arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
package org.programsnail.truffle_lama;
|
||||||
|
|
||||||
|
import com.oracle.truffle.api.TruffleLanguage;
|
||||||
|
import com.oracle.truffle.api.interop.InteropLibrary;
|
||||||
|
import com.oracle.truffle.api.interop.TruffleObject;
|
||||||
|
import com.oracle.truffle.api.interop.UnknownIdentifierException;
|
||||||
|
import com.oracle.truffle.api.library.ExportLibrary;
|
||||||
|
import com.oracle.truffle.api.library.ExportMessage;
|
||||||
|
import org.programsnail.truffle_lama.runtime.LamaException;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@ExportLibrary(InteropLibrary.class)
|
||||||
|
public final class GlobalScopeObject implements TruffleObject {
|
||||||
|
private final Map<String, Object> variables = new HashMap<>();
|
||||||
|
private final Set<String> constants = new HashSet<>();
|
||||||
|
|
||||||
|
public boolean newVariable(String name, Object value, boolean isConst) {
|
||||||
|
Object previousValue = variables.put(name, value);
|
||||||
|
if (isConst) {
|
||||||
|
constants.add(name);
|
||||||
|
}
|
||||||
|
return previousValue == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void newFunction(String name, FunctionObject fun) {
|
||||||
|
variables.put(name, fun);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean updateVariable(String name, Object value) {
|
||||||
|
if (this.constants.contains(name)) {
|
||||||
|
throw new LamaException("Can't assign to const var '" + name + "'.");
|
||||||
|
}
|
||||||
|
Object updatedValue = this.variables.computeIfPresent(name, (k, v) -> value);
|
||||||
|
return updatedValue != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getVariable(String name) {
|
||||||
|
return this.variables.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---
|
||||||
|
|
||||||
|
@ExportMessage
|
||||||
|
boolean isScope() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportMessage
|
||||||
|
boolean hasMembers() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportMessage
|
||||||
|
Object getMembers(@SuppressWarnings("unused") boolean includeInternal) {
|
||||||
|
return new GlobalVariableNamesObject(this.variables.keySet());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportMessage
|
||||||
|
boolean isMemberReadable(String member) {
|
||||||
|
return this.variables.containsKey(member);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportMessage
|
||||||
|
Object readMember(String member) throws UnknownIdentifierException {
|
||||||
|
Object value = this.variables.get(member);
|
||||||
|
if (null == value) {
|
||||||
|
throw UnknownIdentifierException.create(member);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportMessage
|
||||||
|
Object toDisplayString(@SuppressWarnings("unused") boolean allowSideEffects) {
|
||||||
|
return "global";
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportMessage
|
||||||
|
boolean hasLanguage() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportMessage
|
||||||
|
Class<? extends TruffleLanguage<?>> getLanguage() {
|
||||||
|
return LamaLanguage.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportLibrary(InteropLibrary.class)
|
||||||
|
final class GlobalVariablesNamesObject implements TruffleObject {
|
||||||
|
private final List<String> names;
|
||||||
|
|
||||||
|
GlobalVariablesNamesObject(List<String> names) {
|
||||||
|
this.names = names;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportMessage
|
||||||
|
boolean hasArrayElements() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportMessage
|
||||||
|
long getArraySize() {
|
||||||
|
return this.names.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportMessage
|
||||||
|
boolean isArrayElementReadable(long index) {
|
||||||
|
return index >= 0 && index < this.names.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportMessage
|
||||||
|
Object readArrayElement(long index) throws InvalidArrayIndexException {
|
||||||
|
if (!this.isArrayElementReadable(index)) {
|
||||||
|
throw InvalidArrayIndexException.create(index);
|
||||||
|
}
|
||||||
|
return this.names.get((int) index);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,47 +1,59 @@
|
||||||
package org.programsnail.truffle_lama;
|
package org.programsnail.truffle_lama;
|
||||||
|
|
||||||
import com.oracle.truffle.api.Truffle;
|
import com.oracle.truffle.api.Truffle;
|
||||||
|
import com.oracle.truffle.api.TruffleLanguage;
|
||||||
import com.oracle.truffle.api.frame.FrameDescriptor;
|
import com.oracle.truffle.api.frame.FrameDescriptor;
|
||||||
import com.oracle.truffle.api.frame.MaterializedFrame;
|
import com.oracle.truffle.api.frame.MaterializedFrame;
|
||||||
import com.oracle.truffle.api.frame.VirtualFrame;
|
import com.oracle.truffle.api.frame.VirtualFrame;
|
||||||
|
import com.oracle.truffle.api.nodes.Node;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
|
||||||
// TODO
|
public final class LamaContext {
|
||||||
public class LamaContext {
|
private static final TruffleLanguage.ContextReference<LamaContext> REF = TruffleLanguage.ContextReference.create(LamaLanguage.class);
|
||||||
private final FrameDescriptor globalFrameDescriptor;
|
|
||||||
private final Namespace globalNamespace;
|
|
||||||
private final MaterializedFrame globalFrame;
|
|
||||||
private final LamaLanguage language;
|
|
||||||
|
|
||||||
public LamaContext() { this(null); }
|
public static LamaContext get(Node node) {
|
||||||
|
return REF.get(node);
|
||||||
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) {
|
public final GlobalScopeObject globalScopeObject;
|
||||||
VirtualFrame frame = Truffle.getRuntime().createVirtualFrame(null, this.globalFrameDescriptor);
|
|
||||||
addGlobalFunctions(language, frame);
|
|
||||||
return frame.materialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void addGlobalFunctions(LamaLanguage language, VirtualFrame virtualFrame) {
|
public LamaContext() {
|
||||||
// TODO
|
this.globalScopeObject = new GlobalScopeObject();
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return A {@link MaterializedFrame} on the heap that contains all global
|
|
||||||
* values.
|
|
||||||
*/
|
|
||||||
public MaterializedFrame getGlobalFrame() {
|
|
||||||
return this.globalFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Namespace getGlobalNamespace() {
|
|
||||||
return this.globalNamespace;
|
|
||||||
}
|
}
|
||||||
|
// 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;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,9 @@ import com.oracle.truffle.api.nodes.RootNode;
|
||||||
import com.oracle.truffle.api.object.Shape;
|
import com.oracle.truffle.api.object.Shape;
|
||||||
import com.oracle.truffle.api.source.Source;
|
import com.oracle.truffle.api.source.Source;
|
||||||
import com.oracle.truffle.api.strings.TruffleString;
|
import com.oracle.truffle.api.strings.TruffleString;
|
||||||
|
import org.programsnail.truffle_lama.builtins.LamaBuiltinNode;
|
||||||
|
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
|
||||||
|
import org.programsnail.truffle_lama.nodes.LamaRootNode;
|
||||||
import org.programsnail.truffle_lama.parser.LamaParser;
|
import org.programsnail.truffle_lama.parser.LamaParser;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
@ -23,204 +26,185 @@ import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
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)
|
@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,
|
//@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})
|
// StandardTags.ReadVariableTag.class, StandardTags.WriteVariableTag.class})
|
||||||
public class LamaLanguage extends TruffleLanguage<LamaContext> {
|
public class LamaLanguage extends TruffleLanguage<LamaContext> {
|
||||||
public static volatile int counter; // count class instances
|
// public static volatile int counter; // count class instances
|
||||||
|
|
||||||
public static final String ID = "lama";
|
public static final String ID = "lama";
|
||||||
public static final String MIME_TYPE = "application/x-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 Source BUILTIN_SOURCE = Source.newBuilder(ID, "", "LaMa builtin").build();
|
||||||
private static final LanguageReference<LamaLanguage> REFERENCE = LanguageReference.create(LamaLanguage.class);
|
// private static final LanguageReference<LamaLanguage> REFERENCE = LanguageReference.create(LamaLanguage.class);
|
||||||
private static final List<NodeFactory<? extends LamaBuiltinNode>> EXTERNAL_BUILTINS = Collections.synchronizedList(new ArrayList<>());
|
// private static final List<NodeFactory<? extends LamaBuiltinNode>> EXTERNAL_BUILTINS = Collections.synchronizedList(new ArrayList<>());
|
||||||
|
|
||||||
public static final TruffleString.Encoding STRING_ENCODING = TruffleString.Encoding.UTF_16;
|
// public static final TruffleString.Encoding STRING_ENCODING = TruffleString.Encoding.UTF_16;
|
||||||
|
|
||||||
private final Assumption singleContext = Truffle.getRuntime().createAssumption("Single Lama context.");
|
private final Assumption singleContext = Truffle.getRuntime().createAssumption("Single Lama context.");
|
||||||
|
|
||||||
private final Map<NodeFactory<? extends LamaBuiltinNode>, RootCallTarget> builtinTargets = new ConcurrentHashMap<>();
|
@Override
|
||||||
private final Map<TruffleString, RootCallTarget> undefinedFunctions = new ConcurrentHashMap<>();
|
protected CallTarget parse(ParsingRequest request) throws Exception {
|
||||||
|
var exprNode = LamaParser.parseLama(this, request.getSource());
|
||||||
private final Shape rootShape;
|
var rootNode = new LamaRootNode(exprNode);
|
||||||
|
return rootNode.getCallTarget();
|
||||||
//
|
|
||||||
|
|
||||||
public LamaLanguage() {
|
|
||||||
counter++;
|
|
||||||
this.rootShape = Shape.newBuilder().layout(LamaObject.class).build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected LamaContext createContext(Env env) {
|
protected LamaContext createContext(Env env) {
|
||||||
return new LamaContext(this, env, new ArrayList<>(EXTERNAL_BUILTINS));
|
return new LamaContext();
|
||||||
}
|
|
||||||
|
|
||||||
@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. */
|
|
||||||
LamamRootNode rootNode = new LammaRootNode(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 CallTarget parse(ParsingRequest request) throws Exception {
|
|
||||||
Source source = request.getSource();
|
|
||||||
Map<TruffleString, RootCallTarget> functions;
|
|
||||||
/*
|
|
||||||
* Parse the provided source. At this point, we do not have a SLContext yet. Registration of
|
|
||||||
* the functions with the SLContext happens lazily in SLEvalRootNode.
|
|
||||||
*/
|
|
||||||
if (request.getArgumentNames().isEmpty()) {
|
|
||||||
functions = LamaParser.parseLama(this, source);
|
|
||||||
} else {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("function main(");
|
|
||||||
String sep = "";
|
|
||||||
for (String argumentName : request.getArgumentNames()) {
|
|
||||||
sb.append(sep);
|
|
||||||
sb.append(argumentName);
|
|
||||||
sep = ",";
|
|
||||||
}
|
|
||||||
sb.append(") { return ");
|
|
||||||
sb.append(source.getCharacters());
|
|
||||||
sb.append(";}");
|
|
||||||
String language = source.getLanguage() == null ? ID : source.getLanguage();
|
|
||||||
Source decoratedSource = Source.newBuilder(language, sb.toString(), source.getName()).build();
|
|
||||||
functions = LamaParser.parseLama(this, decoratedSource);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: execute source itself, not main function
|
|
||||||
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
|
|
||||||
@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
|
@Override
|
||||||
protected Object getScope(LamaContext context) {
|
protected Object getScope(LamaContext context) {
|
||||||
return context.getFunctionRegistry().getFunctionsObject();
|
return context.globalScopeObject;
|
||||||
}
|
|
||||||
|
|
||||||
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 LamaLanguage() {
|
||||||
}
|
//// counter++;
|
||||||
|
// }
|
||||||
//
|
//
|
||||||
|
// @Override
|
||||||
public static void installBuiltin(NodeFactory<? extends LamaBuiltinNode> builtin) {
|
// protected LamaContext createContext(Env env) {
|
||||||
EXTERNAL_BUILTINS.add(builtin);
|
// return new LamaContext(this, env, new ArrayList<>(EXTERNAL_BUILTINS));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
protected void exitContext(LamaContext context, ExitMode exitMode, int exitCode) {
|
// protected boolean patchContext(LamaContext context, Env newEnv) {
|
||||||
/*
|
// context.patchContext(newEnv);
|
||||||
* Runs shutdown hooks during explicit exit triggered by TruffleContext#closeExit(Node, int)
|
// return true;
|
||||||
* or natural exit triggered during natural context close.
|
// }
|
||||||
*/
|
//
|
||||||
context.runShutdownHooks();
|
// //
|
||||||
}
|
//
|
||||||
|
// 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();
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
package org.programsnail.truffle_lama;
|
|
||||||
|
|
||||||
import com.oracle.truffle.api.dsl.ImplicitCast;
|
|
||||||
import com.oracle.truffle.api.dsl.TypeSystem;
|
|
||||||
|
|
||||||
@TypeSystem({long.class, boolean.class, String.class})
|
|
||||||
public class LamaTypes {}
|
|
||||||
|
|
@ -6,6 +6,9 @@ import com.oracle.truffle.api.dsl.UnsupportedSpecializationException;
|
||||||
import com.oracle.truffle.api.frame.VirtualFrame;
|
import com.oracle.truffle.api.frame.VirtualFrame;
|
||||||
import com.oracle.truffle.api.nodes.UnexpectedResultException;
|
import com.oracle.truffle.api.nodes.UnexpectedResultException;
|
||||||
|
|
||||||
|
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
|
||||||
|
|
||||||
|
|
||||||
@NodeChild(value = "arguments", type = LamaExpressionNode[].class)
|
@NodeChild(value = "arguments", type = LamaExpressionNode[].class)
|
||||||
@GenerateNodeFactory
|
@GenerateNodeFactory
|
||||||
public abstract class LamaBuiltinNode extends LamaExpressionNode {
|
public abstract class LamaBuiltinNode extends LamaExpressionNode {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes;
|
||||||
|
|
||||||
|
import com.oracle.truffle.api.dsl.Cached;
|
||||||
|
import com.oracle.truffle.api.dsl.Fallback;
|
||||||
|
import com.oracle.truffle.api.dsl.Specialization;
|
||||||
|
import com.oracle.truffle.api.nodes.DirectCallNode;
|
||||||
|
import com.oracle.truffle.api.nodes.IndirectCallNode;
|
||||||
|
import com.oracle.truffle.api.nodes.Node;
|
||||||
|
import org.programsnail.truffle_lama.FunctionObject;
|
||||||
|
import org.programsnail.truffle_lama.runtime.LamaException;
|
||||||
|
|
||||||
|
public abstract class FunctionDispatchNode extends Node {
|
||||||
|
public abstract Object executeDispatch(Object function, Object[] arguments);
|
||||||
|
|
||||||
|
@Specialization(guards = "function.callTarget == directCallNode.getCallTarget()", limit = "2")
|
||||||
|
protected static Object dispatchDirectly(FunctionObject function,
|
||||||
|
Object[] arguments,
|
||||||
|
@Cached("create(function.callTarget)")
|
||||||
|
DirectCallNode directCallNode) {
|
||||||
|
return directCallNode.call(arguments); // TODO: check arguments count ??
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization(replaces = "dispatchDirectly")
|
||||||
|
protected static Object dispatchIndirectly(FunctionObject function,
|
||||||
|
Object[] arguments,
|
||||||
|
IndirectCallNode indirectCallNode) {
|
||||||
|
return indirectCallNode.call(function.callTarget, arguments); // TODO: check arguments count ??
|
||||||
|
}
|
||||||
|
|
||||||
|
@Fallback
|
||||||
|
protected static Object targetIsNotAFunction(Object object, Object[] arguments) {
|
||||||
|
throw new LamaException("Called '" + object + "' is not a function");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes;
|
||||||
|
|
||||||
|
public class LamaDeclNode {
|
||||||
|
}
|
||||||
|
|
@ -3,13 +3,13 @@ package org.programsnail.truffle_lama.nodes;
|
||||||
import com.oracle.truffle.api.dsl.TypeSystemReference;
|
import com.oracle.truffle.api.dsl.TypeSystemReference;
|
||||||
import com.oracle.truffle.api.frame.VirtualFrame;
|
import com.oracle.truffle.api.frame.VirtualFrame;
|
||||||
import com.oracle.truffle.api.instrumentation.*;
|
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.NodeInfo;
|
||||||
import com.oracle.truffle.api.nodes.UnexpectedResultException;
|
import com.oracle.truffle.api.nodes.UnexpectedResultException;
|
||||||
|
|
||||||
@TypeSystemReference(SLTypes.class)
|
@TypeSystemReference(LamaTypes.class)
|
||||||
@NodeInfo(description = "The abstract base node for all expressions")
|
@NodeInfo(description = "The abstract base node for all expressions")
|
||||||
@GenerateWrapper
|
public abstract class LamaExpressionNode extends Node {
|
||||||
public abstract class LamaExpressionNode extends LamaStatementNode {
|
|
||||||
|
|
||||||
private boolean hasExpressionTag;
|
private boolean hasExpressionTag;
|
||||||
|
|
||||||
|
|
@ -17,29 +17,21 @@ public abstract class LamaExpressionNode extends LamaStatementNode {
|
||||||
* The execute method when no specialization is possible. This is the most general case,
|
* The execute method when no specialization is possible. This is the most general case,
|
||||||
* therefore it must be provided by all subclasses.
|
* therefore it must be provided by all subclasses.
|
||||||
*/
|
*/
|
||||||
public abstract Object executeGeneric(VirtualFrame frame);
|
public abstract Object executeGeneric(VirtualFrame frame) throws UnexpectedResultException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When we use an expression at places where a {@link LamaStatementNode statement} is already
|
* The return value is just discarded.
|
||||||
* sufficient, the return value is just discarded.
|
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public void executeVoid(VirtualFrame frame) {
|
public void executeVoid(VirtualFrame frame) {
|
||||||
executeGeneric(frame);
|
executeGeneric(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
// LamaExpressionNodeWrapper is generated (?)
|
|
||||||
@Override
|
|
||||||
public InstrumentableNode.WrapperNode createWrapper(ProbeNode probe) {
|
|
||||||
return new LamaExpressionNodeWrapper(this, probe);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasTag(Class<? extends Tag> tag) {
|
public boolean hasTag(Class<? extends Tag> tag) {
|
||||||
if (tag == StandardTags.ExpressionTag.class) {
|
if (tag == StandardTags.ExpressionTag.class) {
|
||||||
return hasExpressionTag;
|
return hasExpressionTag;
|
||||||
}
|
}
|
||||||
return super.hasTag(tag);
|
return false; // no super tags
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -57,6 +49,7 @@ public abstract class LamaExpressionNode extends LamaStatementNode {
|
||||||
|
|
||||||
// LamaTypesGen is generated from LamaTypes
|
// LamaTypesGen is generated from LamaTypes
|
||||||
|
|
||||||
|
// TODO
|
||||||
public long executeLong(VirtualFrame frame) throws UnexpectedResultException {
|
public long executeLong(VirtualFrame frame) throws UnexpectedResultException {
|
||||||
return LamaTypesGen.expectLong(executeGeneric(frame));
|
return LamaTypesGen.expectLong(executeGeneric(frame));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes;
|
||||||
|
|
||||||
|
import com.oracle.truffle.api.frame.VirtualFrame;
|
||||||
|
import com.oracle.truffle.api.nodes.RootNode;
|
||||||
|
|
||||||
|
public class LamaRootNode extends RootNode {
|
||||||
|
@SuppressWarnings("FieldMayBeFinal")
|
||||||
|
@Child
|
||||||
|
private LamaExpressionNode exprNode;
|
||||||
|
|
||||||
|
public LamaRootNode(LamaExpressionNode exprNode) {
|
||||||
|
super(null);
|
||||||
|
|
||||||
|
this.exprNode = exprNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object execute(VirtualFrame frame) {
|
||||||
|
return this.exprNode.executeGeneric(frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes;
|
||||||
|
|
||||||
|
import com.oracle.truffle.api.dsl.TypeSystem;
|
||||||
|
|
||||||
|
@TypeSystem({long.class, boolean.class, String.class})
|
||||||
|
public abstract class LamaTypes {}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes.controlflow;
|
||||||
|
|
||||||
|
public class LamaCaseNode {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes.controlflow;
|
||||||
|
|
||||||
|
public class LamaControlNode {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes.controlflow;
|
||||||
|
|
||||||
|
import com.oracle.truffle.api.Truffle;
|
||||||
|
import com.oracle.truffle.api.frame.VirtualFrame;
|
||||||
|
import com.oracle.truffle.api.nodes.LoopNode;
|
||||||
|
import com.oracle.truffle.api.nodes.Node;
|
||||||
|
import com.oracle.truffle.api.nodes.RepeatingNode;
|
||||||
|
import com.oracle.truffle.api.nodes.UnexpectedResultException;
|
||||||
|
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
|
||||||
|
import org.programsnail.truffle_lama.runtime.LamaUnit;
|
||||||
|
|
||||||
|
public final class LamaDoWhileNode extends LamaExpressionNode {
|
||||||
|
@SuppressWarnings("FieldMayBeFinal")
|
||||||
|
@Child
|
||||||
|
private LoopNode loopNode;
|
||||||
|
|
||||||
|
public LamaDoWhileNode(LamaExpressionNode conditionExpr, LamaExpressionNode bodyExpr) {
|
||||||
|
this.loopNode = Truffle.getRuntime().createLoopNode(
|
||||||
|
new WhileRepeatingNode(conditionExpr, bodyExpr));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object executeGeneric(VirtualFrame frame) throws UnexpectedResultException {
|
||||||
|
this.loopNode.execute(frame);
|
||||||
|
return LamaUnit.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class WhileRepeatingNode extends Node implements RepeatingNode {
|
||||||
|
@SuppressWarnings("FieldMayBeFinal")
|
||||||
|
@Child
|
||||||
|
private LamaExpressionNode conditionExpr, bodyExpr;
|
||||||
|
|
||||||
|
public WhileRepeatingNode(LamaExpressionNode conditionExpr, LamaExpressionNode bodyExpr) {
|
||||||
|
this.conditionExpr = conditionExpr;
|
||||||
|
this.bodyExpr = bodyExpr;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean executeRepeating(VirtualFrame frame) {
|
||||||
|
try {
|
||||||
|
this.bodyExpr.executeGeneric(frame);
|
||||||
|
// NOTE: try/catch for break/continue
|
||||||
|
if (!this.conditionExpr.executeBoolean(frame)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} catch (UnexpectedResultException e) { // TODO: handle in proper way
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes.controlflow;
|
||||||
|
|
||||||
|
import com.oracle.truffle.api.frame.VirtualFrame;
|
||||||
|
import com.oracle.truffle.api.nodes.UnexpectedResultException;
|
||||||
|
import com.oracle.truffle.api.profiles.ConditionProfile;
|
||||||
|
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
|
||||||
|
|
||||||
|
public final class LamaIfNode extends LamaExpressionNode {
|
||||||
|
@Child
|
||||||
|
private LamaExpressionNode conditionExpr;
|
||||||
|
|
||||||
|
@Child
|
||||||
|
private LamaExpressionNode thenExpr;
|
||||||
|
|
||||||
|
@Child
|
||||||
|
private LamaExpressionNode elseExpr;
|
||||||
|
|
||||||
|
private final ConditionProfile condition = ConditionProfile.create();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object executeGeneric(VirtualFrame frame) throws UnexpectedResultException {
|
||||||
|
if (this.condition.profile(this.conditionExpr.executeBoolean(frame))) {
|
||||||
|
return this.thenExpr.executeGeneric(frame);
|
||||||
|
}
|
||||||
|
return this.elseExpr; // TODO: cases with no else
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes.controlflow;
|
||||||
|
|
||||||
|
import com.oracle.truffle.api.Truffle;
|
||||||
|
import com.oracle.truffle.api.frame.VirtualFrame;
|
||||||
|
import com.oracle.truffle.api.nodes.LoopNode;
|
||||||
|
import com.oracle.truffle.api.nodes.Node;
|
||||||
|
import com.oracle.truffle.api.nodes.RepeatingNode;
|
||||||
|
import com.oracle.truffle.api.nodes.UnexpectedResultException;
|
||||||
|
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
|
||||||
|
import org.programsnail.truffle_lama.runtime.LamaUnit;
|
||||||
|
|
||||||
|
public final class LamaWhileNode extends LamaExpressionNode {
|
||||||
|
@SuppressWarnings("FieldMayBeFinal")
|
||||||
|
@Child
|
||||||
|
private LoopNode loopNode;
|
||||||
|
|
||||||
|
public LamaWhileNode(LamaExpressionNode conditionExpr, LamaExpressionNode bodyExpr) {
|
||||||
|
this.loopNode = Truffle.getRuntime().createLoopNode(
|
||||||
|
new WhileRepeatingNode(conditionExpr, bodyExpr));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object executeGeneric(VirtualFrame frame) throws UnexpectedResultException {
|
||||||
|
this.loopNode.execute(frame);
|
||||||
|
return LamaUnit.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class WhileRepeatingNode extends Node implements RepeatingNode {
|
||||||
|
@SuppressWarnings("FieldMayBeFinal")
|
||||||
|
@Child
|
||||||
|
private LamaExpressionNode conditionExpr, bodyExpr;
|
||||||
|
|
||||||
|
public WhileRepeatingNode(LamaExpressionNode conditionExpr, LamaExpressionNode bodyExpr) {
|
||||||
|
this.conditionExpr = conditionExpr;
|
||||||
|
this.bodyExpr = bodyExpr;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean executeRepeating(VirtualFrame frame) {
|
||||||
|
try {
|
||||||
|
if (!this.conditionExpr.executeBoolean(frame)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.bodyExpr.executeGeneric(frame);
|
||||||
|
// NOTE: try/catch for break/continue
|
||||||
|
return false;
|
||||||
|
} catch (UnexpectedResultException e) { // TODO: handle in proper way
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes.expression;
|
||||||
|
|
||||||
|
public class LamaArrayNode {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes.expression;
|
||||||
|
|
||||||
|
public class LamaAssignNode {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes.expression;
|
||||||
|
|
||||||
|
import com.oracle.truffle.api.dsl.NodeChild;
|
||||||
|
import com.oracle.truffle.api.dsl.NodeField;
|
||||||
|
import com.oracle.truffle.api.dsl.Specialization;
|
||||||
|
import com.oracle.truffle.api.frame.VirtualFrame;
|
||||||
|
import com.oracle.truffle.api.nodes.UnexpectedResultException;
|
||||||
|
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
|
||||||
|
|
||||||
|
@NodeChild("leftNode")
|
||||||
|
@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) {
|
||||||
|
case "+" -> leftValue + rightValue;
|
||||||
|
case "-" -> leftValue - rightValue;
|
||||||
|
case "/" -> leftValue / rightValue;
|
||||||
|
case "%" -> leftValue % rightValue;
|
||||||
|
default -> throw new IllegalStateException();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization(replaces = "numOp")
|
||||||
|
protected boolean compOp(long leftValue, long rightValue) {
|
||||||
|
return switch (op) {
|
||||||
|
case "<" -> leftValue < rightValue;
|
||||||
|
case "<=" -> leftValue <= rightValue;
|
||||||
|
case ">" -> leftValue > rightValue;
|
||||||
|
case ">=" -> leftValue >= rightValue;
|
||||||
|
case "==" -> leftValue == rightValue;
|
||||||
|
case "!=" -> leftValue != rightValue;
|
||||||
|
default -> throw new IllegalStateException();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
protected boolean boolOp(boolean leftValue, boolean rightValue) {
|
||||||
|
return switch (op) {
|
||||||
|
case "&&" -> leftValue && rightValue;
|
||||||
|
case "!!" -> leftValue || rightValue;
|
||||||
|
default -> throw new IllegalStateException();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
String op;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes.expression;
|
||||||
|
|
||||||
|
public class LamaCallNode {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
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;
|
||||||
|
|
||||||
|
public final class LamaConstNode extends LamaExpressionNode {
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
public LamaConstNode(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object executeGeneric(VirtualFrame frame) {
|
||||||
|
return this.executeLong(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long executeLong(VirtualFrame frame) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean executeBoolean(VirtualFrame frame) {
|
||||||
|
return value != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes.expression;
|
||||||
|
|
||||||
|
public class LamaElemNode {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes.expression;
|
||||||
|
|
||||||
|
public class LamaElemRefNode {
|
||||||
|
}
|
||||||
|
|
@ -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 LamaIgnoreNode extends LamaExpressionNode {
|
||||||
|
@Child
|
||||||
|
LamaExpressionNode node;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object executeGeneric(VirtualFrame frame) throws UnexpectedResultException {
|
||||||
|
return LamaUnit.INSTANCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes.expression;
|
||||||
|
|
||||||
|
public class LamaIntrinsicNode {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes.expression;
|
||||||
|
|
||||||
|
public class LamaLambdaNode {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes.expression;
|
||||||
|
|
||||||
|
public class LamaLeaveNode {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes.expression;
|
||||||
|
|
||||||
|
public class LamaRefNode {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes.expression;
|
||||||
|
|
||||||
|
public class LamaScopeNode {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes.expression;
|
||||||
|
|
||||||
|
public class LamaSeqNode {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes.expression;
|
||||||
|
|
||||||
|
public class LamaSexpNode {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes.expression;
|
||||||
|
|
||||||
|
public class LamaSkipNode {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes.expression;
|
||||||
|
|
||||||
|
public class LamaStringNode {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
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 LamaUnitNode extends LamaExpressionNode {
|
||||||
|
@Override
|
||||||
|
public Object executeGeneric(VirtualFrame frame) throws UnexpectedResultException {
|
||||||
|
return LamaUnit.INSTANCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package org.programsnail.truffle_lama.nodes.expression;
|
||||||
|
|
||||||
|
public class LamaVarNode {
|
||||||
|
}
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The parser and lexer need to be generated using "mx create-sl-parser".
|
* The parser and lexer need to be generated using "mx create-lama-parser". ???
|
||||||
*/
|
*/
|
||||||
|
|
||||||
grammar Lama;
|
grammar Lama;
|
||||||
|
|
@ -58,7 +58,6 @@ import com.oracle.truffle.api.source.Source;
|
||||||
import com.oracle.truffle.api.strings.TruffleString;
|
import com.oracle.truffle.api.strings.TruffleString;
|
||||||
import org.programsnail.truffle_lama.LamaLanguage;
|
import org.programsnail.truffle_lama.LamaLanguage;
|
||||||
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
|
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
|
||||||
import org.programsnail.truffle_lama.nodes.LamaStatementNode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@lexer::header
|
@lexer::header
|
||||||
|
|
@ -91,11 +90,11 @@ private static void throwParseError(Source source, int line, int charPositionInL
|
||||||
int col = charPositionInLine + 1;
|
int col = charPositionInLine + 1;
|
||||||
String location = "-- line " + line + " col " + col + ": ";
|
String location = "-- line " + line + " col " + col + ": ";
|
||||||
int length = token == null ? 1 : Math.max(token.getStopIndex() - token.getStartIndex(), 0);
|
int length = token == null ? 1 : Math.max(token.getStopIndex() - token.getStartIndex(), 0);
|
||||||
throw new SLParseError(source, line, col, length, String.format("Error(s) parsing script:%n" + location + message));
|
throw new LamaParseError(source, line, col, length, String.format("Error(s) parsing script:%n" + location + message));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<TruffleString, RootCallTarget> parseLama(LamaLanguage language, Source source) {
|
public static LamaExpressionNode parseLama(LamaLanguage language, Source source) {
|
||||||
LamaLexer lexer = new LamamLexer(CharStreams.fromString(source.getCharacters().toString()));
|
LamaLexer lexer = new LamaLexer(CharStreams.fromString(source.getCharacters().toString()));
|
||||||
LamaParser parser = new LamaParser(new CommonTokenStream(lexer));
|
LamaParser parser = new LamaParser(new CommonTokenStream(lexer));
|
||||||
lexer.removeErrorListeners();
|
lexer.removeErrorListeners();
|
||||||
parser.removeErrorListeners();
|
parser.removeErrorListeners();
|
||||||
|
|
@ -105,7 +104,7 @@ public static Map<TruffleString, RootCallTarget> parseLama(LamaLanguage language
|
||||||
parser.factory = new LamaNodeFactory(language, source);
|
parser.factory = new LamaNodeFactory(language, source);
|
||||||
parser.source = source;
|
parser.source = source;
|
||||||
parser.lama();
|
parser.lama();
|
||||||
return parser.factory.getAllFunctions();
|
return parser.factory.getRootExpr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -142,15 +141,15 @@ level : ('at' | 'before' | 'after') INFIX;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
expression returns [SLExpressionNode result]: basic_expression (';' expression)?;
|
expression returns [LamaExpressionNode result]: basic_expression (';' expression)?;
|
||||||
basic_expression returns [SLExpressionNode result]: binary_expression;
|
basic_expression returns [LamaExpressionNode result]: binary_expression;
|
||||||
binary_expression returns [SLExpressionNode result]: postfix_expression (INFIX postfix_expression)*;
|
binary_expression returns [LamaExpressionNode result]: postfix_expression (INFIX postfix_expression)*;
|
||||||
postfix_expression returns [SLExpressionNode result]: ('-')? primary (postfix)*;
|
postfix_expression returns [LamaExpressionNode result]: ('-')? primary (postfix)*;
|
||||||
postfix :
|
postfix :
|
||||||
'(' expression (',' expression)* ')'
|
'(' expression (',' expression)* ')'
|
||||||
| '[' expression ']';
|
| '[' expression ']';
|
||||||
|
|
||||||
primary returns [SLExpressionNode result]:
|
primary returns [LamaExpressionNode result]:
|
||||||
DECIMAL_LITERAL
|
DECIMAL_LITERAL
|
||||||
| STRING_LITERAL
|
| STRING_LITERAL
|
||||||
| CHAR_LITERAL
|
| CHAR_LITERAL
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,12 @@ package org.programsnail.truffle_lama.parser;
|
||||||
|
|
||||||
import org.antlr.v4.runtime.Lexer;
|
import org.antlr.v4.runtime.Lexer;
|
||||||
import org.antlr.v4.runtime.CharStream;
|
import org.antlr.v4.runtime.CharStream;
|
||||||
|
import org.antlr.v4.runtime.Token;
|
||||||
|
import org.antlr.v4.runtime.TokenStream;
|
||||||
import org.antlr.v4.runtime.*;
|
import org.antlr.v4.runtime.*;
|
||||||
import org.antlr.v4.runtime.atn.*;
|
import org.antlr.v4.runtime.atn.*;
|
||||||
import org.antlr.v4.runtime.dfa.DFA;
|
import org.antlr.v4.runtime.dfa.DFA;
|
||||||
|
import org.antlr.v4.runtime.misc.*;
|
||||||
|
|
||||||
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue", "this-escape"})
|
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue", "this-escape"})
|
||||||
public class LamaLexer extends Lexer {
|
public class LamaLexer extends Lexer {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package org.programsnail.truffle_lama.parser;
|
||||||
|
|
||||||
|
import com.oracle.truffle.api.source.Source;
|
||||||
|
import org.programsnail.truffle_lama.LamaLanguage;
|
||||||
|
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
|
||||||
|
|
||||||
|
public class LamaNodeFactory {
|
||||||
|
public LamaNodeFactory(LamaLanguage language, Source source) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
public LamaExpressionNode getRootExpr() {
|
||||||
|
// TODO
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: build expr tree from parsed tokens
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
package org.programsnail.truffle_lama.parser;
|
||||||
|
|
||||||
|
import com.oracle.truffle.api.CompilerDirectives;
|
||||||
|
import com.oracle.truffle.api.exception.AbstractTruffleException;
|
||||||
|
import com.oracle.truffle.api.interop.ExceptionType;
|
||||||
|
import com.oracle.truffle.api.interop.InteropLibrary;
|
||||||
|
import com.oracle.truffle.api.interop.UnsupportedMessageException;
|
||||||
|
import com.oracle.truffle.api.library.ExportLibrary;
|
||||||
|
import com.oracle.truffle.api.library.ExportMessage;
|
||||||
|
import com.oracle.truffle.api.source.Source;
|
||||||
|
import com.oracle.truffle.api.source.SourceSection;
|
||||||
|
|
||||||
|
@ExportLibrary(InteropLibrary.class)
|
||||||
|
public class LamaParseError extends AbstractTruffleException {
|
||||||
|
|
||||||
|
public static final long serialVersionUID = 1L;
|
||||||
|
private final Source source;
|
||||||
|
private final int line;
|
||||||
|
private final int column;
|
||||||
|
private final int length;
|
||||||
|
|
||||||
|
public LamaParseError(Source source, int line, int column, int length, String message) {
|
||||||
|
super(message);
|
||||||
|
this.source = source;
|
||||||
|
this.line = line;
|
||||||
|
this.column = column;
|
||||||
|
this.length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note that any subclass of {@link AbstractTruffleException} must always return
|
||||||
|
* <code>true</code> for {@link InteropLibrary#isException(Object)}. That is why it is correct
|
||||||
|
* to export {@link #getExceptionType()} without implementing
|
||||||
|
* {@link InteropLibrary#isException(Object)}.
|
||||||
|
*/
|
||||||
|
@ExportMessage
|
||||||
|
ExceptionType getExceptionType() {
|
||||||
|
return ExceptionType.PARSE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportMessage
|
||||||
|
boolean hasSourceLocation() {
|
||||||
|
return source != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportMessage(name = "getSourceLocation")
|
||||||
|
@CompilerDirectives.TruffleBoundary
|
||||||
|
SourceSection getSourceSection() throws UnsupportedMessageException {
|
||||||
|
if (source == null) {
|
||||||
|
throw UnsupportedMessageException.create();
|
||||||
|
}
|
||||||
|
return source.createSection(line, column, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ package org.programsnail.truffle_lama.parser;
|
||||||
|
|
||||||
// DO NOT MODIFY - generated from Lama.g4
|
// DO NOT MODIFY - generated from Lama.g4
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
@ -11,12 +12,15 @@ import com.oracle.truffle.api.source.Source;
|
||||||
import com.oracle.truffle.api.strings.TruffleString;
|
import com.oracle.truffle.api.strings.TruffleString;
|
||||||
import org.programsnail.truffle_lama.LamaLanguage;
|
import org.programsnail.truffle_lama.LamaLanguage;
|
||||||
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
|
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
|
||||||
import org.programsnail.truffle_lama.nodes.LamaStatementNode;
|
|
||||||
|
|
||||||
import org.antlr.v4.runtime.atn.*;
|
import org.antlr.v4.runtime.atn.*;
|
||||||
import org.antlr.v4.runtime.dfa.DFA;
|
import org.antlr.v4.runtime.dfa.DFA;
|
||||||
import org.antlr.v4.runtime.*;
|
import org.antlr.v4.runtime.*;
|
||||||
|
import org.antlr.v4.runtime.misc.*;
|
||||||
import org.antlr.v4.runtime.tree.*;
|
import org.antlr.v4.runtime.tree.*;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue", "this-escape"})
|
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue", "this-escape"})
|
||||||
public class LamaParser extends Parser {
|
public class LamaParser extends Parser {
|
||||||
|
|
@ -153,11 +157,11 @@ public class LamaParser extends Parser {
|
||||||
int col = charPositionInLine + 1;
|
int col = charPositionInLine + 1;
|
||||||
String location = "-- line " + line + " col " + col + ": ";
|
String location = "-- line " + line + " col " + col + ": ";
|
||||||
int length = token == null ? 1 : Math.max(token.getStopIndex() - token.getStartIndex(), 0);
|
int length = token == null ? 1 : Math.max(token.getStopIndex() - token.getStartIndex(), 0);
|
||||||
throw new SLParseError(source, line, col, length, String.format("Error(s) parsing script:%n" + location + message));
|
throw new LamaParseError(source, line, col, length, String.format("Error(s) parsing script:%n" + location + message));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<TruffleString, RootCallTarget> parseLama(LamaLanguage language, Source source) {
|
public static LamaExpressionNode parseLama(LamaLanguage language, Source source) {
|
||||||
LamaLexer lexer = new LamamLexer(CharStreams.fromString(source.getCharacters().toString()));
|
LamaLexer lexer = new LamaLexer(CharStreams.fromString(source.getCharacters().toString()));
|
||||||
LamaParser parser = new LamaParser(new CommonTokenStream(lexer));
|
LamaParser parser = new LamaParser(new CommonTokenStream(lexer));
|
||||||
lexer.removeErrorListeners();
|
lexer.removeErrorListeners();
|
||||||
parser.removeErrorListeners();
|
parser.removeErrorListeners();
|
||||||
|
|
@ -167,7 +171,7 @@ public class LamaParser extends Parser {
|
||||||
parser.factory = new LamaNodeFactory(language, source);
|
parser.factory = new LamaNodeFactory(language, source);
|
||||||
parser.source = source;
|
parser.source = source;
|
||||||
parser.lama();
|
parser.lama();
|
||||||
return parser.factory.getAllFunctions();
|
return parser.factory.getRootExpr();
|
||||||
}
|
}
|
||||||
|
|
||||||
public LamaParser(TokenStream input) {
|
public LamaParser(TokenStream input) {
|
||||||
|
|
@ -351,7 +355,7 @@ public class LamaParser extends Parser {
|
||||||
setState(92);
|
setState(92);
|
||||||
_errHandler.sync(this);
|
_errHandler.sync(this);
|
||||||
_alt = getInterpreter().adaptivePredict(_input,1,_ctx);
|
_alt = getInterpreter().adaptivePredict(_input,1,_ctx);
|
||||||
} while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER );
|
} while ( _alt!=2 && _alt!= ATN.INVALID_ALT_NUMBER );
|
||||||
setState(95);
|
setState(95);
|
||||||
_errHandler.sync(this);
|
_errHandler.sync(this);
|
||||||
switch ( getInterpreter().adaptivePredict(_input,2,_ctx) ) {
|
switch ( getInterpreter().adaptivePredict(_input,2,_ctx) ) {
|
||||||
|
|
@ -1057,7 +1061,7 @@ public class LamaParser extends Parser {
|
||||||
|
|
||||||
@SuppressWarnings("CheckReturnValue")
|
@SuppressWarnings("CheckReturnValue")
|
||||||
public static class ExpressionContext extends ParserRuleContext {
|
public static class ExpressionContext extends ParserRuleContext {
|
||||||
public SLExpressionNode result;
|
public LamaExpressionNode result;
|
||||||
public Basic_expressionContext basic_expression() {
|
public Basic_expressionContext basic_expression() {
|
||||||
return getRuleContext(Basic_expressionContext.class,0);
|
return getRuleContext(Basic_expressionContext.class,0);
|
||||||
}
|
}
|
||||||
|
|
@ -1119,7 +1123,7 @@ public class LamaParser extends Parser {
|
||||||
|
|
||||||
@SuppressWarnings("CheckReturnValue")
|
@SuppressWarnings("CheckReturnValue")
|
||||||
public static class Basic_expressionContext extends ParserRuleContext {
|
public static class Basic_expressionContext extends ParserRuleContext {
|
||||||
public SLExpressionNode result;
|
public LamaExpressionNode result;
|
||||||
public Binary_expressionContext binary_expression() {
|
public Binary_expressionContext binary_expression() {
|
||||||
return getRuleContext(Binary_expressionContext.class,0);
|
return getRuleContext(Binary_expressionContext.class,0);
|
||||||
}
|
}
|
||||||
|
|
@ -1165,7 +1169,7 @@ public class LamaParser extends Parser {
|
||||||
|
|
||||||
@SuppressWarnings("CheckReturnValue")
|
@SuppressWarnings("CheckReturnValue")
|
||||||
public static class Binary_expressionContext extends ParserRuleContext {
|
public static class Binary_expressionContext extends ParserRuleContext {
|
||||||
public SLExpressionNode result;
|
public LamaExpressionNode result;
|
||||||
public List<Postfix_expressionContext> postfix_expression() {
|
public List<Postfix_expressionContext> postfix_expression() {
|
||||||
return getRuleContexts(Postfix_expressionContext.class);
|
return getRuleContexts(Postfix_expressionContext.class);
|
||||||
}
|
}
|
||||||
|
|
@ -1235,7 +1239,7 @@ public class LamaParser extends Parser {
|
||||||
|
|
||||||
@SuppressWarnings("CheckReturnValue")
|
@SuppressWarnings("CheckReturnValue")
|
||||||
public static class Postfix_expressionContext extends ParserRuleContext {
|
public static class Postfix_expressionContext extends ParserRuleContext {
|
||||||
public SLExpressionNode result;
|
public LamaExpressionNode result;
|
||||||
public PrimaryContext primary() {
|
public PrimaryContext primary() {
|
||||||
return getRuleContext(PrimaryContext.class,0);
|
return getRuleContext(PrimaryContext.class,0);
|
||||||
}
|
}
|
||||||
|
|
@ -1400,7 +1404,7 @@ public class LamaParser extends Parser {
|
||||||
|
|
||||||
@SuppressWarnings("CheckReturnValue")
|
@SuppressWarnings("CheckReturnValue")
|
||||||
public static class PrimaryContext extends ParserRuleContext {
|
public static class PrimaryContext extends ParserRuleContext {
|
||||||
public SLExpressionNode result;
|
public LamaExpressionNode result;
|
||||||
public TerminalNode DECIMAL_LITERAL() { return getToken(LamaParser.DECIMAL_LITERAL, 0); }
|
public TerminalNode DECIMAL_LITERAL() { return getToken(LamaParser.DECIMAL_LITERAL, 0); }
|
||||||
public TerminalNode STRING_LITERAL() { return getToken(LamaParser.STRING_LITERAL, 0); }
|
public TerminalNode STRING_LITERAL() { return getToken(LamaParser.STRING_LITERAL, 0); }
|
||||||
public TerminalNode CHAR_LITERAL() { return getToken(LamaParser.CHAR_LITERAL, 0); }
|
public TerminalNode CHAR_LITERAL() { return getToken(LamaParser.CHAR_LITERAL, 0); }
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
package org.programsnail.truffle_lama.runtime;
|
||||||
|
|
||||||
|
import com.oracle.truffle.api.exception.AbstractTruffleException;
|
||||||
|
import com.oracle.truffle.api.nodes.Node;
|
||||||
|
|
||||||
|
public class LamaException extends AbstractTruffleException {
|
||||||
|
public LamaException(String message) {
|
||||||
|
this(message, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LamaException(String message, Node location) {
|
||||||
|
super(message, location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
package org.programsnail.truffle_lama.runtime;
|
||||||
|
|
||||||
|
// TODO: truffle object
|
||||||
|
public final class LamaUnit {
|
||||||
|
public static final LamaUnit INSTANCE = new LamaUnit();
|
||||||
|
|
||||||
|
private LamaUnit() { }
|
||||||
|
}
|
||||||
17
src/test/java/BasicNodesTest.java
Normal file
17
src/test/java/BasicNodesTest.java
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
import com.oracle.truffle.api.CallTarget;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
|
||||||
|
import org.programsnail.truffle_lama.nodes.LamaRootNode;
|
||||||
|
|
||||||
|
public class BasicNodesTest {
|
||||||
|
@Test
|
||||||
|
public void basic_test() {
|
||||||
|
LamaExpressionNode exprNode = null; // TODO
|
||||||
|
var rootNode = new LamaRootNode(exprNode);
|
||||||
|
CallTarget callTarget = rootNode.getCallTarget();
|
||||||
|
var result = callTarget.call();
|
||||||
|
|
||||||
|
// TODO: check
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue