#include iolib.h
#include float.h
#include printf2.h
#include transcen.h

char temp1[80], program[80];
double temp2, temp3, temp4, *ptr, stack[50];
int stacktop, stackptr, loop,temp5,temp6,count;

double pop();

int fp;
char fname[16];

main()
{
int pos;

title();

puts("Program filename to run:");
gets(fname);

if((fp=fopen(fname,"r"))==-1)
	{
	puts("\n\nProgram not found.");
	exit();
	}

stacktop = 30; stackptr = 0;

ptr=&program[0];

while(1)
	{
	pos=0;
	while((program[pos]=getc(fp))!='\n')
		pos++;
	loop=1;

	while(loop--)
		{
		if(strncmp(program,"loop",4))
			{
			pos=0;
			while((temp1[pos]=getc(fp))!='\n')
				pos++;
			count=loop=ifix(pop());
			}
		else
			if(strncmp(program,"count",5))
				push(float(count));
		else
			if(strncmp(program,"text",4))
				{
				ptr=&program[5];
				printf("%s",ptr);
				ptr=&program[0];
				}
		else
			if(strncmp(program,"number",6))
				printf("%f\n",pop());
		else
			if(strncmp(program,"input",5))
				{
				puts(">");
				gets(program);
				number();
				}
		else
			if(strncmp(program,"add",3))
				push(pop()+pop());
		else
			if(strncmp(program,"sub",3))
				{
				temp2=pop();
				push(pop()-temp2);
				}
		else
			if(strncmp(program,"mul",3))
				push(pop()*pop());
		else
			if(strncmp(program,"div",3))
				{
				temp2=pop();
				push(pop()/temp2);
				}
		else
			if(strncmp(program,"cr",2))
				putchar('\n');
		else
			if(strncmp(program,"dup",3))
				{
				temp2=pop();
				push(temp2); push(temp2);
				}
		else
			if(strncmp(program,"invert",6))
				push(0-pop());
		else
			if(strncmp(program,"drop",4))
				pop();
		else
			if(strncmp(program,"swap",4))
				{
				temp2=pop(); temp3=pop();
				push(temp2); push(temp3);
				}
		else
			if(strncmp(program,"stop",4))
				{
				fclose(fp);
				exit();
				}
		else
			if(strncmp(program,"sin",3))
				push(sin(pop()));
		else
			if(strncmp(program,"tan",3))
				push(tan(pop()));
		else
			if(strncmp(program,"cos",3))
				push(cos(pop()));
		else
			if(strncmp(program,"sqrt",4))
				push(sqrt(pop()));
		else
			if(strncmp(program,"exp",3))
				push(exp(pop()));
		else
			if(strncmp(program,"log",3))
				push(log(pop()));
		else
			if(strncmp(program,"log10",5))
				push(log10(pop()));
		else
			if(strncmp(program,"pi",2))
				push(3.141592654);
		else
			if(strncmp(program,"random",6))
				push(rand());
		else
			if(strncmp(program,"pow",3))
				push(pow(pop(),pop()));
		else
			if(strncmp(program,"mean",4))
				{
				temp5=ifix((temp3=pop()));
				temp4=0;
				while(temp5--)
					temp4=temp4+pop();
				push(temp4/temp3);
				}
		else
			if(strncmp(program,"max",3))
				{
				temp5=stackptr;
				temp3=0;
				while(temp5--)
					if(stack[temp5]>temp3)
						temp3=stack[temp5];
				push(temp3);
				}
		else
			if(strncmp(program,"min",3))
				{
				temp5=stackptr;
				temp3=0;
				while(temp5--)
					if(stack[temp5]<temp3)
						temp3=stack[temp5];
				push(temp3);
				}
		else number();

                if(loop)
			{
			pos=80;
			while(pos--)
				program[pos]=temp1[pos];
			}

		}
	}
fclose(fp);
}

push(n)
double n;
{
if(stackptr<stacktop)
	{
	stack[stackptr]=n;
	stackptr++; return n;
	}
puts("stack overflow\n");
}

pop()
{
if(stackptr>0)
	{
	stackptr--;
	return stack[stackptr];
	}
puts("stack underflow\n");
return 0;
}

isdigit(c)
char c;
{
return '0' <= c && c <= '9';
}

number(n)
int n;
{
int nbr,l;
double dnbr;
char *nptr;

nptr=&program[0]; l=utoi(nptr,&nbr);
dnbr=float(nbr); push(dnbr);
ptr=&program[l+1];
}

strncmp(st1,st2,l)
char st1[80],st2[80];
int l;
{
int c; c=0;

while(++c<l)
	if(st1[c]!=st2[c]) break;

if(c==l) return 1; else return 0;
}

title()
{
#asm
ld de,title
ld c,9
call 5
ret
title:
db "***********************************************",13,10
db "*   A Mathematics Language Interpreter v2.0   *",13,10
db "*                                             *",13,10
db "*               By Kevin Groves               *",13,10
db "*                                             *",13,10
db "*         Floating Point Maths, Trig          *",13,10
db "*           & Statistics Functions            *",13,10
db "*                                             *",13,10
db "*               (C) 1989  XD-V1               *",13,10
db "***********************************************"
db 13,10,10,"$"
#endasm
}                                                                               