%{
/* Copyright 1996 Tommy Johnson
**
** Permission is hereby granted to copy, reproduce, redistribute or otherwise
** use this software as long as: there is no monetary profit gained
** specifically from the use or reproduction of this software, it is not
** sold, rented, traded or otherwise marketed, and this copyright notice is
** included prominently in any copy made.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ANY USE OF THIS
** SOFTWARE IS AT THE USER'S OWN RISK.
*/ 

#include<stdio.h>
#include<ctype.h>
#include<strings.h>
#include"table.h"
#include"parsetab.h"

#define DEFINE 
#include"asm.h"
static int i;

static char tstr[1024];

%}

%%

\(      {return LPAREN;}
\)      {return RPAREN;}
\+      {return PLUS;}
\-      {return MINUS;}
\*	{return MULT;}
\/	{return DIV;}
\:	{return COLON;}
\#	{return HASH;}
\,	{return COMMA;}
[Xx]	{return XREG;}

0x[0-9A-Fa-f]*  {errno=0;   /* note the &yytext[2] : it removes the 0x */
                returnedint=strtoul(&yytext[2],NULL,16);
                if (errno && (returnedint==0 || returnedint==MAXINT))
                        fprintf(stderr,"Integer overflow on line %d\n",lineno);
                return INT;
                }

0o[0-7]*        {errno=0;  /* note the &yytext[2] : it removes the 0o */
                returnedint=strtoul(&yytext[2],NULL,8);
                if (errno && (returnedint==0 || returnedint==MAXINT))
                        fprintf(stderr,"Integer overflow on line %d\n",lineno);
                return INT;
                }

[0-9][0-9]*     {errno=0;
                returnedint=strtoul(yytext,NULL,10);
                if (errno && (returnedint==0 || returnedint==MAXINT))
                        fprintf(stderr,"Integer overflow on line %d\n",lineno);
                return INT;
                }

[A-Za-z][A-Za-z0-9]*	{errno=0;
			strlower(tstr,yytext);
			returnedint=-1;
			for(i=0;i<NUMINST;i++)
				if (!strcmp(table[i].name,tstr))
					returnedint=i;
			if (returnedint>=0)
			{
				strcpy(returnedstr,tstr);
				return OPCODE;
			}
			/* pseudo opps: */
			if (!strcmp(tstr,"org"))
				return ORG;
			if (!strcmp(tstr,"db"))
				return DB;
			if (!strcmp(tstr,"timex"))
				return TIMEX;
			strcpy(returnedstr,yytext);
			return LABEL;
			}
\".*\"			{
			errno=0;
			strcpy(returnedstr,yytext);
			return STRING;
			}
\;.*$    {;}   /* comments: $ matches end of line */

\n      {lineno++; return NEWLINE;}   /* increment line number on newline char */

\t*[ ]* {;}

.       {printf("An invalid character was encountered on line %d.\n",lineno); }

%%

void strlower(char *dest,char *src)
{
	while(*src)
	{
		if (isupper(*src))
			*dest=(*src)|32;
		else
			*dest=(*src);
		src++;
		dest++;
	}
	*dest=0;
}

int main(int argc, char *argv[])
{
	FILE *fin,*tmp;
	char in[1024];
	char out[1024];
	int p;

        lineno=0;
	pass=1;
	pc=0;
	offset=0;
	initsymbol();
	output=NULL;     /* during pass 1, generate no code */

	if (argc<2)
	{
		fprintf(stderr,"usage... \n");
		exit(0);
	}

	strcpy(in,argv[1]);
	
	if (argc>2)
	{
		strcpy(out,argv[2]);
	}
	else
	{
		strcpy(out,in);
		p=strlen(out);
		while((p>0) && (out[p]!='/'))
		{
			if (out[p]=='.')
			{
				out[p]=0;
				p=0;
			}
			p--;
		}
		strcat(out,".out");
	}		
	
	if (!(fin=fopen(in,"r")))
	{
		fprintf(stderr,"could not open file %s\n",in);
		exit(1);
	}
	yyin=fin;
	if (!(tmp=fopen(out,"w")))
	{
		fprintf(stderr,"could not open file %s\n",out);
		exit(1);
	}

        if (yyparse())
	{
                printf("Incorrect syntax on line %d.\n",lineno);
		exit(1);
	}

	dumpsymboltable(stderr);

        lineno=0;
	pc=0;
	offset=0;
	rewind(fin);
	pass=2;
	yyin=fin;
	output=tmp;
	printf("second pass...\n");
        if (!yyparse())
                printf("Program is syntactically correct.\n");
        else
                printf("Incorrect syntax on line %d.\n",lineno);
	fclose(fin);
	fclose(output);
} 

