2010-10-05 61 views
1

我正在尋找一個堆棧機器的C#實現,最好是一個具有相關的單元測試或至少兩個示例。代碼http://en.wikipedia.org/wiki/P-code_machine似乎是我正在尋找的東西。不幸的是,自從我在Pascal中編程以來,已經有十多年的時間了,並且遇到了一些將它移植到C#中的問題。另外,沒有使用代碼的例子。任何人都可以指向解釋堆棧機器的C#代碼嗎?

不管怎樣,在這方面的任何幫助,將不勝感激....

回答

2

原來的Magpie解釋器是用C#編寫的,然後編譯成基於堆棧的字節碼。看看Machine.cs的核心英特爾類。將源代碼轉換爲此字節碼的編譯器位於Magpie.Compiler中。

+0

美夢!正是我在找什麼.... – 2010-10-06 11:54:38

3

解釋型堆機在概念上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

+0

感謝您的快速回復! – 2010-10-05 18:30:31

+0

雖然我可以使用更完整的示例。例如,我如何處理加載/檢索數據,而不僅僅是簡單的整數。 – 2010-10-05 18:33:40

+0

@lsb:當然。你可以展開你的意思加載/檢索數據?即從哪裏加載/檢索什麼樣的數據? – dtb 2010-10-05 18:36:08

相關問題