/*======================================================================*/
/*  Calculator Main Program                                             */
/*======================================================================*/

#include stdio
#include ssdef
#include ctype
#include rmsdef
#include descrip

/* Calculator Common Definitions */

#include "CALC_INCLUDE.H"

/* global flags and variables */

int  debug_flag          = FALSE;
int  error_flag          = FALSE;
int  exit_flag           = FALSE;
int  foreign_flag        = FALSE;
int  cmd_file_flag       = FALSE;
int  vms_error_flag      = FALSE;
int  cmd_file_level      = 0;
int  format_precision    = 6;

struct token_struct numeric_value;


/*----------------------------------------------------------------------*/
/*  main program                                                        */
/*----------------------------------------------------------------------*/


main (argc,argv)
char *argv[];
int  argc;
{
int         command_length = 0;
int         status = 0;
char        command_string[256];
$DESCRIPTOR (command_desc,command_string);
$DESCRIPTOR (prompt_desc,"Calc: ");

/* get foreigh command if any */

status = LIB$GET_FOREIGN(&command_desc,0,&command_length,0);

if (((status&1)==1) && (command_length>0))
   foreign_flag = TRUE;
else
   foreign_flag = FALSE;

/* process commands */

for (;;)
   {

   /* get command from terminal if no foreign command was to executed */

   if (foreign_flag == FALSE)
      {
      status = LIB$GET_COMMAND(&command_desc,&prompt_desc,&command_length);
      if (((status&1)!=1) && (status != RMS$_EOF))
         {
         printf("-- Internal foreign command error\n");
         if (vms_error_flag) syserror(status);
         break;
         }
      if (command_length == 0) break;
      }

   /* clear error flag */

   error_flag = FALSE;

   /* parse the command */

   status = parse_command(command_string,command_length);

   /* exit if an exit command was executed */

   if (exit_flag == TRUE) break;

   /* exit if a foreign command was executed */

   if (foreign_flag == TRUE) break;

   }
}


/*----------------------------------------------------------------------*/
/*  parse and execute a command string                                  */
/*                                                                      */
/*  Parameter  Description                                              */
/*                                                                      */
/*  command    address of command string                                */
/*  length     length of command string                                 */
/*                                                                      */
/*----------------------------------------------------------------------*/

int parse_command (command,length)
int  length;
char command[];
{
   int i,status;
   struct tpadef tpa;

   /* convert command to upper case */

   for (i=0;i<length;i++) command[i] = _toupper(command[i]);

   /* initilize expression evaluation data structures */

   evaluation_initilization();

   /* setup TPA argument block */

   tpa.tpa$l_count0    = TPA$K_COUNT0;
   tpa.tpa$l_options   = 0;
   tpa.tpa$l_stringcnt = length;
   tpa.tpa$l_stringptr =  command;
   tpa.tpa$l_tokencnt  = 0;
   tpa.tpa$l_tokenptr  = 0;
   tpa.tpa$l_char      = 0;
   tpa.tpa$l_number    = 0;
   tpa.tpa$l_param     = 0;

   /* parse the command */

   status = LIB$TPARSE(&tpa,                  /* argument block      */
                       &CALCULATOR_STATES,    /* state table         */
                       &CALCULATOR_KEYWORDS); /* keyword table       */

   /* return the status from the parser */

   return status;
                                      
}


/*----------------------------------------------------------------------*/
/*  Display VAX/VMS System Error Message                                */
/*                                                                      */
/*  Parameter  Description                                              */
/*                                                                      */
/*  errcode    VAX/VMS error code                                       */
/*                                                                      */
/*----------------------------------------------------------------------*/

syserror (errcode)
int errcode;
{
   static int  status,textlen;
   static char text[256];
   static $DESCRIPTOR(msg_desc,text);

   status = SYS$GETMSG(errcode,&textlen,&msg_desc,15,0);

   printf("%.*s\n",textlen,text);

   return 1;
}


/*----------------------------------------------------------------------*/
/*  Display The Token For A Successful Transition                       */
/*                                                                      */
/*  Parameter  Description                                              */
/*                                                                      */
/*  options    processing option flags                                  */
/*  stringcnt  length of input string                                   */
/*  stringptr  address of input string                                  */
/*  tokencnt   length of current token                                  */
/*  tokenptr   address of current token                                 */
/*  character  character value of character token                       */
/*  number     binary value of numeric token                            */
/*  param      user supplied argument                                   */
/*                                                                      */
/*----------------------------------------------------------------------*/

int display_token (options,stringcnt,stringptr,tokencnt,
                   tokenptr,character,number,param)
int  options,stringcnt,tokencnt,stringptr,tokenptr,number,param;
char character;
{
   if (debug_flag)
      printf("Token:      %.*s\n",tokencnt,tokenptr);

   return 1;
}


/*----------------------------------------------------------------------*/
/*  Toggle The Internal Debug Flag                                      */
/*                                                                      */
/*  Parameter  Description                                              */
/*                                                                      */
/*  errcode    VAX/VMS error code                                       */
/*                                                                      */
/*----------------------------------------------------------------------*/

toggle_debug_flag ()
{
   if (debug_flag)
      {
      debug_flag     = FALSE;
      vms_error_flag = FALSE;
      printf ("Debug flag is OFF\n");
      }
   else
      {
      debug_flag     = TRUE;
      vms_error_flag = TRUE;
      printf ("Debug flag is ON\n");
      }
   return 1;
}


/*----------------------------------------------------------------------*/
/*  Unknown Command                                                     */
/*                                                                      */
/*  Parameter  Description                                              */
/*                                                                      */
/*  options    processing option flags                                  */
/*  stringcnt  length of input string                                   */
/*  stringptr  address of input string                                  */
/*  tokencnt   length of current token                                  */
/*  tokenptr   address of current token                                 */
/*  character  character value of character token                       */
/*  number     binary value of numeric token                            */
/*  parameter  user supplied argument                                   */
/*                                                                      */
/*----------------------------------------------------------------------*/

int unknown_command (options,stringcnt,stringptr,tokencnt,
                     tokenptr,character,number,parameter)
int  options,stringcnt,tokencnt,number,parameter;
char character,stringptr[],tokenptr[];
{
   /* if the error flag is set the assumption is that someone */
   /* else has already reported an error                      */

   if (error_flag) return 1;

   printf ("-- Unknown command (%.*s)\n",stringcnt,stringptr);

   return 1;
}
