Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Write javascript in s-expressions
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
src
tests
README.md

README.md

ethpretho

Write javascript in s-expressions

Ethpretho is a small, lisp-inspired language that compiles to readable, standard javascript. It is in the vein of coffeescript and, more so, in that of sibilant.

The approach:

  • retain normal javascript semantics
  • .. except provide implicit return
  • any non-javascript semantics should be implemented with macros
  • use terse syntax where appropriate

Currently, the base compiler is done and is written in itself (and can compile itself). The macro system, which I intend to make pattern-based and hygenic, will follow.

The tooling / packaging is also pending.

To compile a single .eth file to .js:

cd src
node compile ./somefile.eth

This will place the new .js file next to the .eth file

Syntax

js equivalent shown below each line of ethpretho

Numbers, atoms, and regexes are that same as in js.

Strings are enclosed in double-quotes only.

Assignment

(:= x 1)   

    var x = 1;

(= x 2)   

    x = 2;   

Functions

(-> (x y) (* x y))        

    function (x, y) { return (x * y); }

Arrays

[1 2 3]

    [1,2,3]

Objects

{a 1 "b" 2}

    {a:1, "b":2}

Comments

Comments are not retained in the js output

; somecomment

Member access / method chaining

(. x y)

    x.y

(. x [y])

    x[y]

(. x 0)

    x[0]

(. x (y 1) (z 2 3))

    x.y(1).z(2,3)

(. x [(y z)])

    x[y(z)]

(. x ([(y z)] a))

    x[y(z)](a) 

Conditionals

'if' encompasses 'else' and 'else if' when necessary:

(if x (y))

    if (x) { 
        y(); 
    }

(if (< x y) (a 2) 
    (< x z) (a 3)
            (a 4))

    if (x < y) {
        a(2);
    } else if (x < z) {
        a(3);
    } else {
        a(4);
    }

Note: If you want more than one expression in a result block, you need to expand the block by use of the sequence form, ',':

(if x (y)
      (, (y)
         (z)))

    if (x) { 
        y(); 
    } else {
        y();
        z();
    }

Loops

Only 'for' and 'while' are provided. These map directly to the normal js 'for' and 'while'. Later, more convienient looping constructs will be added as macros that compile to these:

(for ((= i 0) (< i len) (++ i))
     (y i)
     (z i))

    for (i = 0; i < len; i++) {
        y(i);
        z(i);
    }

(while (!== i 0)
       (y i)
       (-- i))

    while (i !== 0) {
        y(i);
        i--;
    }

Try / Catch / Finally

(try e
     (, (x) (y))
     (throw (new Error (+ "The world is ending: " e)))
     (y))

    try {
        x();
        y();
    } catch (e) {
        throw new Error("The world is ending: " + e);
    } finally {
        y();
    }

Implicit return

Almost everything is an expression. Try/catch, loops, and conditionals will be wrapped in self-calling functions if a value is expected of them:

(+ 1 (for ((in i j)) (* i 2)))

    (1 + (function () { 
        res_ = [];
        for (i in j) {
            res_.push(i * 2);
        }
        return res_;
    })())

The last expression of a function will be returned. If it is a conditional, the 'return' will propagate to the last position in all its branches:

(-> (x) (y)
        (z)
        (x))

    function (x) {
        y();
        z();
        return x();
    }

(-> (x) (if (< x y) 2 
            (< x z) 3
                    4))

    function (x) {
        if (x < y) {
            return 2;
        } else if (x < z) {
            return 3;
        } else {
            return 4;
        }
    }

Linked binary primitives and comparisions

(+ "a" "b" "c")

    ("a" + "b" + "c")

(< x y z)

    ((x < y) && (y < z))
Something went wrong with that request. Please try again.