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.