most of node factory nodes (without grammar fixes), different scopes, function arguments, correct way to unreference (without grammar fix), captures (partially, only parsing)

This commit is contained in:
ProgramSnail 2025-06-18 18:00:02 +03:00
parent 587e733f52
commit 91505d247b
19 changed files with 438 additions and 105 deletions

View file

@ -30,7 +30,7 @@ public final class GlobalScopeObject implements TruffleObject {
public boolean updateVariable(String name, Object value) {
if (this.constants.contains(name)) {
throw new LamaException("Can't assign to const var '" + name + "'.");
throw new LamaException("Can't put to const var '" + name + "'.");
}
Object updatedValue = this.variables.computeIfPresent(name, (k, v) -> value);
return updatedValue != null;

View file

@ -16,14 +16,14 @@ public abstract class FunctionDispatchNode extends Node {
protected static Object dispatchDirectly(FunctionObject function,
Object[] arguments,
@Cached("create(function.callTarget)") DirectCallNode directCallNode) {
return directCallNode.call(arguments); // TODO: check arguments count ??
return directCallNode.call(arguments);
}
@Specialization(replaces = "dispatchDirectly")
protected static Object dispatchIndirectly(FunctionObject function,
Object[] arguments,
@Cached IndirectCallNode indirectCallNode) {
return indirectCallNode.call(function.callTarget, arguments); // TODO: check arguments count ??
return indirectCallNode.call(function.callTarget, arguments);
}
@Fallback

View file

@ -24,8 +24,7 @@ public abstract class LamaExpressionNode extends Node {
protected final LamaContext currentLanguageContext() {
return LamaContext.get(this);
}
public abstract Object executeGeneric(VirtualFrame frame);
// ---

View file

@ -0,0 +1,18 @@
package org.programsnail.truffle_lama.nodes.expression;
import com.oracle.truffle.api.frame.VirtualFrame;
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
import org.programsnail.truffle_lama.runtime.LamaArgumentRef;
public final class LamaArgumentRefNode extends LamaExpressionNode {
private final int index;
public LamaArgumentRefNode(int index) {
this.index = index;
}
@Override
public Object executeGeneric(VirtualFrame frame) {
return new LamaArgumentRef(this.index);
}
}

View file

@ -1,13 +1,10 @@
package org.programsnail.truffle_lama.nodes.expression;
import com.oracle.truffle.api.dsl.NodeChild;
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;
import org.programsnail.truffle_lama.runtime.LamaException;
import org.programsnail.truffle_lama.runtime.LamaObjRef;
import org.programsnail.truffle_lama.runtime.LamaUnit;
import org.programsnail.truffle_lama.runtime.LamaGlobalVarRef;
public final class LamaAssignNode extends LamaExpressionNode {
@Child
@ -22,12 +19,12 @@ public final class LamaAssignNode extends LamaExpressionNode {
var leftValue = leftNode.executeGeneric(frame);
var rightValue = rightNode.executeGeneric(frame);
if (leftValue instanceof LamaGlobalVarRef varRef) {
if (!varRef.assign(rightValue, frame)) {
throw new LamaException("Can't update variable by identifier '" + varRef.getName() + "'");
if (leftValue instanceof LamaObjRef varRef) {
if (!varRef.put(rightValue, frame)) {
throw new LamaException("Can't update variable");
}
} else {
throw new LamaException("Can't assign not to ref", this);
throw new LamaException("Can't put not to ref", this);
}
return LamaUnit.INSTANCE;
}

View file

@ -3,6 +3,7 @@ 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.FunctionDispatchNode;
import org.programsnail.truffle_lama.nodes.FunctionDispatchNodeGen;
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
public final class LamaCallNode extends LamaExpressionNode {
@ -15,10 +16,10 @@ public final class LamaCallNode extends LamaExpressionNode {
@Child
private FunctionDispatchNode dispatchNode;
public LamaCallNode(LamaExpressionNode targetFunction, LamaExpressionNode[] callArguments, FunctionDispatchNode dispatchNode) {
public LamaCallNode(LamaExpressionNode targetFunction, LamaExpressionNode[] callArguments) {
this.functionNode = targetFunction;
this.callArgumentNodes = callArguments;
this.dispatchNode = dispatchNode;
this.dispatchNode = FunctionDispatchNodeGen.create();
}
@Override

View file

@ -1,22 +0,0 @@
package org.programsnail.truffle_lama.nodes.expression;
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,12 +1,11 @@
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;
private final String name;
public LamaGlobalRefNode(String name) {
this.name = name;
@ -14,6 +13,6 @@ public final class LamaGlobalRefNode extends LamaExpressionNode {
@Override
public Object executeGeneric(VirtualFrame frame) {
return new LamaGlobalVarRef(this.name, this.currentLanguageContext());
return new LamaGlobalVarRef(this.name, this.currentLanguageContext()).get(frame);
}
}

View file

@ -8,6 +8,10 @@ import org.programsnail.truffle_lama.runtime.LamaUnit;
public final class LamaGlobalVarNode extends LamaExpressionNode {
String name;
public LamaGlobalVarNode(String name) {
this.name = name;
}
@Override
public Object executeGeneric(VirtualFrame frame) {
this.currentLanguageContext().globalScopeObject.newVariable(name, LamaUnit.INSTANCE, false);

View file

@ -1,5 +0,0 @@
package org.programsnail.truffle_lama.nodes.expression;
public final class LamaLeaveNode {
// TODO
}

View file

@ -19,7 +19,8 @@ public final class LamaLocalVarNode extends LamaExpressionNode {
@Override
public Object executeGeneric(VirtualFrame frame) {
frame.getFrameDescriptor().setSlotKind(this.frameSlot, FrameSlotKind.Object);
// NOTE: slot is already created in parser.NodeFactory
// frame.getFrameDescriptor().setSlotKind(this.frameSlot, FrameSlotKind.Object);
return LamaUnit.INSTANCE;
}
}

View file

@ -0,0 +1,26 @@
package org.programsnail.truffle_lama.nodes.expression;
import com.oracle.truffle.api.frame.VirtualFrame;
import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
import org.programsnail.truffle_lama.runtime.LamaException;
import org.programsnail.truffle_lama.runtime.LamaObjRef;
import org.programsnail.truffle_lama.runtime.LamaUnit;
public final class LamaUnrefNode extends LamaExpressionNode {
@Child
private LamaExpressionNode refNode;
public LamaUnrefNode(LamaExpressionNode refNode) {
this.refNode = refNode;
}
public Object executeGeneric(VirtualFrame frame) {
var refValue = refNode.executeGeneric(frame);
if (refValue instanceof LamaObjRef varRef) {
return varRef.get(frame);
}
throw new LamaException("Can't put not to ref", this);
}
}

View file

@ -224,11 +224,11 @@ postfix returns [List<LamaExpressionNode> args, Optional<LamaExpressionNode> acc
primary returns [LamaExpressionNode result]:
DECIMAL_LITERAL { $result = factory.createConstNode($DECIMAL_LITERAL); } // minus - inside decimal literal definition
| STRING_LITERAL { $result = factory.createStringNode(LamaStrings.convertStringLiteral($STRING_LITERAL)); }
| CHAR_LITERAL { $result = factory.createConstNode(LamaStrings.convertCharLiteral($CHAR_LITERAL)); }
| STRING_LITERAL { $result = factory.createStringNode($STRING_LITERAL); }
| CHAR_LITERAL { $result = factory.createCharConstNode($CHAR_LITERAL); }
| LIDENT { $result = factory.createRefNode($LIDENT); }
| 'true' { $result = factory.createConstNode(1); }
| 'false' { $result = factory.createConstNode(0); }
| tok='true' { $result = factory.createValueConstNode($tok, 1); }
| tok='false' { $result = factory.createValueConstNode($tok, 0); }
| 'infix' any_infix { $result = factory.createRefNode($any_infix.result); }
| 'fun' '(' function_arguments ')' function_body
{ $result = factory.createClosureNode($function_arguments.args, $function_body.result); } // TODO: scopes

View file

@ -1,7 +1,7 @@
package org.programsnail.truffle_lama.parser;
import com.oracle.truffle.api.RootCallTarget;
import com.oracle.truffle.api.frame.FrameDescriptor;
import com.oracle.truffle.api.frame.FrameSlotKind;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.strings.TruffleString;
import org.antlr.v4.runtime.Token;
@ -14,47 +14,251 @@ import org.programsnail.truffle_lama.nodes.controlflow.LamaIfNode;
import org.programsnail.truffle_lama.nodes.controlflow.LamaWhileNode;
import org.programsnail.truffle_lama.nodes.expression.*;
import org.programsnail.truffle_lama.nodes.pattern.*;
import org.programsnail.truffle_lama.runtime.LamaException;
import javax.print.attribute.standard.PresentationDirection;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
public class LamaNodeFactory {
static class LexicalScope {
protected final LexicalScope outer;
protected final Map<TruffleString, Integer> locals;
LexicalScope(LexicalScope outer) {
this.outer = outer;
this.locals = new HashMap<>();
static class FunctionData {
protected FrameDescriptor.Builder frameDescriptorBuilder;
protected Map<Integer, Integer> captureList;
protected Map<String, Integer> arguments;
public FunctionData() {
this.frameDescriptorBuilder = FrameDescriptor.newBuilder();
this.captureList = Map.of();
}
public Integer find(TruffleString name) {
public FrameDescriptor.Builder getFrameDescriptorBuilder() {
return frameDescriptorBuilder;
}
public Map<Integer, Integer> getCaptureList() {
return captureList;
}
public Map<String, Integer> getArguments() {
return arguments;
}
public FrameDescriptor buildFrameDescriptor() {
return this.frameDescriptorBuilder.build();
}
public Integer addArgument(String name) {
if (arguments.get(name) != null) {
throw new LamaException("Can't bind argument " + name + " more then once in one function");
}
int index = arguments.size();
return arguments.put(name, index);
}
public int findArgument(String name) {
return arguments.get(name);
}
public int getArgumentsCount() {
return arguments.size();
}
}
static class LexicalScope {
protected final LexicalScope outer;
protected final LexicalScope global;
protected final LexicalScope top;
protected final LexicalScope frame;
protected final boolean isTop;
protected final Map<String, Integer> locals;
FunctionData functionData;
public enum Kind {
INNER_SCOPE,
INNER_CLOSURE,
FUNCTION,
}
// outer scope == null -> global scope
// isTop - for independent lexical scopes separation (functions)
// isFramed - to separate scopes with capture possibility
public LexicalScope(LexicalScope outer, Kind kind) {
boolean isTop = kind == Kind.FUNCTION;
boolean isFramed = kind == Kind.INNER_CLOSURE || kind == Kind.FUNCTION;
// assert !isTop || isFramed;
this.outer = outer;
this.isTop = isTop;
this.locals = new HashMap<>();
this.global = outer == null ? this : outer;
this.top = isTop ? this : (outer == null ? null : outer.top);
this.frame = isFramed ? this : (outer == null ? null : outer.frame);
if (isFramed) {
functionData = new FunctionData();
}
}
public LexicalScope getOuter() {
return outer;
}
public LexicalScope getGlobal() {
return global;
}
public LexicalScope getTop() {
return top;
}
public LexicalScope getFrame() {
return frame;
}
public int getArgumentsCount() {
return frame.functionData.getArgumentsCount();
}
// ---
public FrameDescriptor buildFrameDescriptor() {
return functionData.buildFrameDescriptor();
}
// ---
public boolean isGlobal() {
return outer == null;
}
public boolean isFramed() {
return functionData != null;
}
// ---
public int addArgument(String name) {
if (!isFramed()) {
throw new LamaException("Can't add argument " + name + ": not in the function primary scope");
}
return frame.functionData.addArgument(name);
}
public int add(String name) {
int frameSlot = addSlot(name);
if (locals.get(name) != null) {
throw new LamaException("Can't bind name " + name + " more then once in one scope");
}
locals.put(name, frameSlot);
return frameSlot;
}
public int addToGlobal(String name) {
return global.add(name);
}
// NOTE: only for frame
protected int addWithCapture(String name, Integer capturedSlot) {
int frameSlot = add(name);
if (capturedSlot != null) {
functionData.getCaptureList().put(frameSlot, capturedSlot);
}
return frameSlot;
}
protected int addToFrameWithCapture(String name, Integer capturedSlot) {
if (frame == null) {
throw new LamaException("Can't bind name " + name + " at top scope: no frame scope available");
}
return frame.addWithCapture(name, capturedSlot);
}
public int addToFrame(String name) {
return addToFrameWithCapture(name, null);
}
public Integer capture(String name) {
if (isGlobal()) { // can't capture in global context
return null;
}
if (find(name) != null) {
throw new LamaException("Can't capture name " + name + ": name already is in function scope");
}
return captureNoCheck(name);
}
public Integer captureNoCheck(String name) {
Integer capturedSlot = frame.findNoCheck(name, true);
if (capturedSlot == null) {
return null;
}
return addToFrameWithCapture(name, capturedSlot);
}
// ---
public Integer findArgument(String name) {
return frame.functionData.findArgument(name);
}
public Integer findGlobal(String name) {
return global.findNoCheck(name, false);
}
public Integer find(String name) {
if (isGlobal()) { // global variables are not part of the local scope
return null;
}
return findNoCheck(name, false);
}
protected Integer findNoCheck(String name, boolean throughFrame) {
Integer result = locals.get(name);
if (result != null) {
return result;
} else if (outer != null) {
} else if (outer != null && !isTop && (!isFramed() || throughFrame)) {
return outer.find(name);
} else {
return null;
}
}
public Integer findOrCapture(String name) {
if (isGlobal()) { // global variables are not part of the local scope
return null;
}
Integer result = findNoCheck(name, false);
if (result == null) {
return captureNoCheck(name);
}
return result;
}
// ---
protected int addSlot(String name) {
if (isGlobal()) {
return 0; // no slots
}
if (frame == null) {
throw new LamaException("Can't add slot for name " + name + ": no frame scope available");
}
if (isFramed()) {
return outer.addSlot(name);
}
return functionData.getFrameDescriptorBuilder().addSlot(FrameSlotKind.Object, name, null);
}
}
/* State while parsing a source unit. */
private final Source source;
private final TruffleString sourceString;
// private final Map<TruffleString, RootCallTarget> allFunctions; // defined in scope
/* State while parsing a function. */
private int functionStartPos;
private TruffleString functionName;
private int functionBodyStartPos; // includes parameter list
private int argumentsCount;
private FrameDescriptor.Builder frameDescriptorBuilder;
private LamaExpressionNode functionBody;
/* State while parsing an expr. */
private LexicalScope lexicalScope;
@ -64,24 +268,38 @@ public class LamaNodeFactory {
this.language = language;
this.source = source;
this.sourceString = LamaStrings.fromJavaString(source.getCharacters().toString());
// this.allFunctions = new HashMap<>();
lexicalScope = new LexicalScope(null, LexicalScope.Kind.FUNCTION); // same to top level
}
// ---
public void enterScope() {
// TODO
public void enterScope(LexicalScope.Kind kind) {
lexicalScope = new LexicalScope(lexicalScope, kind);
}
public void exitScope() {
// TODO
lexicalScope = lexicalScope.getOuter();
}
// ---
public LamaExpressionNode defineFunction(String name, LamaExpressionNode[] args, LamaExpressionNode body) {
// TODO: set correct frame descriptor, scope, etc.
return null; // TODO
// TODO: add to parser
public void AddFunctionArguments(Token[] args) {
for (Token arg : args) {
lexicalScope.addArgument(arg.getText());
}
}
// TODO: FIXME: save captures into function
public LamaExpressionNode createClosureNode(Token beginToken, LamaExpressionNode body, int argsCount) {
return addSrcFromTokenAndNode(
new LamaLambdaNode(
body,
"",
lexicalScope.buildFrameDescriptor(),
lexicalScope.getArgumentsCount()),
beginToken,
body);
}
// ---
@ -93,7 +311,7 @@ public class LamaNodeFactory {
}
// TODO: use in grammar
public LamaExpressionNode createConstCharNode(Token token) {
public LamaExpressionNode createCharConstNode(Token token) {
return addSrcFromToken(new LamaConstNode(token.getText().charAt(1)), token); // TODO: special chars
}
@ -101,9 +319,29 @@ public class LamaNodeFactory {
return addSrcFromToken(new LamaConstNode(Long.parseLong(token.getText())), token);
}
public LamaExpressionNode createVarNode(String name, LamaExpressionNode value) {
// TODO: register id in current frame descriptor
return null; // TODO
public LamaExpressionNode createValueConstNode(Token token, long value) {
return addSrcFromToken(new LamaConstNode(value), token);
}
public LamaExpressionNode createVarNode(Token token) {
String name = token.getText();
int slot = lexicalScope.add(name); // TODO: check if not arg ??
return addSrcFromToken(lexicalScope.isGlobal() /*global scope*/
? new LamaGlobalVarNode(name)
: new LamaLocalVarNode(slot), token);
}
public LamaExpressionNode createAssignNode(LamaExpressionNode left, LamaExpressionNode right) {
return addSrcFromNodes(new LamaAssignNode(left, right), left, right);
}
// TODO: fix assignment in parser (var + ref + put ??)
public LamaExpressionNode createAssignVarNode(Token token, LamaExpressionNode value) {
var definition = createVarNode(token);
var reference = createRefNode(token);
var assignment = createAssignNode(reference, value);
return createSeqNode(definition, assignment);
}
public LamaExpressionNode createSeqNode(LamaExpressionNode left, LamaExpressionNode right) {
@ -115,25 +353,41 @@ public class LamaNodeFactory {
}
// TODO: decide Elem or ElemRef
public LamaExpressionNode createElemNode(LamaExpressionNode array, LamaExpressionNode index) {
return addSrcFromNodes(LamaElemNodeGen.create(array, index), array, index);
public LamaExpressionNode createElemRefOrValueNode(LamaExpressionNode array, LamaExpressionNode index, boolean doUnref) {
return addUnref(createElemRefNode(array, index), doUnref);
}
public LamaExpressionNode createElemRefNode(LamaExpressionNode array, LamaExpressionNode index) {
return addSrcFromNodes(LamaElemRefNodeGen.create(array, index), array, index);
}
public LamaExpressionNode createCallNode(LamaExpressionNode func, LamaExpressionNode[] args) {
// TODO: find function in local / global vars
return null; // TODO
return addSrcFromNodes(new LamaCallNode(func, args), func, args.length > 0 ? args[args.length - 1] : func);
}
public LamaExpressionNode createRefNode(String name) {
// TODO: find var in local / global vars
return null; // TODO
public LamaExpressionNode createRefOrValueNode(Token token, boolean doUnref) {
return addUnref(createRefNode(token), doUnref);
}
public LamaExpressionNode createClosureNode(LamaExpressionNode[] args, LamaExpressionNode body) {
// TODO: build frame descriptor from body
// TODO: set correct frame descriptor, scope, etc.
// return new LamaLambdaNode(body, "", /**/, args);
return null; // TODO
public LamaExpressionNode createRefNode(Token token) {
String name = token.getText();
Integer slot = lexicalScope.find(name); // globals => null, check inside
if (slot != null) {
return addSrcFromToken(new LamaLocalRefNode(slot), token);
}
slot = lexicalScope.findArgument(name);
if (slot != null) {
return addSrcFromToken(new LamaArgumentRefNode(slot), token);
}
slot = lexicalScope.captureNoCheck(name);
if (slot != null) {
return addSrcFromToken(new LamaLocalRefNode(slot), token);
}
return addSrcFromToken(new LamaGlobalRefNode(name), token);
}
public LamaExpressionNode createSkipNode(Token token) {
@ -200,11 +454,10 @@ public class LamaNodeFactory {
return result;
}
// TODO: fix name pattern: add possibility of associated pattern
public LamaPattern createNamedPattern(TruffleString name, LamaPattern pattern) {
// TODO: register frame descriptor id
// return new LamaNamedPattern(/*id*/, pattern);
return null; // TODO
public LamaPattern createNamedPattern(Token token, LamaPattern pattern) {
String name = token.getText();
int frameSlot = lexicalScope.add(name);
return new LamaNamedPattern(frameSlot, pattern);
}
public LamaPattern createConstPattern(Token token) {
@ -250,12 +503,35 @@ public class LamaNodeFactory {
return node;
}
private static LamaExpressionNode addSrcFromTokenAndNode(LamaExpressionNode node, Token begin, LamaExpressionNode end) {
int beginIndex = begin.getStartIndex();
node.setSourceSection(beginIndex, end.getSourceEndIndex() - beginIndex);
return node;
}
private static LamaExpressionNode addSrcFromNodeAndToken(LamaExpressionNode node, LamaExpressionNode begin, Token end) {
int beginIndex = begin.getSourceCharIndex();
node.setSourceSection(beginIndex, end.getStopIndex() - beginIndex);
return node;
}
private static LamaExpressionNode addSrcFromNodes(LamaExpressionNode node, LamaExpressionNode begin, LamaExpressionNode end) {
int beginIndex = begin.getSourceCharIndex();
node.setSourceSection(beginIndex, end.getSourceEndIndex() - beginIndex);
return node;
}
private static LamaExpressionNode addSrcFromNode(LamaExpressionNode node, LamaExpressionNode other) {
node.setSourceSection(other.getSourceCharIndex(), other.getSourceLength());
return node;
}
// ---
private static LamaExpressionNode addUnref(LamaExpressionNode node, boolean doUnref) {
return doUnref ? addSrcFromNode(new LamaUnrefNode(node), node) : node;
}
// ---
public LamaExpressionNode getRootExpr() {

View file

@ -0,0 +1,22 @@
package org.programsnail.truffle_lama.runtime;
import com.oracle.truffle.api.frame.VirtualFrame;
public final class LamaArgumentRef extends LamaObjRef {
private int index;
public LamaArgumentRef(int id) {
this.index = id;
}
@Override
public Object get(VirtualFrame frame) {
return frame.getArguments()[index];
}
@Override
public boolean put(Object object, VirtualFrame frame) {
frame.getArguments()[index] = object;
return true;
}
}

View file

@ -12,7 +12,12 @@ public class LamaElemRef extends LamaObjRef {
}
@Override
public boolean assign(Object object, VirtualFrame frame) {
public Object get(VirtualFrame frame) {
return array.readAt(id);
}
@Override
public boolean put(Object object, VirtualFrame frame) {
return array.assignAt(id, object);
}
}

View file

@ -17,7 +17,12 @@ public final class LamaGlobalVarRef extends LamaObjRef {
}
@Override
public boolean assign(Object object, VirtualFrame frame) {
public Object get(VirtualFrame frame) {
return this.context.globalScopeObject.getVariable(name);
}
@Override
public boolean put(Object object, VirtualFrame frame) {
return this.context.globalScopeObject.updateVariable(name, object);
}
}

View file

@ -10,7 +10,12 @@ public final class LamaLocalVarRef extends LamaObjRef {
}
@Override
public boolean assign(Object object, VirtualFrame frame) {
public Object get(VirtualFrame frame) {
return frame.getObject(id);
}
@Override
public boolean put(Object object, VirtualFrame frame) {
frame.setObject(id, object);
return true;
}

View file

@ -3,5 +3,7 @@ package org.programsnail.truffle_lama.runtime;
import com.oracle.truffle.api.frame.VirtualFrame;
public abstract class LamaObjRef {
public abstract boolean assign(Object object, VirtualFrame frame);
public abstract Object get(VirtualFrame frame);
public abstract boolean put(Object object, VirtualFrame frame);
}