C语言解释器-11 控制结构之switch

鲜有解释器(或编译器)实现了switch控制。无它,唯复杂尔。SharpC将switch划分为两个部分实现:switch(表达式)和case。

先看Case的实现,由条件值和执行部分组成:

public class Case : ControlFlow
    {
        public Expression.Operand.Value Value;
        public Block Body
        {
            get { return Children.Count > 0 ? Children.First() as Block : null; }
        }
    }

 

为简化实现,用Block作为case的执行部分。副作用是多了一层,略微影响效率。

再看switch的实现:

public class Switch : ControlFlow
    {
        private Dictionary<int, int> m_caseDict;

        public Expression.ExpressionNode Condition;

        public Block Body
        {
            get { return Children.Count > 0 ? Children.First() as Block : null; }
        }

        public Case Default
        {
            get { return Body != null ? Body.Children.Last() as Case : null; }
        }

        public List<Context> CaseSet
        {
            get { return Body != null ? Body.Children.Count > 1 ? Body.Children.GetRange(0, Body.Children.Count - 1) : null : null; }
        }


switch的执行部分亦为一个block。同时Default是最后一个Case。

再看switch的执行部分:

public override void Run(Context ctx)
        {
            Debug.WriteLine("Begin Switch.");

            bool needBreak = false;

            if (IsFirstRunning)
            {
                m_caseDict = new Dictionary<int, int>();

                int idx = 0;

                Body.OnReturn += delegate(Context stx, Return ret)
                {
                    Debug.WriteLine("Return");

                    needBreak = true;

                    Block parentBlock = this.ParentBlock;

                    if (parentBlock != null && parentBlock.OnReturn != null)
                        parentBlock.OnReturn(stx, ret);
                };

                Body.OnBreak = delegate(Context stx)
                {
                    Debug.WriteLine("Break.");

                    needBreak = true;
                };

                foreach (Context item in CaseSet)
                {
                    Case stxCase = item as Case;

                    m_caseDict.Add(stxCase.Value.AsInt, idx++);
                    stxCase.Body.OnBreak += Body.OnBreak;
                }

                IsFirstRunning = false;
            }

            Expression.Operand.Value val = Condition.Evaluate(this).GetValue(ctx);

            Debug.WriteLine(string.Format("Condition: [{0}] = {1}", Condition, val));


            if (m_caseDict.ContainsKey(val.AsInt))
            {
                int idx = m_caseDict[val.AsInt];
                IEnumerator<Context> caseEnum = CaseSet.GetEnumerator();
                int i = 0;

                while (caseEnum.MoveNext())
                {
                    if (i++ < idx)
                        continue;

                    Debug.WriteLine(string.Format("case {0}", (caseEnum.Current as Case).Value.AsInt));

                    (caseEnum.Current as Case).Body.Run(this);

                    if (needBreak)
                        break;
                } // while
            }
            else
            {
                Debug.WriteLine("Default");

                Default.Run(this);
            }
        }


在第一次执行的时候先建立case字典,希望下次运行的时候能够加快速度。然后,运行与表达式相匹配的case,并从该case开始,依次运行下一个case,直到运行到break为止。


 

 

 

 

你可能感兴趣的:(C#,C语言,解释器,形式语言和自动机)