/* * 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; } }