コード例 #1
0
ファイル: CompileVisitor.cs プロジェクト: CMM-IDE/CMM-IDE
        /*
         *
         * 用于initializer的编译,分成两种情况。
         * 一种情况是直接对已经定义的普通变量进行赋值,另外一种情况是对数组的操作,没看出来。a[1]=[1],[1]
         * 前提:Expression Visit的结果已经被push到操作栈中
         */
        public override object VisitInitializer([NotNull] CMMParser.InitializerContext context)
        {
            if (context.ChildCount == 3)
            {
                // 直接对已经定义的普通变量进行赋值
                if (curLocalVariablesTable.ContainsKey(context.GetChild(0).GetText()))
                {
                    throw new VariableRedefinedException(context.GetChild(0).GetText(), context);
                }
                curLocalVariablesTable.Add(context.GetChild(0).GetText(), curLocalVariablesTableLength);
                curLocalVariablesTableLength++;
                Visit(context.GetChild(2));
                curLocalVariablesTable.TryGetValue(context.GetChild(0).GetText(), out int index);
                IntermediateCode code = new IntermediateCode(index, InstructionType.pop, context.Start.Line);
                codes.Add(code);
            }
            else
            {
                // 定义数组
                // 首先visit a[exp] exp的值被压到当前stack上
                // expStack.Clear();
                // Visit(context.GetChild(2));
                // Double expValue = (Double)expStack.Pop();
                // if (Math.Ceiling(expValue) != expValue) {
                //     throw new CompileException("数组元素个数必须为整数!");
                // }

                // 支支持常量定义
                int size = Convert.ToInt32(context.GetChild(2).GetText());
                curLocalVariablesTable.Add(context.GetChild(0).GetText(), curLocalVariablesTableLength);

                int initialExpCount = context.expression().Length - 1;


                for (int i = 1; i < context.expression().Length; i++)
                {
                    // 求出所有子表达式的值 放在栈上
                    Visit(context.expression()[i]);
                }
                for (int i = 0; i < size - initialExpCount; i++)
                {
                    // 剩下的元素全部赋值为0
                    codes.Add(new IntermediateCode(0, InstructionType.push, context.Start.Line));
                }
                for (int i = size - 1; i >= 0; i--)
                {
                    // 从后往前给数组赋值
                    codes.Add(new IntermediateCode(curLocalVariablesTableLength + i, InstructionType.pop, context.Start.Line));
                }
                // 更新局部变量表大小
                curLocalVariablesTableLength += size;
            }
            return(null);
        }
コード例 #2
0
 /// <summary>
 /// Visit a parse tree produced by <see cref="CMMParser.initializer"/>.
 /// <para>
 /// The default implementation returns the result of calling <see cref="AbstractParseTreeVisitor{Result}.VisitChildren(IRuleNode)"/>
 /// on <paramref name="context"/>.
 /// </para>
 /// </summary>
 /// <param name="context">The parse tree.</param>
 /// <return>The visitor result.</return>
 public virtual Result VisitInitializer([NotNull] CMMParser.InitializerContext context)
 {
     return(VisitChildren(context));
 }
コード例 #3
0
 public VariableRedefinedException(string v, CMMParser.InitializerContext context)
 {
     this.v       = v;
     this.context = context;
     errorInfo    = new ErrorInfo(context.Start.Line, context.Start.Column, "列变量" + v + "多次定义");
 }
コード例 #4
0
 /// <summary>
 /// Exit a parse tree produced by <see cref="CMMParser.initializer"/>.
 /// <para>The default implementation does nothing.</para>
 /// </summary>
 /// <param name="context">The parse tree.</param>
 public virtual void ExitInitializer([NotNull] CMMParser.InitializerContext context)
 {
 }