%token NUM VAR
%right  '='
%left   '-' '+'
%left   '*' '/'
%left   NEG
%right  '^'

%{
use base q{Math::Tail};
my %s; # symbol table
our $VERSION = '1.1';
%}

%%
start: 
    input { \%s }
;

input: line * 
;

line:       
  '\n'         { undef }
  | exp '\n'   { print "$_[1]\n" if defined($_[1]); $_[1] }
  | error  '\n'
    {
      $_[0]->YYErrok; # error recovery
      undef
    }

;

exp:
    $NUM            { $NUM->[0] }
  | $VAR                   
     { 
       my $id = $VAR->[0];
       my $val = $s{$id};
       $_[0]->semantic_error("Accesing undefined variable $id at line $VAR->[1].\n") 
       unless defined($val);
       return $val;
     }
  | $VAR '=' $exp   { $s{$VAR->[0]} = $exp }
  | exp.x '+' exp.y { $x + $y }
  | exp.x '-' exp.y { $x - $y }
  | exp.x '*' exp.y { $x * $y }
  | exp.x '/'.barr exp.y         
    {
       return($x/$y) if $y;
       $_[0]->semantic_error("Illegal division by zero at line $barr->[1].\n");
       undef
    }
  | '-' $exp %prec NEG  { -$exp }
  | exp.x '^' exp.y     { $x ** $y }
  | '(' $exp ')'        { $exp }
;

%%

__PACKAGE__->lexer( \&Math::Tail::lex );

# In case is compiled with eyapp option -b
__PACKAGE__->main unless caller;