Skip to content

twfarland/ethpretho

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 

Repository files navigation

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))

About

Write javascript in s-expressions

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published