Skip to content
Snippets Groups Projects
Commit bbab2322 authored by Lukas Stadler's avatar Lukas Stadler
Browse files

throw better error messages for invalid LHS in replacement

parent 29f7565a
Branches
No related tags found
No related merge requests found
......@@ -58,6 +58,7 @@ import com.oracle.truffle.r.runtime.RInternalError;
import com.oracle.truffle.r.runtime.RRuntime;
import com.oracle.truffle.r.runtime.builtins.FastPathFactory;
import com.oracle.truffle.r.runtime.data.REmpty;
import com.oracle.truffle.r.runtime.data.RNull;
import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor;
import com.oracle.truffle.r.runtime.nodes.EvaluatedArgumentsVisitor;
import com.oracle.truffle.r.runtime.nodes.RCodeBuilder;
......@@ -287,15 +288,18 @@ public final class RASTBuilder implements RCodeBuilder<RSyntaxNode> {
RSyntaxElement current = lhs;
while (!(current instanceof RSyntaxLookup)) {
if (!(current instanceof RSyntaxCall)) {
throw RError.error(RError.NO_CALLER, RError.Message.NON_LANG_ASSIGNMENT_TARGET);
if (current instanceof RSyntaxConstant && ((RSyntaxConstant) current).getValue() == RNull.instance) {
throw RError.error(RError.NO_CALLER, RError.Message.INVALID_LHS, "NULL");
} else {
throw RError.error(RError.NO_CALLER, RError.Message.NON_LANG_ASSIGNMENT_TARGET);
}
}
RSyntaxCall call = (RSyntaxCall) current;
calls.add(call);
RSyntaxElement syntaxLHS = call.getSyntaxLHS();
if (call.getSyntaxArguments().length == 0 || !(syntaxLHS instanceof RSyntaxLookup || isNamespaceLookupCall(syntaxLHS))) {
// TODO: this should only be signaled when run, not when parsed
throw RInternalError.unimplemented("proper error message for RError.INVALID_LHS");
return new ReplacementNode.LHSError(source, operator, new RSyntaxElement[]{lhs, rhs});
}
current = call.getSyntaxArguments()[0];
}
......
......@@ -24,6 +24,7 @@ package com.oracle.truffle.r.nodes.control;
import java.util.List;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.source.SourceSection;
......@@ -31,6 +32,8 @@ import com.oracle.truffle.r.nodes.access.RemoveAndAnswerNode;
import com.oracle.truffle.r.nodes.access.WriteVariableNode;
import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode;
import com.oracle.truffle.r.runtime.ArgumentsSignature;
import com.oracle.truffle.r.runtime.RError;
import com.oracle.truffle.r.runtime.RError.Message;
import com.oracle.truffle.r.runtime.nodes.RNode;
import com.oracle.truffle.r.runtime.nodes.RSourceSectionNode;
import com.oracle.truffle.r.runtime.nodes.RSyntaxCall;
......@@ -119,4 +122,41 @@ public final class ReplacementNode extends RSourceSectionNode implements RSyntax
public ArgumentsSignature getSyntaxSignature() {
return ArgumentsSignature.empty(2);
}
/**
* Used by the parser for assignments that miss a left hand side. This node will raise an error
* once executed.
*/
public static final class LHSError extends RSourceSectionNode implements RSyntaxNode, RSyntaxCall {
private final String operator;
private final RSyntaxElement[] arguments;
public LHSError(SourceSection sourceSection, String operator, RSyntaxElement[] arguments) {
super(sourceSection);
this.operator = operator;
this.arguments = arguments;
}
@Override
public Object execute(VirtualFrame frame) {
CompilerDirectives.transferToInterpreter();
throw RError.error(this, Message.INVALID_LHS, "NULL");
}
@Override
public RSyntaxElement getSyntaxLHS() {
return RSyntaxLookup.createDummyLookup(null, operator, true);
}
@Override
public RSyntaxElement[] getSyntaxArguments() {
return arguments;
}
@Override
public ArgumentsSignature getSyntaxSignature() {
return ArgumentsSignature.empty(2);
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment