%{
/* 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"table.h"

extern int returnedint;
extern char returnedstr[],opcode[];
extern int exprlist[];       /* contents of an expression list */
extern int arg1,arg2,arg3;   /* arguments */
extern int admode; /* addressing mode */
extern int pc;     /* program counter */

#define YYDEBUG 1

int yywrap()
{
        return 1;
}

/* we will do our own error messages...
*/ 
#define yyerror(s)

%}

%token OPCODE
%token INT
%token LABEL
%token WHITE
%token NEWLINE
%token XREG
%token ORG
%token DB
%token TIMEX
%token STRING

%token COLON
%token COMMA
%token HASH
%token LPAREN
%token RPAREN
%token PLUS
%token MINUS
%token MULT
%token DIV
%token BAND
%token BOR

%%
program : statement_list
	;

statement_list : statement
	| statement_list statement
	;

statement : LABEL {defsymbol(returnedstr);} COLON NEWLINE 
	| OPCODE {strcpy(opcode,returnedstr);} args NEWLINE  {gencode(opcode);}
	| ORG expr {pc=$2;} NEWLINE 
	| DB exprlist NEWLINE {gendb($2); }
	| TIMEX STRING {strcpy(opcode,returnedstr);} NEWLINE {gentimex(opcode); }
	| NEWLINE
	;

args	: expr                        {arg1=$1; admode=UNKNOWN1;}
	| HASH expr                   {arg1=$2; admode=IMM;}
	| COMMA XREG                  {admode=IX; }
	| expr COMMA XREG             {arg1=$1; admode=IX1; }
	| expr COMMA expr             {arg1=$1; arg2=$3; admode=UNKNOWN2; }
	| expr COMMA expr COMMA expr  {arg1=$1; arg2=$3; arg3=$5; admode=DIR2; }
	|                             {admode=INH;}
	;

exprlist	: expr {$$=1; exprlist[0]=$1; }
		| expr COMMA exprlist { $$=$3+1; exprlist[$3]=$1; }
		;

expr	: lit PLUS expr   {$$=$1+$3;}
	| lit MINUS expr  {$$=$1-$3;}
	| lit             {$$=$1;}
	;

lit	: term MULT expr  {$$=$1*$3;}
	| term DIV expr   {$$=$1/$3;}
	| term            {$$=$1;}
	;


term	: INT     {$$=returnedint;}
	| LABEL   {$$=getsymbol(returnedstr);}
	| MINUS expr  {$$=-$2;}
	| PLUS expr   {$$=$2;}
	| LPAREN expr RPAREN   {$$=$1;}
	;

