alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (Expression.java)

This example Java source code file (Expression.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

castexpr, constantpoolgen, errormsg, expression, flowlist, goto_w, ifeq, instructionlist, methodgenerator, methodtype, object, string, typecheckerror, util, vector

The Expression.java Java example source code

/*
 * reserved comment block
 * DO NOT REMOVE OR ALTER!
 */
/*
 * Copyright 2001-2004 The Apache Software Foundation.
 *
 * Licensed 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.
 */
/*
 * $Id: Expression.java,v 1.2.4.1 2005/09/01 14:17:51 pvedula Exp $
 */

package com.sun.org.apache.xalan.internal.xsltc.compiler;

import java.util.Vector;

import com.sun.org.apache.bcel.internal.generic.BranchHandle;
import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
import com.sun.org.apache.bcel.internal.generic.GOTO_W;
import com.sun.org.apache.bcel.internal.generic.IFEQ;
import com.sun.org.apache.bcel.internal.generic.InstructionHandle;
import com.sun.org.apache.bcel.internal.generic.InstructionList;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.BooleanType;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodType;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.NodeSetType;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;

/**
 * @author Jacek Ambroziak
 * @author Santiago Pericas-Geertsen
 * @author Morten Jorgensen
 * @author Erwin Bolwidt <ejb@klomp.org>
 */
abstract class Expression extends SyntaxTreeNode {
    /**
     * The type of this expression. It is set after calling
     * <code>typeCheck().
     */
    protected Type _type;

    /**
     * Instruction handles that comprise the true list.
     */
    protected FlowList _trueList = new FlowList();

    /**
     * Instruction handles that comprise the false list.
     */
    protected FlowList _falseList = new FlowList();

    public Type getType() {
        return _type;
    }

    public abstract String toString();

    public boolean hasPositionCall() {
        return false;           // default should be 'false' for StepPattern
    }

    public boolean hasLastCall() {
        return false;
    }

    /**
     * Returns an object representing the compile-time evaluation
     * of an expression. We are only using this for function-available
     * and element-available at this time.
     */
    public Object evaluateAtCompileTime() {
        return null;
    }

    /**
     * Type check all the children of this node.
     */
    public Type typeCheck(SymbolTable stable) throws TypeCheckError {
        return typeCheckContents(stable);
    }

    /**
     * Translate this node into JVM bytecodes.
     */
    public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
        ErrorMsg msg = new ErrorMsg(ErrorMsg.NOT_IMPLEMENTED_ERR,
                                    getClass(), this);
        getParser().reportError(FATAL, msg);
    }

    /**
     * Translate this node into a fresh instruction list.
     * The original instruction list is saved and restored.
     */
    public final InstructionList compile(ClassGenerator classGen,
                                         MethodGenerator methodGen) {
        final InstructionList result, save = methodGen.getInstructionList();
        methodGen.setInstructionList(result = new InstructionList());
        translate(classGen, methodGen);
        methodGen.setInstructionList(save);
        return result;
    }

    /**
     * Redefined by expressions of type boolean that use flow lists.
     */
    public void translateDesynthesized(ClassGenerator classGen,
                                       MethodGenerator methodGen) {
        translate(classGen, methodGen);
        if (_type instanceof BooleanType) {
            desynthesize(classGen, methodGen);
        }
    }

    /**
     * If this expression is of type node-set and it is not a variable
     * reference, then call setStartNode() passing the context node.
     */
    public void startIterator(ClassGenerator classGen,
                                   MethodGenerator methodGen) {
        // Ignore if type is not node-set
        if (_type instanceof NodeSetType == false) {
            return;
        }

        // setStartNode() should not be called if expr is a variable ref
        Expression expr = this;
        if (expr instanceof CastExpr) {
            expr = ((CastExpr) expr).getExpr();
        }
        if (expr instanceof VariableRefBase == false) {
            final InstructionList il = methodGen.getInstructionList();
            il.append(methodGen.loadContextNode());
            il.append(methodGen.setStartNode());
        }
    }

    /**
     * Synthesize a boolean expression, i.e., either push a 0 or 1 onto the
     * operand stack for the next statement to succeed. Returns the handle
     * of the instruction to be backpatched.
     */
    public void synthesize(ClassGenerator classGen, MethodGenerator methodGen) {
        final ConstantPoolGen cpg = classGen.getConstantPool();
        final InstructionList il = methodGen.getInstructionList();
        _trueList.backPatch(il.append(ICONST_1));
        final BranchHandle truec = il.append(new GOTO_W(null));
        _falseList.backPatch(il.append(ICONST_0));
        truec.setTarget(il.append(NOP));
    }

    public void desynthesize(ClassGenerator classGen,
                             MethodGenerator methodGen) {
        final InstructionList il = methodGen.getInstructionList();
        _falseList.add(il.append(new IFEQ(null)));
    }

    public FlowList getFalseList() {
        return _falseList;
    }

    public FlowList getTrueList() {
        return _trueList;
    }

    public void backPatchFalseList(InstructionHandle ih) {
        _falseList.backPatch(ih);
    }

    public void backPatchTrueList(InstructionHandle ih) {
        _trueList.backPatch(ih);
    }

    /**
     * Search for a primop in the symbol table that matches the method type
     * <code>ctype. Two methods match if they have the same arity.
     * If a primop is overloaded then the "closest match" is returned. The
     * first entry in the vector of primops that has the right arity is
     * considered to be the default one.
     */
    public MethodType lookupPrimop(SymbolTable stable, String op,
                                   MethodType ctype) {
        MethodType result = null;
        final Vector primop = stable.lookupPrimop(op);
        if (primop != null) {
            final int n = primop.size();
            int minDistance = Integer.MAX_VALUE;
            for (int i = 0; i < n; i++) {
                final MethodType ptype = (MethodType) primop.elementAt(i);
                // Skip if different arity
                if (ptype.argsCount() != ctype.argsCount()) {
                    continue;
                }

                // The first method with the right arity is the default
                if (result == null) {
                    result = ptype;             // default method
                }

                // Check if better than last one found
                final int distance = ctype.distanceTo(ptype);
                if (distance < minDistance) {
                    minDistance = distance;
                    result = ptype;
                }
            }
        }
        return result;
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java Expression.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.