/* Introducing: Portable False!!!! PortableFalse is different from AmigaFalse in: - its Portable!!! :-) - full stack checking - strongly typed (no joke, really!) - debug-modi - real and meaningfull errormessages - ` inline assembly not supported - : and ; not supported for other than variable access. - "beta" (flush) and "zero-slash" (pick) from the amiga charset are now 'B' and 'O' resp. - 'D' toggles stack-watch mode on and off. format: [ bottom_of_stack , ... , top_of_stack | next_symbol ] - "-q" on command line is quiet mode: no title printing. (usefull for "filter"-type programs: 1> False -q filter.f burp) this source has been writtin in good C style: - no modularity whatsoever (only main()) - only global variables - lots of ugly macros (replacing functions) - great source formatting and indentation still it compiles on 4-5 different ansi-C compilers. if you have trouble porting it to your machine, your compiler sucks. (guaranteed to be digested by: MaxonC++, SAS/C, DICE, GNUC++ (also on other platforms)) todo: - interactive debugging? False, Amiga False, Portable False are all trademarks of $#%! */ #define MZ 10000 #define MS 1000 #include #define NIL 0 #define NUM 0 #define FUNC 1 #define VADR 2 #define UNDEF 3 #define l(x) ;break;case x: #define x(num) {ernum=num;goto er;} #define push(v,a) {if(S-2se)x(5)else{if((ex=(int)a)!=(ge=(int)*S++))x(6);\ v= *S++;};} #define pa(v,av) {if(S+2>se)x(5)else{av= *S++;v= *S++;};} #define ru(v) {if(rp-1rend)x(14)else{v= *rp++;};} #define CA(c) {ru(p);p=c;} #define pu(x) push(x,NUM) #define po(x) pop(x,NUM) #define op(o) {po(b)po(d);pu((X)((int)d o (int)b));} #define cm(o) {po(b)po(d);pu((X)(-((int)d o (int)b)));} #define un(o) {po(b)pu((X)(o (int)b));} #define ne (p1)if(args[1][0]=='-'&&args[1][1]== 'q')t=2;if(t==1)P("Portable False Interpreter/Debugger v0.1 (c) 1993 $#%!" "\n");if(narg='0'&&c<='9' ){int num;sscanf(p-1,"%d",&num);W((*p>='0')&&(*p<='9'))p++;push((X)num,NUM );}else if(c>='a'&&c<='z'){push((X)&var[(c-'a')*2],VADR);}else switch(c){ case' ':case '\n':case'\t':l('+')op(+)l('-')op(-)l('*')op(*)l('/')op(/)l( '&')op(&)l('|')op(|)l('_')un(-)l('~')un(~)l('=')cm(==)l('>')cm(>)l('%')pa( b,e)l('$')pa(b,e)push(b,e)push(b,e)l('\\')pa(b,e)pa(d,f)push(b,e)push(d,f) l('@')pa(b,t1)pa(d,t2)pa(e,t3)push(d,t2)push(b,t1)push(e,t3)l('O')po(b)if( S+((t=(int)b*2)+2)>se)x(5)b= *(S+t);d= *(S+t+1);push(d,b)l(':')pop(b,VADR) pa(d,e)*((XP)b)=d;*(((XP)b)+1)=e;l(';')pop(b,VADR)push(*((XP)b),*(((XP)b)+ 1));l('.')po(b)P("%d",(int)b);l(',')po(b)P("%c",(char)b);l('^')pu((X)fgetc (stdin));l('B')fflush(stdout);fflush(stdin);l('\"')W((*p!='\"')&&ne){fputc (*p,stdout);p++;};p++;if(!ne)x(11);l('{')ec;l('\'')pu((X)*p++);l('`')x(9); l('D')db=!db;l('[')push((X)p,FUNC)t=1;W(t>0&&ne){a= *p++;if(a=='['){t++;} else if(a==']'){t--;}else if(a=='{'){ec}else if(a=='\"'){W((*p!='\"')&&ne) p++;p++;if(!ne)x(11);};};if(!ne)x(12);l(']')ro(e)if((int)e==0){ro(p)po(b) if((int)b){ro(d)ru(d)CA(d)ru((X)1);}else{ro(d)ro(d);};}else if((int)e==1){ ro(p)ro(b)ro(d)ru(d)ru(b)CA(d)ru((X)0);}else{p=e;};l('!')pop(b,FUNC)CA(b); l('?')pop(b,FUNC)po(d)if((int)d){CA(b);};l('#')pop(b,FUNC)pop(d,FUNC)ru(d) ru(b);CA(d)ru((X)0);break;default:x(8);};if(db){c= *p;if(c!=' '&&c!='\n'&& c!='\t'&&c!='{'&&c!='\"'){ts=S+20;if(ts>se)ts=se;P("[");W(ts>S){t=(int)*( ts-2);if(t==FUNC){P("");}else if(t==VADR){P("");}else P("%d",( int)*(ts-1));ts-=2;if(ts>S)P(",");};P("|'%c']\n",*p);}};};c=0;p=0;if(S!=se )x(7);er:if(ernum){P("\nERROR: %s!\n",erstr[ernum-1]);if(c)P("WORD: '%c'" "\n",c);if(ernum==6)P("INFO: Expecting %s type, while reading %s type.\n" ,types[ex],types[ge]);if(p){end=p;beg=p;W(*(beg-1)!='\n'){beg--;};W(*end!= '\n'){end++;};t=end-beg;*end=0;if(t>0){P("LINE: %s\n",beg);qq=p-beg+3;P( "AT:");for(t=0;t