Package org.openquark.cal.samples

Source Code of org.openquark.cal.samples.EventLoop

/*
* 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.
*/


/*
* EventLoop.java
* Created: Jul 21, 2005
* By: Bo Ilic
*/

package org.openquark.cal.samples;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.openquark.cal.CALPlatformTestModuleNames;
import org.openquark.cal.compiler.Compiler;
import org.openquark.cal.compiler.CompilerMessageLogger;
import org.openquark.cal.compiler.MessageLogger;
import org.openquark.cal.compiler.QualifiedName;
import org.openquark.cal.compiler.SourceModel;
import org.openquark.cal.compiler.io.EntryPoint;
import org.openquark.cal.compiler.io.EntryPointSpec;
import org.openquark.cal.compiler.io.InputPolicy;
import org.openquark.cal.compiler.io.OutputPolicy;
import org.openquark.cal.machine.CALExecutor;
import org.openquark.cal.module.Cal.Core.CAL_Prelude;
import org.openquark.cal.runtime.CALExecutorException;
import org.openquark.cal.runtime.CalValue;
import org.openquark.cal.runtime.ExecutionContext;
import org.openquark.cal.services.BasicCALServices;
import org.openquark.cal.services.WorkspaceManager;


/**
* Example class showing several different mechanism for CAL and Java to interact.
* <p>
* The examples are intended to be read in a linear fashion from the beginning of the
* file to the end- they are ordered by complexity.
* <p>
* Some examples show how Java clients can call CAL functions in an "event loop" style
* i.e. different CAL functions may be called depending upon user input between calls.
* <p>
* The Java client is able to supply arguments, some of which are Java
* primitive types, and some of which are CAL values obtained from
* previous calls to CAL functions in the event loop. The CAL function would then
* return a result, part of which may be a Java value directly interpretable by the
* Java code, and part may be a CAL value for use in making further CAL calls.
* Note that the CAL values obtained as intermediate results may not be fully evaluated.
* For example, the value could be a computation producing an infinite list.
* <p>
*
* @author Bo Ilic
*/
public final class EventLoop {
   
    private final BasicCALServices calServices;
    private final ExecutionContext executionContext;
   
    private static final String WORKSPACE_FILE_NAME = "cal.platform.test.cws";  
       
    EventLoop() {
       
        calServices = BasicCALServices.make(WORKSPACE_FILE_NAME);
              
        CompilerMessageLogger messageLogger = new MessageLogger();       
        if (!calServices.compileWorkspace(null, messageLogger)) {
            System.err.println(messageLogger.toString());
        }
              
        executionContext = calServices.getWorkspaceManager().makeExecutionContextWithDefaultProperties();       
                              
    }
       
    /**
     * Turn on various test programs by editing the main method. Useful VM arguments for running this are:
     *
     * -Dorg.openquark.cal.machine.lecc.output_directory="D:\dev\EventLoop_lecc_bytecode"
     * -Xmx256m
     *
     * @param args
     */
    public static void main(String[] args) {
       
        usage();
       
        if (args.length != 1) {           
            return;
        }
       
        String command = args[0];
        System.out.println("\nDemo program: " + command + "\n");
       
        if (command.equalsIgnoreCase("getNthPrime")) {
            EventLoop eventLoop = new EventLoop();
            eventLoop.getNthPrime(5);
       
        } else if (command.equalsIgnoreCase("primesIterator")) {
            EventLoop eventLoop = new EventLoop();
            eventLoop.primesIterator();
           
        } else if (command.equalsIgnoreCase("twoListIterators")) {
            EventLoop eventLoop = new EventLoop();
            eventLoop.twoListIterators();               
           
        } else if (command.equalsIgnoreCase("clientPrimePuller")) {
            EventLoop eventLoop = new EventLoop();
            eventLoop.clientPrimePuller();
                                         
        } else if (command.equalsIgnoreCase("clientTwoListPuller")) {
            EventLoop eventLoop = new EventLoop();           
            eventLoop.clientTwoListPuller()
          
        } else if (command.equalsIgnoreCase("touchlessTwoListPuller")) {
            EventLoop eventLoop = new EventLoop();
            eventLoop.touchlessTwoListPuller();                   
                                          
        } else {
            System.out.println("invalid demo program choice");
        }
    }
   
    private static void usage() {
        System.out.println("EventLoop usage: valid command line arguments are one of");
        System.out.println();
        System.out.println("getNthPrime               --reuse of a single EntryPoint over multiple executions");
        System.out.println();
        System.out.println("primesIterator            --client side lazy evaluation of a single CAL list using a Java iterator");
        System.out.println("twoListIterators          --intertwined multiple client side CAL list lazy evaluation using two Java iterators");
        System.out.println();
        System.out.println("clientPrimePuller         --client side lazy evaluation of a single CAL list");       
        System.out.println("clientTwoListPuller       --multiple lazy lazy evaluation. Multiple EntryPoints");
        System.out.println("touchlessTwoListPuller    --use of EntryPointSpec and IO policies to avoid marshaling functions in CAL");
       
    }

    /**
     * Calls M2.getNthPrime, first with n = 5000, then 5001, etc, and then terminates.
     * This demonstrates reuse of the EntryPoint over multiple executions.
     * In particular, once the EntryPoint has been created, there is no further compilation
     * when evaluating the entry point at different arguments.
     *
     * @param nTimes number of times to call the function in a row. First with 5000, then 5001, etc  
     */   
    private void getNthPrime(int nTimes) {
       
        //sample run:
       
        //Demo program: getNthPrime
        //
        //the result of getNthPrime 5000 is 48619
        //the result of getNthPrime 5001 is 48623
        //the result of getNthPrime 5002 is 48647
        //the result of getNthPrime 5003 is 48649
        //the result of getNthPrime 5004 is 48661
              
        CompilerMessageLogger messageLogger = new MessageLogger();       
        WorkspaceManager workspaceManager = calServices.getWorkspaceManager();
        Compiler compiler = calServices.getCompiler();  
       
        EntryPoint entryPoint = compiler.getEntryPoint(
            EntryPointSpec.make(QualifiedName.make(CALPlatformTestModuleNames.M2, "getNthPrime")),
            CALPlatformTestModuleNames.M2, messageLogger);
        if (messageLogger.getNMessages() > 0) {
            System.err.println(messageLogger.toString());
        }
        CALExecutor executor = workspaceManager.makeExecutor(executionContext);
       
        try {
            for (int i = 0; i < nTimes; ++i) {
                Object result = executor.exec(entryPoint, new Object[] {new Integer(5000 + i)});
                System.out.println("the result of getNthPrime " + (5000 + i) + " is " + result);
            }
        } catch (CALExecutorException executorException) {
            System.out.println("Execution terminated with an executor exception:" + executorException);
        }                                 
    }

    /**
     * Illustrates calling a function that produces a lazy CAL list (M1.allPrimes), and then
     * having the Java client code traverse the list lazily using a java.util.Iterator.
     * <p>
     * Once the EntryPoint is created, there is no further compilation, although the CAL evaluator
     * is involved in evaluating each subsequent element of the list as the Java iterator is traversed.
     * <p>
     * Similar to clientPrimePuller, but uses the List.toJIterator function to simplify
     * client traversal of the CAL list. This approach is perhaps less general than the approach
     * in clientPrimePuller, but is simpler to use.
     */
    private void primesIterator() {   
       
        //sample run:
       
        //Demo program: primesIterator
        //
        //How many more primes would you like? (enter q to quit)
        //3
        //the next 3 primes are [2, 3, 5]
        //How many more primes would you like? (enter q to quit)
        //4
        //the next 4 primes are [7, 11, 13, 17]
        //How many more primes would you like? (enter q to quit)
        //q       

        CompilerMessageLogger messageLogger = new MessageLogger();
       
        WorkspaceManager workspaceManager = calServices.getWorkspaceManager();
        Compiler compiler = calServices.getCompiler();   
      
        CALExecutor executor = workspaceManager.makeExecutor(executionContext)
       
        //the below function represent a model of what is created when using EntryPointSpec classes i.e.
        //explicit input and output policies.
       
        //allPrimesAdjunct :: Prelude.JObject;
        //allPrimesAdjunct = (Prelude.output # List.toJIterator) M1.allPrimes;           

        EntryPointSpec allPrimesEntryPointSpec =
            EntryPointSpec.make(QualifiedName.make(CALPlatformTestModuleNames.M1, "allPrimes"), null, OutputPolicy.ITERATOR_OUTPUT_POLICY);       
       
        EntryPoint allPrimesEntryPoint =
            compiler.getEntryPoint(allPrimesEntryPointSpec, CALPlatformTestModuleNames.M1, messageLogger);
       
        if (messageLogger.getNMessages() > 0) {
            System.err.println(messageLogger.toString());
        }
 
        try {
            Iterator<?> primesIterator = (Iterator<?>)executor.exec(allPrimesEntryPoint, null);
           
            BufferedReader inBuff = new BufferedReader(new BufferedReader(new java.io.InputStreamReader(System.in)));
                              
            while (true) {
               
                System.out.println("How many more primes would you like? (enter q to quit)");
                String command = inBuff.readLine().trim();
                              
                if (command.startsWith("q")) {
                    break;
                   
                } else {
                    int nPrimesMore = 1;
                    try {
                        nPrimesMore = Integer.parseInt(command);                      
                    } catch (NumberFormatException nfe) {
                        System.out.println("I'm extremely sorry, but I did not understand you. I'll assume one more prime.");
                    }                   
                   
                    List<Object> nextNPrimes = new ArrayList<Object>(nPrimesMore);
                    for (int i = 0; i < nPrimesMore; ++i) {
                        nextNPrimes.add(primesIterator.next());
                    }
                                             
                    System.out.println("the next " + nPrimesMore + " primes are " + nextNPrimes);
                   
                    //we can reset cached CAFs here if we like. (Works without this as well. The point here is to not hold onto
                    //the allPrimes CAF).
                    workspaceManager.resetCachedResults(executionContext);                                                      
                }                                                                                              
            }
           
        } catch (IOException ioe) {
            System.out.println(ioe);
        } catch (CALExecutorException executorException) {
            System.out.println("Execution terminated with an executor exception:" + executorException);
        }
    }
   
    /**
     * Illustrates calling two different CAL functions producing lazy CAL lists, and then
     * having the Java client code traverse the lists lazily using two different java.util.Iterators.
     * The traversals are interspersed with each other.
     * <p>
     * Once the EntryPoints are created, there is no further compilation, although the CAL evaluator is involved
     * in evaluating each subsequent element of the two lists as the Java iterators are traversed.
     * <p>
     * Similar to touchlessTwoListPuller but uses the List.toJIterator function to simplify
     * client traversal of the two CAL lists. This approach is perhaps less general than the approach
     * in touchlessTwoListPuller, but is simpler to use.
     */
    private void twoListIterators() {            
       
        //sample run
           
        //  Demo program: twoListIterators
        // 
        //  How many more primes would you like? (enter q to quit)
        //  5
        //  the next 5 primes are [2, 3, 5, 7, 11]
        //  How many more names would you like? (enter q to quit)
        //  3
        //  the next 3 names are [Alexander, Andy, Anton]
        //  How many more primes would you like? (enter q to quit)
        //  3
        //  the next 3 primes are [13, 17, 19]
        //  How many more names would you like? (enter q to quit)
        //  4
        //  the next 4 names are [Frank, Fred, Helen, Linda]
        //  How many more primes would you like? (enter q to quit)
        //  q
                       
        CompilerMessageLogger messageLogger = new MessageLogger();
       
        WorkspaceManager workspaceManager = calServices.getWorkspaceManager();
        Compiler compiler = calServices.getCompiler();           
       
        CALExecutor executor = workspaceManager.makeExecutor(executionContext);               
       
        List<EntryPointSpec> entryPointSpecs = new ArrayList<EntryPointSpec>(); //list of EntryPointSpec
       
        //the below function represent a model of what is created when using EntryPointSpec classes i.e.
        //explicit input and output policies.
       
        //allPrimesAdjunct :: Prelude.JObject;
        //allPrimesAdjunct = (Prelude.output # List.toJIterator) M1.allPrimes;          
       
        EntryPointSpec allPrimesEntryPointSpec =
            EntryPointSpec.make(QualifiedName.make(CALPlatformTestModuleNames.M1, "allPrimes"), null, OutputPolicy.ITERATOR_OUTPUT_POLICY);
        EntryPointSpec stringListEntryPointSpec =
            EntryPointSpec.make(QualifiedName.make(CALPlatformTestModuleNames.M2, "stringList"), null, OutputPolicy.ITERATOR_OUTPUT_POLICY);      
                     
        entryPointSpecs.add(allPrimesEntryPointSpec);
        entryPointSpecs.add(stringListEntryPointSpec);       
        compiler.getEntryPoints(entryPointSpecs, CALPlatformTestModuleNames.M2, messageLogger);
                      
        List<EntryPoint> entryPoints =
            compiler.getEntryPoints(entryPointSpecs, CALPlatformTestModuleNames.M2, messageLogger);
        if (messageLogger.getNMessages() > 0) {
            System.err.println(messageLogger.toString());
        }       
        EntryPoint allPrimesEntryPoint = entryPoints.get(0);
        EntryPoint stringListEntryPoint = entryPoints.get(1);       
       
        try {
            Iterator<?> primesIterator = (Iterator<?>)executor.exec(allPrimesEntryPoint, null);
            Iterator<?> namesIterator = (Iterator<?>)executor.exec(stringListEntryPoint, null);    
                          
            BufferedReader inBuff = new BufferedReader(new BufferedReader(new java.io.InputStreamReader(System.in)));
                              
            while (true) {
               
                System.out.println("How many more primes would you like? (enter q to quit)");
                String command = inBuff.readLine().trim();
                              
                if (command.startsWith("q")) {
                    break;
                   
                } else {
                    int nPrimesMore = 1;
                    try {
                        nPrimesMore = Integer.parseInt(command);                      
                    } catch (NumberFormatException nfe) {
                        System.out.println("I'm extremely sorry, but I did not understand you. I'll assume one more prime.");
                    }                   
                   
                    List<Object> nextNPrimes = new ArrayList<Object>(nPrimesMore);
                    for (int i = 0; i < nPrimesMore; ++i) {
                        nextNPrimes.add(primesIterator.next());
                    }
                                             
                    System.out.println("the next " + nPrimesMore + " primes are " + nextNPrimes);
                   
                    //we can reset cached CAFs here if we like. (Works without this as well. The point here is to not hold onto
                    //the allPrimes CAF).
                    workspaceManager.resetCachedResults(executionContext);                                                      
                }
               
                System.out.println("How many more names would you like? (enter q to quit)");
                command = inBuff.readLine().trim();
                              
                if (command.startsWith("q")) {
                    break;
                   
                } else {
                    int nNamesMore = 1;
                    try {
                        nNamesMore = Integer.parseInt(command);                      
                    } catch (NumberFormatException nfe) {
                        System.out.println("I'm surpassingly sorry, but I did not understand you. I'll assume one more name.");
                    }
                                                         
                    List<Object> nextNNames = new ArrayList<Object>(nNamesMore);
                    for (int i = 0; i < nNamesMore; ++i) {
                        nextNNames.add(namesIterator.next());
                    }                  
                    System.out.println("the next " + nNamesMore + " names are " + nextNNames);
                   
                    //we can reset cached CAFs here if we like. (Works without this as well. The point here is to not hold onto
                    //the Prelude.stringList CAF).
                    workspaceManager.resetCachedResults(executionContext);                     
                }                                               
            }
           
        } catch (IOException ioe) {
            System.out.println(ioe);
        } catch (CALExecutorException executorException) {
            System.out.println("Execution terminated with an executor exception:" + executorException);
        }
    }   
   
    /**
     * Demonstrates an interactive, stateful CAL program with a Java client
     * lazily exploring the results of CAL function. Each "event loop" asks the
     * user how many more primes they want to see. The CAL function that is run
     * produces a Java list with the next number of primes the user asked for,
     * and a CAL list with the remaining primes (this is an infinite list, but
     * since CAL is lazy that is OK). This list of remaining primes is then
     * passed back in subsequent calls.
     */
    private void clientPrimePuller() { 
       
        //Demo program: clientPrimePuller
        //
        //How many more primes would you like? (enter q to quit)
        //4
        //the next 4 are [2, 3, 5, 7]
        //How many more primes would you like? (enter q to quit)
        //6
        //the next 6 are [11, 13, 17, 19, 23, 29]
        //How many more primes would you like? (enter q to quit)
        //2
        //the next 2 are [31, 37]
        //How many more primes would you like? (enter q to quit)
        //q
              
        CompilerMessageLogger messageLogger = new MessageLogger();
       
        WorkspaceManager workspaceManager = calServices.getWorkspaceManager();
        Compiler compiler = calServices.getCompiler();    
       
        CALExecutor executor = workspaceManager.makeExecutor(executionContext);
       
        EntryPoint allPrimesExternalEntryPoint =
            compiler.getEntryPoint(
                EntryPointSpec.make(QualifiedName.make(CALPlatformTestModuleNames.M2, "allPrimesExternal")),
                CALPlatformTestModuleNames.M2, messageLogger);
        if (messageLogger.getNMessages() > 0) {
            System.err.println(messageLogger.toString());
        }
             
        try {
           
            CalValue remainingPrimesCalValue = (CalValue)executor.exec(allPrimesExternalEntryPoint, null);
           
            EntryPoint nextNPrimesExternalEntryPoint =
                compiler.getEntryPoint(
                    EntryPointSpec.make(QualifiedName.make(CALPlatformTestModuleNames.M2, "nextNPrimesExternal")),
                    CALPlatformTestModuleNames.M2, messageLogger);
           
            BufferedReader inBuff = new BufferedReader(new BufferedReader(new java.io.InputStreamReader(System.in)));          

            while (true) {
               
                System.out.println("How many more primes would you like? (enter q to quit)");
                String command = inBuff.readLine().trim();
                              
                if (command.startsWith("q")) {
                    break;
                   
                } else {
                    int nPrimesMore = 1;
                    try {
                        nPrimesMore = Integer.parseInt(command);                      
                    } catch (NumberFormatException nfe) {
                        System.out.println("I'm extremely sorry, but I did not understand you. I'll assume one more prime.");
                    }
                                                            
                    //a java.util.List with 2 elements. The first is a java.util.List of nPrimesMore primes. The second is a CalValue
                    //containing the remaining primes (as a lazy internal CAL list).
                    List<?> result = (List<?>)executor.exec(nextNPrimesExternalEntryPoint, new Object[] {remainingPrimesCalValue, new Integer(nPrimesMore)});
                    List<?> nextNPrimes = (List<?>)result.get(0);
                    remainingPrimesCalValue = (CalValue)result.get(1);
                    System.out.println("the next " + nPrimesMore + " are " + nextNPrimes);
                   
                    //we can reset cached CAFs here if we like. (Works without this as well. The point here is to not hold onto
                    //the allPrimes CAF).
                    workspaceManager.resetCachedResults(executionContext);                                                           
                }               
            }
       
        } catch (IOException ioe) {
            System.out.println(ioe);
        } catch (CALExecutorException executorException) {
            System.out.println("Execution terminated with an executor exception:" + executorException);
            return;
        }                                                 
    }
      
    /**
     * Demonstrates clients pulling values out of 2 different lists:
     * a CAL list of primes
     * a CAL list of Strings
     *
     * All EntryPoints are created once and for all at the beginning.   
     */
    private void clientTwoListPuller() {
       
        //sample run:
       
        //Demo program: clientTwoListPuller
        //
        //How many more primes would you like? (enter q to quit)
        //4
        //the next 4 primes are [2, 3, 5, 7]
        //How many more names would you like? (enter q to quit)
        //3
        //the next 3 names are [Alexander, Andy, Anton]
        //How many more primes would you like? (enter q to quit)
        //6
        //the next 6 primes are [11, 13, 17, 19, 23, 29]
        //How many more names would you like? (enter q to quit)
        //2
        //the next 2 names are [Frank, Fred]
        //How many more primes would you like? (enter q to quit)
        //q      
       
        CompilerMessageLogger messageLogger = new MessageLogger();
       
        WorkspaceManager workspaceManager = calServices.getWorkspaceManager();
        Compiler compiler = calServices.getCompiler();    
       
        CALExecutor executor = workspaceManager.makeExecutor(executionContext);               
       
        List<QualifiedName> entryPointNames = new ArrayList<QualifiedName>(); //list of QualifiedName
        entryPointNames.add(QualifiedName.make(CALPlatformTestModuleNames.M2, "allPrimesExternal"));
        entryPointNames.add(QualifiedName.make(CALPlatformTestModuleNames.M2, "stringListExternal"));
        entryPointNames.add(QualifiedName.make(CALPlatformTestModuleNames.M2, "takeNExternal_ListOfInt"));
        entryPointNames.add(QualifiedName.make(CALPlatformTestModuleNames.M2, "takeNExternal_ListOfString"));                      
       
        List<EntryPoint> entryPoints =
            compiler.getEntryPoints(
                EntryPointSpec.buildListFromQualifiedNames(entryPointNames),
                CALPlatformTestModuleNames.M2,
                messageLogger);
       
        if (messageLogger.getNMessages() > 0) {
            System.err.println(messageLogger.toString());
        }
        EntryPoint allPrimesExternal = entryPoints.get(0);
        EntryPoint stringListExternal = entryPoints.get(1);
        EntryPoint takeNExternal_ListOfInt = entryPoints.get(2);
        EntryPoint takeNExternal_ListOfString = entryPoints.get(3);
       
        try {
            CalValue remainingPrimesCalValue = (CalValue)executor.exec(allPrimesExternal, null);
            CalValue remainingNamesCalValue = (CalValue)executor.exec(stringListExternal, null);    
                          
            BufferedReader inBuff = new BufferedReader(new BufferedReader(new java.io.InputStreamReader(System.in)));
                              
            while (true) {
               
                System.out.println("How many more primes would you like? (enter q to quit)");
                String command = inBuff.readLine().trim();
                              
                if (command.startsWith("q")) {
                    break;
                   
                } else {
                    int nPrimesMore = 1;
                    try {
                        nPrimesMore = Integer.parseInt(command);                      
                    } catch (NumberFormatException nfe) {
                        System.out.println("I'm extremely sorry, but I did not understand you. I'll assume one more prime.");
                    }                   
                    
                    List<?> result = (List<?>)executor.exec(takeNExternal_ListOfInt,
                            new Object[] {remainingPrimesCalValue, new Integer(nPrimesMore)});
                  
                    //a java.util.List with 2 elements. The first is a java.util.List of nPrimesMore primes. The second is a CalValue
                    //containing the remaining primes (as a lazy internal CAL list).                     
                    List<?> nextNPrimes = (List<?>)result.get(0);
                    remainingPrimesCalValue = (CalValue)result.get(1);                     
                    System.out.println("the next " + nPrimesMore + " primes are " + nextNPrimes);
                   
                    //we can reset cached CAFs here if we like. (Works without this as well. The point here is to not hold onto
                    //the allPrimes CAF).
                    workspaceManager.resetCachedResults(executionContext);                                                      
                }
               
                System.out.println("How many more names would you like? (enter q to quit)");
                command = inBuff.readLine().trim();
                              
                if (command.startsWith("q")) {
                    break;
                   
                } else {
                    int nNamesMore = 1;
                    try {
                        nNamesMore = Integer.parseInt(command);                      
                    } catch (NumberFormatException nfe) {
                        System.out.println("I'm surpassingly sorry, but I did not understand you. I'll assume one more name.");
                    }
                                     
                    List<?> result = (List<?>)executor.exec(takeNExternal_ListOfString,
                            new Object[] {remainingNamesCalValue, new Integer(nNamesMore)});
                  
                    //a java.util.List with 2 elements. The first is a java.util.List of nNamesMore names. The second is a CalValue
                    //containing the remaining names (as a CAL list).                     
                    List<?> nextNNames = (List<?>)result.get(0);
                    remainingNamesCalValue = (CalValue)result.get(1);                     
                    System.out.println("the next " + nNamesMore + " names are " + nextNNames);
                   
                    //we can reset cached CAFs here if we like. (Works without this as well. The point here is to not hold onto
                    //the Prelude.stringList CAF).
                    workspaceManager.resetCachedResults(executionContext);                     
                }                               
               
            }
       
        } catch (IOException ioe) {
            System.out.println(ioe);
        } catch (CALExecutorException executorException) {
            System.out.println("Execution terminated with an executor exception:" + executorException);
        }
    }
   
    /**
     * Demonstrates clients pulling values out of CAL lists with no special marshaling
     * wrappers added in a CAL module. All EntryPoints are created once and for all at the beginning.    
     */
    private void touchlessTwoListPuller() { 
       
        //sample run
           
        //  Demo program: touchlessTwoListPuller
        // 
        //  How many more primes would you like? (enter q to quit)
        //  5
        //  the next 5 primes are [2, 3, 5, 7, 11]
        //  How many more names would you like? (enter q to quit)
        //  3
        //  the next 3 names are [Alexander, Andy, Anton]
        //  How many more primes would you like? (enter q to quit)
        //  3
        //  the next 3 primes are [13, 17, 19]
        //  How many more names would you like? (enter q to quit)
        //  4
        //  the next 4 names are [Frank, Fred, Helen, Linda]
        //  How many more primes would you like? (enter q to quit)
        //  q
                       
        CompilerMessageLogger messageLogger = new MessageLogger();
       
        WorkspaceManager workspaceManager = calServices.getWorkspaceManager();
        Compiler compiler = calServices.getCompiler();          
       
        CALExecutor executor = workspaceManager.makeExecutor(executionContext);               
       
        List<EntryPointSpec> entryPointSpecs = new ArrayList<EntryPointSpec>(); //list of EntryPointSpec
       
        //the below 2 functions represent a model of what is created when using EntryPointSpec classes i.e.
        //explicit input and output policies.
       
        //allPrimesAdjunct :: Prelude.JObject;
        //allPrimesAdjunct = (\x -> Prelude.output ((Prelude.unsafeCoerce x) ::  Prelude.CalValue)) M1.allPrimes;
        //
        //takeNIntAdjunct :: Prelude.JObject -> Prelude.JObject -> Prelude.JObject;
        //takeNIntAdjunct list nToTake =
        //    (\x -> Prelude.output ((Prelude.unsafeCoerce x) :: ([Int], CalValue)))
        //        (takeN
        //            ((\x -> (Prelude.unsafeCoerce ((Prelude.input x) :: Prelude.CalValue)) :: [Prelude.Int]) list)
        //            ((Prelude.input :: Prelude.JObject -> Prelude.Int) nToTake)
        //         );
       
        EntryPointSpec allPrimesEntryPointSpec =
            EntryPointSpec.make(QualifiedName.make(CALPlatformTestModuleNames.M1, "allPrimes"), new InputPolicy[] {}, OutputPolicy.CAL_VALUE_OUTPUT_POLICY);
        EntryPointSpec stringListEntryPointSpec =
            EntryPointSpec.make(QualifiedName.make(CALPlatformTestModuleNames.M2, "stringList"), new InputPolicy[] {}, OutputPolicy.CAL_VALUE_OUTPUT_POLICY);
       
        String Prelude_Int = CAL_Prelude.TypeConstructors.Int.getQualifiedName();
        String Prelude_CalValue = CAL_Prelude.TypeConstructors.CalValue.getQualifiedName();
        String Prelude_String = CAL_Prelude.TypeConstructors.String.getQualifiedName();
        String Prelude_unsafeCoerce = CAL_Prelude.Functions.unsafeCoerce.getQualifiedName();
        String Prelude_output = CAL_Prelude.Functions.output.getQualifiedName();
       
        SourceModel.TypeExprDefn listOfIntType = SourceModel.TypeExprDefn.List.make(SourceModel.TypeExprDefn.TypeCons.make(CAL_Prelude.TypeConstructors.Int));
        EntryPointSpec takeNListOfInt =
            EntryPointSpec.make(QualifiedName.make(CALPlatformTestModuleNames.M2, "takeN"), new InputPolicy[] {
            InputPolicy.makeTypedCalValueInputPolicy(listOfIntType),
            InputPolicy.DEFAULT_INPUT_POLICY
            }, OutputPolicy.make("(\\x -> " + Prelude_output + " ((" + Prelude_unsafeCoerce + " x) :: ([" + Prelude_Int + "], " + Prelude_CalValue + ")))"));

       
        SourceModel.TypeExprDefn listOfStringType = SourceModel.TypeExprDefn.List.make(SourceModel.TypeExprDefn.TypeCons.make(CAL_Prelude.TypeConstructors.String));
        EntryPointSpec takeNListOfString =
            EntryPointSpec.make(QualifiedName.make(CALPlatformTestModuleNames.M2, "takeN"), new InputPolicy[] {
            InputPolicy.makeTypedCalValueInputPolicy(listOfStringType),
            InputPolicy.DEFAULT_INPUT_POLICY
        }, OutputPolicy.make("(\\x -> " + Prelude_output + " ((" + Prelude_unsafeCoerce + " x) :: ([" + Prelude_String + "], " + Prelude_CalValue + ")))"));       
                     
        entryPointSpecs.add(allPrimesEntryPointSpec);
        entryPointSpecs.add(stringListEntryPointSpec);
        entryPointSpecs.add(takeNListOfInt);
        entryPointSpecs.add(takeNListOfString);       
                      
        List<EntryPoint> entryPoints =
            compiler.getEntryPoints(entryPointSpecs, CALPlatformTestModuleNames.M2, messageLogger);
        if (messageLogger.getNMessages() > 0) {
            System.err.println(messageLogger.toString());
        }
        EntryPoint allPrimesEntryPoint = entryPoints.get(0);
        EntryPoint stringListEntryPoint = entryPoints.get(1);
        EntryPoint takeNListOfIntEntryPoint = entryPoints.get(2);
        EntryPoint takeNListOfStringEntryPoint = entryPoints.get(3);
       
        try {
            CalValue remainingPrimesCalValue = (CalValue)executor.exec(allPrimesEntryPoint, null);
            CalValue remainingNamesCalValue = (CalValue)executor.exec(stringListEntryPoint, null);    
                          
            BufferedReader inBuff = new BufferedReader(new BufferedReader(new java.io.InputStreamReader(System.in)));
                              
            while (true) {
               
                System.out.println("How many more primes would you like? (enter q to quit)");
                String command = inBuff.readLine().trim();
                              
                if (command.startsWith("q")) {
                    break;
                   
                } else {
                    int nPrimesMore = 1;
                    try {
                        nPrimesMore = Integer.parseInt(command);                      
                    } catch (NumberFormatException nfe) {
                        System.out.println("I'm extremely sorry, but I did not understand you. I'll assume one more prime.");
                    }                   
                    
                    List<?> result = (List<?>)executor.exec(takeNListOfIntEntryPoint,
                            new Object[] {remainingPrimesCalValue, new Integer(nPrimesMore)});
                  
                    //a java.util.List with 2 elements. The first is a java.util.List of nPrimesMore primes. The second is a CalValue
                    //containing the remaining primes (as a lazy internal CAL list).                     
                    List<?> nextNPrimes = (List<?>)result.get(0);
                    remainingPrimesCalValue = (CalValue)result.get(1);                     
                    System.out.println("the next " + nPrimesMore + " primes are " + nextNPrimes);
                   
                    //we can reset cached CAFs here if we like. (Works without this as well. The point here is to not hold onto
                    //the allPrimes CAF).
                    workspaceManager.resetCachedResults(executionContext);                                                      
                }
               
                System.out.println("How many more names would you like? (enter q to quit)");
                command = inBuff.readLine().trim();
                              
                if (command.startsWith("q")) {
                    break;
                   
                } else {
                    int nNamesMore = 1;
                    try {
                        nNamesMore = Integer.parseInt(command);                      
                    } catch (NumberFormatException nfe) {
                        System.out.println("I'm surpassingly sorry, but I did not understand you. I'll assume one more name.");
                    }
                                     
                    List<?> result = (List<?>)executor.exec(takeNListOfStringEntryPoint,
                            new Object[] {remainingNamesCalValue, new Integer(nNamesMore)});
                  
                    //a java.util.List with 2 elements. The first is a java.util.List of nNamesMore names. The second is a CalValue
                    //containing the remaining names (as a lazy internal CAL list).                     
                    List<?> nextNNames = (List<?>)result.get(0);
                    remainingNamesCalValue = (CalValue)result.get(1);                     
                    System.out.println("the next " + nNamesMore + " names are " + nextNNames);
                   
                    //we can reset cached CAFs here if we like. (Works without this as well. The point here is to not hold onto
                    //the Prelude.stringList CAF).
                    workspaceManager.resetCachedResults(executionContext);                     
                }                                               
            }
           
        } catch (IOException ioe) {
            System.out.println(ioe);
        } catch (CALExecutorException executorException) {
            System.out.println("Execution terminated with an executor exception:" + executorException);
        }
    }
               
}

TOP

Related Classes of org.openquark.cal.samples.EventLoop

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.