#
# Reduction rules for arith.pl
# Perl source code automatically generated at Fri Apr 17 14:40:49 1998 by
# py v.0.1 25 Aug 1995
# Source code copyright 1995 M-J. Dominus (mjd@pobox.com)
#

# rule 1
# statement -> expr ';'
sub rule_1 {
  return $_[0];
}

# rule 2
# statement -> ';'
sub rule_2 {
  return '.';
}

# rule 3
# expr -> '(' expr ')'
sub rule_3 {
  return $_[1];
}

# rule 4
# expr -> expr '+' expr
sub rule_4 {
  return $_[0] + $_[2];
}

# rule 5
# expr -> expr '-' expr
sub rule_5 {
  return $_[0] - $_[2];
}

# rule 6
# expr -> expr '*' expr
sub rule_6 {
  return $_[0] * $_[2];
}

# rule 7
# expr -> expr '/' expr
sub rule_7 {
  if ($_[2] == 0) {
    error("Division by 0");
    return undef;
  }
  return $_[0] / $_[2];
}

# rule 8
# expr -> expr POWOP expr
sub rule_8 {
  my $res = eval {$_[0] ** $_[2]};
  if ($@) {
    error($@);
    return undef;
  } else {
    return $res;
  }
}

# rule 9
# expr -> NAME ASSIGNOP expr
sub rule_9 {
  return $vars{$_[0]} = $_[2];
}

# rule 10
# expr -> expr '?' expr ':' expr
sub rule_10 {
  if ($_[0] == 0) {
    $_[4];
  } else {
    $_[2];
  }
}

# rule 11
# expr -> expr ',' expr
sub rule_11 {
  return $_[2];
}

# rule 12
# expr -> NAME
sub rule_12 {
  return $vars{$_[0]};
}

# rule 13
# expr -> NUMBER
sub rule_13 {
  return $_[0];
}






# The lexer converts sequences of characters into 
# tokens.  A token may have a value, which is stored
# in the variable $yylval.  The return value from yylex
# says what the type of token is.
{
  my @tokens = ();

  sub yylex {
    my $token;
    until ($token =~ /\S/) {
      $token = shift @tokens;
      return End_of_Input unless defined $token;
    }

    $yylval = $token;
    if ($token =~ /^[A-Za-z_]/ ) {
      return NAME;
    } elsif ($token =~ /^\d/) {
      return NUMBER;
    } elsif ($token eq '**' || $token eq '^') {
      return POWOP;
    } elsif ($token eq ':=' || $token eq '=') {
      return ASSIGNOP;
    } else {
      return $yylval;
    }
  }

  sub set_input {
    my $instr = join '', @_;
    $instr =~ tr/\n/ /;
    @tokens = split(/(:=	# Special assignment operator
		      |
		      \*\*	# Special power operator
		      |
		      [-()+*\/?=:;,^] # Single-character token
		      |
		      [A-Za-z_]\w* # Name
		      |
		      (?:\d+(?:\.\d+)) # Number
		     )/x, 
		    $instr);
    local $" = '][';
    print STDERR "TOKENS: [@tokens]\n";
  }
}


1;
