Difference between revisions of "Yhc/Javascript"

From HaskellWiki
< Yhc
Jump to navigation Jump to search
(General structure of Users Guide)
(Installation Structure)
Line 20: Line 20:
   
 
==Users Guide==
 
==Users Guide==
  +
  +
<b>Note:</b> '''ycr2js''' is currently a standalone program distributed within the Yhc source tree. The usage guidelines below are relevant only for the standalone version. If '''ycr2js''' gets integrated in Yhc tighter than now, some or all of the following statements may be no longer applicable ansd will be updated accordingly.
   
 
===Downloading===
 
===Downloading===
  +
The '''ycr2js''' program along with additional tools is distributed within the Yhc source tree. Download and install Yhc as recommended [[Yhc#Installing_Yhc|here]] and [[Yhc/Building|here]]. The <code>yhc</code> and <code>ghc</code> executables should be on the PATH.
   
 
===Building and Installation on Unix===
 
===Building and Installation on Unix===
  +
Change from the toplevel directory of the Yhc source tree to the <code>src/translator/js</code> directory. Execute commands:
   
  +
<code>
===Building on Windows===
 
  +
make all<br>
  +
make install<br>
  +
make test
  +
</code>
  +
  +
All three commands should finish without error.
  +
 
===Building and Installation on Windows===
 
<need input from someone experienced with Windows>
 
<need input from someone experienced with Windows>
   
 
===What Is Installed===
 
===What Is Installed===
  +
The <code>Makefile</code> in the '''ycr2js''' directory instructs <code>make</code> to place all necessary files relatively to the <code>yhc</code> executable location. After the installation of '''ycr2js''', the directory structure will be as follows (assuming that ''prefix'' is the base path of the Yhc installation):
  +
  +
{|
  +
|-
  +
|''prefix''/bin
  +
|- valign="top"
  +
|&nbsp;||ycr2js||&nbsp;||Core to Javascript Converter
  +
|- valign="top"
  +
|&nbsp;||pgbuild||&nbsp;||XHTML Page Building Utility
  +
|- valign="top"
  +
|''prefix''/lib
  +
|- valign="top"
  +
|&nbsp;||haskell
  +
|- valign="top"
  +
|&nbsp;||&nbsp;||StdOverlay.hs||Standard Javascript Core Overlay
  +
|- valign="top"
  +
|&nbsp;||&nbsp;||UnsafeJS.hs||Contains <code>unsafeJS</code>, a pseudo-function to inline Javascript code in Haskell functions
  +
|- valign="top"
  +
|&nbsp;|javascript
  +
|- valign="top"
  +
|&nbsp;||&nbsp;||Runtime.js||Runtime Support Javascript Library, needs to be included with every XHTML page generated
  +
|- valign="top"
  +
|&nbsp;|xhtml
  +
|- valign="top"
  +
|&nbsp;||&nbsp;||emptyx.html||An Empty XHTML Page template
  +
|}
  +
  +
The structure shown above represents a "bare" installation essential for '''ycr2js''' to function properly.
   
 
===Compiling Haskell into Core===
 
===Compiling Haskell into Core===

Revision as of 18:49, 7 November 2006

Brief Overview

An experimental sub-project, Yhc Core to Javascript Converter (ycr2js), is aimed to create a tool that generates Javascript out of a binary Yhc core file.

The project was started as an experimental patch to nhc98 in attempt to convert its internal PosLambda constructs into Javascript expressions. After some initial success, the project was switched to use the Yhc Core as the source for transformation. Recently, with a great amount of help from the Yhc Team, the project has been integrated into the main Yhc source tree and is moving towards closer integration with the compiler.

Ability to convert an arbitrary Haskell source into Javascript makes it possible to execute Haskell programs in a Web browser. This, in turn, allows for development of both client and server sides of an Internet application entirely in Haskell.

Server side solutions in Haskell have been around for a while, such as HAppS -- Haskell Application Server, Haskell Server Pages, and others. For the client side, HSPClientSide has been recently introduced, which is a close analog to ycr2js. HSPClientSide provides a domain-specific language to define the client side Web page structure (static HTML and Javascript). On the contrary, ycr2js helps convert any compilable Haskell source into Javascript.

Principles of Operation

The Yhc compiler generally produces a binary bytecode file (usually named with .hbc extension) for each Haskell module compiled. These bytecode files are to be interpreted by yhi, a command-line bytecode interpreter.

The compiler is also capable of producing a binary core file (usually named with .ycr extension), and also its human-readable representation for each Haskell module compiled. The internal structure of core is based on significantly simplified nhc98's PosLambda constructs (Yhc is derived from nhc98 code). Core consists of definitions for compiled Haskell functions and data objects.

The feature of core linking was added recently to Yhc. This allows for merging core files from several modules together, removing functions that are not used (similar to static linking performed by a traditional Unix or Windows executable linker). The resulting file (usually named with .yca extension) has the same format as per-module core files.

Binary core files may be read back into computer memory using the Yhc Core API functions.

The ycr2js program reads the binary core file specified (.yca or .ycr), and performs conversion of Haskell functions compiled into Core to their Javascript representation storing the generated Javascript code in a file. Resulting Javascript may be embedded on a (X)HTML page to be loaded into a Web browser.

Users Guide

Note: ycr2js is currently a standalone program distributed within the Yhc source tree. The usage guidelines below are relevant only for the standalone version. If ycr2js gets integrated in Yhc tighter than now, some or all of the following statements may be no longer applicable ansd will be updated accordingly.

Downloading

The ycr2js program along with additional tools is distributed within the Yhc source tree. Download and install Yhc as recommended here and here. The yhc and ghc executables should be on the PATH.

Building and Installation on Unix

Change from the toplevel directory of the Yhc source tree to the src/translator/js directory. Execute commands:

make all
make install
make test

All three commands should finish without error.

Building and Installation on Windows

<need input from someone experienced with Windows>

What Is Installed

The Makefile in the ycr2js directory instructs make to place all necessary files relatively to the yhc executable location. After the installation of ycr2js, the directory structure will be as follows (assuming that prefix is the base path of the Yhc installation):

prefix/bin
  ycr2js   Core to Javascript Converter
  pgbuild   XHTML Page Building Utility
prefix/lib
  haskell
    StdOverlay.hs Standard Javascript Core Overlay
    UnsafeJS.hs Contains unsafeJS, a pseudo-function to inline Javascript code in Haskell functions
javascript
    Runtime.js Runtime Support Javascript Library, needs to be included with every XHTML page generated
xhtml
    emptyx.html An Empty XHTML Page template

The structure shown above represents a "bare" installation essential for ycr2js to function properly.

Compiling Haskell into Core

Converting Core into Javascript

Building a XHTML Page

Tools Summary

Sample Makefile

Inner Workings

In this section, internal structure of Javascript objects and runtime support algorithms is reviewed.

Javascript Objects

The table below summarizes types of Javascript objects used in the ycr2jsgenerated Javascript code.

Javascript Object Types and Their Methods and Properties
Member/
Constructor
Prop
Meth
Constr
H
S
C
o
n
s
H
S
E
O
L
H
S
F
u
n
H
S
D
l
y
H
S
D
a
t
a
Description/Arguments
HSCons C *         Builds a list CONS cell head:
head element
tail:
remainder of the list
HSEOL C   *       Final element of a list or an empty list  
HSFun C     *     Creates a function thunk with no arguments applied to name:
function name to be used for debugging/exception tracing
arity:
arity of the function known by the compiler
body:
expression to apply to function's arguments and evaluate
HSDly C       *   A special object to wrap around a saturated function call thunk:
saturated function call that is a HSFun object with number of arguments applied to (_a) equal to the function arity (_x); evaluation of this thunk will be delayed until it is applied to an argument which would have oversaturated the call in the absence of HSDly
HSData C         * Builds a data object other than a CONS cell or an Empty List con:
constructor name (with non-alphanumeric characters replaced with underscored character codes)
arrs:
a Javascript Array containing contructor arguments
_r P * * * * * Boolean: true when a thunk may be evaluated.
  • true in HSFun when the call is saturated (_a.length == _x)
  • Always true in HSDly
  • Always false in HSCons, HSEOL, HSData
_c M * * * * * Evaluate a thunk. If this method is said as "has no action", this means that it just returns this and does nothing else.
  • No action in HSFun unless the call is saturated (_a.length == _x) in which case it applies the function body (_b) to the accumulated arguments array (_a) and returns whatever the body returns
  • In HSDly, evaluates the delayed function call first and then applies the oversaturating arguments to the result (_ap), and returns whatever results from this (a non-function value or unsaturated function call or saturated function call wrapped in another HSDly object)
  • No action in HSCons, HSEOL, HSData
_a P     * *   Array:
  • in HSFun, holds accumulated arguments
  • in HSDly, holds oversaturating arguments
_ap M     * *   Apply function call/delayed saturated call to argument(s)
  • In HSFun, clones the HSFun object, and concatenates its argument to the accumulated arguments array (_a) of the copy. If the copy becomes a saturated call, sets it's _r property to true and returns the copy wrapped into HSDly, otherwise just returns the copy
  • In HSDly, clones the HSDly object and concatenates its argument to the oversaturating arguments array (_a) of the copy. No evaluation is done at this time; it will be performed by the _c method
targs:
Array containing the arguments to be applied to
_b P     *     Holds the expression to apply to function's arguments and evaluate: the third argument of the HSFun constructor is copied here
_x P     *     Holds the function arity: the second argument of the HSFun constructor is copied here
_n P     *     Holds the function name: the first argument of the HSFun constructor is copied here
_d P       *   Holds the saturated function call (HSFun object with _a.length == _x: the first argument of the HSDly constructor is copied here
_t P * *     * Constructor name for a Data or a CONS/Empty list cell to be used for pattern matching
  • In HSData, contains qualified name of the constructor that created the Data object with all non-alphanumeric character replaced with underscored character codes
  • In HSCons, always contains "Prelude_46_58" (Prelude.:)
  • In HSEOL, always contains "Prelude_46_91_93" (Prelude.[])
_f P * *     * Constructor arguments (may be empty)
  • In HSData, the second argument of the HSData constructor is copied here
  • In HSCons, this is an array of two elements: copies of the first (head) and the second (tail) arguments of the HSCons constructor
  • In HSEOL, always empty
toString M *         Method of Object overridden by HSCons. Used for unmarshalling of Haskell lists (including Strings) into Javascript as Strings. The method evaluates all elements of the list (therefore it should be finite) and if the list contains characters, they are concatenated into a Javascript String, otherwise the _toArray method is called, and the toString method is called upon _toArray's result.
_toArray M *         Method used for unmarshalling of Haskell lists (including Strings) into Javascript as Arrays. The method evaluates all elements of the list (therefore it should be finite) and concatenates them into a Javascript Array. Internal representation of Haskell type Char is its numeric value, so a Haskell String will be converted into a Javascript Array of Number's.

Evaluation of Expressions

The Javascript runtime support library provides a function exprEval which is used to evaluate all expressions starting with the toplevel expression (starting point).

In essence, this function looks like this:

function exprEval (e) {

 for (var ex = e; ex != undefined && ex._r ; ex = ex._c())
   ;
 return ex;

};

This is a loop that checks whether a given expression exists (not undefined) and can be evaluated (_r == true). In this case, it calls the expression's _c method and analyzes its return. If the returned expression also may be evaluated, the function loops and evaluates it. This is repeated until an expression that no longer can be evaluated is returned (normal situation, e. g. a primitive value or a Data object), or an undefined value is returned (this is abnormal situation).

While evaluating an expression, exprEval may be recursively called to evaluate nested expressions.

Examples and Demos


--DimitryGolubovsky 19:02, 6 November 2006 (UTC)