mirror of
https://codeberg.org/ProgramSnail/truffle-lama.git
synced 2025-12-05 22:38:43 +00:00
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:
parent
587e733f52
commit
91505d247b
19 changed files with 438 additions and 105 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ public abstract class LamaExpressionNode extends Node {
|
|||
return LamaContext.get(this);
|
||||
}
|
||||
|
||||
|
||||
public abstract Object executeGeneric(VirtualFrame frame);
|
||||
|
||||
// ---
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
package org.programsnail.truffle_lama.nodes.expression;
|
||||
|
||||
public final class LamaLeaveNode {
|
||||
// TODO
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue