Skip to content

Commit

Permalink
Try to fix return and block passing mixup after it has been parsed - f…
Browse files Browse the repository at this point in the history
…ixes #305.
  • Loading branch information
chrisseaton committed Oct 2, 2014
1 parent 1c35453 commit 39c9ca5
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 8 deletions.
19 changes: 14 additions & 5 deletions core/src/main/java/org/jruby/parser/RubyParser.java
Expand Up @@ -44,6 +44,7 @@
import org.jruby.ast.BlockNode;
import org.jruby.ast.BlockPassNode;
import org.jruby.ast.BreakNode;
import org.jruby.ast.CallNode;
import org.jruby.ast.ClassNode;
import org.jruby.ast.ClassVarNode;
import org.jruby.ast.ClassVarAsgnNode;
Expand Down Expand Up @@ -146,7 +147,7 @@ public void setWarnings(IRubyWarnings warnings) {
support.setWarnings(warnings);
lexer.setWarnings(warnings);
}
// line 150 "-"
// line 151 "-"
// %token constants
public static final int kCLASS = 257;
public static final int kMODULE = 258;
Expand Down Expand Up @@ -4048,8 +4049,16 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
if (((Node)yyVals[-1+yyTop]) instanceof BlockAcceptingNode && ((BlockAcceptingNode)yyVals[-1+yyTop]).getIterNode() instanceof BlockPassNode) {
throw new SyntaxException(PID.BLOCK_ARG_AND_BLOCK_GIVEN, ((Node)yyVals[-1+yyTop]).getPosition(), lexer.getCurrentLine(), "Both block arg and actual block given.");
}
if (((Node)yyVals[-1+yyTop]) instanceof NonLocalControlFlowNode) {
yyVal = ((BlockAcceptingNode) ((NonLocalControlFlowNode)yyVals[-1+yyTop]).getValueNode()).setIterNode(((IterNode)yyVals[0+yyTop]));
if (yyVal instanceof IterNode
&& ((Node)yyVals[-1+yyTop]) instanceof ReturnNode
&& ((ReturnNode)yyVals[-1+yyTop]).getValueNode() instanceof BlockAcceptingNode) {
final IterNode iterNode = ((IterNode)yyVal);
final ReturnNode returnNode = ((ReturnNode)yyVals[-1+yyTop]);
final BlockAcceptingNode blockAcceptingNode = (BlockAcceptingNode) returnNode.getValueNode();
blockAcceptingNode.setIterNode(iterNode);
yyVal = returnNode;
} else if (((Node)yyVals[-1+yyTop]) instanceof NonLocalControlFlowNode) {
yyVal = ((BlockAcceptingNode) ((NonLocalControlFlowNode)yyVals[-1+yyTop]).getValueNode()).setIterNode(((IterNode)yyVals[0+yyTop]));
} else {
yyVal = ((BlockAcceptingNode)yyVals[-1+yyTop]).setIterNode(((IterNode)yyVals[0+yyTop]));
}
Expand Down Expand Up @@ -5198,7 +5207,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
}
};
}
// line 2480 "RubyParser.y"
// line 2489 "RubyParser.y"

/** The parse method use an lexer stream and parse it to an AST node
* structure
Expand All @@ -5217,4 +5226,4 @@ public RubyParserResult parse(ParserConfiguration configuration, LexerSource sou
return support.getResult();
}
}
// line 9614 "-"
// line 9623 "-"
13 changes: 11 additions & 2 deletions core/src/main/java/org/jruby/parser/RubyParser.y
Expand Up @@ -41,6 +41,7 @@ import org.jruby.ast.BlockArgNode;
import org.jruby.ast.BlockNode;
import org.jruby.ast.BlockPassNode;
import org.jruby.ast.BreakNode;
import org.jruby.ast.CallNode;
import org.jruby.ast.ClassNode;
import org.jruby.ast.ClassVarNode;
import org.jruby.ast.ClassVarAsgnNode;
Expand Down Expand Up @@ -1730,8 +1731,16 @@ block_call : command do_block {
if ($1 instanceof BlockAcceptingNode && $<BlockAcceptingNode>1.getIterNode() instanceof BlockPassNode) {
throw new SyntaxException(PID.BLOCK_ARG_AND_BLOCK_GIVEN, $1.getPosition(), lexer.getCurrentLine(), "Both block arg and actual block given.");
}
if ($1 instanceof NonLocalControlFlowNode) {
$$ = ((BlockAcceptingNode) $<NonLocalControlFlowNode>1.getValueNode()).setIterNode($2);
if ($$ instanceof IterNode
&& $1 instanceof ReturnNode
&& $<ReturnNode>1.getValueNode() instanceof BlockAcceptingNode) {
final IterNode iterNode = $<IterNode>$;
final ReturnNode returnNode = $<ReturnNode>1;
final BlockAcceptingNode blockAcceptingNode = (BlockAcceptingNode) returnNode.getValueNode();
blockAcceptingNode.setIterNode(iterNode);
$$ = returnNode;
} else if ($1 instanceof NonLocalControlFlowNode) {
$$ = ((BlockAcceptingNode) $<NonLocalControlFlowNode>1.getValueNode()).setIterNode($2);
} else {
$$ = $<BlockAcceptingNode>1.setIterNode($2);
}
Expand Down
1 change: 0 additions & 1 deletion spec/tags/ruby/language/return_tags.txt
@@ -1,2 +1 @@
fails:The return keyword within define_method stops at the method when the return is used directly
fails:The return keyword invoked with a method call without parentheses with a block returns the value returned from the method call

0 comments on commit 39c9ca5

Please sign in to comment.