/* This is a simple demo program for the S-Lang interpreter.  It would 
 * take very little work to make this demo *really* useful.
 */

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

#include "slang.h"

int Read_Only_Array [100];
int Writable_Array [100];
FLOAT XXX;

void help()
{
   puts("ALL statements MUST be terminated with a ';' character, e.g., quit();\n");
   puts("Available functions:");
   puts("  cos, sin, tan, atan, acos, asin, exp, log, sqrt, fabs, log10, pow, PI, E");
   puts("\nas well as intrinsic S-Lang functions.");
   puts("See S-Lang language documentation for further details.");
   puts("\nAdditional functions:");
   puts("  print -- prints string, e.g. print(\"hello world!\\n\");");
   puts("  p();     -- displays top element of the stack.");
   puts("  quit();  -- quit calculator");
   puts("  apropos(\"STRING\");  -- lists all objects containing \"STRING\"");
   puts("\nExample: p (2.4 * E);    yields 6.52388.\n");
}      

/* The following three functions will be callable from the interpreter */
void quit_calc()
{
   exit(0);
}


void print(char *s)
{
   fputs(s, stdout);
}

void error(char *s)
{
   fprintf(stderr, "%s\n", s);
   SLang_Error = 1;
}

/* Now here is a table that provides the link between the above functions and
   the S-Lang interpreter */
SLang_Name_Type Calc_Intrinsics[] =
{
   MAKE_INTRINSIC(".print", print, VOID_TYPE, 1),
   MAKE_INTRINSIC(".quit", quit_calc, VOID_TYPE, 0),
   MAKE_INTRINSIC(".help", help, VOID_TYPE, 0),
   MAKE_INTRINSIC(".error", error, VOID_TYPE, 1),
   MAKE_VARIABLE(".XXX", &XXX, FLOAT_TYPE, 0),
   SLANG_END_TABLE
};
   

int main (int argc, char **argv)
{
   if (!init_SLang() 		       /* basic interpreter functions */
       || !init_SLmath() 	       /* sin, cos, etc... */
#ifdef unix
       || !init_SLunix()
#endif
       || !init_SLfiles()	       /* file i/o */
       || !SLang_add_table(Calc_Intrinsics, "Calc"))   /* calc specifics */
     {
	fprintf(stderr, "Unable to initialize S-Lang.\n");
	exit(1);
     }

   if ((-1 == SLang_add_array ("Read_only_array", (long *) Read_Only_Array,
			       1, 100, 0, 0, 'i', LANG_RVARIABLE))
       || (-1 == SLang_add_array ("Writable_array", (long *) Writable_Array,
				  1, 100, 0, 0, 'i', LANG_IVARIABLE)))
     {
	fprintf(stderr, "Failed to add arrays\n");
	exit (-1);
     }
       
   SLang_User_Prompt = "CALC> ";
   
   SLang_Traceback = 1;
   SLang_load_file("calc.sl");
   
   while (--argc && !SLang_Error)
     {
	argv++;
	SLang_load_file (*argv);
     }
   

   
   fputs("Type 'help();' for help and a list of available functions.\n", stdout);
   fputs("Note also that statements end in a ';'\n", stdout);
   fputs("\nIt is also important to note that most binary operators +, -, *, /,\n", stdout);
   fputs("as well as the '=' sign must be surrrounded by spaces!\n", stdout);
   
   while(1)
     {
	if (SLang_Error) SLang_restart(1);
	SLang_Error = 0;
	SLang_load_file(NULL);
	if (!SLang_Error) break;
     }
   return (SLang_Error);
}
