package flash.tools.debugger.expression;

header
{
	/*
    
      Licensed to the Apache Software Foundation (ASF) under one or more
      contributor license agreements.  See the NOTICE file distributed with
      this work for additional information regarding copyright ownership.
      The ASF licenses this file to You under the Apache License, Version 2.0
      (the "License"); you may not use this file except in compliance with
      the License.  You may obtain a copy of the License at
    
          http://www.apache.org/licenses/LICENSE-2.0
    
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      See the License for the specific language governing permissions and
      limitations under the License.

		AS3DebuggerBURM.java is a Bottom-Up Rewrite Machine for ActionScript 3.0.

		A BURM recognizes patterns of nodes within an tree (in this case, an
		abstract syntax tree for AS 3.0 expressions) and performs rule-based reduction
		on them (in this case producing DebuggerValues).

		AS3DebuggerBURM.java is generated from AS3DebuggerBURM.jbg using JBurg, an open-source
		Java implementation of a Bottom-Up Rewrite Generator.

		The most important entry point of this class is burm(),
		which is called by the code generator.
	*/

    import static org.apache.flex.abc.ABCConstants.*;
    import static org.apache.flex.compiler.tree.ASTNodeID.*;

    import org.apache.flex.compiler.constants.IASLanguageConstants;
    import org.apache.flex.compiler.exceptions.BURMAbortException;
    import org.apache.flex.compiler.problems.*;
    import org.apache.flex.compiler.internal.semantics.SemanticUtils;
    import org.apache.flex.compiler.tree.ASTNodeID;
    import org.apache.flex.compiler.tree.as.IASNode;
    import org.apache.flex.compiler.tree.as.ITryNode;
}

INodeType IASNode;
OpcodeType ASTNodeID;

/*
 *  The I-node type is IASNode, and it has its own adapter.
 */
INodeAdapter org.apache.flex.compiler.internal.as.codegen.IASNodeAdapter;

//  Generate Java output.
Language java;

// Return type of all the reductions
ReturnType Object;

/**
 *  This is a name to use in an expression context.
 *
 *  TODO: What type should this be?
 */
ReturnType name = Object;

ReturnType decl_name = Object;

/**
 *  Qualified name - this acts the same as a name above, but is built a little differently.
 */
ReturnType qualifiedName = Object;
ReturnType qualifiedNamePart = Object;

/**
 *  This is a name used in a type annotation context, such as 'Foo' in:
 *      var x : Foo;
 *  It is a Binding, as type annotations must always be resolved.
 *  A type_name also allows '*', which can't happen in a general expression context.
 */
ReturnType type_name = Object;

/**
 *  This is a name used in a new context, such as 'Foo' in:
 *      new Foo();
 *  We can do additional analysis when the new expression resolves to a Type, which
 *  is why we have a special name for the new expression.
 */
ReturnType new_type_name = Object;

ReturnType dottedNamePart = String;

ReturnType non_resolving_identifier = String;

ReturnType runtime_name_expression = Object;
ReturnType multinameL = Object;
ReturnType e4x_literal = String;

ReturnType integer_constant = Integer;
ReturnType uint_constant = Long;
ReturnType double_constant = Double;
ReturnType string_constant = String;
ReturnType boolean_constant = Boolean;
ReturnType float_constant = Float;

ReturnType numeric_constant = Number;

ReturnType constant_value = Object;

/**
 * Value to use to indicate a cost that is not feasible
 */
JBurg.Constant ERROR_TRAP = 268435456;

{
    final static boolean NEED_VALUE = true;
    final static boolean DISCARD_VALUE = false;


    /**
     *  The reducer has all the implementation
     *  logic for the rewrite; the BURM constructed
     *  by this specification drives that logic.
     */
    AS3DebuggerReducer reducer;


    /*
     *  **  Cost functions  **
     * Cost functions are Java code that returns an int value.
     * The value is used to compute the cost of a particular
     * candidate reduction. The BURM searches for the lowest
     * total cost sequence of reductions to transform the input
     * AST into a value, so low values mean "good cost," higher
     * values mean "less desirable."   The total cost of a reduction
     * is always strictly less than Integer.MAX_VALUE; a cost of
     * Integer.MAX_VALUE tells the pattern matcher that the
     * reduction is not feasible.
     */


    /**
     *  @return "feasible" if the reducer can reduce this to a dotted name.
     */
    int isDottedName(IASNode iNode)
    {
       return reducer.isDottedName(iNode);
    }

    /**
     *  @return "feasible" if the reducer can reduce this to a package name.
     */
    int isPackageName(IASNode iNode)
    {
       return reducer.isPackageName(iNode);
    }

    /**
     *  @return "feasible" if this node's qualifier is a compile-time constant.
     */
    int qualifierIsCompileTimeConstant(IASNode iNode)
    {
       return reducer.qualifierIsCompileTimeConstant(iNode);
    }

    /**
     *  @return "feasible" if this node can be resolved to a compile-time constant.
     */
    int isCompileTimeConstant(IASNode iNode)
    {
       return reducer.isCompileTimeConstant(iNode);
    }

    /**
     *  @return "feasible" if this function call node can be resolved to a compile-time constant function.
     */
    int isCompileTimeConstantFunction(IASNode iNode)
    {
       return reducer.isCompileTimeConstantFunction(iNode);
    }

    /**
     *  @return "feasible" if this binary node has at least one expression that is
     *          of type "float".
     */
    int isFloatBinOp(IASNode iNode)
    {
       return reducer.isFloatBinOp(iNode);
    }

    /**
     *  @return "feasible" if this node is for 'new Array()'.
     */
    int isEmptyArrayConstructor(IASNode iNode)
    {
        return reducer.isEmptyArrayConstructor(iNode);
    }

    /**
     *  @return "feasible" if this node is for 'new Object()'.
     */
    int isEmptyObjectConstructor(IASNode iNode)
    {
        return reducer.isEmptyObjectConstructor(iNode);
    }

    /**
     * @return "feasible" if this node resolves to a type definition.
     */
    int isKnownType(IASNode iNode)
    {
        return reducer.isKnownType(iNode);
    }

    /**
     * @return "feasible" if the type parameter resolves to a type definition.
     */
    int parameterTypeIsConstant(IASNode iNode)
    {
        return reducer.parameterTypeIsConstant(iNode);
    }

    /**
     *  recordError is a convenience method for error reductions;
     *  it adds a problem to the current set of problems and
     */
    Object recordError(ICompilerProblem problem)
    {
        return new Object();
    }

    int isIntLiteral(IASNode iNode)
    {
        return reducer.isIntLiteral(iNode);
    }

    int isUintLiteral(IASNode iNode)
    {
        return reducer.isUintLiteral(iNode);
    }

    int isDoubleLiteral(IASNode iNode)
    {
        return reducer.isDoubleLiteral(iNode);
    }

    int isFloatLiteral(IASNode iNode)
    {
        return reducer.isDoubleLiteral(iNode);
    }

}

/*
 *  Error recovery routine: deduce what we can from the problem
 *  tree, then abort this BURM with an exception that the caller
 *  can catch and ignore.
 */
DefaultErrorHandler
{
    BURMAbortException.abort();
}

/*
 *  Patterns and rules are stored in their own, shareable file.
 */
JBurg.include "CmcPatterns.jbg"


/*
 * This pattern is used by the debugger to call special functions 
 * like $obj() when handling the ‘print #ObjectRefNumber’ feature.
 * I don’t think I would have a rule like this in the compiler as 
 * calling foo() where foo is just an identifier is probably likely
 * and “foo” has to be resolved from an identifier to, in most cases,
 * a MemberAccessExpression, but I don’t think folks print function
 * calls in the debugger.  And even if they do, there is a chance it
 * will work anyway.
 *
 * If the debugger is missing the ability to print something, it may be
 * that a new Pattern and Rule need to be added.  First, set a breakpoint
 * in DebuggerExpressionEvaluator at the call to burm.burm().  Examine 
 * the node to make sure it was parsed correctly into a tree of nodes.
 *
 * If the node tree is correct, step into the burm() call.  You should
 * see the code call label() and return a different tree of instances.
 * For lots of things, there are custom classes like:
 *   JBurgAnnotation_FunctionCallID_2_n
 * which represents a FunctionCallID in the AST.  If the top node is an
 * instance of JBurgAnnotationGeneral, that means that the BURM did not
 * expect a node of that type.  This may be true throughout the tree
 * but I’ve seen that ContainerID, which represents parenthesis around
 * parameters to a function also becomes a JBurgAnnotationGeneral because
 * the BURM theoretically never examines that node in the tree, it examines
 * its children.
 *
 * If a pattern is missing, add the pattern.  A Pattern seems to be a node ID
 * with a parameter list of the children node ID’s or other Patterns.  The
 * names you use in the parameter list will be used in the reduction function
 * later.
 *
 * Then add a Rule for it in AS3DebuggerRules.jbg.  
 *
 * It seems like the BURM
 * operates on “levels” of constructs, the higher order construct being an
 * “expression”.  Expressions are composed of other expressions or lower-level
 * constructs like name or constants (like uint_constant) or literals (like
 * boolean_literal.  It seems like, even if the string you want the debugger
 * to print is just a string or number, it may get “reduced” by the BURM into
 * higher-level things first.
 *
 * So, I think most new Rules for complex patterns will be an expression,
 * but if it doesn’t recognize a constant of some sort you may need to 
 * add that.  Anyway, you add an expression like the one in this change list
 * and then assign a value (or cost) for the rule.  Lower numbers 
 * (but greater than 0) win.  The actual cost is computed by factoring in the
 * cost of reducing the children.
 *
 * On the next line below the rule and its cost, add, for most things, a
 * JBurg.reduction method call that you will write to do the reduction. Pass
 * in the node (__p) and any of the parameters from the Pattern.
 *
 * Next, in AS3DebuggerReducer.java, add that reduction method and fill
 * in the method body.  Try to look for similar reductions and copy what
 * they do.  For the debugger, you eventually want to return a DebuggerValue.
 * DebuggerValues seem to be what expressions reduce to and you’ll find they
 * get passed into the reduction method as well.
 *
 */
// $obj()
Pattern functionCallSpecial
FunctionCallID(IdentifierID(void) specialName, ContainerID(expression args*));


JBurg.include "AS3DebuggerRules.jbg"
