/***********************
 *  ACALC V1.011       *
 * by David Schweikert *
 * Made on 16/3/91     *
 * Compiled with       *
 * Lattice C v5.02     *
 * Compile it with     *
 * LC -Lm acalc        * 
 ***********************

 *************************************************************
 * VARIABLES NAMES :     	                             *
 *              	                                     *
 * a 		= Flag to mark a number + an operation       *
 * bak[]        = A save of the last digits pressed          *
 * c 		= Input Character in ASCII                   *
 * car		= Input from program character               *
 * d 		= Flag to mark if decimal                    *
 * donnees(2)   = The program                                *      
 * dummy        = Only important for the compiler...         *
 * ff - fi      = Fractional and integer part                *
 * flags[]      = The programmable flags                     *
 * handle       = Handle of RAW:                             *
 * hfile        = Handle of a file                           *
 * imp          = Flag to mark on a program a direct input   *
 * inputp	= Input program name character               *
 * lab          = Label name                                 *
 * lastprn      = Prn backup for the Go function             *
 * ligne        = Only important for to write a thing        *
 * m            = Counter of various for cicles              *
 * mem[]        = Memory (variables)                         *
 * n 		= Digit on number position                   *
 * nbtrans      = Octects write                              *
 * newprn       = NewPrn for the Go function                 *
 * nombreX      = Only important on file opening             *
 * nomfich      = Name of the program                        *
 * noret        = Flag to mark to not do the Return function *
 * prg          = Flag to mark if a program is running       *
 * prn          = Digit on program position                  *
 * reach        = Flag to mark if label found in Go function *   
 * retu		= Flag to mark RETURN pressed                *
 * q 		= Input Number                               *
 * s 		= Flag to mark the negativ sign              *
 * stack[] 	= THE STACK !!!                              *
 * var		= Variable name                              *
 * vtest	= Test type                                  *
 *************************************************************/ 


#include <stdio.h>
#include <math.h>

#define c *caract
#define inputp *progi
#define var *ivar
#define car *icar
#define lab *ilab
#define vtest *ivtest

int q,a=0,d=0,retu=0,noret=0;
double stack[10],n=-1;

void main()
{
	int dummy=0,nombre,handle,hfile,nombre2,nombre3;
	int prg=0,prn=0,lastprn,reach,newprn,bak[15],m;
	char caract[81],ligne[256],progi[1],ivar[1],icar[1];
	char ilab[1],ivtest[1];
	int nbtrans,imp=0,flags[26];
	double mem[26],ff,fi;
	int donnees[100];
	int donnees2[100];
	char nomfich[81];
	handle =  open("RAW:100/100/300/32/    A C A L C  v1.0",2,dummy);
	if (handle != -1) {
	sprintf(ligne,">>>");
	write(handle,ligne,strlen(ligne));
	do {
		if (prg==1)
		{
			if (imp != 1)
			{
				prn++;
				c = donnees2[prn];
				if (c=='E')
				{
					prg = 0;
					prn = 0;
					c='`';
				}
			} 
			else
			{
				nombre = read(handle,caract,1);
			}
		}
		else
			nombre = read(handle,caract,1);
		n+=1;
		if (c >= '0' && c <= '9')
		{	
			q=c-48;
			for(m=10;m>0;m--)
			bak[m]=bak[m-1];
			bak[0]=q;
			sprintf(ligne,"%d",q); 
			write(handle,ligne,strlen(ligne));
			if (a==1)
				up();
			if (stack[0]<0)
			{
				if (d==1)
					stack[0]=stack[0]-1/pow(10.0000,n)*q;
				else
					stack[0]=stack[0]*10-q;
			}
			else
			{
				if (d==1)
					stack[0]=stack[0]+1/pow(10.0000,n)*q;
				else
					stack[0]=stack[0]*10+q;
			}
		}
		switch(c)
		{
		case '.': d=1;	n=0;	
			sprintf(ligne,"."); 
			write(handle,ligne,strlen(ligne));	
			break;
		case 13 : /* RETURN */
			if (imp!=1)
		 	{
				if(noret==0)
				{
				sprintf(ligne,"\n%.5f\n>>>",stack[0]); 
        			write(handle,ligne,strlen(ligne));	
				up();
				retu=1;
				}
				else
				{
				sprintf(ligne,"\n%.2f >>>",stack[0]); 
        			write(handle,ligne,strlen(ligne));	
				up();
				retu=1;
				}
			}
			else
			{
				mem[var-96]=stack[0];	
				imp = 0;
				a=1;
				sprintf(ligne,"\n>>>"); 
				write(handle,ligne,strlen(ligne));
			}
			noret=0;
			break;
		case ' ':if (imp!=1)
		 	{
		 		sprintf(ligne,"\n%.5f\n>>>",stack[0]); 
				write(handle,ligne,strlen(ligne));	
				up();
				retu=1;	
			}
			else
			{
				mem[var-96]=stack[0];	
				imp = 0;
				a=1;
				sprintf(ligne,"\n>>>"); 
				write(handle,ligne,strlen(ligne));
			}
			break;
		case 8 : /* BACK */ 
			n--;
			if(d==1)
			{
				if (stack[0]==0)
				{
				sprintf(ligne,"\n%.5f\n>>>",stack[0]); 
					write(handle,ligne,strlen(ligne));
					break;
				}
				else if(stack[0]>0)
			stack[0]=stack[0]-1/pow(10.0000,n)*bak[0];
				else
			stack[0]=stack[0]+1/pow(10.0000,n)*bak[0];
			}
			else
			{
				if (stack[0]==0)
					break;
				else if(stack[0]>0)
					stack[0]=(stack[0]-bak[0])/10;
				else
					stack[0]=(stack[0]+bak[0])/10;
			}
			sprintf(ligne,"\b \b",stack[0]); 
			write(handle,ligne,strlen(ligne));
			n--;
			for(m=0;m<10;m++)
			bak[m]=bak[m+1];
			break;
		case '_': stack[0]=-stack[0];
			n--;
			if(d==1)
			{
				sprintf(ligne,"\n\nTHEN ",stack[0]); 
				write(handle,ligne,strlen(ligne));
			}
			else
			{
				sprintf(ligne,"\n\n>>>%.0f",stack[0]); 
				write(handle,ligne,strlen(ligne));
			}	
			break;
		case 'I': up(); 
			if (prg != 1)
			{
				sprintf(ligne,"\nvar ? ",stack[0]); 
				write(handle,ligne,strlen(ligne));
				nombre3 = read(handle,ivar,1);
				sprintf(ligne,"\n\n%s   ? ",ivar); 
				write(handle,ligne,strlen(ligne));
			}
			else
			{
				prn++;
				var = donnees2[prn];
				sprintf(ligne,"\n%.1s  ? ",ivar); 
				write(handle,ligne,strlen(ligne));
			}
			imp=1;	break;
		case 'W':
			if(prg==1)
			{
			sprintf(ligne,"\n",icar); 
			write(handle,ligne,strlen(ligne));
			do {
				prn++;
				car=donnees2[prn];
				if(car!=')')
				{
					sprintf(ligne,"%.1s",icar); 
					write(handle,ligne,strlen(ligne));
				}
			} while(car != ')');
			}
			noret=1;
			break;
		case 'K':
			if(prg==1){
			prn++;
			vtest = donnees2[prn];
			if(vtest=='0')
			{
				prn++;
				vtest = donnees2[prn];
				if(vtest=='=')
				{
					if(stack[0]!=0)
					{
					prn++;
					prn++;
					}	
				}
				if(vtest=='<')
				{
					if(stack[0]>=0)
					{
					prn++;
					prn++;
					}	
				}
				if(vtest=='>')
				{
					if(stack[0]<=0)
					{
					prn++;
					prn++;
					}	
				}
				if(vtest=='!')
				{
					if(stack[0]==0)
					{
					prn++;
					prn++;
					}	
				}
			}
			if(vtest=='y')
			{
				prn++;
				vtest = donnees2[prn];
				if(vtest=='=')
				{
					if(stack[0]!=stack[1])
					{
					prn++;
					prn++;
					}	
				
				}
				if(vtest=='<')
				{
					if(stack[0]>=stack[1])
					{
					prn++;
					prn++;
					}	
				}
				if(vtest=='>')
				{
					if(stack[0]<=stack[1])
					{
					prn++;
					prn++;
					}	
				}
				if(vtest=='!')
				{
					if(stack[0]==stack[1])
					{
					prn++;
					prn++;
					}		
				}
			}
			}
			break;
			
		case 'Q':
			prg=0;
			prn=0;
			break;
		case 'G':
			if (prg==1)
			{
				prn++;
				lastprn=prn;
				lab = donnees2[prn];
				prn=0;
				do {
					car=donnees2[prn];
					if(car=='L')
					{
						prn++;
						car=donnees2[prn];
						if (car==lab)
						{
							reach=1;
							newprn=prn;
						}
						else
							printf(" Sorry !\n");
					}
					prn++;
				} while (donnees2[prn]!='E');
				if(reach==1)
					prn=newprn;
				else
					prn=lastprn;
			}
			break;
		case 'R':
			if(retu!=1)
				up();
			if (prg != 1)
			{
				sprintf(ligne,"\nvar ? \n",stack[0]); 
				write(handle,ligne,strlen(ligne));
				nombre3 = read(handle,ivar,1);
				sprintf(ligne," %s = ",ivar); 
				write(handle,ligne,strlen(ligne));
				stack[0]=mem[var-96];
				sprintf(ligne,"%.5f\n>>>",stack[0]); 
				write(handle,ligne,strlen(ligne));
			}
			else
			{
				prn++;
				var = donnees2[prn];
				stack[0]=mem[var-96];
			}
			a=1;
			break;
		case 'M': if (prg != 1)
			{
				sprintf(ligne,"\nvar ? \n",stack[0]); 
				write(handle,ligne,strlen(ligne));
				nombre3 = read(handle,ivar,1);
				sprintf(ligne," %s = ",ivar); 
				write(handle,ligne,strlen(ligne));
				mem[var-96]=stack[0];
				sprintf(ligne,"%.5f\n>>>",stack[0]); 
				write(handle,ligne,strlen(ligne));
			}
			else
			{
				prn++;
				var = donnees2[prn];
				mem[var-96]=stack[0];
			}
			a=1;
			break;
		case 'v': 
		sprintf(ligne,"\nX=%.5f Y=%.5f\n>>>",stack[0],stack[1]); 
			write(handle,ligne,strlen(ligne));
			break;
		case 'A': if(prg==1) {
				prn++;
				var = donnees2[prn];
				flags[var-96]=1;
			}
			break;
		case 'D': if(prg==1) {
				prn++;
				var = donnees2[prn];
				flags[var-96]=0;
			}
			break;
		case 'F': if(prg==1) {
				up();
				prn++;
				var = donnees2[prn];
				if(flags[var-96]!=1)
					prn+=2;
				}
			break;
		case 'f': ff=modf(stack[0],&fi);
			stack[0]=ff;	
			sprintf(ligne,"\n%.5f\n>>>",stack[0]); 
			write(handle,ligne,strlen(ligne));
			demi();	break;
		case 'i': ff=modf(stack[0],&fi);
			stack[0]=fi;	
			sprintf(ligne,"\n%.5f\n>>>",stack[0]); 
			write(handle,ligne,strlen(ligne));
			demi();	break;
		case 'd': down();
			break;
		case 'X':
			up();
			sprintf(ligne,"\nPROGRAM NAME ?"); 
			write(handle,ligne,strlen(ligne));
			prn=0;
			do {
				nombre2 = read(handle,progi,1);
				if (inputp!=13)
				{
					if(inputp!=8)
					{
					sprintf(ligne,"%.1s",progi); 
					write(handle,ligne,strlen(ligne));
					nomfich[prn] = inputp;
					prn++;
					}
					else
					{
						if(prn!=0)
						{
				prn--;
				nomfich[prn] = '\0';
				sprintf(ligne,"\n\nPROGRAM NAME ?%s",nomfich); 
				write(handle,ligne,strlen(ligne));
						}
					}
				}
				else
					nomfich[prn]='\0';
			} while(inputp != 13);
			hfile = open(nomfich, 0, dummy);
			if(hfile != -1)
			{
				nbtrans = read(hfile, donnees2, sizeof(donnees));
				close (hfile);
			}
			else
			{
				printf("Error : can't open %s !\n",nomfich);
				down();
				sprintf(ligne,"\n\n>>>");
				write(handle,ligne,strlen(ligne));
				break;
			}
			sprintf(ligne,"\n\nPROGRAM %s", nomfich); 
			write(handle,ligne,strlen(ligne));
			prg=1;
			prn=0;
			break;
		case 'P': 
			prn = 0;
			sprintf(ligne,"\n\nPROGRAM NAME ?"); 
			write(handle,ligne,strlen(ligne));
			do {
				nombre2 = read(handle,progi,1);
				if (inputp!=13)
				{
					if(inputp!=8)
					{
				sprintf(ligne,"%.1s",progi); 
				write(handle,ligne,strlen(ligne));
				nomfich[prn] = inputp;
				prn++;
					}
					else
					{
						if(prn!=0)
						{
				prn--;
				nomfich[prn] = '\0';
				sprintf(ligne,"\n\nPROGRAM NAME ?%s",nomfich); 
				write(handle,ligne,strlen(ligne));
						}
					}
				}
				else
					nomfich[prn]='\0';
			} while(inputp != 13);
			sprintf(ligne,"\nPRG>>>"); 
			write(handle,ligne,strlen(ligne));
			prn = 0;
			do {
				nombre2 = read(handle,progi,1);
				if(inputp!=8)
				{
					sprintf(ligne,"%.1s",progi); 
					write(handle,ligne,strlen(ligne));
					donnees[prn+1] = inputp;
					prn++;
				}
				else
				{
					if(prn!=0)
					{
			prn--;
			donnees[prn+1] = '\0';
			sprintf(ligne,"\b \b"); 
			write(handle,ligne,strlen(ligne));
					}
				}
			} while(inputp != 13);
			prn++;
			donnees[prn]='E';
			hfile = creat(nomfich, dummy);
			if(hfile == -1)
			{
				printf("\n\nError on %s creation !\n", nomfich);	
				close(hfile);
				sprintf(ligne,"\n\n>>>"); 
				write(handle,ligne,strlen(ligne));
				break;
			}
			nbtrans = write(hfile, donnees, prn*8);
			close(hfile);
			sprintf(ligne,"\n\n>>>"); 
			write(handle,ligne,strlen(ligne));
			break;
		case '+': stack[0]=stack[1]+stack[0];	
			sprintf(ligne,"\n%.5f\n>>>",stack[0]); 
			write(handle,ligne,strlen(ligne));
			semi();	break;
		case '-': stack[0]=stack[1]-stack[0];	
			sprintf(ligne,"\n%.5f\n>>>",stack[0]); 
			write(handle,ligne,strlen(ligne));
			semi();	break;
		case '*': stack[0]=stack[1]*stack[0];	
			sprintf(ligne,"\n%.5f\n>>>",stack[0]); 
			write(handle,ligne,strlen(ligne));
			semi();	break;
		case '/': if(stack[0]!=0)
			{
				stack[0]=stack[1]/stack[0];	
				sprintf(ligne,"\n%.5f\n>>>",stack[0]); 
				write(handle,ligne,strlen(ligne));
				semi();
			}
			else
			{
				sprintf(ligne,"I Can't divide by 0 !\n%.2f >>>",stack[0]); 
				write(handle,ligne,strlen(ligne));
			}
			break;
		case 'p': stack[0]=pow(stack[1],stack[0]);	
			sprintf(ligne,"\n%.5f\n>>>",stack[0]); 
			write(handle,ligne,strlen(ligne));
			semi();	break;
		case 'r': stack[0]=pow(stack[1],(1/stack[0]));	
			sprintf(ligne,"\n%.5f\n>>>",stack[0]); 
			write(handle,ligne,strlen(ligne));
			semi();	break;
		case 'q': stack[0]=sqrt(stack[0]);	
			sprintf(ligne,"\n%.5f\n>>>",stack[0]); 
			write(handle,ligne,strlen(ligne));
			demi();	break;
		case 's': stack[0]=sin(stack[0]);	
			sprintf(ligne,"\n%.5f\n>>>",stack[0]); 
			write(handle,ligne,strlen(ligne));
			demi();	break;
		case 'S': stack[0]=asin(stack[0]);	
			sprintf(ligne,"\n%.5f\n>>>",stack[0]); 
			write(handle,ligne,strlen(ligne));
			demi();	break;
		case 'h': stack[0]=sinh(stack[0]);	
			sprintf(ligne,"\n%.5f\n>>>",stack[0]); 
			write(handle,ligne,strlen(ligne));
			demi();	break;
		case 'c': stack[0]=cos(stack[0]);	
			sprintf(ligne,"\n%.5f\n>>>",stack[0]); 
			write(handle,ligne,strlen(ligne));
			demi();	break;
		case 'C': stack[0]=acos(stack[0]);	
			sprintf(ligne,"\n%.5f\n>>>",stack[0]); 
			write(handle,ligne,strlen(ligne));
			demi();	break;
		case 'j': stack[0]=cosh(stack[0]);	
			sprintf(ligne,"\n%.5f\n>>>",stack[0]); 
			write(handle,ligne,strlen(ligne));
			demi(); break;
		case 't': stack[0]=tan(stack[0]);	
			sprintf(ligne,"\n%.5f\n>>>",stack[0]); 
			write(handle,ligne,strlen(ligne));
			demi();	break;
		case 'T': stack[0]=atan(stack[0]); 	
			sprintf(ligne,"\n%.5f\n>>>",stack[0]); 
			write(handle,ligne,strlen(ligne));
			demi();	break;
		case 'k': stack[0]=tanh(stack[0]);	
			sprintf(ligne,"\n%.5f\n>>>",stack[0]); 
			write(handle,ligne,strlen(ligne));
			demi();	break;
		case 'Z': stack[0]=cot(stack[0]);	
			sprintf(ligne,"\n%.5f\n>>>",stack[0]); 
			write(handle,ligne,strlen(ligne));
			demi();	break;
		case 'z': stack[0]=atan2(stack[1],stack[0]);
			sprintf(ligne,"\n%.5f\n>>>",stack[0]); 
			write(handle,ligne,strlen(ligne));
			semi();	break;
		}
	} while(c != '\033');
	close(handle);
	}
}

up()
{
	int m;
	a=0;
	for(m=10;m>0;m--)
	stack[m]=stack[m-1];
	stack[0]=0;
	n=0;
	d=0;
	retu=0;
	noret=0;
	return 0;
}

down()
{
	int m;
	for(m=0;m<10;m++)
	stack[m]=stack[m+1];
	d=0;
	n=0;
	retu=0;
	noret=0;
	return 0;
}	
	
semi()
{
	int m;
	for(m=1;m<10;m++)
	stack[m]=stack[m+1];
	a=1;
	d=0;
	n=0;
	retu=0;
	noret=0;
	return 0;
}

demi()
{
	a=1;
	d=0;
	n=0;
	retu=0;
	noret=0;
	return 0;
}


 




