我正在寻找一个堆栈机器的C#实现,最好是一个具有相关的单元测试或至少两个示例。代码http://en.wikipedia.org/wiki/P-code_machine似乎是我正在寻找的东西。不幸的是,自从我在Pascal中编程以来,已经有十多年的时间了,并且遇到了一些将它移植到C#中的问题。另外,没有使用代码的例子。任何人都可以指向解释堆栈机器的C#代码吗?
不管怎样,在这方面的任何帮助,将不胜感激....
我正在寻找一个堆栈机器的C#实现,最好是一个具有相关的单元测试或至少两个示例。代码http://en.wikipedia.org/wiki/P-code_machine似乎是我正在寻找的东西。不幸的是,自从我在Pascal中编程以来,已经有十多年的时间了,并且遇到了一些将它移植到C#中的问题。另外,没有使用代码的例子。任何人都可以指向解释堆栈机器的C#代码吗?
不管怎样,在这方面的任何帮助,将不胜感激....
原来的Magpie解释器是用C#编写的,然后编译成基于堆栈的字节码。看看Machine.cs的核心英特尔类。将源代码转换为此字节码的编译器位于Magpie.Compiler中。
解释型堆机在概念上Reverse Polish notation非常相似。
表达
3 + (6 - 2)
在RPN表示为
3 6 2 - +
这被评价如下:
Input Operation Stack Comment 3 Push value 3 6 Push value 6 3 2 Push value 2 6 3 - Subtract 4 Pop two values (6, 2) and push result (4) 3 + Add 7 Pop two values (3, 4) and push result (7)
从那里,它应该很容易建立一个简单的解释在C#中堆栈机器。例如。
var stack = new Stack<int>();
var program = new[]
{
OpCode.Ldc_3,
OpCode.Ldc_6,
OpCode.Ldc_2,
OpCode.Sub,
OpCode.Add,
};
for (int i = 0; i < program.Length; i++)
{
int a, b;
switch (program[i])
{
case OpCode.Add: b = stack.Pop(); a = stack.Pop(); stack.Push(a + b); break;
case OpCode.Sub: b = stack.Pop(); a = stack.Pop(); stack.Push(a - b); break;
case OpCode.Mul: b = stack.Pop(); a = stack.Pop(); stack.Push(a * b); break;
case OpCode.Div: b = stack.Pop(); a = stack.Pop(); stack.Push(a/b); break;
case OpCode.Ldc_0: stack.Push(0); break;
case OpCode.Ldc_1: stack.Push(1); break;
case OpCode.Ldc_2: stack.Push(2); break;
case OpCode.Ldc_3: stack.Push(3); break;
case OpCode.Ldc_4: stack.Push(4); break;
case OpCode.Ldc_5: stack.Push(5); break;
case OpCode.Ldc_6: stack.Push(6); break;
case OpCode.Ldc_7: stack.Push(7); break;
case OpCode.Ldc_8: stack.Push(8); break;
}
}
var result = stack.Pop();
与
enum OpCode
{
Nop, // No operation is performed.
Add, // Adds two values and pushes the result onto the evaluation stack.
Sub, // Subtracts one value from another and pushes the result onto the
// evaluation stack.
Mul, // Multiplies two values and pushes the result on the evaluation
// stack.
Div, // Divides two values and pushes the result onto the evaluation
// stack.
Ldc_0, // Pushes the integer value of 0 onto the evaluation stack.
Ldc_1, // Pushes the integer value of 1 onto the evaluation stack.
Ldc_2, // Pushes the integer value of 2 onto the evaluation stack.
Ldc_3, // Pushes the integer value of 3 onto the evaluation stack.
Ldc_4, // Pushes the integer value of 4 onto the evaluation stack.
Ldc_5, // Pushes the integer value of 5 onto the evaluation stack.
Ldc_6, // Pushes the integer value of 6 onto the evaluation stack.
Ldc_7, // Pushes the integer value of 7 onto the evaluation stack.
Ldc_8, // Pushes the integer value of 8 onto the evaluation stack.
}
对于现实世界的例子,有在.NET Framework看看fields of the OpCodes class。
感谢您的快速回复! – 2010-10-05 18:30:31
虽然我可以使用更完整的示例。例如,我如何处理加载/检索数据,而不仅仅是简单的整数。 – 2010-10-05 18:33:40
@lsb:当然。你可以展开你的意思加载/检索数据?即从哪里加载/检索什么样的数据? – dtb 2010-10-05 18:36:08
美梦!正是我在找什么.... – 2010-10-06 11:54:38