
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