public override void VisitJumpStmt(JumpStmt x) { if (x.Type == JumpStmt.Types.Return) { Add(x); Connect(_current, this.Exit); } else if (x.Type == JumpStmt.Types.Break || x.Type == JumpStmt.Types.Continue) { int level = (x.Expression is LongIntLiteral) ? (int)((LongIntLiteral)x.Expression).Value : 1; var brk = GetBreakScope(level); var target = (x.Type == JumpStmt.Types.Break) ? brk.BreakTarget : brk.ContinueTarget; if (target != null) { Connect(_current, target); _current.NextEdge.PhpSyntax = x; } else { throw new InvalidOperationException(); // TODO: ErrCode //Connect(_current, this.GetExceptionBlock()); // unreachable // fatal error in PHP } } else { throw new InvalidOperationException(); } _current = NewDeadBlock(); // anything after these statements is unreachable }
public override void VisitJumpStmt(JumpStmt x) { if (x.Type == JumpStmt.Types.Return) { Add(x); Connect(_current, this.Exit); } else if (x.Type == JumpStmt.Types.Break || x.Type == JumpStmt.Types.Continue) { int level = (x.Expression is LongIntLiteral) ? (int)((LongIntLiteral)x.Expression).Value : 1; var brk = GetBreakScope(level); var target = (x.Type == JumpStmt.Types.Break) ? brk.BreakTarget : brk.ContinueTarget; if (target != null) { Connect(_current, target); _current.NextEdge.PhpSyntax = x; } else { // fatal error in PHP: _binder.Diagnostics.Add(_binder.Routine, x, Errors.ErrorCode.ERR_NeedsLoopOrSwitch, x.Type.ToString().ToLowerInvariant()); Connect(_current, this.GetExceptionBlock()); // unreachable, wouldn't compile } } else { throw Peachpie.CodeAnalysis.Utilities.ExceptionUtilities.UnexpectedValue(x.Type); } _current = NewDeadBlock(); // anything after these statements is unreachable }
override public void VisitJumpStmt(JumpStmt x) { _serializer.StartSerialize(typeof(JumpStmt).Name, SerializeSpan(x.Span), new NodeObj("Type", x.Type.ToString())); base.VisitJumpStmt(x); _serializer.EndSerialize(); }
/// <summary> /// JumpStmt /// (CONTINUE | BREAK | RETURN (ListExpr)?) SEMICOLON /// </summary> /// <returns></returns> private JumpStmt ParseJumpStmt() { JumpStmt ret = new JumpStmt(); Token t = Consume(TokenType.CONTINUE, TokenType.BREAK, TokenType.RETURN); switch (t.Type) { case TokenType.CONTINUE: ret.Type = JumpType.CONTINUE; break; case TokenType.BREAK: ret.Type = JumpType.BREAK; break; case TokenType.RETURN: ret.Type = JumpType.RETURN; if (!Check(TokenType.SEMICOLON)) { ret.ReturnVal = ParseExprList(); } break; default: break; // 不会执行到这里 } Consume(TokenType.SEMICOLON); return(ret); }
public override void VisitJumpStmt(JumpStmt x) { if (x.Type == JumpStmt.Types.Return && x.Expression != null) { AddVar(new VariableName(SourceReturnSymbol.SpecialName), x.Span, VariableKind.ReturnVariable, x.Expression); } base.VisitJumpStmt(x); }
public override void VisitJumpStmt(JumpStmt x) { switch (x.Type) { case JumpStmt.Types.Return: ConsumeToken(Tokens.T_RETURN, "return", x.Span.Start); break; case JumpStmt.Types.Continue: ConsumeToken(Tokens.T_CONTINUE, "continue", x.Span.Start); break; case JumpStmt.Types.Break: ConsumeToken(Tokens.T_BREAK, "break", x.Span.Start); break; } VisitElement(x.Expression); ConsumeToken(Tokens.T_SEMI, ";", x.Span.End - 1); }
virtual public void VisitJumpStmt(JumpStmt x) { VisitElement(x.Expression); }
internal JumpStmtPoint(ValuePoint expression, JumpStmt jmp) { Jump = jmp; Expression = expression; }
/// <inheritdoc /> public override void VisitJumpStmt(JumpStmt x) { var expression = CreateRValue(x.Expression); Result(new JumpStmtPoint(expression, x)); }
public override void VisitJumpStmt(JumpStmt x) { // Force traversing VisitElement(x.Expression); }
/// <summary> /// Visits JumpStmt (break, continue, return). /// </summary> /// <param name="x">JumpStmt</param> public override void VisitJumpStmt(JumpStmt x) { switch (x.Type) { case JumpStmt.Types.Break: case JumpStmt.Types.Continue: if (x.Expression == null) //break without saying how many loops to break { BasicBlock target; //break/continue if (loopData.Count == 0) { if (x.Type == JumpStmt.Types.Break) { throw new ControlFlowException(ControlFlowExceptionCause.BREAK_NOT_IN_CYCLE, x.Position); } else { throw new ControlFlowException(ControlFlowExceptionCause.CONTINUE_NOT_IN_CYCLE, x.Position); } } if (x.Type == JumpStmt.Types.Break) { target = loopData.Peek().BreakTarget; } else { target = loopData.Peek().ContinueTarget; } BasicBlockEdge.ConnectDirectEdge(currentBasicBlock, target); } else { int breakValue = 1; for (int i = loopData.Count - 1; i >= 0; --i) { BasicBlock target; if (x.Type == JumpStmt.Types.Break) { target = loopData.ElementAt(i).BreakTarget; } else { target = loopData.ElementAt(i).ContinueTarget; } BinaryEx condition = new BinaryEx(x.Position, Operations.Equal, new IntLiteral(Position.Invalid, breakValue), x.Expression); graph.cfgAddedElements.Add(condition); BasicBlockEdge.ConnectConditionalBranching(condition, currentBasicBlock, target, new BasicBlock()); //BasicBlockEdge.AddConditionalEdge(currentBasicBlock, target, condition); ++breakValue; } } break; case JumpStmt.Types.Return: PHP.Core.Debug.Assert(functionSinkStack.Count > 0); currentBasicBlock.AddElement(x); BasicBlockEdge.ConnectDirectEdge(currentBasicBlock, functionSinkStack.Peek()); currentBasicBlock = new BasicBlock(); break; } currentBasicBlock = new BasicBlock(); }
private static ReturnExpression ToReturnExpression(JumpStmt e) { return(new ReturnExpression(Parse(e.Expression))); }
private static ContinueExpression ToContinueExpression(JumpStmt e) { return(new ContinueExpression(Parse(e.Expression))); }
private static BreakExpression ToBreakExpression(JumpStmt e) { return(new BreakExpression(Parse(e.Expression))); }