Skip to content

Instantly share code, notes, and snippets.

Created June 4, 2014 22:25
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 anonymous/1e21ce1bfc0739671019 to your computer and use it in GitHub Desktop.
Save anonymous/1e21ce1bfc0739671019 to your computer and use it in GitHub Desktop.
Befunge interpretor c++11
#include <iostream>
#include <stack>
#include <vector>
#include <istream>
#include <fstream>
#include <string>
#include <time.h>
using namespace std;
class Interpretor{
private:
vector<vector<char>> mem;
stack<int> sta;
bool bridge;
bool strMode;
enum direction{
r, l, u, d
};
direction dir = r;
struct position{
int x;
int y;
};
position pos;
int pop(){
int a = sta.top();
sta.pop();
return a;
}
void push(int a){
sta.push(a);
}
void add(){
int a = pop();
int b = pop();
push(a+b);
}
void subtr(){
int a = pop();
int b = pop();
push(b-a);
}
void multiply(){
int a = pop();
int b = pop();
push(a*b);
}
void divide(){
int a = pop();
int b = pop();
push(b/a);
}
void mod(){
int a = pop();
int b = pop();
push(b%a);
}
void l_not(){
int a = pop();
if(!a) push(1);
else push(0);
}
void gt(){
int a = pop();
int b = pop();
if(b>a) push(1);
else push(0);
}
void get(){
int y = pop();
int x = pop();
push(mem[y][x]);
}
void put(){
int y = pop();
int x = pop();
mem[y][x] = pop();
}
void duplicate(){
push(sta.top());
}
void swp(){
int a = pop();
int b = pop();
push(a);
push(b);
}
void randDir(){
int tmp = rand() % 4;
switch(tmp){
case 0: dir = r; break;
case 1: dir = l; break;
case 2: dir = u; break;
case 3: dir = d; break;
}
}
void horIf(){
int tmp = pop();
if(tmp == 0) dir = r;
else dir = l;
}
void verIf(){
int tmp = pop();
if(tmp == 0) dir = d;
else dir = u;
}
void intOut(){
cout << pop();
}
void charOut(){
cout << (char)pop();
}
public:
bool endProg;
Interpretor(){};
~Interpretor(){};
Interpretor(istream& file){
strMode = false;
bridge = false;
endProg = false;
pos.x = 0;
pos.y = 0;
string tmp;
while(file.good()){
getline(file, tmp);
mem.push_back(vector<char>(tmp.begin(), tmp.end()));
}
}
void jump(){
switch(dir){
case r:
if(pos.x == (int)mem[pos.y].size()-1) pos.x = 0;
else pos.x++;
break;
case l:
if(pos.x == 0) pos.x = (int)mem[pos.y].size()-1;
else pos.x--;
break;
case d:
if(pos.y == (int)mem.size()-1) pos.y = 0;
else pos.y++;
break;
case u:
if(pos.y == 0) pos.y = (int)mem.size()-1;
else pos.y--;
break;
}
}
void step(){
char inst = mem[pos.y][pos.x];
if(strMode){
if(inst == '"'){
strMode = false;
jump();
return;
}
push((int)inst);
jump();
return;
}
if(bridge){
bridge = false;
jump();
return;
}
if(inst >= '0' && inst <= '9'){
push(inst - '0');
jump();
return;
}
switch(inst){
case '+':
add();
break;
case '-':
subtr();
break;
case '*':
multiply();
break;
case '/':
divide();
break;
case '%':
mod();
break;
case '!':
l_not();
break;
case '`':
gt();
break;
case '>':
dir = r;
break;
case '<':
dir = l;
break;
case 'v':
dir = d;
break;
case '^':
dir = u;
break;
case '?':
randDir();
break;
case '_':
horIf();
break;
case '|':
verIf();
break;
case '"':
strMode = true;
break;
case ':':
duplicate();
break;
case '\\':
swp();
break;
case '$':
pop();
break;
case '.':
intOut();
break;
case ',':
charOut();
break;
case'#':
bridge = true;
break;
case 'g':
get();
break;
case 'p':
put();
break;
case '&':
int s;
cin >> s;
push(s);
break;
case '~':
char c;
cin >> c;
push((int)c);
break;
case '@':
endProg = true;
break;
}
jump();
}
};
int main(int argc, char** argv)
{
srand(time(NULL));
if(argc != 2){
cout << "Usage: " << argv[0] << " [filename]\n";
return 0;
}
fstream file(argv[1], fstream::in);
Interpretor i(file);
file.close();
while(!i.endProg){
i.step();
}
cout << endl;
return 0;
}
&v
v<
v >>0 v
>#^?v
>>1v
.
1
-
:
^ _@
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment