%{
static char *RcsIdy = "$Id: propery.y,v 1.2 1997/06/04 01:18:13 david Exp $";

/* formind( offset, AccReg, AddReg, INCDEC, ind, force )
	where     offset = offset or expression.
		  AccReg = registers 'A' 'B' or 'D'.
		  AddReg = registers 'X' 'Y' 'U' (UR) 'S' or PCR
		  INCDEC = P if '+'
			   PP if '++'
			   M if '-'
			   MM if '--'
		  ind    = 1 if there is a '[' and ']'
		  force  = 0 Don't force
			 = 1 Force to  8 bit offset
			 = 2 Force to 16 bit offset
*/
#include "xasm.h"
#include "propery.h"
#define Word( x ) ( x & 0xffff )
#define Long( x ) ( (long) x )
#define	Wong( x	) ( (long) (x &	0xffff ) )
#define INH 0
#define IMM 1
#define DIR 2
#define EXT 3
#define IND 4
#define REL 5
%}
%token ID
%token HEXNUMBER
%token BINARYNUMBER
%token DECIMALNUMBER
%token STRING
%token P
%token PP
%token M
%token MM
%token A
%token B
%token CC
%token DP
%token D
%token X
%token Y
%token UR
%token S
%token PCR
%token AND OR NOT
%left '+' M OR
%left '*' '/' AND
%%
Operand  : '{' pushregs              { ;                                 }
	 | '}' pushregu              { ;                                 }
	 | ':' REG8 ',' REG8         {formtfr( $2, $4 );                 }
	 | ':' REG16 ',' REG16       {formtfr( $2, $4 );                 }
         | '#' expr                  {formimm( Word( $2 ) );             }
	 | '#' STRING                {formims( $2 );                     }
	 | strings                   { ;                                 }
	 | '<' expr                  {formde( Word($2), DIR );}
	 | '>' expr                  {formde( Word($2), EXT );}
	 | expr                      {formde( Word($1),   0 );}
	 | expr	',' AddReg	     {formind(Wong($1),	 0, $3,	0, 0,0);}
	 | '<' expr ','	AddReg	     {formind(Wong($2),	 0, $4,	0, 0,1);}
	 | '>' expr ','	AddReg	     {formind(Wong($2),	 0, $4,	0, 0,2);}
	 | AccReg ',' AddReg         {formind(Long(-1), $1, $3, 0, 0,0);}
	 | ',' AddReg                {formind(Long(-1),  0, $2, 0, 0,0);}
	 | AddReg                    {formind(Long(-1),  0, $1, 0, 0,0);}
	 | ',' AddReg PP             {formind(Long(-1),  0, $2,PP, 0,0);}
	 | AddReg PP                 {formind(Long(-1),  0, $1,PP, 0,0);}
	 | ',' AddReg P              {formind(Long(-1),  0, $2, P, 0,0);}
	 | AddReg P                  {formind(Long(-1),  0, $1, P, 0,0);}
	 | ',' MM AddReg             {formind(Long(-1),  0, $3,MM, 0,0);}
	 | MM AddReg                 {formind(Long(-1),  0, $2,MM, 0,0);}
	 | ',' M AddReg              {formind(Long(-1),  0, $3, M, 0,0);}
	 | M AddReg                  {formind(Long(-1),  0, $2, M, 0,0);}
	 | expr	',' PCR		     {formind(Wong($1),	 0,PCR,	0, 0,0);}
	 | '<' expr ','	PCR	     {formind(Wong($2),	 0,PCR,	0, 0,1);}
	 | '>' expr ','	PCR	     {formind(Wong($2),	 0,PCR,	0, 0,2);}
	 | '[' expr ']'		     {formind(Wong($2),	 0,  0,	0, 1,0);}
	 | '[' expr ','	AddReg ']'   {formind(Wong($2),	 0, $4,	0, 1,0);}
	 | '<' '[' expr	',' AddReg ']' {formind(Wong($3),0, $5,	0, 1,1);}
	 | '>' '[' expr	',' AddReg ']' {formind(Wong($3),0, $5,	0, 1,2);}
	 | '[' AccReg ',' AddReg ']' {formind(Long(-1), $2, $4, 0, 1,0);}
	 | '[' ',' AddReg ']'        {formind(Long(-1),  0, $3, 0, 1,0);}
	 | '[' ',' AddReg PP ']'     {formind(Long(-1),  0, $3,PP, 1,0);}
	 | '[' AddReg PP ']'         {formind(Long(-1),  0, $2,PP, 1,0);}
	 | '[' ',' MM AddReg ']'     {formind(Long(-1),  0, $4,MM, 1,0);}
	 | '[' MM AddReg ']'         {formind(Long(-1),  0, $3,MM, 1,0);}
	 | '[' expr ','	PCR ']'	     {formind(Wong($2),	 0,PCR,	0, 1,0);}
	 | '<' '[' expr	',' PCR	']'  {formind(Wong($3),	 0,PCR,	0, 1,1);}
	 | '>' '[' expr	',' PCR	']'  {formind(Wong($3),	 0,PCR,	0, 1,2);}
	 | /* No operator */         { ; }
	 | error                     {xerror( "propery: Syntax Error"  );}
         ;
expr     : ID                    { WORD value;
                                   if ( symfind( $1, &value, 1 ) != 'D' )
				      xerror("propery: Undefined Symbol");
				   $$ = value; }
	 | HEXNUMBER                 { $$ = $1; }
	 | BINARYNUMBER              { $$ = $1; }
	 | DECIMALNUMBER             { $$ = $1; }
	 | '$'                       { $$ = loc;}
         | expr '*' expr             { $$ = $1 * $3; }
	 | expr '/' expr             { $$ = $1 / $3; }
	 | expr  P  expr             { $$ = $1 + $3; }
	 | expr  M  expr             { $$ = $1 - $3; }
	 | '(' expr ')'              { $$ = $2; }
         |  M  expr %prec  M         { $$ = - $2; }
	 | expr AND expr             { $$ = $1 & $3; }
	 | expr OR expr              { $$ = $1 | $3; }
	 | NOT expr %prec NOT        { $$ = ~ $2; }
         ;
strings  : strings ',' STRING        { fprintf(stderr,"STRINGS found\n");}
         | STRING                    { formstr( $1 ); }
         ;
AddReg   : X                         { $$ =   X; }
         | Y                         { $$ =   Y; }
         | UR                        { $$ =  UR; }
         | S                         { $$ =   S; }
	 ;
AccReg   : A                         { $$ =  A; }
         | B                         { $$ =  B; }
         | D                         { $$ =  D; }
	 ;
REG8     : A                         { $$ = A;   }
         | B                         { $$ = B;   }
	 | CC                        { $$ = CC;  }
	 | DP                        { $$ = DP;  }
	 ;
REG16    : D                         { $$ = D;   }
         | X                         { $$ = X;   }
         | Y                         { $$ = Y;   }
         | UR                        { $$ = UR;  }
	 | S                         { $$ = S;   }
	 | PCR                       { $$ = PCR; }
	 ;
pushregs : pushregs ',' pushregs     { ;              }
         | UR                        { formpsh( UR ); }
         | pushreg                   { formpsh( $1 ); }
         ;
pushregu : pushregu ',' pushregu     { ;              }
         | S                         { formpsh( S  ); }
         | pushreg                   { formpsh( $1 ); }
         ;
pushreg  : A                         { $$ = A;   }
	 | B                         { $$ = B;   }
         | CC                        { $$ = CC;  }
	 | D                         { $$ = D;   }
	 | DP                        { $$ = DP;  }
	 | X                         { $$ = X;   }
	 | Y                         { $$ = Y;   }
	 | PCR                       { $$ = PCR; }
	 ;
%%
#include "xasm.h"
#include "properl.c"
