Created
September 7, 2010 06:05
-
-
Save hogelog/567934 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <iostream> | |
#include <string> | |
#include <sstream> | |
#include <vector> | |
#include <stack> | |
#define MEMSIZE 30000 | |
#define CODESIZE 30000 | |
#include "xbyak/xbyak.h" | |
class BFVM : public Xbyak::CodeGenerator { | |
private: | |
std::istream& input; | |
int membuf[MEMSIZE]; | |
static const char* toLabel(char ch, int num) | |
{ | |
static std::stringstream labelStream; | |
labelStream.str(""); | |
labelStream << ch << num; | |
return labelStream.str().c_str(); | |
} | |
public: | |
BFVM(std::istream& input) : | |
CodeGenerator(CODESIZE), | |
input(input) | |
{ | |
using namespace Xbyak; | |
push(ebx); | |
Reg32 mem(ebx); | |
mov(mem, (int) membuf); | |
char ch = 0; | |
std::stack<int> labelStack; | |
int labelNum = 0; | |
std::string label; | |
while(input.get(ch).good()) { | |
switch(ch) { | |
case '+': | |
mov(eax, ptr[mem]); | |
inc(eax); | |
mov(ptr[mem], eax); | |
break; | |
case '-': | |
mov(eax, ptr[mem]); | |
dec(eax); | |
mov(ptr[mem], eax); | |
break; | |
case '>': | |
add(mem, 4); | |
break; | |
case '<': | |
add(mem, -4); | |
break; | |
case ',': | |
call((void*) getchar); | |
mov(ptr[mem], eax); | |
break; | |
case '.': | |
push(ptr[mem]); | |
call((void*) putchar); | |
add(esp, 4); | |
break; | |
case '[': | |
L(toLabel('L', labelNum)); | |
mov(eax, ptr[mem]); | |
test(eax, eax); | |
jz(toLabel('R', labelNum), T_NEAR); | |
labelStack.push(labelNum); | |
++labelNum; | |
break; | |
case ']': | |
int beginNum = labelStack.top(); | |
labelStack.pop(); | |
jmp(toLabel('L', beginNum), T_NEAR); | |
L(toLabel('R', beginNum)); | |
break; | |
} | |
} | |
pop(ebx); | |
ret(); | |
} | |
void execute() | |
{ | |
void (*codes)() = (void (*)()) getCode(); | |
codes(); | |
} | |
}; | |
int main() | |
{ | |
BFVM bf(std::cin); | |
bf.execute(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment