项目作者: phresnel

项目描述 :
Pug is a tiny, small, minimalistic, evening studyable,tweakable, C++11 self-contained, embeddable and header-only Stack Virtual-Machine.
高级语言: C++
项目地址: git://github.com/phresnel/pug.git
创建时间: 2013-09-13T11:51:32Z
项目社区:https://github.com/phresnel/pug

开源协议:GNU General Public License v3.0

下载


pug-vm

Pug is a tiny, small, minimalistic, evening studyable,tweakable, C++11 self-contained, embeddable and header-only Stack Virtual-Machine.

Use it for learning, fun, or as a backend to your own tiny programming language.

Overview

The machine is a stack-machine, meaning that most instructions work on values in the stack.

Examples

The following is an example of using PugVM directly using the raw C++ API. An assembler which makes for better redable code is being planned:

  1. // Recursive faculty program.
  2. int res = 5;
  3. std::vector<Instruction> program {
  4. {LoadInt, &res}
  5. {Call, 5},
  6. {PopReduce},
  7. {StoreInt, &res},
  8. {Exit},
  9. // fac(x)
  10. {LoadArg, 0},
  11. {PushInt, 1},
  12. {NotEqualsII},
  13. {JumpRelIfTrue, 3},
  14. {PushInt, 1},
  15. {ReturnTos},
  16. {LoadArg,0},
  17. {DecrementI},
  18. {Call, 5},
  19. {PopReduce},
  20. {LoadArg,0},
  21. {MulII},
  22. {ReturnTos}
  23. };
  24. PugVM::StackMachine<true> m(program);
  25. while (!m.halted()) {
  26. m.tick();
  27. }
  28. std::cout << "result: " << res << std::endl;

This code would output 120 as the factulty for 5.

Loops are also possible. The following is the iterative faculty variation:

  1. // Iterative faculty program.
  2. std::vector<Instruction> program{
  3. {LoadInt, &res}, // [local 0]
  4. {Dup}, // [local 1] duplicate input to be used as counter
  5. // start of while loop
  6. {Dup}, // \
  7. {PushInt,1}, // | compare counter to 1
  8. {EqualsII}, // / \
  9. {JumpRelIfTrue, 7}, // quit if counter is 1
  10. {DecrementI},
  11. {LoadLocal, 0},
  12. {LoadLocal, 1},
  13. {MulII},
  14. {StoreLocal, 0},
  15. {Jump, 2},
  16. // loop end
  17. {Pop},
  18. {StoreInt, &res},
  19. {Exit}
  20. };

Instructions

  • PushFloat
  • PushInt
  • PushBool

  • Pop

  • PopReduce

  • Dup

  • StoreFloat

  • StoreInt
  • StoreBool
  • StoreStAbs
  • StoreStRel
  • StoreLocal
  • StoreArg

  • LoadFloat

  • LoadInt
  • LoadBool
  • LoadStAbs
  • LoadStRel
  • LoadLocal
  • LoadArg

  • EqualsFF

  • EqualsII
  • EqualsBB
  • NotEqualsFF
  • NotEqualsII
  • NotEqualsBB

  • Jump

  • JumpIfTrue
  • JumpRel
  • JumpRelIfTrue

  • Call

  • Return
  • ReturnTos

  • AddFF

  • AddII

  • SubFF

  • SubII

  • MulFF

  • MulII

  • DecrementI

  • IncrementI

  • Dump

  • Exit

Debugging

It offers some runtime introspection:

  1. [ 0] LoadInt :
  2. [ 1] Call : 5 |
  3. [ 5] LoadArg : 5 | 2 | 0 |
  4. [ 6] PushInt : 5 | 2 | 0 | 5 |
  5. [ 7] NotEqualsII : 5 | 2 | 0 | 5 | 1 |
  6. [ 8] JumpRelIfTrue : 5 | 2 | 0 | 1 |
  7. [ 11] LoadArg : 5 | 2 | 0 |

Here, the first number is the address of the instruction, the second is the operation mnemonic, and the information on the right hand side of ‘:’ is the stack before the operation happens. You can read it e.g. like this: Execute NotEquals upon the stack [5, 2, 0, 5, 1].