package compiler.language.parser.rules.expression;

import static compiler.language.parser.ParseType.CAST_EXPRESSION;
import static compiler.language.parser.ParseType.EXCLAIMATION_MARK;
import static compiler.language.parser.ParseType.MINUS;
import static compiler.language.parser.ParseType.PLUS;
import static compiler.language.parser.ParseType.TILDE;
import static compiler.language.parser.ParseType.UNARY_EXPRESSION;

import compiler.language.ast.ParseInfo;
import compiler.language.ast.expression.BitwiseNotExpression;
import compiler.language.ast.expression.BooleanNotExpression;
import compiler.language.ast.expression.Expression;
import compiler.language.ast.expression.UnaryMinusExpression;
import compiler.language.ast.expression.UnaryPlusExpression;
import compiler.parser.ParseException;
import compiler.parser.Rule;

/*
 * Created on 11 Aug 2010
 */

/**
 * @author Anthony Bryant
 */
public class UnaryExpressionRule extends Rule
{

  private static final Object[] UNARY_PLUS_PRODUCTION = new Object[] {PLUS, UNARY_EXPRESSION};
  private static final Object[] UNARY_MINUS_PRODUCTION = new Object[] {MINUS, UNARY_EXPRESSION};
  private static final Object[] BOOLEAN_NOT_PRODUCTION = new Object[] {EXCLAIMATION_MARK, UNARY_EXPRESSION};
  private static final Object[] BITWISE_NOT_PRODUCTION = new Object[] {TILDE, UNARY_EXPRESSION};

  private static final Object[] CAST_PRODUCTION = new Object[] {CAST_EXPRESSION};


  public UnaryExpressionRule()
  {
    super(UNARY_EXPRESSION, UNARY_PLUS_PRODUCTION, UNARY_MINUS_PRODUCTION,
                            BOOLEAN_NOT_PRODUCTION, BITWISE_NOT_PRODUCTION,
                            CAST_PRODUCTION);
  }

  /**
   * {@inheritDoc}
   * @see compiler.parser.Rule#match(java.lang.Object[], java.lang.Object[])
   */
  @Override
  public Object match(Object[] types, Object[] args) throws ParseException
  {
    if (types == UNARY_PLUS_PRODUCTION)
    {
      Expression expression = (Expression) args[1];
      return new UnaryPlusExpression(expression, ParseInfo.combine((ParseInfo) args[0], expression.getParseInfo()));
    }
    if (types == UNARY_MINUS_PRODUCTION)
    {
      Expression expression = (Expression) args[1];
      return new UnaryMinusExpression(expression, ParseInfo.combine((ParseInfo) args[0], expression.getParseInfo()));
    }
    if (types == BOOLEAN_NOT_PRODUCTION)
    {
      Expression expression = (Expression) args[1];
      return new BooleanNotExpression(expression, ParseInfo.combine((ParseInfo) args[0], expression.getParseInfo()));
    }
    if (types == BITWISE_NOT_PRODUCTION)
    {
      Expression expression = (Expression) args[1];
      return new BitwiseNotExpression(expression, ParseInfo.combine((ParseInfo) args[0], expression.getParseInfo()));
    }
    if (types == CAST_PRODUCTION)
    {
      // the cast expression has already been built, so return it
      return args[0];
    }
    throw badTypeList();
  }

}

@@ -286,24 +286,82 @@
 eType.PLUS;%0A
+import static compiler.language.parser.ParseType.PRIMARY;%0A
 import stati
@@ -997,16 +997,176 @@
 Rule%0A%7B%0A%0A
+  private static final Object%5B%5D PRIMARY_PRODUCTION = new Object%5B%5D %7BPRIMARY%7D;%0A  private static final Object%5B%5D CAST_PRODUCTION = new Object%5B%5D %7BCAST_EXPRESSION%7D;%0A%0A
   privat
@@ -1560,154 +1560,136 @@
 %7D;%0A%0A
-  private static final Object%5B%5D CAST_PRODUCTION = new Object%5B%5D %7BCAST_EXPRESSION%7D;%0A%0A%0A  public UnaryExpressionRule()%0A  %7B%0A    super(UNARY_EXPRESSION,
+%0A  public UnaryExpressionRule()%0A  %7B%0A    super(UNARY_EXPRESSION, PRIMARY_PRODUCTION, CAST_PRODUCTION,%0A                           
  UNA
@@ -1810,53 +1810,8 @@
 TION
-,%0A                            CAST_PRODUCTION
 );%0A 
@@ -2009,24 +2009,184 @@
 ception%0A  %7B%0A
+    if (types == PRIMARY_PRODUCTION %7C%7C types == CAST_PRODUCTION)%0A    %7B%0A      // the expression has already been built, so return it%0A      return args%5B0%5D;%0A    %7D%0A
     if (type
@@ -3067,142 +3067,8 @@
   %7D%0A
-    if (types == CAST_PRODUCTION)%0A    %7B%0A      // the cast expression has already been built, so return it%0A      return args%5B0%5D;%0A    %7D%0A
     

Fix UnaryExpressionRule, by adding PRIMARY as one of its productions.