Elikkäs tein tässä ajankuluksi brainfuck++ tulkin C++:lla (kutsun sitä brainfuck++ koska Qman kutsuu omaa tulkkiaan brainfuck+ ja tässä on enemmän ominaisuuksia kuin siinä ^^)
Syntaksilista löytyy osoitteessa http://koodataan.aineissa.com/b .txt ja sourcet ilman kommentteja http://koodataan.aineissa.com/brain.txt
win sourcet http://koodataan.aineissa.com/brain_win32.txt
Linuxilla toimii loistavasti windowsilla en niinkään ole testannut...
Ja huom syntaksilista...
Käyttö:
normaali ajomode
binäärinnimi tiedostojostaluetaan
debugmode
binäärinnimi tiedostojostaluetaan -d
Hello wolrd kyseisellä tulkilla
[Ap@F*3p@F**FFAp@F**FFF3p@F**FFF9p@F**FFF6p@F**FCp@F*2p@F**FFF6p@F**FFF3p@F**FFF3p@F**FFBp@F**Cp@Ap@r:r:r:r:r:r:r:r:r:r:r:r:r:r:]
#include <iostream>
#include <time.h>
#include <stdio.h>
#include <fstream>
//kirjastot
int debug;
int stack_push(int nmb);
int stack_pop();
int debug1=0;
int debug2=500;
int printmemory(int wh, int tw);
void tsleep(int mseconds);
using namespace std;
int point[20000];
char code[500];
int stack[150];
int stc=0;
int p=0;
int parse();
//muuttujien ja funktioiden esittely
//pääfunktio alkaa
int main(int argc, char *argv[]) {
char dbg[0];
if (argc < 2) { //jos ei ole tarpeeksi parametrejä niin kerrotaan mitä pitää laittaa
cout << "Usage: " << argv[0] << " file\n";
}
else {
if (argc == 2) {
if (strcmp(argv[2],"-d")==0) { //tarkistetaan onko toinen parametri olemassa
cout << "Debug mode enabled\n";
cout << "Give debug space start: ";
cin >> debug1;
cout << "Give debug space end: ";
cin >> debug2;
if (debug2 != 0) {
debug = 1;
}
else {
cout << "\nError no space defined disabling debugmode\n";
debug = 0;
} //jos asiat on kunnossa niin asetetaan debugmode päälle
}
}
int i=0;
int a=0;
ifstream luku(argv[1]);
if (!luku) {
cout << "Cant find specified file\n";
}
else {
for (i=0; i<=5000; i++) {
if (luku != '\0') {
luku >> code[a];
a++;
}
else {
break;
}
}
}
luku.close(); //luetaan tiedostosta koodi
parse(); //parsetaan
}
}
int stack_push(int nmb) {
stack[stc] = nmb;
stc++; //pinoon työntö
}
int stack_pop() { //pinosta otto
int rt;
stc--;
rt = stack[stc];
stack[stc] = '\0';
return rt;
}
int parse() {
int len=5000;
int i;
int jakjn=0;
int c1=0;
int c2=0;
int kuittaus=0;
int whileaddr=0;
int currentpointer=0;
int slp=0;
int alipaalla=0;
int ceflag; //parsefunktion muuttujat
for (i=0; i<=20000; i++) {
point[i] = 0;
}
if (code[0] != '[') { //tarkastetaan alkaako koodi [ merkillä
cout << "Error on line 1 program must start using [ and end using ]\n";
return 0;
}
for (i=0; i<=500; i++) { //parserointi
switch (code[i]) {
case '{':
currentpointer = p;
whileaddr = i;
break;
case '}':
if (point[currentpointer] >= 0) {
i = whileaddr;
}
else {
whileaddr = 0;
currentpointer = 0;
}
break;
case 'l':
stack_push(i+1);
alipaalla=1;
i = point[p];
break;
case 't':
if (alipaalla == 1) {
i = stack_pop();
alipaalla=0;
}
break;
case '<':
p=p-1;
break;
case '>':
p=p+1;
break;
case '^':
point[p] = point[p] * point[p];
break;
case '@':
point[p] = 0;
break;
case '*':
point[p] = point[p] * 2;
break;
case '/':
jakjn = point[p] % 2;
if (jakjn == 0) {
point[p] = point[p] / 2;
}
else {
cout << "Error on line " << i+1 << " remainder must be 0\n";
break;
}
break;
case '1':
point[p]++;
break;
case '2':
point[p] = point[p] + 2;
break;
case '3':
point[p] = point[p] + 3;
break;
case '4':
point[p] = point[p] + 4;
break;
case '5':
point[p] = point[p] + 5;
break;
case '6':
point[p] = point[p] + 6;
break;
case '7':
point[p] = point[p] + 7;
break;
case '8':
point[p] = point[p] + 8;
break;
case '9':
point[p] = point[p] + 9;
break;
case 'A':
point[p] = point[p] + 10;
break;
case 'B':
point[p] = point[p] + 11;
break;
case 'C':
point[p] = point[p] + 12;
break;
case 'D':
point[p] = point[p] + 13;
break;
case 'E':
point[p] = point[p] + 14;
break;
case 'F':
point[p] = point[p] + 15;
break;
case '+':
point[p]++;
break;
case '-':
--point[p];
break;
case ':':
char charac;
charac = point[p];
cout << charac;
break;
case '.':
cout << point[p];
break;
case ',':
cout << "\nInput> ";
cin >> point[p];
break;
case 'j':
if (point[p] != 0) {
i=point[p];
}
else {
cout << "Error on line " << i+1 << " jmp address cant be 0\n";
break;
}
break;
case ' ':
cout << "Warning on line " << i+1 << "\n";
break;
case 'p':
if (point[p] != 0) {
stack_push(point[p]);
}
else {
cout << "Error on line " << i+1 << " cant push 0 into the stack\n";
}
break;
case 'r':
point[p] = stack_pop();
break;
case 'c':
if (c1 != 0 && c2 != 0) {
if (c1 == c2) {
if (point[0] !=0 ) {
i=point[0];
c1 = 0;
c2 = 0;
p = 0;
}
else {
cout << "Error on line " << i+1 << " jmp address not defined\n";
break;
}
}
else {
ceflag = 1;
}
}
else {
if (c1 != 0) {
c2 = point[p];
}
else {
c1 = point[p];
}
}
break;
case '!':
p = 0;
break;
case 'n':
break;
case 'z':
if (ceflag == 1) {
c1 = 0;
c2 = 0;
p = point[p];
i = point[0];
}
break;
case 'd':
if (point[p] != 0) {
slp = point[p];
sleep(slp);
}
else {
cout << "Error on line " << i+1 << " pointer cant be 0 when using sleep\n";
break;
}
break;
case '\0':
return 0;
break;
}
if (debug == 1) { //jos debugmode on yksi niin tulostetaan taulukko ja vaaditaan käyttäjältä kuittaus
cout << "\nCharacter: " << code[i] << "\n";
cout << "Pointer: " << p << "\n";
printmemory(debug1, debug2);
cout << "write 1 to continue\n";
while (1) {
cout << "> ";
cin >> kuittaus;
if (kuittaus == 1) {
break;
}
}
}
}
}
int printmemory(int wh, int tw) {
int d;
cout << "Array:\n|";
for (d=wh; d<=tw; d++) { //debugin tulostus
if (d == p) {
cout << "-> " << point[d] << " <-|";
}
else {
cout << point[d] << "|";
}
}
cout << "\n";
}
void tsleep(int mseconds)
{
cout << "\nStarting sleep\n";
clock_t goal = mseconds + clock();
while (goal > clock()); //windowsilla jostainsyystä sleep ei toiminut niin tämä on windowsia varten
}Uusin versio
win32: http://koodataan.aineissa.com/brain_win32.txt
*nix: http://koodataan.aineissa.com/brain.txt
Aihe on jo aika vanha, joten et voi enää vastata siihen.