Ejemplo n.º 1
0
        public void VisitProcStatementSwitch(DMASTProcStatementSwitch statementSwitch)
        {
            SimplifyExpression(ref statementSwitch.Value);

            foreach (DMASTProcStatementSwitch.SwitchCase switchCase in statementSwitch.Cases)
            {
                if (switchCase.Body != null)
                {
                    switchCase.Body.Visit(this);
                }
            }
        }
Ejemplo n.º 2
0
        public void VisitProcStatementSwitch(DMASTProcStatementSwitch statementSwitch)
        {
            SimplifyExpression(ref statementSwitch.Value);

            foreach (DMASTProcStatementSwitch.SwitchCase switchCase in statementSwitch.Cases)
            {
                if (switchCase is DMASTProcStatementSwitch.SwitchCaseValues switchCaseValues)
                {
                    for (var i = 0; i < switchCaseValues.Values.Length; i++)
                    {
                        SimplifyExpression(ref switchCaseValues.Values[i]);
                    }
                }
                switchCase.Body?.Visit(this);
            }
        }
Ejemplo n.º 3
0
        public void ProcessStatementSwitch(DMASTProcStatementSwitch statementSwitch)
        {
            string endLabel = _proc.NewLabelName();
            List <(string CaseLabel, DMASTProcBlockInner CaseBody)> valueCases = new();
            DMASTProcBlockInner defaultCaseBody = null;

            DMExpression.Emit(_dmObject, _proc, statementSwitch.Value);
            foreach (DMASTProcStatementSwitch.SwitchCase switchCase in statementSwitch.Cases)
            {
                if (switchCase is DMASTProcStatementSwitch.SwitchCaseValues switchCaseValues)
                {
                    string caseLabel = _proc.NewLabelName();

                    foreach (DMASTExpression value in switchCaseValues.Values)
                    {
                        if (value is DMASTSwitchCaseRange range)
                        {
                            if (!DMExpression.TryConstant(_dmObject, _proc, range.RangeStart, out var lower))
                            {
                                throw new CompileErrorException(new CompilerError(range.RangeStart.Location, "Expected a constant"));
                            }
                            if (!DMExpression.TryConstant(_dmObject, _proc, range.RangeEnd, out var upper))
                            {
                                throw new CompileErrorException(new CompilerError(range.RangeEnd.Location, "Expected a constant"));
                            }

                            lower.EmitPushValue(_dmObject, _proc);
                            upper.EmitPushValue(_dmObject, _proc);
                            _proc.SwitchCaseRange(caseLabel);
                        }
                        else
                        {
                            if (!DMExpression.TryConstant(_dmObject, _proc, value, out var constant))
                            {
                                throw new CompileErrorException(new CompilerError(value.Location, "Expected a constant"));
                            }

                            constant.EmitPushValue(_dmObject, _proc);
                            _proc.SwitchCase(caseLabel);
                        }
                    }

                    valueCases.Add((caseLabel, switchCase.Body));
                }
                else
                {
                    defaultCaseBody = ((DMASTProcStatementSwitch.SwitchCaseDefault)switchCase).Body;
                }
            }
            _proc.Pop();

            if (defaultCaseBody != null)
            {
                _proc.StartScope();
                {
                    ProcessBlockInner(defaultCaseBody);
                }
                _proc.EndScope();
            }
            _proc.Jump(endLabel);

            foreach ((string CaseLabel, DMASTProcBlockInner CaseBody)valueCase in valueCases)
            {
                _proc.AddLabel(valueCase.CaseLabel);
                _proc.StartScope();
                {
                    ProcessBlockInner(valueCase.CaseBody);
                }
                _proc.EndScope();
                _proc.Jump(endLabel);
            }

            _proc.AddLabel(endLabel);
        }