Package org.formulacompiler.compiler.internal.bytecode

Source Code of org.formulacompiler.compiler.internal.bytecode.HelperCompilerForFoldVectors

/*
* Copyright (c) 2006-2009 by Abacus Research AG, Switzerland.
* All rights reserved.
*
* This file is part of the Abacus Formula Compiler (AFC).
*
* For commercial licensing, please contact sales(at)formulacompiler.com.
*
* AFC is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AFC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AFC.  If not, see <http://www.gnu.org/licenses/>.
*/

package org.formulacompiler.compiler.internal.bytecode;

import java.util.Collection;
import java.util.Iterator;

import org.formulacompiler.compiler.CompilerException;
import org.formulacompiler.compiler.internal.expressions.ExpressionNode;
import org.formulacompiler.compiler.internal.expressions.ExpressionNodeForFoldApply;
import org.formulacompiler.compiler.internal.expressions.LetDictionary.LetEntry;
import org.formulacompiler.compiler.internal.model.ExpressionNodeForSubSectionModel;


@SuppressWarnings( "unqualified-field-access" )
final class HelperCompilerForFoldVectors extends HelperCompilerForFoldApply
{

  public HelperCompilerForFoldVectors( SectionCompiler _section, ExpressionNodeForFoldApply _applyNode,
      Iterable<LetEntry> _closure )
  {
    super( _section, _applyNode, _closure );
  }

  @Override
  protected boolean argumentsAreVectors()
  {
    return true;
  }


  @Override
  protected final void compileTraversal() throws CompilerException
  {
    final int eltCount = fold.eltCount();

    final Iterator<ExpressionNode> eltsIter = apply.elements().iterator();
    final ExpressionNode[] elts = new ExpressionNode[ eltCount ];
    for (int i = 0; i < eltCount; i++)
      elts[ i ] = eltsIter.next();

    final Iterator<ExpressionNode>[] vecs = getVectorArray( elts, eltCount );
    compileTraversalOf( vecs );
  }


  private void compileTraversalOf( Iterator<ExpressionNode>[] _vecs ) throws CompilerException
  {
    final int eltCount = fold.eltCount();
    final ExpressionNode[] elts = new ExpressionNode[ eltCount ];
    final int reuseLocalsAt = localsOffset();
    while (_vecs[ 0 ].hasNext()) {
      resetLocalsTo( reuseLocalsAt );
      for (int iVec = 0; iVec < eltCount; iVec++) {
        elts[ iVec ] = _vecs[ iVec ].next();
      }
      if (elts[ 0 ] instanceof ExpressionNodeForSubSectionModel) {
        verifyAllElementsReferenceTheSameSubSection( elts );
        compileSubSectionTraversal( (ExpressionNodeForSubSectionModel) elts[ 0 ], new SubSectionTraversal()
        {

          public void compile( Collection<ExpressionNode> _elements ) throws CompilerException
          {
            final Iterator<ExpressionNode>[] subVecs = getVectorArray( elts, eltCount );
            compileTraversalOf( subVecs );
          }

        } );
      }
      else {
        for (int iVec = 0; iVec < eltCount; iVec++) {
          final ExpressionNode elt = elts[ iVec ];
          letDict().let( fold.eltName( iVec ), elt.getDataType(), elt );
        }

        compileFoldStepsWithEltsBound();

        letDict().unlet( eltCount );
      }

    }
  }

  @SuppressWarnings( "unchecked" )
  private Iterator<ExpressionNode>[] getVectorArray( ExpressionNode[] _vecs, int _eltCount )
  {
    final Iterator<ExpressionNode>[] result = new Iterator[ _eltCount ];
    int iVec = 0;
    for (ExpressionNode vec : _vecs) {
      result[ iVec++ ] = vec.arguments().iterator();
    }
    assert iVec == result.length;
    return result;
  }


  private void verifyAllElementsReferenceTheSameSubSection( ExpressionNode[] _elts ) throws CompilerException
  {
    final ExpressionNodeForSubSectionModel sub = (ExpressionNodeForSubSectionModel) _elts[ 0 ];
    for (int iVec = 1; iVec < _elts.length; iVec++) {
      final ExpressionNode elt = _elts[ iVec ];
      if (elt instanceof ExpressionNodeForSubSectionModel) {
        final ExpressionNodeForSubSectionModel sub2 = (ExpressionNodeForSubSectionModel) elt;
        if (sub.getSectionModel() != sub2.getSectionModel()) {
          throw differentSubSections( sub, sub2 );
        }
      }
      else throw differentSubSections( sub, elt );
    }
  }

  private CompilerException differentSubSections( ExpressionNode _a, ExpressionNode _b )
  {
    return new CompilerException.ParallelVectorsSpanDifferentSubSections(
        "Cannot aggregate parallel vectors crossing subsections differently at " + _a + " and " + _b );
  }

}
TOP

Related Classes of org.formulacompiler.compiler.internal.bytecode.HelperCompilerForFoldVectors

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.