コード例 #1
0
        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;
            }
        }
コード例 #2
0
        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();
            }
        }
コード例 #3
0
 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++;
 }
コード例 #4
0
        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++;
        }