Beispiel #1
0
        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();
        }
Beispiel #2
0
 public override void Visit(SwitchStmt n)
 {
     foreach (AST ast in n.stmt_list)
     {
         ast.accept(this);
     }
 }
Beispiel #3
0
 public override void Visit(SwitchStmt n)
 {
     emit($"switch( {n.id} )" + "{\n");
     foreach (AST ast in n.stmt_list)
     {
         ast.accept(this);
     }
     emit("}\n");
 }
Beispiel #4
0
        public virtual bool VisitSwitchStmt(SwitchStmt stmt)
        {
            if (!VisitStmt(stmt))
            {
                return(false);
            }

            return(true);
        }
Beispiel #5
0
 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, "}");
 }
Beispiel #6
0
 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();
 }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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;
                }
            }
        }
Beispiel #9
0
 public bool VisitSwitchStmt(SwitchStmt stmt)
 {
     throw new NotImplementedException();
 }
Beispiel #10
0
 /// <summary>
 /// Visit switch value and switch items.
 /// </summary>
 /// <param name="x"></param>
 virtual public void VisitSwitchStmt(SwitchStmt x)
 {
     VisitElement(x.SwitchValue);
     VisitList(x.SwitchItems);
 }
Beispiel #11
0
        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();
 }
Beispiel #13
0
        /// <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;
        }
Beispiel #14
0
        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;
                }
            }
        }