All Downloads are FREE. Search and download functionalities are using the official Maven repository.

manifold.internal.javac.AbstractBinder Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2019 - Manifold Systems LLC
 *
 * 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.
 */

package manifold.internal.javac;

import java.util.ArrayList;
import java.util.List;

/**
 * 
 * expression (velocity: length/time): 5 mi/hr
 * 
 *   (bad)   (good)
 *     ÷        ?
 *    / \      / \
 *   ?   hr   5   ÷
 *  / \          / \
 * 5   mi       mi  hr
 *
 * 
*

* A list of all the terminal operands maintains the operators in RHS operand nodes. The binding algorithm uses type * information to test for operator compatibility and binding reactions between adjacent operands to recursively reduce * the list to a single expression: *

 * initial list ==>  (? 5) -> (? mi) -> (/ hr)
 * ==>  (5) -> (? (mi/hr))
 * ==>  ((5(mi/hr)))
 * 
*/ public abstract class AbstractBinder { abstract protected MS findBinderMethod( Node left, Node right ); abstract protected Node makeBinaryExpression( Node left, Node right, MS binderMethod ); @SuppressWarnings("WeakerAccess") public B bind( ArrayList> operands ) { if( operands.isEmpty() ) { return null; } if( operands.size() == 1 ) { //noinspection unchecked return (B)operands.get( 0 ).getExpr(); } for( Root root = nextRoot( operands, 0 ); root != null; root = nextRoot( operands, root._index + 1 ) ) { //noinspection unchecked ArrayList> reduced = (ArrayList>)operands.clone(); root.replaceWithPair( reduced ); B solution = bind( reduced ); if( solution != null ) { return solution; } } return null; } private Root nextRoot( List> operands, int startIndex ) { Node left = null; for( int i = startIndex; i < operands.size(); i++ ) { Node right = operands.get( i ); if( left != null ) { MS binderMethod = findBinderMethod( left, right ); if( binderMethod != null ) { return new Root( i - 1, binderMethod ); } } left = right; } return null; } private class Root { int _index; MS _binderMethod; Root( int index, MS binderMethod ) { _index = index; _binderMethod = binderMethod; } private void replaceWithPair( List> operands ) { Node left = operands.get( _index ); operands.remove( _index ); Node right = operands.get( _index ); Node rootExpr = makeBinaryExpression( left, right, _binderMethod ); operands.set( _index, rootExpr ); } } public static class Node { E _expr; O _operatorLeft; public Node( E expr ) { this( expr, null ); } public Node( E expr, O operatorLeft ) { _expr = expr; _operatorLeft = operatorLeft; } public E getExpr() { return _expr; } @SuppressWarnings("unused") public O getOperatorLeft() { return _operatorLeft; } @SuppressWarnings("unused") public void setOperatorLeft( O value ) { _operatorLeft = value; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy