aboutsummaryrefslogblamecommitdiff
path: root/xcpu/xas_parse.y
blob: d6b2fd2054cd68d1d71b953272e72bdda3b7e2d7 (plain) (tree)















































































































































                                                                            
/* xas_parse.y
 * Parser description file for XAS, an assembler for XCPU.
 *
 */

%{
#include "xas.h"

int yylex (YYSTYPE *lvalp, YYLTYPE *llocp);
%}

%locations
%pure-parser
%error-verbose

%union {
  char reg;
  uint32_t val;
  char *id;
  char character;
  char *string;
}


%token <id>        ID
%token <val>       NUMBER
%token <val>       BIT
%token <reg>       REGISTER
%token <character> CHARACTER
%token <string>    STRING
%token <id>        FILENAME

%token NOP
%token JUMP
%token PUSH
%token POP
%token MEMOP
%token CPUOP
%token ASSIGN
%token ADD
%token SHIFT
%token AND
%token OR
%token NOT
%token MOVE
%token COMPARE
%token HALT
%token CONFIG

%token INCLUDE
%token DEFINE
%token LABEL
%token IMMED

/* %token MACRO */
/* %token ENDMACRO */
/* %token MACROREF */

%left  '|'
%left  '$'
%left  '&'
%left  '<' '>'
%left  '-' '+'
%left  '*' '/' '%'
%left  NEG POS
%right '~'
%right '^'

%type <val> arg
%type <val> expr

%%

input:          /* empty */
              | input line
;

line:           '\n'
              | instruction
              | directive
              | error                { yyclearin; yyerrok;           }
/*               | macroref */
;

instruction:    NOP                  { ins_nop ();                   }
              | JUMP    arg          { ins_jump ($2);                }
              | PUSH    REGISTER     { ins_push ($2);                }
              | POP     REGISTER     { ins_pop ($2);                 }
              | MEMOP   REGISTER     { ins_memop ($2);               }
              | CPUOP   arg ',' arg  { ins_cpuop ($2, $4);           }
              | ASSIGN  REGISTER ',' expr { ins_assign ($2, $4);     }
              | ADD     REGISTER     { ins_add ($2);                 }
              | SHIFT   REGISTER     { ins_shift ($2);               }
              | AND     REGISTER     { ins_and ($2);                 }
              | OR      REGISTER     { ins_or ($2);                  }
              | NOT     REGISTER     { ins_not ($2);                 }
              | MOVE    REGISTER     { ins_move ($2);                }
              | COMPARE REGISTER     { ins_compare ($2);             }
              | HALT                 { ins_halt ();                  }
              | CONFIG  arg          { ins_config ($2);              }
;

directive:      INCLUDE FILENAME     { dir_include ($2);             }
              | DEFINE  ID expr      { dir_define ($2, $3);          }
              | LABEL   ID           { dir_label ($2);               }
              | IMMED   STRING       { dir_immed_string ($2);        }
              | IMMED   expr         { dir_immed_bytes ($2);         }
/*               | MACRO   ID mparam    { dir_begin_ignore ();          } */
/*               | ENDMACRO             { dir_end_ignore ();            } */
;

/* macroref:       MACROREF mparam      { expand_macro ($2);            } */
/* ; */

arg:            NUMBER               { $$ = $1;                      }
              | BIT                  { $$ = $1;                      }
              | ID                   { $$ = resolve_identifier ($1); }
;

expr:           NUMBER               { $$ = $1;                      }
              | BIT                  { $$ = $1;                      }
              | ID                   { $$ = resolve_identifier ($1); }
              | CHARACTER            { $$ = (uint32_t)$1;            }
              | expr '|' expr        { $$ = $1 | $3;                 }
              | expr '$' expr        { $$ = $1 ^ $3;                 }
              | expr '&' expr        { $$ = $1 & $3;                 }
              | expr '<' expr        { $$ = $1 << $3;                }
              | expr '>' expr        { $$ = $1 >> $3;                }
              | expr '+' expr        { $$ = $1 + $3;                 }
              | expr '-' expr        { $$ = $1 - $3;                 }
              | expr '*' expr        { $$ = $1 * $3;                 }
              | expr '/' expr        { $$ = $1 / $3;                 }
              | expr '%' expr        { $$ = $1 % $3;                 }
              | '+' expr %prec POS   { $$ = +$2;                     }
              | '-' expr %prec NEG   { $$ = -$2;                     }
              | '~' expr             { $$ = ~$2;                     }
              | expr '^' expr        { $$ = pow ($1, $3);            }
              | '(' expr ')'         { $$ = $2;                      }
;

/* mparam:         mparam ',' arg */
/* ; */

%%