Skip to content

Instantly share code, notes, and snippets.

@Arnolxu
Created June 20, 2022 16:28
Show Gist options
  • Save Arnolxu/98f795da992bc55d133687d1854e36b7 to your computer and use it in GitHub Desktop.
Save Arnolxu/98f795da992bc55d133687d1854e36b7 to your computer and use it in GitHub Desktop.
Befunge interpreter written in QoLang (inputs are not implemented)
include qo;
include stack;
include random;
if (len(qo.args) < 2) {
println("You need to provide a file!");
exit(1);
};
file = readlines(qo.args[1]);
settings = [
0, /* Line length */
0, /* Line count */
0, /* Direction
0 - Right >
1 - Down v
2 - Left <
3 - Up ^
*/
0, /* x position */
0 /* y position */
];
thestack = 0;
stack.push(&thestack);
func newpos(settings) {
if (settings[2] == 0) {
settings[3] += 1;
if (settings[3] == settings[0]) {
settings[3] = 0;
};
} else if (settings[2] == 1) {
settings[4] += 1;
if (settings[4] == settings[1]) {
settings[4] = 0;
};
} else if (settings[2] == 2) {
settings[3] -= 1;
if (settings[3] == -1) {
settings[3] = settings[0] - 1;
};
} else if (settings[2] == 3) {
settings[4] -= 1;
if (settings[4] == 0) {
settings[4] = settings[1];
};
};
return settings;
};
foreach &line in file {
len_ = len(line);
if(len_ > settings[0]) {
settings[0] = len_;
};
};
settings[1] = len(file);
program = [0] * settings[1];
times settings[1] as &i {
tmplist = [" "] * settings[0];
program[i] = tmplist;
};
times len(file) as &line {
times len(file[line]) as &char {
/* TODO: Use this on future:
program[line][char] = file[line][char];
This is not possible right now due to restrictions on QoLang.
*/
pline = program[line];
fline = file[line];
pline[char] = fline[char];
program[line] = pline;
};
};
running = True;
while (running) {
char = program[settings[4]];
char = char[settings[3]];
if (char == '>') {
settings[2] = 0;
} else if (char == 'v') {
settings[2] = 1;
} else if (char == '<') {
settings[2] = 2;
} else if (char == '^') {
settings[2] = 3;
} else if (char == '"') {
settings = newpos(settings);
char = program[settings[4]];
char = char[settings[3]];
while (char != '"'){
thestack = ord(char);
stack.push(&thestack);
settings = newpos(settings);
char = program[settings[4]];
char = char[settings[3]];
};
} else if (char == ':') {
stack.push(&thestack);
} else if (char == '_') {
stack.pop(&thestack);
if (thestack == 0) {
settings[2] = 0;
} else {
settings[2] = 2;
};
} else if (char == ',') {
stack.pop(&thestack);
print(chr(thestack));
} else if (char == '@') {
exit(0);
} else if (char == '1') {
thestack = 1;
stack.push(&thestack);
} else if (char == '2') {
thestack = 2;
stack.push(&thestack);
} else if (char == '3') {
thestack = 3;
stack.push(&thestack);
} else if (char == '4') {
thestack = 4;
stack.push(&thestack);
} else if (char == '5') {
thestack = 5;
stack.push(&thestack);
} else if (char == '6') {
thestack = 6;
stack.push(&thestack);
} else if (char == '7') {
thestack = 7;
stack.push(&thestack);
} else if (char == '8') {
thestack = 8;
stack.push(&thestack);
} else if (char == '9') {
thestack = 9;
stack.push(&thestack);
} else if (char == '0') {
thestack = 0;
stack.push(&thestack);
} else if (char == '+') {
stack.pop(&thestack);
a = thestack;
stack.pop(&thestack);
b = thestack;
thestack = a + b;
stack.push(&thestack);
} else if (char == '-') {
stack.pop(&thestack);
a = thestack;
stack.pop(&thestack);
b = thestack;
thestack = b - a;
stack.push(&thestack);
} else if (char == '*') {
stack.pop(&thestack);
a = thestack;
stack.pop(&thestack);
b = thestack;
thestack = a * b;
stack.push(&thestack);
} else if (char == '/') {
stack.pop(&thestack);
a = thestack;
stack.pop(&thestack);
b = thestack;
thestack = b / a;
stack.push(&thestack);
} else if (char == '%') {
stack.pop(&thestack);
a = thestack;
stack.pop(&thestack);
b = thestack;
thestack = mod(b, a);
stack.push(&thestack);
} else if (char == '!') {
stack.pop(&thestack);
if (thestack == 0) {
thestack = 1;
} else {
thestack = 0;
};
stack.push(&thestack);
} else if (char == '`') {
stack.pop(&thestack);
a = thestack;
stack.pop(&thestack);
b = thestack;
if (b > a) {
thestack = 1;
} else {
thestack = 0;
};
stack.push(&thestack);
} else if (char == '|') {
stack.pop(&thestack);
if (thestack == 0) {
settings[2] = 1;
} else {
settings[2] = 3;
};
} else if (char == '\') {
stack.pop(&thestack);
a = thestack;
stack.pop(&thestack);
b = thestack;
thestack = a;
stack.push(&thestack);
thestack = b;
stack.push(&thestack);
} else if (char == '$') {
stack.pop(&thestack);
} else if (char == '.') {
stack.pop(&thestack);
print(thestack);
} else if (char == '#') {
settings = newpos(settings);
} else if (char == 'g') {
stack.pop(&thestack);
y = thestack;
stack.pop(&thestack);
x = thestack;
if ((x >= settings[0] || y >= settings[1]) || (x < 0 || y < 0)) {
thestack = 0;
} else {
getline = program[y];
thestack = ord(getline[x]);
};
stack.push(&thestack);
} else if (char == 'p') {
stack.pop(&thestack);
y = thestack;
stack.pop(&thestack);
x = thestack;
stack.pop(&thestack);
v = thestack;
if ((x < settings[0] || y < settings[1]) || (x >= 0 || y >= 0)) {
getline = program[y];
getline[x] = v;
program[y] = getline;
};
} else if (char == '?') {
settings[2] = random.int(0, 3);
};
settings = newpos(settings);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment