# XY implementation in JavaScript

## Chris Double — 2009-02-17 00:35:10

    I've been playing around with an implementation of XY in JavaScript to

    explore client side web programming in a concatenative language. XY is

    one of Stevan Apter's language experiments:

    http://nsl.com/k/xy/xy.htm

    I've got the core of the language implemented and it's fun to play

    around with and use as a simple learning tool. A simple

    read/eval/print listener is available here:

    http://www.bluishcoder.co.nz/xyjs/xylistener.html

    Click somewhere on the page and then enter an expression. For example:

    [ 1 2 3 4 ] [ 2 * ] map .

    The '.' at the end will pop the last item off the X stack and print

    it. This implementation has large integers, using a big number

    implementation in JavaScript. So this works:

    ; fac dup 1 = [] [dup 1 - fac *] if ;

    100 fac .

    Or you can use linrec:

    10 [dup 1 =] [] [dup 1 -] [*] linrec alert

    This 'alert' word displays a pop up alert box. Operations that take a

    long time can hit the browsers 'kill long running scripts' message.

    I'll do a workaround for this at some point.

    If you do a 'view source' on the page you'll see the library of XY

    functions, taken from Stevan's page. The XY code is in an HTML script

    block of type 'text/x-xy':

      <script type="text/x-xy">

    ; pop           {  a                            } ;

    ; drop          pop ;

    ; dip           swap => / <= ;

    ; dup           {  a            \a \a           } ;

    ; swap          { [a b]         \b \a           } ;

    </script>

    Not all of the included library works due to unimplemented core

    library functions. XY uses primitives based on K. I don't know what

    most of these are so I'm slowly working through them as I need to.

    There is a very simple JavaScript FFI to allow calling JavaScript

    functions. A 'js-global' word evals a given string and returns a

    JavaScript object:

    "document" js-global .

     => js([object HTMLDocument])

    A 'js-call' word calls a JavaScript function given an array of

    arguments, the 'this' object, and the function object on the stack:

     [ [ "hello" alert ] >js-function / 1000 / ] "window" js-global

    "window.setTimeout" js-global js-call

    The '>js-function' word converts an XY quotation to a JavaScript function.

    Continuations seem to work:

    [ "hello" . ] 0 call/cc "there" .

     => "hello"

           "there"

    dup /

     => "there"

    dup /

     => "there"

    In the listener Ctrl+Up and Ctrl+Down can be used to cycle through the

    history of last entered commands. There's not much error checking or

    reporting at the moment so errors tend to give obscure JavaScript

    related messages. Also I've mainly tested on Firefox so other browsers

    may or may not work. I believe Safari worked last time I tried.

    Another simple test page is:

    http://www.bluishcoder.co.nz/xyjs/xy.html

    Entering an expression and hitting 'Eval' will show each step as the

    expression is evaluated. For example, 1 2 dup + *, gives:

         1 -> 2 dup + *

         1 2 -> dup + *

         1 2 -> { a \ a \ a } + *

         1 2 { -> a \ a \ a } + *

         1 2 { a -> \ a \ a } + *

         1 2 { a \ -> a \ a } + *

         1 2 { a \ a -> \ a } + *

         1 2 { a \ a \ -> a } + *

         1 2 { a \ a \ a -> } + *

         1 -> \ 2 \ 2 + *

         1 2 -> \ 2 + *

         1 2 2 -> + *

         1 4 -> *

         4 ->

    The information on the left hand side of the '->' is the X stack, the

    right hand side is the Y queue.

    The core builtin words at the moment are listed here:

    http://www.bluishcoder.co.nz/xyjs/xy.txt

    There is a 'source' word that outputs a quotation containing the

    definition of a word:

    \ dup source .

     => [ { a \ a \ a } ]

    Any suggestions or ideas for improving/adding to this would be appreciated.

    Chris.

    --

    http://www.bluishcoder.co.nz

## Christopher Diggins — 2009-02-17 03:05:23

    Cool stuff.

    I also implemented Cat in JavaScript http://cat-language.com/interpreter.html.

    If you see anything you like feel free to reuse it, I've released the

    source code into the public domain.

    - Christopher

     On Mon, Feb 16, 2009 at 7:35 PM, Chris Double <chris.double@...> wrote:

    > I've been playing around with an implementation of XY in JavaScript to

    > explore client side web programming in a concatenative language. XY is

    > one of Stevan Apter's language experiments:

    >

    > http://nsl.com/k/xy/xy.htm

    >

    > I've got the core of the language implemented and it's fun to play

    > around with and use as a simple learning tool. A simple

    > read/eval/print listener is available here:

    >

    > http://www.bluishcoder.co.nz/xyjs/xylistener.html

    >

    > Click somewhere on the page and then enter an expression. For example:

    >

    > [ 1 2 3 4 ] [ 2 * ] map .

    >

    > The '.' at the end will pop the last item off the X stack and print

    > it. This implementation has large integers, using a big number

    > implementation in JavaScript. So this works:

    >

    > ; fac dup 1 = [] [dup 1 - fac *] if ;

    > 100 fac .

    >

    > Or you can use linrec:

    >

    > 10 [dup 1 =] [] [dup 1 -] [*] linrec alert

    >

    > This 'alert' word displays a pop up alert box. Operations that take a

    > long time can hit the browsers 'kill long running scripts' message.

    > I'll do a workaround for this at some point.

    >

    > If you do a 'view source' on the page you'll see the library of XY

    > functions, taken from Stevan's page. The XY code is in an HTML script

    > block of type 'text/x-xy':

    >

    > <script type="text/x-xy">

    > ; pop { a } ;

    > ; drop pop ;

    > ; dip swap => / <= ;

    > ; dup { a \a \a } ;

    > ; swap { [a b] \b \a } ;

    > </script>

    >

    > Not all of the included library works due to unimplemented core

    > library functions. XY uses primitives based on K. I don't know what

    > most of these are so I'm slowly working through them as I need to.

    >

    > There is a very simple JavaScript FFI to allow calling JavaScript

    > functions. A 'js-global' word evals a given string and returns a

    > JavaScript object:

    >

    > "document" js-global .

    > => js([object HTMLDocument])

    >

    > A 'js-call' word calls a JavaScript function given an array of

    > arguments, the 'this' object, and the function object on the stack:

    >

    > [ [ "hello" alert ] >js-function / 1000 / ] "window" js-global

    > "window.setTimeout" js-global js-call

    >

    > The '>js-function' word converts an XY quotation to a JavaScript function.

    >

    > Continuations seem to work:

    >

    > [ "hello" . ] 0 call/cc "there" .

    > => "hello"

    > "there"

    > dup /

    > => "there"

    > dup /

    > => "there"

    >

    > In the listener Ctrl+Up and Ctrl+Down can be used to cycle through the

    > history of last entered commands. There's not much error checking or

    > reporting at the moment so errors tend to give obscure JavaScript

    > related messages. Also I've mainly tested on Firefox so other browsers

    > may or may not work. I believe Safari worked last time I tried.

    >

    > Another simple test page is:

    >

    > http://www.bluishcoder.co.nz/xyjs/xy.html

    >

    > Entering an expression and hitting 'Eval' will show each step as the

    > expression is evaluated. For example, 1 2 dup + *, gives:

    >

    > 1 -> 2 dup + *

    > 1 2 -> dup + *

    > 1 2 -> { a \ a \ a } + *

    > 1 2 { -> a \ a \ a } + *

    > 1 2 { a -> \ a \ a } + *

    > 1 2 { a \ -> a \ a } + *

    > 1 2 { a \ a -> \ a } + *

    > 1 2 { a \ a \ -> a } + *

    > 1 2 { a \ a \ a -> } + *

    > 1 -> \ 2 \ 2 + *

    > 1 2 -> \ 2 + *

    > 1 2 2 -> + *

    > 1 4 -> *

    > 4 ->

    >

    > The information on the left hand side of the '->' is the X stack, the

    > right hand side is the Y queue.

    >

    > The core builtin words at the moment are listed here:

    >

    > http://www.bluishcoder.co.nz/xyjs/xy.txt

    >

    > There is a 'source' word that outputs a quotation containing the

    > definition of a word:

    >

    > \ dup source .

    > => [ { a \ a \ a } ]

    >

    > Any suggestions or ideas for improving/adding to this would be appreciated.

    >

    > Chris.

    > --

    > http://www.bluishcoder.co.nz

    >

    >