示例#1
0
 /// <summary>
 /// Exit a parse tree produced by <see cref="CMMParser.forStatement"/>.
 /// <para>The default implementation does nothing.</para>
 /// </summary>
 /// <param name="context">The parse tree.</param>
 public virtual void ExitForStatement([NotNull] CMMParser.ForStatementContext context)
 {
 }
示例#2
0
 /// <summary>
 /// Visit a parse tree produced by <see cref="CMMParser.forStatement"/>.
 /// <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 VisitForStatement([NotNull] CMMParser.ForStatementContext context)
 {
     return(VisitChildren(context));
 }
示例#3
0
        /*
         * 处理for语句
         */
        public override object VisitForStatement([NotNull] CMMParser.ForStatementContext context)
        {
            // 当前局部变量表的大小,访问完ForStatement之后要恢复局部变量表
            int curSize = curLocalVariablesTableLength;

            // 这里面可能会定义新的变量,不过没关系,直接插入局部变量表中就可以了,最后我们恢复的。
            if (context.forInitializer() != null)
            {
                Visit(context.forInitializer());
            }
            // 访问expression,将执行的结果压入栈中
            // addr_expression是expression(比较)的地址
            int addr_expression = codes.Count;
            IntermediateCode code0, code1 = null;

            if (context.expression() != null)
            {
                Visit(context.expression());


                // 如果expression的结果是真,才会访问
                // 这里的0是数字,不是索引,要加上范围!!
                code0 = new IntermediateCode(0, InstructionType.push, context.Start.Line);
                // 如果是0的话,就直接跳转到codeBlock之后,并且释放局部变量。目的地址待回填
                code1 = new IntermediateCode(InstructionType.je, context.Start.Line);

                // addr0是codeBlock的起始地址
                codes.Add(code0);
                codes.Add(code1);
            }
            int addr0 = codes.Count;

            // 访问codeBlock
            if (context.codeBlock() != null)
            {
                Visit(context.codeBlock());
            }

            // 访问更新操作,更新操作的起始地址是addr1
            int addr1 = codes.Count;

            if (context.assignment() != null)
            {
                Visit(context.assignment());
            }
            // 跳转回去expression去判断
            codes.Add(new IntermediateCode(addr_expression, InstructionType.j, context.Start.Line));

            // addr2是执行完codeBlock,而且判断确定不跳转的代码
            int addr2 = codes.Count;

            if (code1 != null)
            {
                code1.setOperant(addr2);
            }
            // 替换所有出现的continue break,代码的范围是addr0-add2, 更新操作的代码在addr1
            replaceBreakAndConti(codes, addr0, addr2 - 1, addr1);
            //局部变量表大于curSize的部分全部删掉!
            codes.Add(new IntermediateCode(curSize, InstructionType.delv, context.Stop.Line));
            curLocalVariablesTableLength = curSize;
            removeVariableBiggerThanK(curSize);
            return(null);
        }