public void Visit(SwitchStmt switchStmt, object[] args) { RightValue value = exprProcessor.Eval(switchStmt.Expression); if (value is FloatConst) { kernel.IssueWarning(new Error(ErrorType.EqualOnFloat, switchStmt.Location)); } foreach (SwitchCase switchCase in switchStmt.SwitchCaseList) { if (!(value is FloatConst) && switchCase.Value is FloatConst) { kernel.IssueWarning(new Error(ErrorType.EqualOnFloat, switchCase.Location)); } if (switchCase.Value == null || switchCase.Value.IsEqualValueTo(value)) { kernel.RuntimeData.ScopeStack.Open(new LocalScope()); kernel.RuntimeData.InstructionStack.Push(InstructionStack.CLOSE_LOCAL_SCOPE_FLAG); kernel.RuntimeData.InstructionStack.Push(switchCase.CaseContent); break; } } kernel.Next(); }
public override void Visit(SwitchStmt n) { foreach (AST ast in n.stmt_list) { ast.accept(this); } }
public override void Visit(SwitchStmt n) { emit($"switch( {n.id} )" + "{\n"); foreach (AST ast in n.stmt_list) { ast.accept(this); } emit("}\n"); }
public virtual bool VisitSwitchStmt(SwitchStmt stmt) { if (!VisitStmt(stmt)) { return(false); } return(true); }
public override void VisitSwitchStmt(SwitchStmt x) { // switch(VALUE){CASES} ConsumeToken(Tokens.T_SWITCH, "switch", x.Span.Start); // TODO: ENDSWITCH or { } ConsumeToken(Tokens.T_LPAREN, "("); VisitElement(x.SwitchValue); ConsumeToken(Tokens.T_RPAREN, ")"); ConsumeToken(Tokens.T_LBRACE, "{"); VisitList(x.SwitchItems); ConsumeToken(Tokens.T_RBRACE, "}"); }
override public void VisitSwitchStmt(SwitchStmt x) { _serializer.StartSerialize(typeof(SwitchStmt).Name, SerializeSpan(x.Span)); _serializer.StartSerialize("SwitchValue"); VisitElement(x.SwitchValue); _serializer.EndSerialize(); _serializer.StartSerialize("SwitchItems"); foreach (SwitchItem item in x.SwitchItems) { VisitElement(item); } _serializer.EndSerialize(); _serializer.EndSerialize(); }
public override void VisitSwitchStmt(SwitchStmt x) { var items = x.SwitchItems; if (items == null || items.Length == 0) { return; } var end = NewBlock(); bool hasDefault = false; var cases = new List <CaseBlock>(items.Length); for (int i = 0; i < items.Length; i++) { cases.Add(NewBlock(items[i])); hasDefault |= (items[i] is DefaultItem); } if (!hasDefault) { // create implicit default: cases.Add(NewBlock(new DefaultItem(x.Span, EmptyArray <Statement> .Instance))); } // SwitchEdge // Connects _current to cases var edge = new SwitchEdge(_current, _binder.BindExpression(x.SwitchValue, BoundAccess.Read), cases.ToArray(), end); _current = WithNewOrdinal(cases[0]); OpenBreakScope(end, end); // NOTE: inside switch, Continue ~ Break for (int i = 0; i < cases.Count; i++) { OpenScope(_current); if (i < items.Length) { items[i].Statements.ForEach(VisitElement); // any break will connect block to end } CloseScope(); _current = WithNewOrdinal(Connect(_current, (i == cases.Count - 1) ? end : cases[i + 1])); } CloseBreakScope(); Debug.Assert(_current == end); }
public void Visit(SwitchStmt switchStmt, object[] args) { reader.MoveToAttribute("expr"); switchStmt.Expression = exprParser.ParseExpr(reader.Value, new Location(file, reader.LineNumber, reader.LinePosition).Offset(6)); switchStmt.SwitchCaseList = new List <SwitchCase>(); while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element) { SwitchCase switchCase = new SwitchCase(); switchCase.Parent = switchStmt; switchCase.Location = new Location(file, reader.LineNumber, reader.LinePosition); switchCase.Accept(this); switchStmt.SwitchCaseList.Add(switchCase); } else if (reader.NodeType == XmlNodeType.EndElement) { break; } } }
public bool VisitSwitchStmt(SwitchStmt stmt) { throw new NotImplementedException(); }
/// <summary> /// Visit switch value and switch items. /// </summary> /// <param name="x"></param> virtual public void VisitSwitchStmt(SwitchStmt x) { VisitElement(x.SwitchValue); VisitList(x.SwitchItems); }
public override void VisitSwitchStmt(SwitchStmt x) { var items = x.SwitchItems; if (items == null || items.Length == 0) { return; } // get bound item for switch value & connect potential pre-switch-value blocks var boundBagForSwitchValue = _binder.BindWholeExpression(x.SwitchValue, BoundAccess.Read); ConnectBoundItemsBagBlocksToCurrentBlock(boundBagForSwitchValue); var switchValue = boundBagForSwitchValue.BoundElement; var end = NewBlock(); bool hasDefault = false; var cases = new List <CaseBlock>(items.Length); for (int i = 0; i < items.Length; i++) { cases.Add(NewBlock(items[i])); hasDefault |= (items[i] is DefaultItem); } if (!hasDefault) { // create implicit default: cases.Add(NewBlock(new DefaultItem(x.Span, EmptyArray <Statement> .Instance))); } // if switch value isn't a constant & there're case values with preBoundStatements // -> the switch value might get evaluated multiple times (see SwitchEdge.Generate) -> preemptively evaluate and cache it if (!switchValue.IsConstant() && !cases.All(c => c.CaseValue.IsOnlyBoundElement)) { var result = GeneratorSemanticsBinder.CreateAndAssignSynthesizedVariable(switchValue, BoundAccess.Read, $"<switchValueCacher>{x.Span}"); switchValue = result.BoundExpr; _current.Add(new BoundExpressionStatement(result.Assignment)); } // SwitchEdge // Connects _current to cases var edge = new SwitchEdge(_current, switchValue, cases.ToArray(), end); _current = WithNewOrdinal(cases[0]); OpenBreakScope(end, end); // NOTE: inside switch, Continue ~ Break for (int i = 0; i < cases.Count; i++) { OpenScope(_current); if (i < items.Length) { items[i].Statements.ForEach(VisitElement); // any break will connect block to end } CloseScope(); _current = WithNewOrdinal(Connect(_current, (i == cases.Count - 1) ? end : cases[i + 1])); } CloseBreakScope(); Debug.Assert(_current == end); }
public void Visit(SwitchStmt switchStmt, object[] args) { throw new NotImplementedException(); }
/// <summary> /// Visits switch statement and builds controlflow graf for switch construct. /// /// </summary> /// <param name="x">SwitchStmt</param> public override void VisitSwitchStmt(SwitchStmt x) { var aboveCurrentCaseBlock = currentBasicBlock; BasicBlock lastDefaultStartBlock = null; BasicBlock lastDefaultEndBlock = null; currentBasicBlock = new BasicBlock(); //in case of switch statement, continue and break means the same so we make the edge always to the block under the switch BasicBlock underLoop = new BasicBlock(); loopData.Push(new LoopData(underLoop, underLoop)); aboveCurrentCaseBlock.CreateWorklistSegment(underLoop); for (int j = 0; j < x.SwitchItems.Count; j++) { var switchItem = x.SwitchItems[j]; var caseItem = switchItem as CaseItem; // The basic block corresponding to current switch item var switchBlock = new BasicBlock(); // Connect previous switch item (implicitly, subsequent switch items are connected - break must // be there to force the flow to not go to subsequent switch item) if (j > 0) { BasicBlockEdge.ConnectDirectEdge(currentBasicBlock, switchBlock); } if (caseItem == null) { // Default branch // Just mark the last default branch lastDefaultStartBlock = switchBlock; } else { // Case branch // Create condition of the current case branch BinaryEx condition = new BinaryEx(caseItem.CaseVal.Position, Operations.Equal, x.SwitchValue, caseItem.CaseVal); graph.cfgAddedElements.Add(condition); // Create conditional branching: true condition goes to the case, else condition goes above the next switch item var elseBlock = new BasicBlock(); BasicBlockEdge.ConnectConditionalBranching(condition, aboveCurrentCaseBlock, switchBlock, elseBlock); aboveCurrentCaseBlock = elseBlock; } // Builds CFG for the body of the switch element currentBasicBlock = switchBlock; switchItem.VisitMe(this); if (caseItem == null) { // Just to mark the last default branch lastDefaultEndBlock = currentBasicBlock; } } loopData.Pop(); if (lastDefaultStartBlock == null) // No default branch { // Connect the last case with the code under the switch BasicBlockEdge.ConnectDirectEdge(currentBasicBlock, underLoop); // Connect the else of the last case with the code under the switch BasicBlockEdge.ConnectDirectEdge(aboveCurrentCaseBlock, underLoop); } else // There is default branch { // The last default branch is the else of the last case BasicBlockEdge.ConnectDirectEdge(aboveCurrentCaseBlock, lastDefaultStartBlock); if (lastDefaultEndBlock.DefaultBranch == null) // break/continue in the default branch // Connect it with the code under the swithch { BasicBlockEdge.ConnectDirectEdge(lastDefaultEndBlock, underLoop); } else // no break/continue in the default branch // Connect the last case with the code under the switch { BasicBlockEdge.ConnectDirectEdge(currentBasicBlock, underLoop); } } currentBasicBlock = underLoop; }
private void visitMainContent(ASTNode parent, List <Statement> content) { bool endWithBr = false; while (reader.Read()) { reader.MoveToContent(); Location location = new Location(file, reader.LineNumber, reader.LinePosition); switch (reader.NodeType) { case XmlNodeType.Text: string text = reader.Value; string[] lines = text.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); foreach (string line in lines) { string trimed = line.Trim(); if (trimed.Length == 0) { continue; } if (endWithBr && content.Count > 0 && content[content.Count - 1] is DialogStmt) { DialogStmt dialog = content[content.Count - 1] as DialogStmt; dialog.Text += Environment.NewLine + trimed; } else { DialogStmt dialog = new DialogStmt(); dialog.Parent = parent; dialog.Location = location; dialog.Text = trimed; content.Add(dialog); } endWithBr = false; } break; case XmlNodeType.Element: Statement statement = null; switch (dic[reader.Name]) { case "br": endWithBr = true; continue; case "expr": statement = new ExpressionStmt(); break; case "return": statement = new ReturnStmt(); break; case "include": statement = new IncludeStmt(); break; case "actor": statement = new ActorStmt(); break; case "bg": statement = new BackgroundStmt(); break; case "echo": statement = new EchoStmt(); break; case "select": statement = new SelectStmt(); break; case "selectWithValue": statement = new SelectStmt(); break; case "if": statement = new IfStmt(); break; case "else": return; case "elseif": return; case "switch": statement = new SwitchStmt(); break; case "break": statement = new BreakStmt(); break; case "continue": statement = new ContinueStmt(); break; case "loop": statement = new LoopStmt(); break; case "music": statement = new MusicStmt(); break; case "musicStop": statement = new MusicStopStmt(); break; case "musicVol": statement = new MusicVolStmt(); break; default: statement = new FunctionCallStmt(); break; } statement.Parent = parent; statement.Location = location; statement.Accept(this); content.Add(statement); break; case XmlNodeType.EndElement: //reader.Read(); //MainContent结束 return; } } }