/*
 * Simple PASCAL compiler
 * File name: main.c
 * ----------------------
 * This is the main progam of the compiler.
 *    Chakma Junan
 *    e993178@edu.tut.ac.jp
 *    Information and Computer Science
 *    Toyohashi University of Technology
 *
 * It was originally implemented by 
 *    ohno@edu.tut.ac.jp
 */
#include <stdio.h>
#include <strings.h>
#include "getsym.h"
#include "table.h"

#include <stdlib.h>
#include <unistd.h>

#define	OPTION	":O:s:b:"          /* Valid options -O -s -b         */
#define	ASM	"../asm"	   /* assembler's position           */
extern char *optarg;               /* getopt() function uses it      */
extern int  optind, optopt;        /* Initialized by the system      */

struct	list	*Table;            /* Variable table       */
struct	list	*procedure_table;  /* Procedure Variable table       */
TOKEN	tok;                       /* token                */
FILE	*infile, *outfile;         /* infile: source-file  */
                                   /* outfile: output-file */
int	label;			   /* for labels           */
int	procedure_flag = 0;        /* Procedure flag */

TOKEN	stack[100];
int	top = 0;

extern	void	compiler();
extern	void	printData(struct list *);

void    usage();

int main(argc, argv)
int	argc;
char	*argv[];
{
   int c;
   int oflg, bflg, Oflg;         /* Flags                         */
   char *outputfilename;         /* output filename is saved here */ 
   char *inputfilename;          /* input filename is saved here  */ 
   char *binfilename;            /* binary filename is saved here */

   /* 
    * Hmm.......chekcing the options 
    */
   oflg = bflg = Oflg = 0;
   while((c = getopt(argc, argv, OPTION)) != -1)
       switch(c) {
           case 's':
                    oflg++;
                    outputfilename = optarg;
                    break;
           case 'b':
                    binfilename = optarg;
                    bflg++;
                    break;
           case 'O':
                    outputfilename = optarg;
                    Oflg++;
                    fprintf(stderr, "Currently this option is not availabel! \n");
                    usage();
                    break;
           case ':':
                    fprintf(stderr, "option -%c requires and argument!\n", optopt);
                    break;
           case '?':
                    fprintf(stderr, "Unrecognized option: -%c \n", optopt);
		    usage();
       }
   argc -= optind;
   argv += optind;

   if(*argv)
       inputfilename = *argv;
   else
       usage();

   if(oflg <= 0)
       outputfilename = "a.asm";

   /*
    * Opening the input file.  
    */
   if((infile = fopen(inputfilename, "r")) == NULL) {
      fprintf(stderr, "Source file %s can't open. \n", inputfilename);
      exit(1);
   }

   /*
    * Opening the output file. Default is a.asm.
    */
   if((outfile = fopen(outputfilename, "w")) == NULL) {
      fprintf(stderr, "Object file: %s creation failed \n", outputfilename);
      exit(1);
   }

   fprintf(stderr, "Simple compiler: compile start. \n");
   label = 0;     /* initializing label        */
   compiler();

   /* 
    * Halt message at the end 
    */
   fprintf(outfile, "\n      halt \n");
   fclose(infile);
   fclose(outfile);

   /*
    * Let's assemble it! Here, ASM should be asm's path! 
    */
   if(bflg > 0)
       execl(ASM, "", outputfilename, binfilename, 0);

   return 0;
}

/*
 * Function: usage
 * Usage: (void) usage();
 * ----------------------
 * This function shows the usage of the program. 
 */
void usage()
{
    fprintf(stderr, "Usage: comp [-Osb file] sourcefile \n\n");
    fprintf(stderr, "        -O Optimize the code.(not yet available). \n");
    fprintf(stderr, "        -s saves the assembly code in a file.     \n");
    fprintf(stderr, "           a filename is required.                \n");
    fprintf(stderr, "        -b places the machine codes in a file.    \n");
    fprintf(stderr, "           a filename is required                 \n");
    fprintf(stderr, "\n\n");
    fprintf(stderr, "Or you might want to visit the page:              \n");
    fprintf(stderr, "\n");
    fprintf(stderr, "   http://avenue.tutics.tut.ac.jp/jchakma/compiler\n");
    exit(1);
}
