private void InterpretWhileStmt(TreeNode node) { isRepeat = true; var jumpLine = Line + 1; var instruction = new Quadruple(InstructionType.Jump, InterpretExp(node.LeftNode), null, null, Line); Codes.AddLast(instruction); Line++; inPos.AddLast(Line); var breakCode = new LinkedList <Quadruple>(); if (node.MiddleNode != null) { if (node.MiddleNode.Type != StmtType.StmtBlock) { Codes.AddLast(new Quadruple(InstructionType.In, null, null, null, Line)); Line++; var table = new SymbolTable(); Level++; InterpretStmt(node.MiddleNode, breakCode); Level--; SymbolTable.DeRegister(); Codes.AddLast(new Quadruple(InstructionType.Out, null, null, null, Line)); Line++; } else { InterpretStmt(node.MiddleNode, breakCode); } } Codes.AddLast(new Quadruple(InstructionType.Jump, null, null, jumpLine.ToString(), Line)); Line++; outPos.AddLast(Line + 1); if (breakCode != null) { foreach (var c in breakCode) { c.Third = (Line + 1).ToString(); } } instruction.Third = (Line + 1).ToString(); outPos.RemoveLast(); inPos.RemoveLast(); if (Level == 0) { isRepeat = false; } }
private void InterpretIfStmt(TreeNode node, LinkedList <Quadruple> breakCode) { var jump = new Quadruple(InstructionType.Jump, InterpretExp(node.LeftNode), null, null, Line); Codes.AddLast(jump); Line++; if (node.MiddleNode != null) { if (node.MiddleNode.Type == StmtType.ElseStmt) { Codes.AddLast(new Quadruple(InstructionType.In, null, null, null, Line)); Line++; Codes.AddLast(new Quadruple(InstructionType.Out, null, null, null, Line)); Line++; InterpretELseStmt(node, jump, breakCode); } else { if (node.MiddleNode.LeftNode.Type != StmtType.StmtBlock) { Codes.AddLast(new Quadruple(InstructionType.In, null, null, null, Line)); Line++; var table = new SymbolTable(); Level++; InterpretStmt(node.MiddleNode.LeftNode, breakCode); Level--; SymbolTable.DeRegister(); Codes.AddLast(new Quadruple(InstructionType.Out, null, null, null, Line)); Line++; } else { InterpretStmt(node.MiddleNode.LeftNode, breakCode); } jump.Third = (Line + 1).ToString(); if (node.MiddleNode.MiddleNode != null) { InterpretELseStmt(node.MiddleNode.MiddleNode, jump, breakCode); } } } else { jump.Third = (Line + 1).ToString(); } }
private void InterpretJumpStmt(TreeNode node, out Quadruple jump) { if (!isRepeat) { throw new InterpretException("ERROR : 跳转语句需要在循环体内.\n"); } jump = new Quadruple(InstructionType.Jump, null, null, null, Line); if (node.DataType == TokenType.Break) { jump.Second = "break"; jump.Third = outPos.Last.Value.ToString(); } else if (node.DataType == TokenType.Continue) { jump.Second = "continue"; jump.Third = inPos.Last.Value.ToString(); } Codes.AddLast(jump); Line++; }
private void InterpretQuadruple(Quadruple code) { var instrType = code.Instruction; if (instrType.Equals(InstructionType.Jump)) //跳转指令 { if (code.First == null || SymbolTable.GetSymbolValue(code.First).Type == SymbolType.False || (SymbolTable.GetSymbolValue(code.First).IntVal == 0 && SymbolTable.GetSymbolValue(code.First).RealVal == 0 && SymbolTable.GetSymbolValue(code.First).CharVal == 0) ) //需要跳转 { pc = int.Parse(code.Third); return; } } if (instrType.Equals(InstructionType.Scan)) //输入指令 { var input = Console.ReadLine(); var type = SymbolTable.FindSymbol(GetId(code.Third)).Type; switch (type) { case SymbolType.IntArray: case SymbolType.IntValue: { var value = ParseValue(input); if (value.Type == SymbolType.IntValue) { SetValue(code.Third, value); } else { throw new InterpretException("Error : 类型不匹配.\n"); //Console.WriteLine(@"Error : 类型不匹配."); } break; } case SymbolType.RealArray: case SymbolType.RealValue: { var value = ParseValue(input); SetValue(code.Third, value); break; } case SymbolType.CharArray: case SymbolType.CharValue: { var value = ParseValue(input); if (value.Type == SymbolType.IntValue) { value.CharVal = (char)value.IntVal; SetValue(code.Third, value); } if (value.Type == SymbolType.CharValue) { SetValue(code.Third, value); } else { throw new InterpretException("Error : 类型不匹配.\n"); // Console.WriteLine(@"Error : 类型不匹配."); } break; } } } if (instrType.Equals(InstructionType.Print)) { var index = -1; if (IsArrayElement(code.Third)) { var dims = SymbolTable.GetSymbolValue(GetId(code.Third)).DimArray; dims[dims.Length - 1] = 1; index = GetIndex(code.Third, dims); } result += SymbolTable.GetSymbolValue(GetId(code.Third), index).ToString(); Console.WriteLine(SymbolTable.GetSymbolValue(GetId(code.Third), index)); } if (instrType.Equals(InstructionType.In)) { Level++; var table = new SymbolTable(); } if (instrType.Equals(InstructionType.Out)) { SymbolTable.DeRegister(); Level--; } if (instrType.Equals(InstructionType.Int)) { if (code.Second != null && code.First != null) { var symbol = new Symbol(code.Third, SymbolType.IntArray, Level); symbol.Value.InitArray(GetLength(code.Second, out var dims)); symbol.Value.DimArray = dims.ToArray(); SymbolTable.Register(symbol); } else { var intValue = 0; if (code.First != null) { intValue = GetInt(code.First); } var symbol = new Symbol(code.Third, SymbolType.IntValue, Level, intValue); SymbolTable.Register(symbol); } } if (instrType.Equals(InstructionType.Real)) { if (code.Second != null && code.First != null) { var symbol = new Symbol(code.Third, SymbolType.RealArray, Level); symbol.Value.InitArray(GetLength(code.Second, out var dims)); symbol.Value.DimArray = dims.ToArray(); SymbolTable.Register(symbol); } else { double doubleValue = 0; if (code.First != null) { doubleValue = GetDouble(code.First); } Symbol symbol = new Symbol(code.Third, SymbolType.RealValue, Level, doubleValue); SymbolTable.Register(symbol); } } if (instrType.Equals(InstructionType.Char)) { if (code.Second != null && code.First != null) { var symbol = new Symbol(code.Third, SymbolType.CharArray, Level); symbol.Value.InitArray(GetLength(code.Second, out var dims)); symbol.Value.DimArray = dims.ToArray(); SymbolTable.Register(symbol); } else { var charValue = '\0'; if (code.First != null) { charValue = GetChar(code.First); } var symbol = new Symbol(code.Third, SymbolType.CharValue, Level, charValue); SymbolTable.Register(symbol); } } if (instrType.Equals(InstructionType.Assign)) { var value = GetValue(code.First); SetValue(code.Third, value); } if (instrType.Equals(InstructionType.Plus)) { SetValue(code.Third, GetValue(code.First).Plus(GetValue(code.Second))); } if (instrType.Equals(InstructionType.Minus)) { if (code.Second != null) { SetValue(code.Third, GetValue(code.First).Minus(GetValue(code.Second))); } else { SetValue(code.Third, Value.Not(GetValue(code.First))); } } if (instrType.Equals(InstructionType.Mul)) { SetValue(code.Third, GetValue(code.First).Mul(GetValue(code.Second))); } if (instrType.Equals(InstructionType.Div)) { SetValue(code.Third, GetValue(code.First).Div(GetValue(code.Second))); } if (instrType.Equals(InstructionType.Mod)) { SetValue(code.Third, GetValue(code.First).Mod(GetValue(code.Second))); } if (instrType.Equals(InstructionType.GreaterThan)) { SetValue(code.Third, GetValue(code.First).GreaterThan(GetValue(code.Second))); } if (instrType.Equals(InstructionType.LessThan)) { SetValue(code.Third, GetValue(code.First).LessThan(GetValue(code.Second))); } if (instrType.Equals(InstructionType.Eq)) { SetValue(code.Third, GetValue(code.First).Equal(GetValue(code.Second))); } if (instrType.Equals(InstructionType.GreaterEqThan)) { SetValue(code.Third, GetValue(code.First).GreaterEqual(GetValue(code.Second))); } if (instrType.Equals(InstructionType.LessEqThan)) { SetValue(code.Third, GetValue(code.First).LessEqual(GetValue(code.Second))); } if (instrType.Equals(InstructionType.NotEq)) { SetValue(code.Third, GetValue(code.First).NotEqual(GetValue(code.Second))); } if (instrType.Equals(InstructionType.And)) { SetValue(code.Third, GetValue(code.First).And(GetValue(code.Second))); } if (instrType.Equals(InstructionType.Or)) { SetValue(code.Third, GetValue(code.First).Or(GetValue(code.Second))); } if (instrType.Equals(InstructionType.Not)) { SetValue(code.Third, Value.Not(GetValue(code.First))); } pc++; }