OpenCores
URL https://opencores.org/ocsvn/zipcpu/zipcpu/trunk

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [sw/] [zasm/] [zasm.y] - Diff between revs 46 and 69

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 46 Rev 69
/*******************************************************************************
/*******************************************************************************
**
**
** Filename:    zasm.y
** Filename:    zasm.y
**
**
** Project:     Zip CPU -- a small, lightweight, RISC CPU core
** Project:     Zip CPU -- a small, lightweight, RISC CPU core
**
**
** Purpose:     The parser for the Zip Assembler.  This is actually not just
** Purpose:     The parser for the Zip Assembler.  This is actually not just
**              the parser, but the main program as well.
**              the parser, but the main program as well.
**
**
** Creator:     Dan Gisselquist, Ph.D.
** Creator:     Dan Gisselquist, Ph.D.
**              Gisselquist Tecnology, LLC
**              Gisselquist Technology, LLC
**
**
********************************************************************************
********************************************************************************
**
**
** Copyright (C) 2015, Gisselquist Technology, LLC
** Copyright (C) 2015, Gisselquist Technology, LLC
**
**
** This program is free software (firmware): you can redistribute it and/or
** This program is free software (firmware): you can redistribute it and/or
** modify it under the terms of  the GNU General Public License as published
** modify it under the terms of  the GNU General Public License as published
** by the Free Software Foundation, either version 3 of the License, or (at
** by the Free Software Foundation, either version 3 of the License, or (at
** your option) any later version.
** your option) any later version.
**
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
** ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
** FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
** FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
** for more details.
** for more details.
**
**
** You should have received a copy of the GNU General Public License along
** You should have received a copy of the GNU General Public License along
** with this program.  (It's in the $(ROOT)/doc directory, run make with no
** with this program.  (It's in the $(ROOT)/doc directory, run make with no
** target there if the PDF file isn't present.)  If not, see
** target there if the PDF file isn't present.)  If not, see
**  for a copy.
**  for a copy.
**
**
** License:     GPL, v3, as defined and found on www.gnu.org,
** License:     GPL, v3, as defined and found on www.gnu.org,
**              http://www.gnu.org/licenses/gpl.html
**              http://www.gnu.org/licenses/gpl.html
**
**
**
**
*******************************************************************************/
*******************************************************************************/
%{
%{
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include "asmdata.h"
 #include "asmdata.h"
#define DEFAULT_OUTPUT_FNAME    "z.out"
#define DEFAULT_OUTPUT_FNAME    "z.out"
#define YYDEBUG 1
#define YYDEBUG 1
  extern "C" int yylex(void);
  extern "C" int yylex(void);
  extern "C" int yyparse(void);
  extern "C" int yyparse(void);
  // extern "C" FILE *yyin;
  // extern "C" FILE *yyin;
  void yyerror(const char *);
  void yyerror(const char *);
  unsigned int global_parser_pc;
  unsigned int global_parser_pc;
  char *master_input_filename = NULL;
  char *master_input_filename = NULL;
  extern int yylineno;
  extern int yylineno;
  char  *linecp = NULL; // A copy of the input line
  char  *linecp = NULL; // A copy of the input line
%}
%}
%token COMMA EQU PLUS MINUS TIMES HERE DOLLAR COLON
%token COMMA EQU PLUS MINUS TIMES HERE DOLLAR COLON
%token BOOLEANOR BITWISEOR BOOLEANAND BITWISEAND BITWISEXOR DOT
%token BOOLEANOR BITWISEOR BOOLEANAND BITWISEAND BITWISEXOR DOT
%token WORD FILL
%token WORD FILL
%token LOADOP STOROP LDIOP
%token LOADOP STOROP LDIOP
%token BAREOP BRANCHOP COND DUALOP IDENTIFIER INT LDHLOP REG SINGLOP
%token BAREOP BRANCHOP COND DUALOP IDENTIFIER INT LDHLOP REG SINGLOP
%union {
%union {
        ZPARSER::ZIPREG         u_reg;
        ZPARSER::ZIPREG         u_reg;
        ZPARSER::ZIPCOND        u_cond;
        ZPARSER::ZIPCOND        u_cond;
        int                     u_ival;
        int                     u_ival;
        LEXOPCODE               u_op;
        LEXOPCODE               u_op;
        char                    *u_id;
        char                    *u_id;
        ASMLINE                 *u_ln;
        ASMLINE                 *u_ln;
        AST                     *u_ast;
        AST                     *u_ast;
}
}
%type                   REG
%type                   REG
%type           COND opcond
%type           COND opcond
%type           INT
%type           INT
%type                   IDENTIFIER
%type                   IDENTIFIER
%type                   BAREOP SINGLOP DUALOP BRANCHOP LDHLOP
%type                   BAREOP SINGLOP DUALOP BRANCHOP LDHLOP
%type                   unlabeledline instruction wordlist fillist opb
%type                   unlabeledline instruction wordlist fillist opb
%type                   bareop singlop dualop loadop storop line
%type                   bareop singlop dualop loadop storop line
%type                   expr value multident
%type                   expr value multident
%left BOOLEANOR
%left BOOLEANOR
%left BOOLEANAND
%left BOOLEANAND
%left BITWISEOR BITWISEXOR
%left BITWISEOR BITWISEXOR
%left BITWISEAND
%left BITWISEAND
%left '%'
%left '%'
%left PLUS MINUS
%left PLUS MINUS
%left TIMES '/'
%left TIMES '/'
%% /* The grammar follows */
%% /* The grammar follows */
input:
input:
  %empty
  %empty
| input line { if ($2) {objcode += $2; global_parser_pc += $2->nlines(); if ($2->isdefined()) delete $2; } }
| input line { if ($2) {objcode += $2; global_parser_pc += $2->nlines(); if ($2->isdefined()) delete $2; } }
;
;
line:
line:
   '\n' { $$ = NULL; }
   '\n' { $$ = NULL; }
| unlabeledline '\n' { $$ = $1; }
| unlabeledline '\n' { $$ = $1; }
| multident COLON unlabeledline '\n' {
| multident COLON unlabeledline '\n' {
        if ($1->m_node_type == 'I') {
        if ($1->m_node_type == 'I') {
                if (((AST_IDENTIFIER*)$1)->m_id[0] == 'L')
                if (((AST_IDENTIFIER*)$1)->m_id[0] == 'L')
                        stb_define(((AST_IDENTIFIER *)$1)->m_id, new AST_NUMBER(global_parser_pc));
                        stb_define(((AST_IDENTIFIER *)$1)->m_id, new AST_NUMBER(global_parser_pc));
                else
                else
                        gbl_define(((AST_IDENTIFIER *)$1)->m_id, new AST_NUMBER(global_parser_pc));
                        gbl_define(((AST_IDENTIFIER *)$1)->m_id, new AST_NUMBER(global_parser_pc));
                delete $1;
                delete $1;
                }
                }
        $$ = $3;
        $$ = $3;
        }
        }
| multident COLON '\n' {
| multident COLON '\n' {
        if ($1->m_node_type == 'I') {
        if ($1->m_node_type == 'I') {
                if (((AST_IDENTIFIER*)$1)->m_id[0] == 'L')
                if (((AST_IDENTIFIER*)$1)->m_id[0] == 'L')
                        stb_define(((AST_IDENTIFIER *)$1)->m_id, new AST_NUMBER(global_parser_pc));
                        stb_define(((AST_IDENTIFIER *)$1)->m_id, new AST_NUMBER(global_parser_pc));
                else
                else
                        gbl_define(((AST_IDENTIFIER *)$1)->m_id, new AST_NUMBER(global_parser_pc));
                        gbl_define(((AST_IDENTIFIER *)$1)->m_id, new AST_NUMBER(global_parser_pc));
                delete $1;
                delete $1;
        }
        }
        $$ = new VLINE();
        $$ = new VLINE();
        }
        }
| multident EQU expr '\n' {
| multident EQU expr '\n' {
        if ($1->m_node_type == 'I') {
        if ($1->m_node_type == 'I') {
                stb_define(((AST_IDENTIFIER *)$1)->m_id, $3);
                stb_define(((AST_IDENTIFIER *)$1)->m_id, $3);
                delete $1;
                delete $1;
        }
        }
        $$ = new VLINE();
        $$ = new VLINE();
        }
        }
;
;
unlabeledline:
unlabeledline:
  instruction   { $$ = $1; }
  instruction   { $$ = $1; }
| WORD wordlist { $$ = $2; }
| WORD wordlist { $$ = $2; }
| FILL fillist { $$ = $2; }
| FILL fillist { $$ = $2; }
;
;
wordlist:
wordlist:
  expr  {
  expr  {
        if ($1->isdefined())
        if ($1->isdefined())
                $$ = new DLINE($1->eval());
                $$ = new DLINE($1->eval());
        else {
        else {
                $$ = new VLINE();
                $$ = new VLINE();
                yyerror("ERROR: word list undefined");
                yyerror("ERROR: word list undefined");
        }}
        }}
| wordlist COMMA expr {
| wordlist COMMA expr {
        if ($3->isdefined()) {
        if ($3->isdefined()) {
                LLINE   *ln;
                LLINE   *ln;
                if ($1->m_state == 'L') {
                if ($1->m_state == 'L') {
                        ln = ((LLINE *)$1);
                        ln = ((LLINE *)$1);
                } else {
                } else {
                        ln = new LLINE();
                        ln = new LLINE();
                        ln->addline($1);
                        ln->addline($1);
                } ln->addline(new DLINE($3->eval()));
                } ln->addline(new DLINE($3->eval()));
                $$ = ln;
                $$ = ln;
        } else {
        } else {
                $$ = new VLINE();
                $$ = new VLINE();
                yyerror("ERROR: word list undefined\n");
                yyerror("ERROR: word list undefined\n");
        }}
        }}
;
;
fillist:
fillist:
  expr COMMA expr {
  expr COMMA expr {
                if (($1->isdefined())&&($3->isdefined())) {
                if (($1->isdefined())&&($3->isdefined())) {
                        int     ntimes = $1->eval(),
                        int     ntimes = $1->eval(),
                                val = $3->eval();
                                val = $3->eval();
                        LLINE   *ln = new LLINE();
                        LLINE   *ln = new LLINE();
                        for(int i=0; i
                        for(int i=0; i
                                ln->addline(new DLINE(val));
                                ln->addline(new DLINE(val));
                        $$ = ln;
                        $$ = ln;
                } else {
                } else {
                        yyerror("Fill list undefined\n");
                        yyerror("Fill list undefined\n");
                        $$ = new VLINE();
                        $$ = new VLINE();
                }
                }
        }
        }
;
;
instruction:
instruction:
  dualop  opb COMMA REG {
  dualop  opb COMMA REG {
                $$ = $1;
                $$ = $1;
                ((TLINE*)$1)->m_imm = ((TLINE*)$2)->m_imm; ((TLINE*)$2)->m_imm = NULL;
                ((TLINE*)$1)->m_imm = ((TLINE*)$2)->m_imm; ((TLINE*)$2)->m_imm = NULL;
                ((TLINE*)$1)->m_opb = ((TLINE*)$2)->m_opb;
                ((TLINE*)$1)->m_opb = ((TLINE*)$2)->m_opb;
                ((TLINE*)$1)->m_opa = $4;
                ((TLINE*)$1)->m_opa = $4;
                if ($1->isdefined()) {
                if ($1->isdefined()) {
                        $$ = ((TLINE*)$1)->eval();
                        $$ = ((TLINE*)$1)->eval();
                        delete $1;
                        delete $1;
                        delete $2;
                        delete $2;
                }
                }
        }
        }
| dualop  opb COMMA multident {
| dualop  opb COMMA multident {
                char    buf[256];
                char    buf[256];
                sprintf(buf, "%s is not a register", ((AST_IDENTIFIER *)$4)->m_id.c_str());
                sprintf(buf, "%s is not a register", ((AST_IDENTIFIER *)$4)->m_id.c_str());
                yyerror(buf);
                yyerror(buf);
                $$ = new VLINE();
                $$ = new VLINE();
                delete $1;
                delete $1;
                delete $2;
                delete $2;
                delete $4;
                delete $4;
        }
        }
| singlop opb   {
| singlop opb   {
                $$ = $1;
                $$ = $1;
                ((TLINE*)$1)->m_imm = ((TLINE*)$2)->m_imm; ((TLINE*)$2)->m_imm = NULL;
                ((TLINE*)$1)->m_imm = ((TLINE*)$2)->m_imm; ((TLINE*)$2)->m_imm = NULL;
                ((TLINE*)$1)->m_opb = ((TLINE*)$2)->m_opb;
                ((TLINE*)$1)->m_opb = ((TLINE*)$2)->m_opb;
                if ($1->isdefined()) {
                if ($1->isdefined()) {
                        $$ = ((TLINE *)$1)->eval();
                        $$ = ((TLINE *)$1)->eval();
                        delete $1;
                        delete $1;
                }
                }
        }
        }
| bareop        { $$ = $1; }
| bareop        { $$ = $1; }
| LDHLOP  opcond expr COMMA REG {
| LDHLOP  opcond expr COMMA REG {
                TLINE *tln = new TLINE;
                TLINE *tln = new TLINE;
                tln->m_opcode = $1;
                tln->m_opcode = $1;
                tln->m_cond   = $2;
                tln->m_cond   = $2;
                tln->m_imm    = $3;
                tln->m_imm    = $3;
                tln->m_opa    = $5;
                tln->m_opa    = $5;
                if (tln->isdefined()) {
                if (tln->isdefined()) {
                        $$ = tln->eval();
                        $$ = tln->eval();
                        delete tln;
                        delete tln;
                } else
                } else
                        $$ = tln;
                        $$ = tln;
        }
        }
| LDHLOP  opcond expr COMMA multident {
| LDHLOP  opcond expr COMMA multident {
                char    buf[256];
                char    buf[256];
                sprintf(buf, "%s is not a register", ((AST_IDENTIFIER *)$5)->m_id.c_str());
                sprintf(buf, "%s is not a register", ((AST_IDENTIFIER *)$5)->m_id.c_str());
                yyerror(buf);
                yyerror(buf);
                $$ = new VLINE();
                $$ = new VLINE();
                delete $3;
                delete $3;
                delete $5;
                delete $5;
        }
        }
| LDIOP          expr COMMA REG {
| LDIOP          expr COMMA REG {
                TLINE *tln = new TLINE;
                TLINE *tln = new TLINE;
                tln->m_opcode = OP_LDI;
                tln->m_opcode = OP_LDI;
                tln->m_cond   = ZPARSER::ZIPC_ALWAYS;
                tln->m_cond   = ZPARSER::ZIPC_ALWAYS;
                tln->m_imm    = $2;
                tln->m_imm    = $2;
                tln->m_opa    = $4;
                tln->m_opa    = $4;
                if (tln->isdefined()) {
                if (tln->isdefined()) {
                        $$ = tln->eval();
                        $$ = tln->eval();
                        delete tln;
                        delete tln;
                } else
                } else
                        $$ = tln;
                        $$ = tln;
        }
        }
| LDIOP  expr COMMA multident {
| LDIOP  expr COMMA multident {
                char    buf[256];
                char    buf[256];
                sprintf(buf, "%s is not a register", ((AST_IDENTIFIER *)$4)->m_id.c_str());
                sprintf(buf, "%s is not a register", ((AST_IDENTIFIER *)$4)->m_id.c_str());
                yyerror(buf);
                yyerror(buf);
                $$ = new VLINE();
                $$ = new VLINE();
                delete $2;
                delete $2;
                delete $4;
                delete $4;
        }
        }
| BRANCHOP  expr        {
| BRANCHOP  expr        {
                TLINE *tln = new TLINE;
                TLINE *tln = new TLINE;
                tln->m_opcode = $1;
                tln->m_opcode = $1;
                tln->m_imm    = $2;
                tln->m_imm    = $2;
                if (tln->isdefined()) {
                if (tln->isdefined()) {
                        $$ = tln->eval();
                        $$ = tln->eval();
                        delete tln;
                        delete tln;
                } else
                } else
                        $$ = tln;
                        $$ = tln;
        }
        }
| loadop opb COMMA REG {
| loadop opb COMMA REG {
                TLINE *tln = new TLINE;
                TLINE *tln = new TLINE;
                ((TLINE*)$2)->m_opcode = OP_LOD;
                ((TLINE*)$2)->m_opcode = OP_LOD;
                ((TLINE*)$2)->m_cond   = ((TLINE*)$1)->m_cond;
                ((TLINE*)$2)->m_cond   = ((TLINE*)$1)->m_cond;
                ((TLINE*)$2)->m_opa    = $4;
                ((TLINE*)$2)->m_opa    = $4;
                delete $1;
                delete $1;
                if (((TLINE *)$2)->isdefined()) {
                if (((TLINE *)$2)->isdefined()) {
                        $$ = ((TLINE *)$2)->eval();
                        $$ = ((TLINE *)$2)->eval();
                        delete $2;
                        delete $2;
                } else
                } else
                        $$ = $2;
                        $$ = $2;
        }
        }
| loadop opb COMMA multident {
| loadop opb COMMA multident {
                char    buf[256];
                char    buf[256];
                sprintf(buf, "%s is not a register", ((AST_IDENTIFIER *)$4)->m_id.c_str());
                sprintf(buf, "%s is not a register", ((AST_IDENTIFIER *)$4)->m_id.c_str());
                yyerror(buf);
                yyerror(buf);
                $$ = new VLINE();
                $$ = new VLINE();
                delete $1;
                delete $1;
                delete $2;
                delete $2;
                delete $4;
                delete $4;
        }
        }
| storop REG COMMA opb {
| storop REG COMMA opb {
                TLINE *tln = new TLINE;
                TLINE *tln = new TLINE;
                tln->m_opcode = OP_STO;
                tln->m_opcode = OP_STO;
                tln->m_cond   = ((TLINE*)$1)->m_cond;
                tln->m_cond   = ((TLINE*)$1)->m_cond;
                tln->m_imm    = ((TLINE*)$4)->m_imm;
                tln->m_imm    = ((TLINE*)$4)->m_imm;
                tln->m_opb    = ((TLINE*)$4)->m_opb;
                tln->m_opb    = ((TLINE*)$4)->m_opb;
                tln->m_opa    = $2;
                tln->m_opa    = $2;
                delete $1;
                delete $1;
                if (tln->isdefined()) {
                if (tln->isdefined()) {
                        $$ = tln->eval();
                        $$ = tln->eval();
                        delete tln;
                        delete tln;
                } else
                } else
                        $$ = tln;
                        $$ = tln;
        }
        }
| storop multident COMMA opb {
| storop multident COMMA opb {
                char    buf[256];
                char    buf[256];
                sprintf(buf, "%s is not a register", ((AST_IDENTIFIER *)$2)->m_id.c_str());
                sprintf(buf, "%s is not a register", ((AST_IDENTIFIER *)$2)->m_id.c_str());
                yyerror(buf);
                yyerror(buf);
                $$ = new VLINE();
                $$ = new VLINE();
                delete $1;
                delete $1;
                delete $2;
                delete $2;
                delete $4;
                delete $4;
        }
        }
;
;
dualop: DUALOP  opcond {
dualop: DUALOP  opcond {
        TLINE *tln = new TLINE();
        TLINE *tln = new TLINE();
        tln->m_opcode = $1;
        tln->m_opcode = $1;
        tln->m_cond   = $2;
        tln->m_cond   = $2;
        $$ = tln;
        $$ = tln;
        }
        }
;
;
singlop: SINGLOP opcond {
singlop: SINGLOP opcond {
        TLINE *tln = new TLINE();
        TLINE *tln = new TLINE();
        tln->m_opcode = $1;
        tln->m_opcode = $1;
        tln->m_cond   = $2;
        tln->m_cond   = $2;
        $$ = tln;
        $$ = tln;
        }
        }
;
;
storop: STOROP opcond {
storop: STOROP opcond {
        TLINE *tln = new TLINE();
        TLINE *tln = new TLINE();
        tln->m_opcode = OP_STO;
        tln->m_opcode = OP_STO;
        tln->m_cond   = $2;
        tln->m_cond   = $2;
        $$ = tln;
        $$ = tln;
        }
        }
;
;
loadop: LOADOP opcond {
loadop: LOADOP opcond {
        TLINE *tln = new TLINE();
        TLINE *tln = new TLINE();
        tln->m_opcode = OP_LOD;
        tln->m_opcode = OP_LOD;
        tln->m_cond   = $2;
        tln->m_cond   = $2;
        $$ = tln;
        $$ = tln;
        }
        }
;
;
bareop: BAREOP  opcond {
bareop: BAREOP  opcond {
        TLINE *tln = new TLINE();
        TLINE *tln = new TLINE();
        tln->m_opcode = $1;
        tln->m_opcode = $1;
        tln->m_cond   = $2;
        tln->m_cond   = $2;
        $$ = tln;
        $$ = tln;
        }
        }
;
;
opcond:
opcond:
        COND    { $$ = $1; }
        COND    { $$ = $1; }
|       %empty  { $$ = ZPARSER::ZIPC_ALWAYS; }
|       %empty  { $$ = ZPARSER::ZIPC_ALWAYS; }
;
;
opb:
opb:
        expr    {
        expr    {
                TLINE *tln = new TLINE();
                TLINE *tln = new TLINE();
                tln->m_imm = $1;
                tln->m_imm = $1;
                $$ = tln;
                $$ = tln;
        }
        }
|       expr PLUS REG {
|       expr PLUS REG {
                TLINE *tln = new TLINE();
                TLINE *tln = new TLINE();
                tln->m_imm = $1;
                tln->m_imm = $1;
                tln->m_opb = $3;
                tln->m_opb = $3;
                $$ = tln;
                $$ = tln;
        }
        }
|       expr '(' REG ')' {
|       expr '(' REG ')' {
                TLINE *tln = new TLINE();
                TLINE *tln = new TLINE();
                tln->m_imm = $1;
                tln->m_imm = $1;
                tln->m_opb = $3;
                tln->m_opb = $3;
                $$ = tln;
                $$ = tln;
        }
        }
|       '(' REG ')' {
|       '(' REG ')' {
                TLINE *tln = new TLINE();
                TLINE *tln = new TLINE();
                tln->m_imm = new AST_NUMBER(0);
                tln->m_imm = new AST_NUMBER(0);
                tln->m_opb = $2;
                tln->m_opb = $2;
                $$ = tln;
                $$ = tln;
        }
        }
|       REG {
|       REG {
                TLINE *tln = new TLINE();
                TLINE *tln = new TLINE();
                tln->m_imm = new AST_NUMBER(0);
                tln->m_imm = new AST_NUMBER(0);
                tln->m_opb = $1;
                tln->m_opb = $1;
                $$ = tln;
                $$ = tln;
        }
        }
;
;
expr:
expr:
        value                   { $$ = $1; }
        value                   { $$ = $1; }
|       MINUS value %prec TIMES  { $$ = new AST_BRANCH('-',new AST_NUMBER(0), $2); }
|       MINUS value %prec TIMES  { $$ = new AST_BRANCH('-',new AST_NUMBER(0), $2); }
|       expr PLUS expr          { $$ = new AST_BRANCH('+',$1,$3); }
|       expr PLUS expr          { $$ = new AST_BRANCH('+',$1,$3); }
|       expr MINUS expr         { $$ = new AST_BRANCH('-',$1,$3); }
|       expr MINUS expr         { $$ = new AST_BRANCH('-',$1,$3); }
|       expr TIMES expr         { $$ = new AST_BRANCH('*',$1,$3); }
|       expr TIMES expr         { $$ = new AST_BRANCH('*',$1,$3); }
|       expr '/' expr           { $$ = new AST_BRANCH('/',$1,$3); }
|       expr '/' expr           { $$ = new AST_BRANCH('/',$1,$3); }
|       expr '%' expr           { $$ = new AST_BRANCH('%',$1,$3); }
|       expr '%' expr           { $$ = new AST_BRANCH('%',$1,$3); }
|       expr BOOLEANOR expr     { $$ = new AST_BRANCH('o',$1,$3); }
|       expr BOOLEANOR expr     { $$ = new AST_BRANCH('o',$1,$3); }
|       expr BITWISEOR expr     { $$ = new AST_BRANCH('|',$1,$3); }
|       expr BITWISEOR expr     { $$ = new AST_BRANCH('|',$1,$3); }
|       expr BOOLEANAND expr    { $$ = new AST_BRANCH('a',$1,$3); }
|       expr BOOLEANAND expr    { $$ = new AST_BRANCH('a',$1,$3); }
|       expr BITWISEAND expr    { $$ = new AST_BRANCH('&',$1,$3); }
|       expr BITWISEAND expr    { $$ = new AST_BRANCH('&',$1,$3); }
|       expr BITWISEXOR expr    { $$ = new AST_BRANCH('^',$1,$3); }
|       expr BITWISEXOR expr    { $$ = new AST_BRANCH('^',$1,$3); }
|       '(' expr ')'            { $$ = $2; }
|       '(' expr ')'            { $$ = $2; }
;
;
        /* expr OR  (|) value */
        /* expr OR  (|) value */
        /* expr XOR (^) value */
        /* expr XOR (^) value */
        /* expr AND (&) value */
        /* expr AND (&) value */
value:
value:
        INT     { $$ = new AST_NUMBER($1); }
        INT     { $$ = new AST_NUMBER($1); }
| multident     { $$ = $1; }
| multident     { $$ = $1; }
| HERE          { $$ = new AST_NUMBER(global_parser_pc); }
| HERE          { $$ = new AST_NUMBER(global_parser_pc); }
;
;
multident:
multident:
        IDENTIFIER              { $$ = new AST_IDENTIFIER($1); delete $1; }
        IDENTIFIER              { $$ = new AST_IDENTIFIER($1); delete $1; }
| multident DOT IDENTIFIER      { $$ = new AST_IDENTIFIER($1,$3); delete $3; }
| multident DOT IDENTIFIER      { $$ = new AST_IDENTIFIER($1,$3); delete $3; }
;
;
%%
%%
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
OBJFILE objcode;
OBJFILE objcode;
void    yyerror(const char *str) {
void    yyerror(const char *str) {
        fprintf(stderr, "%s:%d: ERROR: %s\n", master_input_filename, yylineno, str);
        fprintf(stderr, "%s:%d: ERROR: %s\n", master_input_filename, yylineno, str);
        if (linecp) fprintf(stderr, "Offending line was: %s\n", linecp);
        if (linecp) fprintf(stderr, "Offending line was: %s\n", linecp);
}
}
FILE    *run_preprocessor(pid_t &pid, const char *path = NULL, const char *zname = NULL) {
FILE    *run_preprocessor(pid_t &pid, const char *path = NULL, const char *zname = NULL) {
        int     pipefd[2];
        int     pipefd[2];
        if (pipe(pipefd)!=0) {
        if (pipe(pipefd)!=0) {
                fprintf(stderr, "PIPE FAILED!\n");
                fprintf(stderr, "PIPE FAILED!\n");
                perror("O/S Err:");
                perror("O/S Err:");
                exit(-2);
                exit(-2);
        } if ((zname)&&(access(zname, R_OK)!=0)) { // if !zname, then use stdin
        } if ((zname)&&(access(zname, R_OK)!=0)) { // if !zname, then use stdin
                fprintf(stderr, "Cannot open %s\n", zname);
                fprintf(stderr, "Cannot open %s\n", zname);
                perror("O/S Err:");
                perror("O/S Err:");
                exit(-2);
                exit(-2);
        }
        }
        if (0 == (pid = fork())) {
        if (0 == (pid = fork())) {
                int     fdin, fdout;
                int     fdin, fdout;
                // Child process -- run the preprocessor
                // Child process -- run the preprocessor
                // Close the reader: we write only
                // Close the reader: we write only
                close(pipefd[0]);
                close(pipefd[0]);
                // Adjust stdout to write to our pipe instead of anywhere else
                // Adjust stdout to write to our pipe instead of anywhere else
                fdout = pipefd[1];
                fdout = pipefd[1];
                close(STDOUT_FILENO);
                close(STDOUT_FILENO);
                dup2(fdout, STDOUT_FILENO);
                dup2(fdout, STDOUT_FILENO);
                char    *zpp_path;
                char    *zpp_path;
                if (path != NULL) {
                if (path != NULL) {
                        zpp_path = new char[strlen(path+1+strlen("/zpp"))];
                        zpp_path = new char[strlen(path+1+strlen("/zpp"))];
                        strcpy(zpp_path, path);
                        strcpy(zpp_path, path);
                        strcat(zpp_path, "/zpp");
                        strcat(zpp_path, "/zpp");
                } else zpp_path = strdup("zpp");
                } else zpp_path = strdup("zpp");
                // This call should never return
                // This call should never return
                //      We have to pass the name here, rather than an open file,
                //      We have to pass the name here, rather than an open file,
                // since zpp needs to mark for us what file it is in at all
                // since zpp needs to mark for us what file it is in at all
                // times.
                // times.
                if (zname)
                if (zname)
                        execlp(zpp_path, "zpp", zname, NULL);
                        execlp(zpp_path, "zpp", zname, NULL);
                else
                else
                        execlp(zpp_path, "zpp", NULL);
                        execlp(zpp_path, "zpp", NULL);
                fprintf(stderr, "Could not start pre-processor!\n");
                fprintf(stderr, "Could not start pre-processor!\n");
                perror("O/S Err:");
                perror("O/S Err:");
                exit(-5);
                exit(-5);
        }
        }
        close(pipefd[1]);
        close(pipefd[1]);
        return fdopen(pipefd[0], "r");
        return fdopen(pipefd[0], "r");
}
}
void    usage(void) {
void    usage(void) {
        printf("USAGE: zasm [-h] [-d] [-E] [-o ]  [ ]* ...\n");
        printf("USAGE: zasm [-h] [-d] [-E] [-o ]  [ ]* ...\n");
        printf("\t-d\tTurns on debugging in the parser\n");
        printf("\t-d\tTurns on debugging in the parser\n");
        printf("\t-E\tProduces preprocessor output only\n");
        printf("\t-E\tProduces preprocessor output only\n");
        printf("\t-h\tDisplays this message\n");
        printf("\t-h\tDisplays this message\n");
        printf("\t-o \tWrites the output to .  The\n"
        printf("\t-o \tWrites the output to .  The\n"
                "\t\tdefault output file is \"" DEFAULT_OUTPUT_FNAME "\".\n");
                "\t\tdefault output file is \"" DEFAULT_OUTPUT_FNAME "\".\n");
        printf("\t-I \tSearch  for include files.\n");
        printf("\t-I \tSearch  for include files.\n");
}
}
int     main(int argc, char **argv) {
int     main(int argc, char **argv) {
        int     skp = 0;
        int     skp = 0;
        const char      *zout_fname = NULL;
        const char      *zout_fname = NULL;
        char            *path_to_zasm = NULL;
        char            *path_to_zasm = NULL;
        bool    preprocess_only = false;
        bool    preprocess_only = false;
        FILE            *ppout;
        FILE            *ppout;
        pid_t           zpp_pid;
        pid_t           zpp_pid;
        int             zpp_status;
        int             zpp_status;
        std::string     inclist;
        std::string     inclist;
        if (NULL != getenv("ZIPINC"))
        if (NULL != getenv("ZIPINC"))
                inclist = getenv("ZIPINC");
                inclist = getenv("ZIPINC");
        master_input_filename = NULL;
        master_input_filename = NULL;
        // Find what directory zasm is in, so that we can find zpp when
        // Find what directory zasm is in, so that we can find zpp when
        // necessary.
        // necessary.
        path_to_zasm = NULL;
        path_to_zasm = NULL;
        if (strchr(argv[0], '/')) {
        if (strchr(argv[0], '/')) {
                path_to_zasm = strdup(argv[0]);
                path_to_zasm = strdup(argv[0]);
                char *ptr = strrchr(path_to_zasm,'/');
                char *ptr = strrchr(path_to_zasm,'/');
                *ptr = '\0';
                *ptr = '\0';
        }
        }
        skp=1;
        skp=1;
        for(int argn=0; argn+skp
        for(int argn=0; argn+skp
                if (argv[argn+skp][0] == '-') {
                if (argv[argn+skp][0] == '-') {
                        if (argv[argn+skp][1] == 'o') {
                        if (argv[argn+skp][1] == 'o') {
                                if (zout_fname)
                                if (zout_fname)
                                        free((void *)zout_fname);
                                        free((void *)zout_fname);
                                zout_fname = strdup(argv[argn+skp+1]);
                                zout_fname = strdup(argv[argn+skp+1]);
                                skp++;
                                skp++;
                        } else if (argv[argn+skp][1] == 'E')
                        } else if (argv[argn+skp][1] == 'E')
                                preprocess_only = true;
                                preprocess_only = true;
                        else if (argv[argn+skp][1] == 'I') {
                        else if (argv[argn+skp][1] == 'I') {
                                if (argv[argn+skp][2]) {
                                if (argv[argn+skp][2]) {
                                        if (inclist.size() != 0) {
                                        if (inclist.size() != 0) {
                                                inclist += std::string(":");
                                                inclist += std::string(":");
                                                inclist += &argv[argn+skp][2];
                                                inclist += &argv[argn+skp][2];
                                        } else
                                        } else
                                                inclist = &argv[argn+skp][2];
                                                inclist = &argv[argn+skp][2];
                                } else if (argn+skp+1
                                } else if (argn+skp+1
                                        if (inclist.size() != 0) {
                                        if (inclist.size() != 0) {
                                                inclist += std::string(":");
                                                inclist += std::string(":");
                                                inclist += argv[argn+skp+1];
                                                inclist += argv[argn+skp+1];
                                        } else
                                        } else
                                                inclist = argv[argn+skp+1];
                                                inclist = argv[argn+skp+1];
                                        skp++;
                                        skp++;
                                }
                                }
                        } else if (argv[argn+skp][1] == 'd')
                        } else if (argv[argn+skp][1] == 'd')
                                yydebug = 1;
                                yydebug = 1;
                        else if (argv[argn+skp][1] == 'h') {
                        else if (argv[argn+skp][1] == 'h') {
                                usage();
                                usage();
                                exit(0);
                                exit(0);
                        }
                        }
                        skp++;
                        skp++;
                        argn--;
                        argn--;
                } else {
                } else {
                        argv[argn] = argv[argn+skp];
                        argv[argn] = argv[argn+skp];
                }
                }
        } argc -= skp;
        } argc -= skp;
        if (zout_fname) {
        if (zout_fname) {
                for(int argn=0; argn
                for(int argn=0; argn
                        if (strcmp(zout_fname, argv[argn])==0) {
                        if (strcmp(zout_fname, argv[argn])==0) {
                                fprintf(stderr, "ERR: Cowardly refusing to overwrite \'%s\'\n", zout_fname);
                                fprintf(stderr, "ERR: Cowardly refusing to overwrite \'%s\'\n", zout_fname);
                                exit(-2);
                                exit(-2);
                        }
                        }
                }
                }
        }
        }
        if (preprocess_only) {
        if (preprocess_only) {
                objcode.open("/dev/null");
                objcode.open("/dev/null");
                if (zout_fname)
                if (zout_fname)
                        ppout = fopen(zout_fname, "w");
                        ppout = fopen(zout_fname, "w");
                else
                else
                        ppout = stdout;
                        ppout = stdout;
        } else {
        } else {
                if (!zout_fname)
                if (!zout_fname)
                        zout_fname = DEFAULT_OUTPUT_FNAME;
                        zout_fname = DEFAULT_OUTPUT_FNAME;
                objcode.open(zout_fname);
                objcode.open(zout_fname);
        }
        }
        setenv("ZIPINC",inclist.c_str(), 1);
        setenv("ZIPINC",inclist.c_str(), 1);
        master_input_filename = NULL;
        master_input_filename = NULL;
        if (argc > 0) {
        if (argc > 0) {
                for(int argn=0; argn
                for(int argn=0; argn
                        extern  FILE    *yyin;
                        extern  FILE    *yyin;
                        extern  void    yyrestart(FILE *);
                        extern  void    yyrestart(FILE *);
                        FILE    *tst;
                        FILE    *tst;
                        create_new_context();
                        create_new_context();
                        if (master_input_filename)
                        if (master_input_filename)
                                free(master_input_filename);
                                free(master_input_filename);
                        master_input_filename = strdup(argv[argn]);
                        master_input_filename = strdup(argv[argn]);
                        if (preprocess_only) {
                        if (preprocess_only) {
                                FILE    *fp = run_preprocessor(zpp_pid, path_to_zasm, master_input_filename);
                                FILE    *fp = run_preprocessor(zpp_pid, path_to_zasm, master_input_filename);
                                int     ch;
                                int     ch;
                                while(EOF != (ch = fgetc(fp)))
                                while(EOF != (ch = fgetc(fp)))
                                        fputc(ch, ppout);
                                        fputc(ch, ppout);
                                waitpid(zpp_pid, &zpp_status, WNOHANG);
                                waitpid(zpp_pid, &zpp_status, WNOHANG);
                        } else {
                        } else {
                                yyrestart(run_preprocessor(zpp_pid, path_to_zasm, master_input_filename));
                                yyrestart(run_preprocessor(zpp_pid, path_to_zasm, master_input_filename));
                                yylineno = 1;
                                yylineno = 1;
                                yyparse();
                                yyparse();
                                waitpid(zpp_pid, &zpp_status, WNOHANG);
                                waitpid(zpp_pid, &zpp_status, WNOHANG);
                        }
                        }
                }
                }
        } else { // Run from Stdin
        } else { // Run from Stdin
                extern  FILE    *yyin;
                extern  FILE    *yyin;
                extern  void    yyrestart(FILE *);
                extern  void    yyrestart(FILE *);
                create_new_context();
                create_new_context();
                master_input_filename = strdup("(stdin)");
                master_input_filename = strdup("(stdin)");
                if (preprocess_only) {
                if (preprocess_only) {
                        int     ch;
                        int     ch;
                                FILE    *fp = run_preprocessor(zpp_pid, path_to_zasm, master_input_filename);
                                FILE    *fp = run_preprocessor(zpp_pid, path_to_zasm, master_input_filename);
                        while(EOF != (ch = fgetc(fp)))
                        while(EOF != (ch = fgetc(fp)))
                                fputc(ch, ppout);
                                fputc(ch, ppout);
                        waitpid(zpp_pid, &zpp_status, WNOHANG);
                        waitpid(zpp_pid, &zpp_status, WNOHANG);
                } else {
                } else {
                        yyin = run_preprocessor(zpp_pid, NULL);
                        yyin = run_preprocessor(zpp_pid, NULL);
                        yyrestart(yyin);
                        yyrestart(yyin);
                        yyparse();
                        yyparse();
                        waitpid(zpp_pid, &zpp_status, WNOHANG);
                        waitpid(zpp_pid, &zpp_status, WNOHANG);
                }
                }
        }
        }
        if (0 != WEXITSTATUS(zpp_status)) {
        if (0 != WEXITSTATUS(zpp_status)) {
                if (!preprocess_only) {
                if (!preprocess_only) {
                        objcode.close();
                        objcode.close();
                        unlink(zout_fname);
                        unlink(zout_fname);
                }
                }
        } if (!objcode.reduce())
        } if (!objcode.reduce())
                fprintf(stderr, "Not all symbols defined!\n");
                fprintf(stderr, "Not all symbols defined!\n");
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.