Может кто-нибудь указать мне код C # для интерпретируемой машины стека? - PullRequest
1 голос
/ 05 октября 2010

Я ищу C # реализацию стекового компьютера, предпочтительно с сопутствующими модульными тестами или хотя бы парой примеров.Код в http://en.wikipedia.org/wiki/P-code_machine, похоже, именно то, что я ищу.К сожалению, прошло более десяти лет с тех пор, как я запрограммировал на Pascal и столкнулся с кучей проблем при переносе его на C #.Кроме того, не было примеров использования кода.

В любом случае, любая помощь в этом отношении будет принята с благодарностью ....

Ответы [ 2 ]

3 голосов
/ 05 октября 2010

Машины с интерпретируемыми стеками очень похожи по концепции на Обратная польская запись .

Выражение

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.
}

Для примера из реального мира взгляните на поля класса OpCodes в .NET Framework.

2 голосов
/ 06 октября 2010

Исходный интерпретатор Magpie был написан на C # и скомпилирован в байт-код на основе стека. Взгляните на Machine.cs для базового класса интерпретатора. Компилятор, который переводит исходный код в этот байт-код, находится в Magpie.Compiler .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...