Skip to content

Instantly share code, notes, and snippets.

@xplorld
Created February 27, 2017 04:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xplorld/c44aa2e4b4daaff84647665f4c97e43a to your computer and use it in GitHub Desktop.
Save xplorld/c44aa2e4b4daaff84647665f4c97e43a to your computer and use it in GitHub Desktop.
a simple-to-stupid stack vm
#include <iostream>
#include <stack>
//a stupid stack machine
typedef enum : int {
ADD, //0
SUB,
MUL,
DIV,
PUSH, //1
POP, //0
PRINT,//0
JMP, //1
CALL, //1, save returning ip for RET
RET //0, if ret_ip == -1, exit. else jump to ret_ip
} InstType;
struct Inst {
InstType typ;
int val = 0;
};
struct VM {
std::stack<int> s;
Inst* insts;
int get_pop() {
int a = s.top();
s.pop();
return a;
}
int run() {
int ip = 0;
int a,b,ret_ip = -1; //"registers"
while (1) {
Inst inst = insts[ip];
switch (inst.typ) {
case ADD:
a = get_pop();
b = get_pop();
s.push(a + b);
++ip;
break;
case SUB:
a = get_pop();
b = get_pop();
s.push(a - b);
++ip;
break;
case MUL:
a = get_pop();
b = get_pop();
s.push(a * b);
++ip;
break;
case DIV:
a = get_pop();
b = get_pop();
s.push(a / b);
++ip;
break;
case PUSH:
a = inst.val;
s.push(a);
++ip;
break;
case POP:
s.pop();
++ip;
break;
case PRINT:
a = s.top();
std::cout << a << std::endl;
++ip;
break;
case JMP:
a = inst.val;
ip = a;
break;
case CALL:
ret_ip = ip + 1;
a = inst.val;
ip = a;
break;
case RET:
if (ret_ip < 0) {
return s.top();
} else {
ip = ret_ip;
ret_ip = -1;
break;
}
}
}
}
};
void play() {
Inst inst[] = {
{JMP, 4},
//func increment(int i) -> int
{PUSH, 1},
{ADD},
{RET},
{PUSH, 1},
{PUSH, 2},
{CALL, 1},
{PRINT},
{RET}
};
VM vm;
vm.insts = inst;
std::cout << vm.run() << std::endl;
}
int main(int argc, const char * argv[]) {
play();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment