001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements. See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership. The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the  "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    /*
019     * $Id: AlternativePattern.java 468650 2006-10-28 07:03:30Z minchau $
020     */
021    
022    package org.apache.xalan.xsltc.compiler;
023    
024    import org.apache.bcel.generic.GOTO;
025    import org.apache.bcel.generic.InstructionHandle;
026    import org.apache.bcel.generic.InstructionList;
027    import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
028    import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
029    import org.apache.xalan.xsltc.compiler.util.Type;
030    import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
031    
032    /**
033     * @author Jacek Ambroziak
034     * @author Santiago Pericas-Geertsen
035     */
036    final class AlternativePattern extends Pattern {
037        private final Pattern _left;
038        private final Pattern _right;
039                    
040        /**
041         * Construct an alternative pattern. The method <code>setParent</code>
042         * should not be called in this case.
043         */
044        public AlternativePattern(Pattern left, Pattern right) {
045            _left = left;
046            _right = right;
047        }
048                    
049        public void setParser(Parser parser) {
050            super.setParser(parser);
051            _left.setParser(parser);
052            _right.setParser(parser);
053        }
054        
055        public Pattern getLeft() {
056            return _left;
057        }
058    
059        public Pattern getRight() {
060            return _right;
061        }
062    
063        /**
064         * The type of an '|' is not really defined, hence null is returned.
065         */
066        public Type typeCheck(SymbolTable stable) throws TypeCheckError {
067            _left.typeCheck(stable);
068            _right.typeCheck(stable);
069            return null;
070        }
071    
072        public double getPriority() {
073            double left = _left.getPriority();
074            double right = _right.getPriority();
075            
076            if (left < right)
077                return(left);
078            else
079                return(right);
080        }
081    
082        public String toString() {
083            return "alternative(" + _left + ", " + _right + ')';
084        }
085    
086        public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
087            final InstructionList il = methodGen.getInstructionList();
088    
089            _left.translate(classGen, methodGen);
090            final InstructionHandle gotot = il.append(new GOTO(null));
091            il.append(methodGen.loadContextNode());
092            _right.translate(classGen, methodGen);
093    
094            _left._trueList.backPatch(gotot);
095            _left._falseList.backPatch(gotot.getNext());
096    
097            _trueList.append(_right._trueList.add(gotot));
098            _falseList.append(_right._falseList);
099        }
100    }