private void Add(PNode node) { Programs.Add(node); }
private void Execute(PNode cmd) { switch (cmd.INS) { case PCode.OPR: switch (cmd.Arg) { case 1: Push(-Pop()); break; case 2: Push(Pop() + Pop()); break; case 3: int tmp1 = Pop(); Push(Pop() - tmp1); break; case 4: Push(Pop() * Pop()); break; case 5: tmp1 = Pop(); Push(Pop() / tmp1); break; case 6: Push(Math.Abs(Pop()) & 1); break; case 7: Push(~(Math.Abs(Pop()) & 1)); break; case 8: PushBoolean(Pop() == Pop()); break; case 9: PushBoolean(Pop() != Pop()); break; case 10: PushBoolean(Pop() > Pop()); break; case 11: PushBoolean(Pop() <= Pop()); break; case 12: PushBoolean(Pop() < Pop()); break; case 13: PushBoolean(Pop() >= Pop()); break; } break; case PCode.CAL: Push(EIP + 1); EIP = cmd.Arg; return; case PCode.EXP: TempPool.Clear(); EIP = Pop(); return; case PCode.HALT: return; case PCode.JMP: EIP = cmd.Arg; TempPool.Clear(); return; case PCode.JPC: if (Pop() == 1) { EIP++; } else { EIP = cmd.Arg; } TempPool.Clear(); return; case PCode.LIT: Push(cmd.Arg); break; case PCode.LOD: if (cmd.DataType == 3) { if (Initialized[cmd.Arg] == false) { throw new Exception($"使用了未初始化的变量{VarSeg[cmd.Arg].Value}"); } Push(DataSegment[cmd.Arg]); } else { Push(TempPool[cmd.Arg]); } break; case PCode.RED: string i; if (WriteString == null) { Console.WriteLine($"Please input a value for {VarSeg[cmd.Arg].Value}"); } else { WriteString($"Please input a value for {VarSeg[cmd.Arg].Value}"); } if (Read == null) { i = Console.ReadLine(); } else { i = Read(); } int res; while (!int.TryParse(i, out res)) { if (WriteString != null) { WriteString("Please input a legal INT"); } else { Console.WriteLine("Please input a legal INT"); } if (Read != null) { i = Read(); } else { i = Console.ReadLine(); } } Initialized[cmd.Arg] = true; DataSegment[cmd.Arg] = res; break; case PCode.STO: if (cmd.DataType == 3) { Initialized[cmd.Arg] = true; DataSegment[cmd.Arg] = Pop(); } else { if (TempPool.ContainsKey(cmd.Arg)) { TempPool[cmd.Arg] = Pop(); } else { TempPool.Add(cmd.Arg, Pop()); } } break; case PCode.WRT: if (Write == null) { Console.WriteLine(Pop()); } else { Write(Pop()); } break; } ++EIP; }
private void Translate(QuadrupleNode Node, int Index) { Node.Start = Programs.Count; int typeV = Convert.ToInt32(Node.Type); if (typeV <= IsJump) { TranslateJump(Node); return; } switch (Node.Type) { case QuadrupleType.Return: Add(new PNode(PCode.EXP)); Address.Add(Index + 1, Programs.Count); break; case QuadrupleType.Call: int a = 1; if (Address.ContainsKey((int)Node.Result)) { a = Address[(int)Node.Result]; } Add(new PNode(PCode.CAL, a, 4)); break; case QuadrupleType.Add: case QuadrupleType.Sub: case QuadrupleType.Mul: case QuadrupleType.Div: TranslateOpr(Node); break; case QuadrupleType.Assign: if (Node.Arg2 is int) { var node = new PNode(PCode.LOD, (int)Node.Arg2, 2); Add(node); } else if (Node.Arg2 is string) { int arg = int.Parse(((string)Node.Arg2).Substring(1)); Add(new PNode(PCode.LIT, arg, 1)); } else { Add(new PNode(PCode.LOD, ((QuadrupleNode)(Node.Arg2)).Offset, 3) { Offset = ((QuadrupleNode)(Node.Arg2)).AddressOffset, Level = ((QuadrupleNode)(Node.Arg2)).Level }); } var qnode = (QuadrupleNode)(Node.Arg1); Add(new PNode(PCode.STO, qnode.Offset, 3) { Offset = qnode.AddressOffset, Level = qnode.Level }); break; case QuadrupleType.Write: var list = Node.Arg1 as ArrayList; foreach (var i in list) { if (i is string) { Add(new PNode(PCode.LIT, Convert.ToInt32(((string)i).Substring(1)), 1)); Add(new PNode(PCode.WRT)); continue; } var param = i as QuadrupleNode; Add(new PNode(PCode.LOD, param.Offset, 3) { Offset = param.AddressOffset, Level = param.Level }); Add(new PNode(PCode.WRT)); } break; case QuadrupleType.Read: list = Node.Arg1 as ArrayList; foreach (var i in list) { var param = i as QuadrupleNode; Add(new PNode(PCode.RED, param.Offset, 3) { Offset = param.AddressOffset, Level = param.Level }); } break; } }