/* * * 用于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); }
/// <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)); }
public VariableRedefinedException(string v, CMMParser.InitializerContext context) { this.v = v; this.context = context; errorInfo = new ErrorInfo(context.Start.Line, context.Start.Column, "列变量" + v + "多次定义"); }
/// <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) { }