%scanner ../scanner/scanner.h
%baseclass-preinclude ../rulevalue/_rulevalue.h
%filenames parser
//%debug

%stype RuleValue

%token  IDENT
        QUIT
        LIST
        INT CHAR 
        DOUBLE
        DATATYPE
        ANGLETYPE
        MATHCONST
        HELP

    // A of 'assignment'. Priorities: see C book, p. 518
%right  '=' ADDA SUBA MULA DIVA MODA ANDA XORA ORA LSHIFTA RSHIFTA
%left   '|'
%left   '^'
%left   '&'
%left   LEFTSHIFT RIGHTSHIFT
%left   '+' '-'
%left   '*' '/' '%'
%right  uMinus
%left   '('

%%

start:
    prompt
    lines
;

lines:
    lines line
|
    line
;

line:
    action
    prompt
;

action:
    cmd
    '\n'
|
    error
;

prompt:
    {
        prompt();
    }
;

cmd:
    QUIT
    {
        ACCEPT();
    }
|
    LIST
    {
        list();
    }
|
    help
    {
        help();
    }
|
    angletype
|
    expr
    {
        display($1);
    }
|
    // empty
;

angletype:
    ANGLETYPE
    {
        setAngleType();
    }
;
    

expr:
    MATHCONST
    {
        $$ = mathConst();
    }
|
    CHAR
    {
        $$ = newValue(CHAR);
    }
|
    INT
    {
        $$ = newValue(INT);
    }
|
    DOUBLE
    {
        $$ = newValue(DOUBLE);
    }
|
    IDENT
    {
        $$ = newValue(IDENT);
    }
|
    expr '(' arglist ')'
    {
        $$ = call($1, $3);
    }
|
    '-' expr                %prec uMinus
    {
        $$ = unary('-', $2);
    }
|
    '~' expr                %prec uMinus
    {
        $$ = unary('~', $2);
    }
|
    '(' type ')' expr       %prec uMinus
    {
        $$ = unary($2.asInt(), $4);
    }
|
    expr '+' expr
    {
        $$ = binary($1, '+', $3);
    }    
|
    expr '-' expr
    {
        $$ = binary($1, '-', $3);
    }    
|
    expr '*' expr
    {
        $$ = binary($1, '*', $3);
    }    
|
    expr '/' expr
    {
        $$ = binary($1, '/', $3);
    }    
|
    expr '%' expr
    {
        $$ = binary($1, '%', $3);
    }    
|
    expr '&' expr
    {
        $$ = binary($1, '&', $3);
    }    
|
    expr '^' expr
    {
        $$ = binary($1, '^', $3);
    }    
|
    expr '|' expr
    {
        $$ = binary($1, '|', $3);
    }    
|
    expr RIGHTSHIFT expr
    {
        $$ = binary($1, RIGHTSHIFT, $3);
    }    
|
    expr LEFTSHIFT expr
    {
        $$ = binary($1, LEFTSHIFT, $3);
    }    
|
    '(' expr ')'
    {
        $$ = $2;
    }
|
    expr '=' expr
    {
        $$ = assign($1, '=', $3);
    }
|
    expr ADDA expr
    {
        $$ = assign($1, ADDA, $3);
    }
|
    expr SUBA expr
    {
        $$ = assign($1, SUBA, $3);
    }
|
    expr MULA expr
    {
        $$ = assign($1, MULA, $3);
    }
|
    expr DIVA expr
    {
        $$ = assign($1, DIVA, $3);
    }
|
    expr MODA expr
    {
        $$ = assign($1, MODA, $3);
    }
|
    expr ANDA expr
    {
        $$ = assign($1, ANDA, $3);
    }
|
    expr ORA expr
    {
        $$ = assign($1, ORA, $3);
    }
|
    expr XORA expr
    {
        $$ = assign($1, XORA, $3);
    }
|
    expr LSHIFTA expr
    {
        $$ = assign($1, LSHIFTA, $3);
    }
|
    expr RSHIFTA expr
    {
        $$ = assign($1, RSHIFTA, $3);
    }
;

arglist:
    arglist ',' expr
    {
        $$ = addArg($1, $3);
    }
|
    expr
    {
        $$ = firstArg($1);
    }
;
    
type:
    DATATYPE
    {
        $$ = setDataType();
    }
;

help:
    '?'
|
    HELP
;

