SAPL infrastructure consists of a few main parts built around the SAPL Language.
Source filters convert the source language to the SAPL language. Currently we have source filters for Clean and Haskell/GHC. For Clean, the filter is integrated into the compiler. As for Haskell/GHC, a separate compiler is provided based on the original one. Detailed instructions for their usages can be found at SAPL/Clean and SAPL/GHC, respectively.
SAPL has hierarchical module support based on directory layout. Prior to the target compilation a linking step is required to collect and combine, based on arbitrary root expressions, the necessary functions recursively from the separate modules into one SAPL file which will be the input of the target compilers.
A flavour is a kind of configuration file used by the target compilers. It provides information about how to compile the built-in functions of a given source language to a given target language. It must be in sync with source compiler and source language dependent part of the run-time system. Flavours are provided for all the combinations of source and target languages.
Run-time functions are necessary to execute the target code. Some of these are independent of the source language and cope with e.g. lazy evaluation, while some are dependent of the source language and must be in sync with the source filter and the supporting flavour. Some language features must be supported by the run-time system, for the current state of/features supported by the run-times please consult with the appropriate page:
As for GHC a carefully adjusted environment must be used for the SAPL compilation (e.g. 32bit compiler must be used, for more explanation please consult to Sapl/GHC). We use [www.vagrantup.com Vagrant] to provide this environment by virtualisation. However, you don't need any knowledge on Vagrant, all you have to do is to install Vagrant in one easy step, check out the following SVN URL
and in directory where you checked out type
$ vagrant up
$ vagrant ssh
and you find yourself using a shell where all the SAPL components are available precompiled. The current directory outside the virtual machine can be accessed at the directory /vagrant. Now, create a hello.hs with the well knows "Hello, World!" example:
$ mkdir hello $ cd hello $ cat > hello.hs $ main = putStrLn "Hello, World!"^D
First step, compile it to SAPL:
$ ghcsapl hello.hs
It creates a Main.sapl, as SAPL file names are the names of the modules rather than the original file names.
If you are brave enough, have a look at the generated SAPL source code. It consists of three simple lines only, with references to functions located in other modules, e.g. System.IO. For proper compilation you need to collect the necessary functions from these modules. Precompiled SAPL files can be found in ~/sapl/packages, the base system modules are in core/base and core/ghc-prim within that. Use the sl command for linking:
$ sl -I ~/sapl/packages/core/base -I ~/sapl/packages/core/ghc-prim -i Main.sapl -e Main.main hello.sapl
This command produces a hello.sapl file which is already self-contained. Finally the
$ sapl2js -f ghc hello.sapl
$ java -jar ~/sapl/tools/closure-compiler.jar --js_output_file hello_opt.js hello.js
For the execution check out the necessary run-time from the following URLs:
It contains a template HTML file named client.html for the execution of a function placed in a file main.js. So all you need is to copy all the files of the run-time and either hello.js or hello_opt.js (renamed to main.js) into one common directory.
For more elaborated projects I also recommend to create a Makefile. For this simplistic case it could be like this:
SL=sl --include-dir=~/sapl/packages/core/base \ --include-dir=~/sapl/packages/core/ghc-prim S2JS=sapl2js -f ghc GHCSAPL=ghcsapl -O2 CC=java -jar ~/sapl/tools/closure-compiler.jar all: create hello_opt.js hello_opt.js: $(GHCSAPL) hello.hs $(SL) -i Main.sapl -e Main.main hello.sapl $(SAPL2JS) hello.sapl $(CC) --js_output_file hello_opt.js hello.js