Package org.openquark.gems.client

Source Code of org.openquark.gems.client.TestSourceGeneration$TestGemEntityGem

/*
* Copyright (c) 2007 BUSINESS OBJECTS SOFTWARE LIMITED
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*     * Redistributions of source code must retain the above copyright notice,
*       this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of Business Objects nor the names of its contributors
*       may be used to endorse or promote products derived from this software
*       without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/


/*
* GemGraphTest.java
* Creation date: Mar 25, 2003.
* By: Edward Lam
*/
package org.openquark.gems.client;

import java.util.Arrays;
import java.util.HashSet;

import org.openquark.cal.compiler.CALSourceGenerator;
import org.openquark.cal.compiler.CompilerMessage;
import org.openquark.cal.compiler.CompilerMessageLogger;
import org.openquark.cal.compiler.CompositionNode;
import org.openquark.cal.compiler.MessageLogger;
import org.openquark.cal.compiler.ModuleName;
import org.openquark.cal.compiler.QualifiedName;
import org.openquark.cal.compiler.Scope;
import org.openquark.cal.compiler.SourceModel;
import org.openquark.cal.compiler.SourceModelUtilities;
import org.openquark.cal.machine.StatusListener;
import org.openquark.cal.module.Cal.Collections.CAL_List;
import org.openquark.cal.module.Cal.Core.CAL_Prelude;
import org.openquark.cal.services.BasicCALServices;


/**
* Simple class to test source generation from composition nodes.
* This class consists of a number of methods which construct composition node trees,
* and dumps the corresponding source definition (as generated by the source generator) to the console.
*
* @author Edward Lam
*/
public class TestSourceGeneration {

    /**
     * A simplified CompositionNode.Value / Gem class that just takes and emits a string as its value.
     * @author Edward Lam
     */
    private static class TestValueGem extends Gem implements CompositionNode.Value {

        private final String stringValue;

        TestValueGem(String stringValue) {
            super(0);
            this.stringValue = stringValue;
        }

        public String getStringValue() {
            return stringValue;
        }
       
        public SourceModel.Expr getSourceModel() {
            return SourceModelUtilities.TextParsing.parseExprIntoSourceModel(stringValue);
        }
    }

    /**
     * A simplified CompositionNode.GemEntityNode / Gem class that takes an emits a string as its name,
     *   and optionally the names of its inputs as well.
     * @author Edward Lam
     */
    private static class TestGemEntityGem extends Gem implements CompositionNode.GemEntityNode {
       
        private final QualifiedName name;

        TestGemEntityGem(String qualifiedName, String[] argNames) {
            this(QualifiedName.makeFromCompoundName(qualifiedName), argNames);
        }

        TestGemEntityGem(String qualifiedName, int nArgs) {
            this(QualifiedName.makeFromCompoundName(qualifiedName), new String[nArgs]);
        }

        TestGemEntityGem(QualifiedName name, String[] argNames) {
            super(argNames.length);
            this.name = name;
        }
       
        /**
         * {@inheritDoc}
         */
        public QualifiedName getName() {
            return name;
        }
       
        /**
         * {@inheritDoc}
         */
        @Override
        public String toString() {
            return super.toString() + ".  Name = " + name;
        }
    }

    /**
     * Run the test(s)..
     * @param args
     */
    public static void main2(String[] args) {
        System.out.println("\nTest 12:");
        CollectorGem rootGem = test12();
        System.out.println(CALSourceGenerator.getFunctionText("scName", rootGem, Scope.PUBLIC));
    }

    /**
     * Run the test(s)..
     * @param args
     */
    public static void main(String[] args) {
       
        String workspaceFileName = "gemcutter.default.cws";
        BasicCALServices services = BasicCALServices.make(workspaceFileName);
       
        // A simple status listener which provides feedback with dots.
        StatusListener statusListener = new StatusListener() {

            private int nDotsInLine = 0;
            private static final int DOTS_PER_LINE = 120;
           
            public void setModuleStatus(StatusListener.Status.Module moduleStatus, ModuleName moduleName) {
                dumpDot();
            }
           
            public void setEntityStatus(StatusListener.Status.Entity entityStatus, String entityName) {
                dumpDot();
            }
           
            public void incrementCompleted(double d) {
                dumpDot();
            }

            private void dumpDot() {
                System.out.print('.');
                nDotsInLine++;
                if (nDotsInLine >= DOTS_PER_LINE) {
                    nDotsInLine = 0;
                    System.out.println();
                }
            }
        };
       
        System.out.println("Compiling...");
       
        CompilerMessageLogger logger = new MessageLogger();
        services.compileWorkspace(statusListener, logger);
       
        System.out.println();
       
        // Just dump messages to the console.
        if (logger.getNMessages() > 0) {
            for (final CompilerMessage compilerMessage : logger.getCompilerMessages()) {
                System.out.println(compilerMessage.getMessage());
            }
        }
       
        System.out.println("Test 1:");
        CollectorGem rootGem = test1();
        System.out.println(CALSourceGenerator.getFunctionText(rootGem.getUnqualifiedName(), rootGem, Scope.PUBLIC));
       
        System.out.println("Test 2:");
        rootGem = test2();
        System.out.println(CALSourceGenerator.getFunctionText(rootGem.getUnqualifiedName(), rootGem, Scope.PUBLIC));
       
        System.out.println("Test 3:");
        rootGem = test3();
        System.out.println(CALSourceGenerator.getFunctionText(rootGem.getUnqualifiedName(), rootGem, Scope.PUBLIC));
       
        System.out.println("\nTest 12:");
        rootGem = test12();
        System.out.println(CALSourceGenerator.getFunctionText(rootGem.getUnqualifiedName(), rootGem, Scope.PUBLIC));

        System.out.println("\nTest 13:");
        rootGem = test13(true);
        System.out.println(CALSourceGenerator.getFunctionText(rootGem.getUnqualifiedName(), rootGem, Scope.PUBLIC));

        rootGem = test13(false);
        System.out.println(CALSourceGenerator.getFunctionText(rootGem.getUnqualifiedName(), rootGem, Scope.PUBLIC));

        System.out.println("\nTest 14:");
        rootGem = test14();
        System.out.println(CALSourceGenerator.getFunctionText(rootGem.getUnqualifiedName(), rootGem, Scope.PUBLIC));

        System.out.println("\nTest 16:");
        rootGem = test16();
        System.out.println(CALSourceGenerator.getFunctionText(rootGem.getUnqualifiedName(), rootGem, Scope.PUBLIC));

        System.out.println("\nTest 18:");
        rootGem = test18(services);
        System.out.println(CALSourceGenerator.getFunctionText(rootGem.getUnqualifiedName(), rootGem, Scope.PUBLIC));

        System.out.println("\nTest 19:");
        rootGem = test19(services);
        System.out.println(CALSourceGenerator.getFunctionText(rootGem.getUnqualifiedName(), rootGem, Scope.PUBLIC));

        System.out.println("\nTest 25:");
        rootGem = test25();
        System.out.println(CALSourceGenerator.getFunctionText(rootGem.getUnqualifiedName(), rootGem, Scope.PUBLIC));
       
        System.out.println("\nTest 26:");
        rootGem = test26();
        System.out.println(CALSourceGenerator.getFunctionText(rootGem.getUnqualifiedName(), rootGem, Scope.PUBLIC));
    }
   
    /**
     * Connect an input and an output without doing any checking.
     * @param from
     * @param to
     */
    private static Connection simpleConnect(Gem.PartOutput from, Gem.PartInput to) {
        // Create a new Connection and add it to the graph
        Connection conn = new Connection(from, to);
   
        // Let the Gems know that their interfaces are bound
        from.bindConnection(conn);
        to.bindConnection(conn);
       
        return conn;
    }
   
    /**
     * Prelude.add - collector1
     * @return Gem
     */
    private static CollectorGem test1() {
        // Collector
        CollectorGem cGem = new CollectorGem(null);
        cGem.setName("collector1");
       
        // Prelude.add
        TestGemEntityGem faGem = new TestGemEntityGem(CAL_Prelude.Functions.add.getQualifiedName(), 2);
       
        // Connect Prelude.add - Collector
        simpleConnect(faGem.getOutputPart(), cGem.getCollectingPart());

        // Update cGem arguments.
        cGem.addArguments(Arrays.asList(faGem.getInputParts()));
        cGem.updateReflectedInputs();
       
        return cGem;
    }

    /**
     * Emitter for collector1
     * @return Gem
     */
    private static CollectorGem test2() {
        CollectorGem rootGem = test1();

        ReflectorGem reflectorGem = new ReflectorGem(rootGem);
       
        CollectorGem scGem = new CollectorGem(null);
        scGem.setName("scName");
       
        simpleConnect(reflectorGem.getOutputPart(), scGem.getCollectingPart());
       
        return scGem;
    }

    /**
     * Return a graph for a factorial function.
     *
     *   fac n =
     *     if n < 1 then 1
     *              else n * fac (n - 1);
     *
     * @return Gem
     */
    private static CollectorGem test3() {

        // collector fac
        CollectorGem fac = new CollectorGem(null);
        fac.setName("fac");
       
        // Collector n
        CollectorGem nCollector = new CollectorGem(fac);
        nCollector.setName("n");
       
//        TestGemEntityGem idGem = new TestGemEntityGem(CAL_Prelude.Functions.id.getQualifiedName(), 1);
//        simpleConnect(idGem.getOutputPart(), nCollector.getCollectingPart());
       
        // Prelude.lessThan
        TestGemEntityGem lessThanGem = new TestGemEntityGem(CAL_Prelude.Functions.lessThan.getQualifiedName(), 2);
       
        // 1
        TestValueGem value1_0 = new TestValueGem("1");
       
        // (lessThan n 1)
        ReflectorGem nEmitter = new ReflectorGem(nCollector);
        simpleConnect(nEmitter.getOutputPart(), lessThanGem.getInputPart(0));
        simpleConnect(value1_0.getOutputPart(), lessThanGem.getInputPart(1));
       
        // Prelude.iff
        TestGemEntityGem iffGem = new TestGemEntityGem(CAL_Prelude.Functions.iff.getQualifiedName(), 3);
       
        // 1 again
        TestValueGem value1_1 = new TestValueGem("1");

        // iff (lessThan n 1) 1 (blah)
        simpleConnect(lessThanGem.getOutputPart(), iffGem.getInputPart(0));
        simpleConnect(value1_1.getOutputPart(), iffGem.getInputPart(1));
       
        // Prelude.multiply n (blah)
        TestGemEntityGem multiplyGem = new TestGemEntityGem(CAL_Prelude.Functions.multiply.getQualifiedName(), 2);
        ReflectorGem nEmitter2 = new ReflectorGem(nCollector);
        simpleConnect(nEmitter2.getOutputPart(), multiplyGem.getInputPart(0));
       
        // iff (lessThan n 1) 1 (Prelude.multiply n blah)
        simpleConnect(multiplyGem.getOutputPart(), iffGem.getInputPart(2));
       
        // n - 1
        ReflectorGem nEmitter3 = new ReflectorGem(nCollector);
        TestValueGem value1_2 = new TestValueGem("1");
        TestGemEntityGem subtractGem = new TestGemEntityGem(CAL_Prelude.Functions.subtract.getQualifiedName(), 2);
        simpleConnect(nEmitter3.getOutputPart(), subtractGem.getInputPart(0));
        simpleConnect(value1_2.getOutputPart(), subtractGem.getInputPart(1));
       
        // iff - fac
        simpleConnect(iffGem.getOutputPart(), fac.getCollectingPart());
       
        // Update fac arguments.
        fac.addArgument(nCollector.getCollectingPart());
        fac.updateReflectedInputs();

        // Prelude.subtract - fac - multiply(1)
        ReflectorGem facReflector = new ReflectorGem(fac);
        simpleConnect(subtractGem.getOutputPart(), facReflector.getInputPart(0));
        simpleConnect(facReflector.getOutputPart(), multiplyGem.getInputPart(1));
 
//        ReflectorGem anotherFacReflector = new ReflectorGem(fac);
//        TestGemEntityGem idGem2 = new TestGemEntityGem(CAL_Prelude.Functions.id.getQualifiedName(), 1);
//        simpleConnect(idGem2.getOutputPart(), anotherFacReflector.getInputPart(0));
       
//        return anotherFacReflector;

        return fac;
    }

    /**
     * public foo y =
     *   let
     *     bar x =
     *       let
     *         baz = isEmpty x;
     *       in
     *         (baz, True);
     *     cuz = fst (bar y);
     *   in
     *     cuz;
     *
     * This tests having collectors both within a collector, and at the same scope as the collector.
     *
     * @return Gem
     */
    private static CollectorGem test12() {

        // Bar Collector:
        //
        // 1)   :x: - isEmpty - (baz(bar))
        //
        // 2)   (baz) - Tuple2 - (bar(foo):x)
        //       True /
        //
        //
       
        // Outer scope:
        //
        // 1)   ((bar(foo):x))
        //
        // 2)   :y: - (bar) - fst - (cuz(foo))
        //
        // 3)   (cuz) - (foo():y)
        //

        CollectorGem fooCollector = new CollectorGem(null);
        fooCollector.setName("foo");
       
        //
        // bar collector
        //
        CollectorGem barCollector = new CollectorGem(fooCollector);
        barCollector.setName("bar");
       

        // 1)
        CollectorGem bazCollector = new CollectorGem(barCollector);
        bazCollector.setName("baz");
        TestGemEntityGem isEmptyGem = new TestGemEntityGem(CAL_Prelude.Functions.isEmpty.getQualifiedName(), 1);
        simpleConnect(isEmptyGem.getOutputPart(), bazCollector.getCollectingPart());
       
        // 2)
        TestGemEntityGem pairGem = new TestGemEntityGem(CAL_Prelude.Functions.pair.getQualifiedName(), 2);
        ReflectorGem bazEmitter = new ReflectorGem(bazCollector);
        TestValueGem trueGem = new TestValueGem(CAL_Prelude.DataConstructors.True.getQualifiedName());
        simpleConnect(bazEmitter.getOutputPart(), pairGem.getInputPart(0));
        simpleConnect(trueGem.getOutputPart(), pairGem.getInputPart(1));
        simpleConnect(pairGem.getOutputPart(), barCollector.getCollectingPart());
       
        // Update bar arguments.
        barCollector.addArgument(isEmptyGem.getInputPart(0));
        barCollector.updateReflectedInputs();

        //
        // Outer scope
        //

        // 1)
       
        // 2)
        ReflectorGem barEmitter = new ReflectorGem(barCollector);
        TestGemEntityGem fstGem = new TestGemEntityGem(CAL_Prelude.Functions.fst.getQualifiedName(), 1);
        CollectorGem cuzCollector = new CollectorGem(fooCollector);
        cuzCollector.setName("cuz");
        simpleConnect(barEmitter.getOutputPart(), fstGem.getInputPart(0));
        simpleConnect(fstGem.getOutputPart(), cuzCollector.getCollectingPart());
       
        // 3)
        ReflectorGem cuzEmitter = new ReflectorGem(cuzCollector);
        simpleConnect(cuzEmitter.getOutputPart(), fooCollector.getCollectingPart());

        // Update foo arguments.
        fooCollector.addArgument(barEmitter.getInputPart(0));
        fooCollector.updateReflectedInputs();

        return fooCollector;
    }
   
    /**
     * public foo x =
     *   let
     *     bar y =
     *       let
     *         baz = isEmpty y;
     *         coo = 2.0;
     *       in
     *         (baz, coo, True);
     *     cuz = fst (bar x);
     *   in
     *     cuz;
     *
     * This tests the proper handling of collectors defined according to the scope of an collector in which it is used.
     *
     * @param liftCoo if true, coo is defined at the same scope as bar and cuz
     * @return Gem
     */
    private static CollectorGem test13(boolean liftCoo) {

        // Bar Collector:
        //
        // 1)   :y: - isEmpty - (baz(bar))
        //
        // 2)   2.0 - (coo(bar or foo))             - if liftCoo is true, target is foo, else bar.
        //
        // 3)   (baz) \
        //      (coo) - triple - (bar(foo):y)
        //       True /
        //
       
        // Outer scope:
        //
        // 1)   ((bar:y))
        //
        // 2)   :x: - (bar) - fst - (cuz(foo))
        //
        // 3)   (cuz) - (foo():x)
        //

        CollectorGem fooCollector = new CollectorGem(null);
        fooCollector.setName("foo");
        //
        // bar collector
        //
        CollectorGem barCollector = new CollectorGem(fooCollector);
        barCollector.setName("bar");
       
        // 1)
        CollectorGem bazCollector = new CollectorGem(barCollector);
        bazCollector.setName("baz");
        TestGemEntityGem isEmptyGem = new TestGemEntityGem(CAL_Prelude.Functions.isEmpty.getQualifiedName(), new String[]{"y"});
        simpleConnect(isEmptyGem.getOutputPart(), bazCollector.getCollectingPart());
       
        // 2)
        CollectorGem cooCollector = new CollectorGem((liftCoo ? null : barCollector));
        cooCollector.setName("coo");
        TestValueGem doubleGem = new TestValueGem("2.0");
        simpleConnect(doubleGem.getOutputPart(), cooCollector.getCollectingPart());
       
        // 3)
        TestGemEntityGem tripleGem = new TestGemEntityGem("Prelude.Tuple3", 3);
        ReflectorGem bazEmitter = new ReflectorGem(bazCollector);
        ReflectorGem cooEmitter = new ReflectorGem(cooCollector);
        TestValueGem trueGem = new TestValueGem(CAL_Prelude.DataConstructors.True.getQualifiedName());
        simpleConnect(bazEmitter.getOutputPart(), tripleGem.getInputPart(0));
        simpleConnect(cooEmitter.getOutputPart(), tripleGem.getInputPart(1));
        simpleConnect(trueGem.getOutputPart(), tripleGem.getInputPart(2));
        simpleConnect(tripleGem.getOutputPart(), barCollector.getCollectingPart());
       
        // Update bar arguments.
        barCollector.addArgument(isEmptyGem.getInputPart(0));
        barCollector.updateReflectedInputs();

       
        //
        // Outer scope
        //

        // 1)
       
        // 2)
        ReflectorGem barEmitter = new ReflectorGem(barCollector);
        TestGemEntityGem fstGem = new TestGemEntityGem(CAL_Prelude.Functions.fst.getQualifiedName(), 1);
        CollectorGem cuzCollector = new CollectorGem(fooCollector);
        cuzCollector.setName("cuz");
        simpleConnect(barEmitter.getOutputPart(), fstGem.getInputPart(0));
        simpleConnect(fstGem.getOutputPart(), cuzCollector.getCollectingPart());
       
        // 3)
        ReflectorGem cuzEmitter = new ReflectorGem(cuzCollector);
        simpleConnect(cuzEmitter.getOutputPart(), fooCollector.getCollectingPart());

        // Update foo arguments.
        fooCollector.addArgument(barEmitter.getInputPart(0));
        fooCollector.updateReflectedInputs();

        return fooCollector;
    }
   
    /**
     * public result =
     *   let
     *     c1 = [[1.1, 2.2], [3.3, 4.4]]
     *     child1 x =
     *       let
     *         child2 y = makeDoubleContainer (y + sum x);
     *       in
     *         vbox (map child2 x);
     *   in
     *     vbox (map child1 c1);
     *
     * @return Gem
     */
    private static CollectorGem test14() {
       
        // child1 collector:
        //
        // 1)  :x: - (x(child1))
        //
        // 2)        :y: \
        //                add - makeDoubleContainer - (child2(child1):y)
        //     (x) - sum /
        //
        // 3)  :y(burnt): - (child2) \
        //                            map - vbox - (child1(result):x)
        //                       (x) /
       
        // Outer scope:
        //
        // 1)  Value - (c1(result))
        //
        // 2)  ((child1(result):x))
        //
        // 3)  :x(burnt): - (child1) \
        //                            map - vbox - (result())
        //                      (c1) /
       
        CollectorGem resultCollector = new CollectorGem(null);
        resultCollector.setName("result");
        //
        // child1 collector
        //
        CollectorGem child1Collector = new CollectorGem(resultCollector);
        child1Collector.setName("child1");
       
        // 1)
        CollectorGem xCollector = new CollectorGem(child1Collector);
        xCollector.setName("x");
       
        // 2)
        ReflectorGem xEmitter1 = new ReflectorGem(xCollector);
        TestGemEntityGem sumGem = new TestGemEntityGem(CAL_List.Functions.sum.getQualifiedName(), 1);
        simpleConnect(xEmitter1.getOutputPart(), sumGem.getInputPart(0));
       
        TestGemEntityGem addGem = new TestGemEntityGem(CAL_Prelude.Functions.add.getQualifiedName(), new String[]{"y", "z"});
        simpleConnect(sumGem.getOutputPart(), addGem.getInputPart(1));
       
        TestGemEntityGem makeDGem = new TestGemEntityGem("Layout.makeDoubleContainer", 1);
        simpleConnect(addGem.getOutputPart(), makeDGem.getInputPart(0));
       
        CollectorGem child2Collector = new CollectorGem(child1Collector);
        child2Collector.setName("child2");
        simpleConnect(makeDGem.getOutputPart(), child2Collector.getCollectingPart());

        // Update child2 arguments.
        child2Collector.addArgument(addGem.getInputPart(0));
        child2Collector.updateReflectedInputs();

        // 3)
        ReflectorGem child2Reflector = new ReflectorGem(child2Collector);
        child2Reflector.getInputPart(0).setBurnt(true);

        TestGemEntityGem mapGem1 = new TestGemEntityGem(CAL_List.Functions.map.getQualifiedName(), 2);
        simpleConnect(child2Reflector.getOutputPart(), mapGem1.getInputPart(0));
       
        ReflectorGem xEmitter2 = new ReflectorGem(xCollector);
        simpleConnect(xEmitter2.getOutputPart(), mapGem1.getInputPart(1));
       
        TestGemEntityGem vboxGem1 = new TestGemEntityGem("Layout.vbox", 1);
        simpleConnect(mapGem1.getOutputPart(), vboxGem1.getInputPart(0));
       
        simpleConnect(vboxGem1.getOutputPart(), child1Collector.getCollectingPart());
       
        //
        // Outer scope
        //
       
        // 1)
        TestValueGem testValue = new TestValueGem("[[1.1, 2.2], [3.3, 4.4]]");
        CollectorGem c1Collector = new CollectorGem(resultCollector);
        c1Collector.setName("c1");
        simpleConnect(testValue.getOutputPart(), c1Collector.getCollectingPart());
       
        // 2)
        // Update child1 arguments.
        child1Collector.addArgument(xCollector.getCollectingPart());
        child1Collector.updateReflectedInputs();


        // 3)
        ReflectorGem child1Reflector = new ReflectorGem(child1Collector);
        child1Reflector.getInputPart(0).setBurnt(true);

        TestGemEntityGem mapGem2 = new TestGemEntityGem(CAL_List.Functions.map.getQualifiedName(), 2);
        simpleConnect(child1Reflector.getOutputPart(), mapGem2.getInputPart(0));
       
        ReflectorGem c1Emitter = new ReflectorGem(c1Collector);
        simpleConnect(c1Emitter.getOutputPart(), mapGem2.getInputPart(1));
       
        TestGemEntityGem vboxGem2 = new TestGemEntityGem("Layout.vbox", 1);
        simpleConnect(mapGem2.getOutputPart(), vboxGem2.getInputPart(0));
       
        simpleConnect(vboxGem2.getOutputPart(), resultCollector.getCollectingPart());
       
        return resultCollector;
    }

    /**
     * public result x =
     *   let
     *     foo y =
     *       let
     *         foo = isEmpty y;
     *         coo = 2.0;
     *       in
     *         (foo, coo, True);
     *     cuz = fst (foo x);
     *   in
     *     cuz;
     *
     * This tests the ability to handle collectors with the same name but different scopes
     *
     * @return Gem
     */
    private static CollectorGem test16() {

        // outer foo collector:
        //
        // 1)   :y: - isEmpty - (foo(outer foo))
        //
        // 2)   2.0 - (coo(outer foo or result))             - if liftCoo is true, targeted at result, else outer foo.
        //
        // 3)   (foo) \
        //      (coo) - Tuple3 - (foo(outer foo):y)
        //       True /
        //
       
        // Outer scope:
        //
        // 1)   ((foo(outer foo):y))
        //
        // 2)   :x: - (foo) - fst - (cuz(result))
        //
        // 3)   (cuz) - (result():x)
        //

        CollectorGem resultCollector = new CollectorGem(null);
        resultCollector.setName("result");
        //
        // outer foo collector
        //
        CollectorGem outerFooCollector = new CollectorGem(resultCollector);
        outerFooCollector.setName("foo");
       
        // 1)
        CollectorGem foo1Collector = new CollectorGem(outerFooCollector);
        foo1Collector.setName("foo");
        TestGemEntityGem isEmptyGem = new TestGemEntityGem(CAL_Prelude.Functions.isEmpty.getQualifiedName(), new String[]{"x"});
        simpleConnect(isEmptyGem.getOutputPart(), foo1Collector.getCollectingPart());
       
        // 2)
        CollectorGem cooCollector = new CollectorGem(outerFooCollector);
        cooCollector.setName("coo");
        TestValueGem doubleGem = new TestValueGem("2.0");
        simpleConnect(doubleGem.getOutputPart(), cooCollector.getCollectingPart());
       
        // 3)
        TestGemEntityGem tripleGem = new TestGemEntityGem("Prelude.Tuple3", 3);
        ReflectorGem foo1Emitter = new ReflectorGem(foo1Collector);
        ReflectorGem cooEmitter = new ReflectorGem(cooCollector);
        TestValueGem trueGem = new TestValueGem(CAL_Prelude.DataConstructors.True.getQualifiedName());
        simpleConnect(foo1Emitter.getOutputPart(), tripleGem.getInputPart(0));
        simpleConnect(cooEmitter.getOutputPart(), tripleGem.getInputPart(1));
        simpleConnect(trueGem.getOutputPart(), tripleGem.getInputPart(2));
        simpleConnect(tripleGem.getOutputPart(), outerFooCollector.getCollectingPart());
       
        //
        // Outer scope
        //

        // 1)
        // Update outer foo arguments.
        outerFooCollector.addArgument(isEmptyGem.getInputPart(0));
        outerFooCollector.updateReflectedInputs();
       
        // 2)
        ReflectorGem foo2Emitter = new ReflectorGem(outerFooCollector);
        TestGemEntityGem fstGem = new TestGemEntityGem(CAL_Prelude.Functions.fst.getQualifiedName(), 1);
        CollectorGem cuzCollector = new CollectorGem(resultCollector);
        cuzCollector.setName("cuz");
        simpleConnect(foo2Emitter.getOutputPart(), fstGem.getInputPart(0));
        simpleConnect(fstGem.getOutputPart(), cuzCollector.getCollectingPart());
       
        // 3)
        ReflectorGem cuzEmitter = new ReflectorGem(cuzCollector);
        simpleConnect(cuzEmitter.getOutputPart(), resultCollector.getCollectingPart());
       
        // Update result arguments.
        resultCollector.addArgument(foo2Emitter.getInputPart(0));
        resultCollector.updateReflectedInputs();
       
        return resultCollector;
    }
   
    /**
     * public bar = let
     *   foo :: Double;
     *   foo = 2;
     * in
     *   foo;
     *
     * Test local type declarations.
     * This gave us headaches for a long time in code gems.
     * @param services
     *
     * @return Gem
     */
    private static CollectorGem test18(BasicCALServices services) {

        //
        // 1)   2.0 - (foo(bar))
        //
        // 2)   (foo) - (bar)
        //

        CollectorGem barCollector = new CollectorGem(null);
        barCollector.setName("bar");

        // 1)
        TestValueGem testValueGem = new TestValueGem("2");
        CollectorGem fooCollector = new CollectorGem(barCollector);
        fooCollector.setName("foo");
        simpleConnect(testValueGem.getOutputPart(), fooCollector.getCollectingPart());
        fooCollector.setDeclaredType(services.getPreludeTypeConstants().getDoubleType());
       
        ReflectorGem fooEmitter = new ReflectorGem(fooCollector);
        simpleConnect(fooEmitter.getOutputPart(), barCollector.getCollectingPart());
       
        return barCollector;
    }

    /**
     * public foo x =
     *   let
     *     bar y =
     *       let
     *         baz :: Boolean;
     *         baz = isEmpty y;
     *       in
     *         (baz, True);
     *     cuz :: Boolean;
     *     cuz = fst (bar x);
     *   in
     *     cuz;
     *
     * This tests local type declarations with nesting.
     * The same as test 12, but with local type declarations on emitters.
     *
     * @return Gem
     */
    private static CollectorGem test19(BasicCALServices services) {

        // bar collector:
        //
        // 1)   :y: - isEmpty - (baz(bar))
        //
        // 2)   (baz) - Tuple2 - (bar(foo):y)
        //       True /
        //
       
        // Outer scope:
        //
        // 1)   ((bar(foo):y))
        //
        // 2)   :x: - (bar) - fst - (cuz(foo))
        //
        // 3)   (cuz) - (foo():x)
        //

        CollectorGem fooCollector = new CollectorGem(null);
        fooCollector.setName("foo");

        //
        // bar collector
        //
        CollectorGem barCollector = new CollectorGem(fooCollector);
        barCollector.setName("bar");
       
        // 1)
        CollectorGem bazCollector = new CollectorGem(barCollector);
        bazCollector.setName("baz");
        TestGemEntityGem isEmptyGem = new TestGemEntityGem(CAL_Prelude.Functions.isEmpty.getQualifiedName(), 1);
        simpleConnect(isEmptyGem.getOutputPart(), bazCollector.getCollectingPart());
        bazCollector.setDeclaredType(services.getPreludeTypeConstants().getBooleanType());
       
        // 2)
        TestGemEntityGem pairGem = new TestGemEntityGem("Prelude.Tuple2", 2);
        ReflectorGem bazEmitter = new ReflectorGem(bazCollector);
        TestValueGem trueGem = new TestValueGem(CAL_Prelude.DataConstructors.True.getQualifiedName());
        simpleConnect(bazEmitter.getOutputPart(), pairGem.getInputPart(0));
        simpleConnect(trueGem.getOutputPart(), pairGem.getInputPart(1));
        simpleConnect(pairGem.getOutputPart(), barCollector.getCollectingPart());
       
        //
        // Outer scope
        //

        // 1)
        // Update foo arguments.
        barCollector.addArgument(isEmptyGem.getInputPart(0));
        barCollector.updateReflectedInputs();

       
        // 2)
        ReflectorGem barEmitter = new ReflectorGem(barCollector);
        TestGemEntityGem fstGem = new TestGemEntityGem(CAL_Prelude.Functions.fst.getQualifiedName(), 1);
        CollectorGem cuzCollector = new CollectorGem(fooCollector);
        cuzCollector.setName("cuz");
        simpleConnect(barEmitter.getOutputPart(), fstGem.getInputPart(0));
        simpleConnect(fstGem.getOutputPart(), cuzCollector.getCollectingPart());
        cuzCollector.setDeclaredType(services.getPreludeTypeConstants().getBooleanType());
       
        // 3)
        ReflectorGem cuzEmitter = new ReflectorGem(cuzCollector);
        simpleConnect(cuzEmitter.getOutputPart(), fooCollector.getCollectingPart());

        // Update foo arguments.
        fooCollector.addArgument(barEmitter.getInputPart(0));
        fooCollector.updateReflectedInputs();
       
        return fooCollector;
    }

    /**
     * public foo x2 =
     *   let
     *     f x =
     *       let
     *         g y = x + y;
     *       in
     *         g x;
     *   in
     *     f x2;
     * ;
     *
     * This tests the source code generated during the type checking of collectors which use variables from outer scopes.
     *
     * @return Gem
     */
    private static CollectorGem test25() {
       
        // f collector:
        //
        // 1) :x: - (x(f))
        //
        // 2) (x) \
        //         add - (g(f):y)
        //    :y: /
        //
        // 3) (x) - g - (f(foo):x)
        //
        //
        // Outer scope:
        //
        // 1) ((f(foo):x))
        //
        // 2) :x2: - f - (foo():x2)
        //
       
        CollectorGem fooCollector = new CollectorGem(null);
        fooCollector.setName("foo");
        //
        // f collector
        //
        CollectorGem fCollector = new CollectorGem(fooCollector);
        fCollector.setName("f");
       
        // 1)
        CollectorGem xCollector = new CollectorGem(fCollector);
        xCollector.setName("x");
       
        // 2)
        ReflectorGem xEmitter1 = new ReflectorGem(xCollector);
       
        TestGemEntityGem addGem = new TestGemEntityGem(CAL_Prelude.Functions.add.getQualifiedName(), new String[]{"x", "y"});
        simpleConnect(xEmitter1.getOutputPart(), addGem.getInputPart(0));
       
        CollectorGem gCollector = new CollectorGem(fCollector);
        gCollector.setName("g");
        simpleConnect(addGem.getOutputPart(), gCollector.getCollectingPart());
       
        // Update g arguments.
        gCollector.addArgument(addGem.getInputPart(1));
        gCollector.updateReflectedInputs();
       
        // 3)
        ReflectorGem xEmitter2 = new ReflectorGem(xCollector);
       
        ReflectorGem gReflector = new ReflectorGem(gCollector);
        simpleConnect(xEmitter2.getOutputPart(), gReflector.getInputPart(0));
       
        simpleConnect(gReflector.getOutputPart(), fCollector.getCollectingPart());
       
       
        //
        // Outer scope
        //
       
        // 1)
       
        // 2)
        // Update f arguments.
        fCollector.addArgument(xCollector.getCollectingPart());
        fCollector.updateReflectedInputs();
       
        ReflectorGem fReflector = new ReflectorGem(fCollector);
        simpleConnect(fReflector.getOutputPart(), fooCollector.getCollectingPart());
       
        // 3)
        // (defined above in f collector/1)
       
        // Update foo arguments.
        fooCollector.addArgument(fReflector.getInputPart(0));
        fooCollector.updateReflectedInputs();
       
       
        System.out.println(CALSourceGenerator.getDebugCheckGraphSource(new HashSet<Gem>(Arrays.asList(new Gem[]{gCollector, fCollector, fCollector, fooCollector, xCollector}))));
       
        return fooCollector;
    }
   
    /**
     * public h a b =
     *   let
     *     g xs =
     *       let
     *         f x = head (x : xs);
     *       in
     *         (f a, xs);
     *   in
     *     g b;
     * ;
     *
     * Another test for the source code generated during the type checking of collectors which use variables from outer scopes.
     *
     * @return Gem
     */
    private static CollectorGem test26() {
       
        // g collector:
        //
        // 1) :xs: - (xs(g))
        //
        // 2)  :x: \
        //          Cons - head - (f(g):x)
        //    (xs) /
        //
        // 3) (a) - f \
        //             pair - (g(h):xs)
        //       (xs) /
        //
        //
        // Outer scope:
        //
        // 1) :a: - (a(h))
        //
        // 2) :b: - (b(h))
        //
        // 3) ((g(h):xs))
        //
        // 4) (b) - g - (h():a:b)
        //
       
        CollectorGem hCollector = new CollectorGem(null);
        hCollector.setName("h");
       
        //
        // (g collector)
        //
        CollectorGem gCollector = new CollectorGem(hCollector);
        gCollector.setName("g");
       
        CollectorGem aCollector = new CollectorGem(hCollector);          // outer scope
        aCollector.setName("a");
       
       
        // 1)
        CollectorGem xsCollector = new CollectorGem(gCollector);
        xsCollector.setName("xs");
       
        // 2)
        CollectorGem fCollector = new CollectorGem(gCollector);
        fCollector.setName("f");
       
        TestGemEntityGem headGem = new TestGemEntityGem(CAL_List.Functions.head.getQualifiedName(), 1);
        simpleConnect(headGem.getOutputPart(), fCollector.getCollectingPart());
       
        TestGemEntityGem consGem = new TestGemEntityGem(CAL_Prelude.DataConstructors.Cons.getQualifiedName(), new String[]{"x", "y"});
        simpleConnect(consGem.getOutputPart(), headGem.getInputPart(0));
       
        ReflectorGem xsEmitter = new ReflectorGem(xsCollector);
        simpleConnect(xsEmitter.getOutputPart(), consGem.getInputPart(1));
       
        // 3)
        TestGemEntityGem pairGem = new TestGemEntityGem("Prelude.Tuple2", 2);
        simpleConnect(pairGem.getOutputPart(), gCollector.getCollectingPart());
       
        // Update f arguments.
        fCollector.addArgument(consGem.getInputPart(0));
        fCollector.updateReflectedInputs();
       
        ReflectorGem fReflector = new ReflectorGem(fCollector);
        simpleConnect(fReflector.getOutputPart(), pairGem.getInputPart(0));
       
        ReflectorGem aEmitter = new ReflectorGem(aCollector);
        simpleConnect(aEmitter.getOutputPart(), fReflector.getInputPart(0));
       
        ReflectorGem xsEmitter2 = new ReflectorGem(xsCollector);
        simpleConnect(xsEmitter2.getOutputPart(), pairGem.getInputPart(1));
       
        //
        // Outer scope
        //
       
        // 1)
        // defined above
       
        // 2)
        CollectorGem bCollector = new CollectorGem(hCollector);
        bCollector.setName("b");
       
        // 3)
        // Update f arguments.
        gCollector.addArgument(xsCollector.getCollectingPart());
        gCollector.updateReflectedInputs();
       
        // 4)
        ReflectorGem gReflector = new ReflectorGem(gCollector);
        simpleConnect(gReflector.getOutputPart(), hCollector.getCollectingPart());

        ReflectorGem bEmitter = new ReflectorGem(bCollector);
        simpleConnect(bEmitter.getOutputPart(), gReflector.getInputPart(0));
       
        // Update h arguments.
        hCollector.addArguments(Arrays.asList(new Gem.PartInput[]{aCollector.getCollectingPart(), bCollector.getCollectingPart()}));
        hCollector.updateReflectedInputs();
       
        // Vars:    h, xs, a, b, f arg, g, Prelude.pair (f a) xs.
        // Types: ((a, [a]), [a], a, [a], a, (a, [a]), (a, [a]))
        System.out.println(CALSourceGenerator.getDebugCheckGraphSource(new HashSet<Gem>(Arrays.asList(
                new Gem[]{xsCollector, fCollector, gCollector, aCollector, bCollector, gCollector, hCollector}))));
       
        return hCollector;
    }

}
TOP

Related Classes of org.openquark.gems.client.TestSourceGeneration$TestGemEntityGem

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.