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