// 2dfbi, © Du-Ne, 2002
// Enjoy! - Please Note: Give no second parameter for interpreting
// Use --debug or --brainfuck for debugging
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
//Editierbare Kosntanten
#define maxc 10000
#define maxx 200
#define maxb 50000
#define maxa 30000
//Interpreter Variablen
#include <stdio.h>
int p, r, q;
char a[maxa], f[maxb], b, o, *s=f;
int interpret(char *k);
// 2dbf -> bf Teil
void wdh(char m_zeichen, int m_anzahl);
int getdirection( int m_predirection,
int m_posc, int m_posx);
char field[maxc][maxx];
char bffield[maxb];
char result[11];
int main(int argc, char *argv[])
{
if(argc==1)
{
cout<<endl
<<"\t----------------------------------------------------"<<endl
<<"\t|2dbfi - The origininal 2dbf interpreter by Du-Ne |"<<endl
<<"\t|Presented by: www.legacy-project.de and www.gcf.de|"<<endl
<<"\t----------------------------------------------------"<<endl<<
endl<<"This program must be started with at least one parameter, the "<<
endl<<"name of the file which is to interpret. If you give a second "<<
endl<<"parameter like --debug, your source is converted and then "<<
endl<<"shown in brainfuck for debugging purposes."<<endl<<"Syntax: "
<<endl<<argv[0]<<" filename [--debug]";
return 0;
}
ifstream in(argv[1]);
if(!in){cout<<"file not found"<<endl; return 0;}
int line = 0;
int pos = 0;
int c = 0;
int x = 0;
int z = 0;
int find = 0;
int pred = 0;
bool dorun;
dorun = true;
for(c=0; c<maxc; c++)
{
for(x=0; x<maxx; x++)
{
field[c][x]=char(32);
}
}
for(find=0; find<maxb; find++)
{
bffield[find] = char(32);
}
find = 0;
while(!in.eof())
{
char ch;
ch=in.get();
if(ch==char(10))
{
line++;
pos = 0;
}else{
field[line][pos] = ch;
pos++;
}
};
pos--;
field[line][pos] = char(32); //Müll entfernen
//cout<<getdirection(dpre, dc, dx)<<endl; //DEBUG
//cout<<field[dc][dx]<<endl; //DEBUG
c = 0;
x = 0;
pred = 0;
int gotback;
int gotdir;
int gotcount;
char giveout;
find = 0;
while(dorun)
{
gotback = getdirection(pred, c, x);
gotdir = gotback / 10;
gotcount = gotback % 10;
switch(gotdir)
{
case 0: // Error
cout<<endl<<"2dbf Layout Error at ["<<c+1<<"]["<<x+1
<<"]... (Line|Letter)"
<<endl
<<"Debug Information: gotback = "<<gotback<<" gotdir = "
<<gotdir<<" gotcount = "<<gotcount<<" pre-direction = "
<<pred
<<endl;
return 0;
break;
case 9: // Ende
if(argc>2)
{
return 0;
}else{
dorun = false;
}
break;
case 1: // Nach Rechts
x++;
giveout = char(43); // +
break;
case 2: // Nach Links
x--;
giveout = char(45); // -
break;
case 3: // Nach Rechts-Unten
x++;
c++;
giveout = char(62); // >
break;
case 4: // Nach Links-Unten
x--;
c++;
giveout = char(60); // <
break;
case 5: // Nach Unten
c++;
giveout = char(91); // [
break;
case 6: // Nach Oben
c--;
giveout = char(93); // ]
break;
case 7: // Nach Rechts-Oben
x++;
c--;
giveout = char(46); // .
break;
case 8: // Nach Links-Oben
x--;
c--;
giveout = char(44); // ,
break;
}
z = 0;
wdh(giveout, gotcount);
while(true) //wdh schleife
{
if(result[z]==char(32)) break;
if(argc>2)
{
cout<<result[z];
}else{
//cout<<"find: "<<find<<" ";
bffield[find] = result[z];
//cout<<"result: "<<result[z]<<" ";
//cout<<"bffield: "<<bffield[find]<<endl;
find++;
}
z++;
}
pred = gotdir;
//cout<<"x";
}
if(argc<3) interpret(bffield);
//DEBUG: Output bffield
//cout<<"Dedugging..."<<endl;
//for(find=0; find<100; find++)
//{
// cout<<bffield[find];
//}
return 0;
}
int getdirection( int m_predirection,
int m_posc, int m_posx)
{
int m_newdir = 0;
int m_counter = 0;
int m_c_dirs = 0;
char m_betrchr;
bool m_allowed[9];
bool keepdir = false;
//allowed-array initialisieren in Abhängigkeit der predirection
m_allowed[0] = false;
m_allowed[1] = true;
m_allowed[2] = true;
m_allowed[3] = true;
m_allowed[4] = true;
m_allowed[5] = true;
m_allowed[6] = true;
m_allowed[7] = true;
m_allowed[8] = true;
switch(m_predirection)
{
case 0:
m_allowed[0] = true;
break;
case 1:
m_allowed[2] = false;
break;
case 2:
m_allowed[1] = false;
break;
case 3:
m_allowed[8] = false;
break;
case 8:
m_allowed[3] = false;
break;
case 4:
m_allowed[7] = false;
break;
case 7:
m_allowed[4] = false;
break;
case 5:
m_allowed[6] = false;
break;
case 6:
m_allowed[5] = false;
break;
}
//Erlaubte Directions bestimmen
if(m_posx==0)
{
m_allowed[2] = false;
m_allowed[4] = false;
m_allowed[8] = false;
}
if(m_posx==(maxx-1))
{
m_allowed[1] = false;
m_allowed[3] = false;
m_allowed[7] = false;
}
if(m_posc==0)
{
m_allowed[6] = false;
m_allowed[7] = false;
m_allowed[8] = false;
}
if(m_posc==(maxc-1))
{
m_allowed[5] = false;
m_allowed[4] = false;
m_allowed[3] = false;
}
//Direction bestimmen
if(m_allowed[1] && field[m_posc ][m_posx+1] != char(32) && !keepdir)
{
m_newdir = 1;
m_betrchr = field[m_posc ][m_posx+1];
m_c_dirs++;
if(m_newdir == m_predirection){keepdir=true;}
}
if(m_allowed[2] && field[m_posc ][m_posx-1] != char(32) && !keepdir)
{
m_newdir = 2;
m_betrchr = field[m_posc ][m_posx-1];
m_c_dirs++;
if(m_newdir == m_predirection){keepdir=true;}
}
if(m_allowed[3] && field[m_posc+1][m_posx+1] != char(32) && !keepdir)
{
m_newdir = 3;
m_betrchr = field[m_posc+1][m_posx+1];
m_c_dirs++;
if(m_newdir == m_predirection){keepdir=true;}
}
if(m_allowed[4] && field[m_posc+1][m_posx-1] != char(32) && !keepdir)
{
m_newdir = 4;
m_betrchr = field[m_posc+1][m_posx-1];
m_c_dirs++;
if(m_newdir == m_predirection){keepdir=true;}
}
if(m_allowed[5] && field[m_posc+1][m_posx ] != char(32) && !keepdir)
{
m_newdir = 5;
m_betrchr = field[m_posc+1][m_posx ];
m_c_dirs++;
if(m_newdir == m_predirection){keepdir=true;}
}
if(m_allowed[6] && field[m_posc-1][m_posx ] != char(32) && !keepdir)
{
m_newdir = 6;
m_betrchr = field[m_posc-1][m_posx ];
m_c_dirs++;
if(m_newdir == m_predirection){keepdir=true;}
}
if(m_allowed[7] && field[m_posc-1][m_posx+1] != char(32) && !keepdir)
{
m_newdir = 7;
m_betrchr = field[m_posc-1][m_posx+1];
m_c_dirs++;
if(m_newdir == m_predirection){keepdir=true;}
}
if(m_allowed[8] && field[m_posc-1][m_posx-1] != char(32) && !keepdir)
{
m_newdir = 8;
m_betrchr = field[m_posc-1][m_posx-1];
m_c_dirs++;
if(m_newdir == m_predirection){keepdir=true;}
}
//Anzahl bestimmen und Ausgeben
m_counter = int(m_betrchr)-48;
//if(m_posx == 66 & m_posc == 76)
//{
// cout<<"Debug: couter: "<<m_counter<<" c_dir: "<<m_c_dirs<<
// " keepdir: "<<keepdir<<" newdir: "<<m_newdir
// <<endl;
//}
if(m_c_dirs==1)
{
if((m_counter <10) && (m_counter >=0))
{
return (m_newdir * 10) + m_counter;
}else{
if(keepdir){return m_newdir * 10;} // Ausnahme bei Arm-Verlängerung
return m_newdir * 10 + 1;
}
}else{
if(m_c_dirs>1)
{
if((m_counter <10) && (m_counter >=0))
{
if(keepdir){return (m_newdir * 10) + m_counter;} else {return 0;}
}else{ // 0 = Fehler
if(keepdir){return (m_newdir * 10) ;} else {return 0;}
}
}else{
return 90; // 90 = Ende
}
}
}
void wdh(char m_zeichen, int m_anzahl)
{
int m_x = 0;
int m_y = 0;
char m_result[11] = " ";
if(m_anzahl != 0)
{
for(m_x = 0; m_x < m_anzahl; m_x++)
{
//cout<<m_zeichen;
m_result[m_x] = m_zeichen;
m_y++;
}
}
strncpy(result, m_result, 11);
}
// INTERPRETER TEIL (taken from bfi)
int interpret(char *k)
{
char *d;
r++;
while( *k ) {
switch(o=1,*k++) {
case '<': p--; break;
case '>': p++; break;
case '+': a[p]++; break;
case '-': a[p]--; break;
case '.': putchar(a[p]); fflush(stdout); break;
case ',': a[p]=getchar();fflush(stdout); break;
case '[':
for( b=1,d=k; b && *k; k++ )
b+=*k=='[', b-=*k==']';
if(!b) {
k[-1]=0;
while( a[p] )
interpret(d);
k[-1]=']';
break;
}
case ']':
puts("2dbf Syntax Error: Unbalanced brackets []"), exit(0);
case '#':
if(q>2)
printf("%2d %2d %2d %2d %2d %2d %2d %2d %2d %2d\n%*s\n",
*a,a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],3*p+2,"^");
break;
default: o=0;
}
if( p<0 || p>maxa)
puts("2dbf Syntax Error: Array-Over/Underflow"), exit(0);
}
r--;
return 0;
}