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

Subversion Repositories marca

[/] [marca/] [trunk/] [spar/] [exprs.y] - Rev 8

Compare with Previous | Blame | View Log

/* This file is part of the assembler "spar" for marca.
   Copyright (C) 2007 Wolfgang Puffitsch

   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU Library General Public License as published
   by the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA */

%{

#include <stdlib.h>
#include <stdio.h>

#include "exprs.h"

int exprslex(void);
void yyerror(int64_t *, const char *);

%}

%union {
  int64_t intval;
}

%parse-param {
  int64_t *retval, int64_t *symcount
}

%token <intval> NUM IDENT

%token CUMOD CEQU CUGT CSHR CUMIN CLE CNEQ CMIN CLAND
%token CGE CUDIV CUGE CULE CLOR CULT CSHL CMAX CUMAX CSLR
%token HI LO

%type <intval> PrimaryExpr UnaryExpr MultExpr AddExpr ShiftExpr
%type <intval> RelatExpr EqualExpr AndExpr XorExpr OrExpr
%type <intval> LAndExpr LOrExpr CondExpr MinMaxExpr HiLoExpr Expr

%start Expr

%%

PrimaryExpr : NUM 
            { $$ = $1;
            }
            | IDENT 
            { (*symcount)++;
              $$ = $1;
            }
            | '(' Expr ')' 
            { $$ = $2;
            }
;

UnaryExpr : PrimaryExpr
          | '+' UnaryExpr
          { $$ = $2;
          }
          | '-' UnaryExpr
          { $$ = -$2;
          }
          | '~' UnaryExpr
          { $$ = ~$2;
          }
          | '!' UnaryExpr
          { $$ = !$2;
          }
;

MultExpr : UnaryExpr
         | MultExpr '*' UnaryExpr
         { $$ = $1 * $3;
         }
         | MultExpr '/' UnaryExpr
         {
           if ($3 == 0)
             {
               fprintf(stderr, "division by zero");
               $$ = 0;
             }
           else
             {
               $$ = $1 / $3;
             }
         }
         | MultExpr CUDIV UnaryExpr
         {
           if ($3 == 0)
             {
               fprintf(stderr, "division by zero");
               $$ = 0;
             }
           else
             {
               $$ = (uint64_t)$1 / (uint64_t)$3;
             }
         }
         | MultExpr '%' UnaryExpr
         {
           if ($3 == 0)
             {
               fprintf(stderr, "modulo zero");
               $$ = 0;
             }
           else
             {
               $$ = $1 % $3;
             }
         }
         | MultExpr CUMOD UnaryExpr
         {
           if ($3 == 0)
             {
               fprintf(stderr, "modulo zero");
               $$ = 0;
             }
           else
             {
               $$ = (uint64_t)$1 % (uint64_t)$3;
             }
         }
;

AddExpr : MultExpr
        | AddExpr '+' MultExpr
        { $$ = $1 + $3;
        }
        | AddExpr '-' MultExpr
        { $$ = $1 - $3;
        }
;

ShiftExpr : AddExpr
          | ShiftExpr CSHR AddExpr
          { $$ = $1 >> $3;
          }
          | ShiftExpr CSHL AddExpr
          { $$ = $1 << $3;
          }
          | ShiftExpr CSLR AddExpr
          { $$ = (uint64_t)$1 >> $3;
          }
;

RelatExpr : ShiftExpr
          | RelatExpr '<' ShiftExpr
          { $$ = $1 < $3;
          }
          | RelatExpr '>' ShiftExpr
          { $$ = $1 > $3;
          }
          | RelatExpr CLE ShiftExpr
          { $$ = $1 <= $3;
          }
          | RelatExpr CGE ShiftExpr
          { $$ = $1 >= $3;
          }
          | RelatExpr CULT ShiftExpr
          { $$ = (uint64_t)$1 < (uint64_t)$3;
          }
          | RelatExpr CUGT ShiftExpr
          { $$ = (uint64_t)$1 > (uint64_t)$3;
          }
          | RelatExpr CULE ShiftExpr
          { $$ = (uint64_t)$1 <= (uint64_t)$3;
          }
          | RelatExpr CUGE ShiftExpr
          { $$ = (uint64_t)$1 >= (uint64_t)$3;
          }
;

EqualExpr : RelatExpr
          | EqualExpr CEQU RelatExpr
          { $$ = $1 == $3;
          }
          | EqualExpr CNEQ RelatExpr
          { $$ = $1 != $3;
          }
;

AndExpr : EqualExpr
        | AndExpr '&' EqualExpr
        { $$ = $1 & $3;
        }
;

XorExpr : AndExpr
        | XorExpr '^' AndExpr
        { $$ = $1 ^ $3;
        }
;

OrExpr : XorExpr
       | OrExpr '|' XorExpr
       { $$ = $1 | $3;
       }
;

LAndExpr : OrExpr
         | LAndExpr CLAND OrExpr
         { $$ = $1 && $3;
         }
;

LOrExpr : LAndExpr
        | LOrExpr CLOR LAndExpr
        { $$ = $1 || $3;
        }
;

CondExpr : LOrExpr
         | LOrExpr '?' Expr ':' CondExpr
         { $$ = $1 ? $3 : $5;
         }
;

MinMaxExpr : CondExpr
           | MinMaxExpr CMIN CondExpr
           { $$ = $1 < $3 ? $1 : $3;
           }
           | MinMaxExpr CMAX CondExpr
           { $$ = $1 > $3 ? $1 : $3;
           }
           | MinMaxExpr CUMIN CondExpr
           { $$ = (uint64_t)$1 < (uint64_t)$3 ? $1 : $3;
           }
           | MinMaxExpr CUMAX CondExpr
           { $$ = (uint64_t)$1 > (uint64_t)$3 ? $1 : $3;
           }
;

HiLoExpr : MinMaxExpr
         | HI '(' MinMaxExpr ')'
         { $$ = ($3 >> 8) & 0xFF;
         }
         | LO '(' MinMaxExpr ')'
         { $$ = $3 & 0xFF;
         }

Expr: HiLoExpr
    { *retval = $1;
    }
;

%%

void yyerror(int64_t *r, const char *msg)
{
  fprintf(stderr, "within expression: %s\n", msg);
}

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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