• Stars
    star
    296
  • Rank 140,464 (Top 3 %)
  • Language
    Racket
  • Created about 9 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Urlang is JavaScript with a sane syntax

URLANG

Urlang is JavaScript with a sane syntax

Urlang is a language designed to allow straightforward translation to JavaScript. Think of Urlang as JavaScript with sane syntax and JavaScript semantics. JavaScript in this context is short for ECMAScript 5 in strict mode.

Although the constructs of Urlang and JavaScript map almost one-to-one, a little sugar was added:

  • function definitions allow default arguments
  • let expressions

Even though the syntax of Urlang is Racket-like, remember that the semantics is standard JavaScript. This means in particular that tail calls build context.

Examples

The following examples are compiled using the urlang form.

(urlang <module> ...)

The urlang form compiles the modules. The result of compiling a module is saved a file whose path is the module-name with .js added.

The urlang form is controlled by the following parameters:

(current-urlang-run?                           #t)  ; compile and run (using node)
(current-urlang-echo?                          #t)  ; print JavaScript to screen
(current-urlang-console.log-module-level-expr? #t)  ; use conole.log to print module-level exprs

Example (factorial)

 > (urlang
     (urmodule fact                                           ; module name
       (export fact)                                          ; fact is exported
       (import + - * = displayln ref console)
       (define (fact n) (if (= n 0) 1 (* n (fact (- n 1)))))
       (fact 5)))

The generated JavaScript:

 "use strict";
 function fact(n){return (((n===0)===false)?(n*(fact((n-1)))):1);};
 console.log((fact(5)));
 exports.fact=fact;

The output from Node:

 "120\n"

Example (cond-macro and array)

Urlang macro transformers receive and produce standard Racket syntax objects. This implies that standard tools such as syntax-parse are available.

Consider an Urlang version of cond:

SYNTAX (cond [e0 e1 e2 ...] ... [else en]), 
   like Racket cond except there is no new scope 

The urlang macro transformer is an standard (phase 0) Racket function.

  (define-urlang-macro cond
    (Ξ» (stx)   
      (syntax-parse stx
        [(_cond [else e0:Expr e:Expr ...])
         #'(begin e0 e ...)]
        [(_cond [e0 e1 e2 ...] clause ...)
         (syntax/loc stx
           (if e0 (begin e1 e2 ...) (cond clause ...)))]
        [(_cond)
         (raise-syntax-error 'cond "expected an else clause" stx)])))

The macro can now we be used:

> (urlang
    (urmodule sum-example
      (define (even? x) (=== (% x 2) 0))
      (var (sum 0) x (a (array 1 2 3 4 5)) (i 0) (n a.length))
      (while (< i n)
        (:= x (ref a i))
        (cond
          [(even? x)  (+= sum (ref a i))]
          [else       "skip"])
        (+= i 1))
      sum))

The generated JavaScript:

"use strict";
function even_p(x){return ((x%2)===0);};
var sum=0,x,a=[1,2,3,4,5],i=0,n=a.length;
while((i<n)){(x=a[i]);(((even_p(x))===false)?"skip":(sum+=a[i]));(i+=1);};
console.log(sum);

The output from Node:

"6\n"

Overview

The heart of the system is a compiler written using the Nanopass compiler Framework. The compiler is exported as a function

compile : urlang-module -> JavaScript

that compiles an urlang module and produces JavaScript, that can be evaluated by the Node.js platform (or be embedded in a web page).

The Urlang module to be compiled can be represented

  1. as a syntax object
  2. as a Nanopass structure (representing an Lurlang program)

Use 1) to program in Urlang directly.

Use 2) if you intend to use Urlang as a compiler backend.

[Note: Nanopass is a framework for implementing compilers.]

The intended use of Urlang is to use 1) to write (generate) a Racket runtime in JavaScript. The middle-end of the Racket-to-JavaScript compiler will produce output as Nanopass structures, so 2) will be used as the backend for the Racket-to-JavaScript compiler.

Internally the function expand

expand : syntax -> LUrlang

will parse and expand its input and produce an LUrlang representation.

Note that expand allows the user to extend the input language using define-urlang-macro. An Urlang macro is a syntax to syntax transformation implemented as a normal Racket function. This allow you to use all of the standard Racket macro machinery.

Main functions:

expand : syntax -> Lurlang
    expand the input and produce a fully expanded Urlang program
    represented as a Lurlang structure
    
compile : syntax ->
    Expand and compile. The output is written to standard out.
    
eval : syntax -> value
    expand, compile and run the input (an Urlang module represented as a syntax object)
    Running means that `node` is used to run the generated JavaScript.

Having Urlang as a #lang language allows

  • macros (using full Racket at compile time)
  • export of defined names
  • easier testing

In the grammar below:

  • x stands for a non-keyword identifier
  • f stands for an identifier defined as a function
 <module>            ::= (urmodule <module-name> <module-path> <module-level-form> ...)

 <module-level-form> ::= <export> | <import> | <definition> | <statement> 
 <export>            ::= (export x ...)
 <import>            ::= (import x ...)
 <definition>        ::= (define (f <formal> ...) <body>)
                      |  (define x <expr>)
 <formal>           ::= x | [x <expr>]

 <statement>         ::= <var-decl> | <block> | <while> | <do-while> | <if> | <break> | <expr> 
 <var-decl>          ::= (var <var-binding> ...)
 <block>             ::= (block <statement> ...)
 <var-binding>       ::= x | (x e)
 <while>             ::= (while <expr> <statement> ...)
 <do-while>          ::= (do-while <expr> <statement> ...)
 <if>                ::= (sif <expr> <statement> <statement>)
 <break>             ::= (break) | (break label)

 <body>              ::= <statement> ... <expr>

 <expr>              ::= <datum>   | <reference> | <application> | <sequence>
                      |  <ternary> | <assignment> | <let> | <lambda> | <dot>
 <ternary>           ::= (if <expr> <expr> <expr>)
 <reference>         ::= x
 <application>       ::= (<expr> <expr> ...)
 <sequence>          ::= (begin <expr> ...)
 <assignment>        ::= (:= x <expr>)
 <let>               ::= (let ((x <expr>) ...) <statement> ... <expr>)
 <lambda>            ::= (lambda (<formal> ...) <body>)

 <keyword>           ::= define | begin | urmodule | if | := | ...se code...

 <datum>             ::= <fixnum> | <string> | #t | #f

 <identifier>     an identifier that is not a keyword
 <fixnum>         an integer between -2^53 and 2^53
 <module-name>    a symbol or string

NOTES

Some application are special cases:

(ref e0 e1)     becomes  e0[e1]
(ref e0 "str")  becomes  e0.str    
(array e ...)   becomes  [e,...]

Property access with dot notation is rewritten to use bracket syntax in the parser.

Example: object.property becomes object["property"]

SEMANTICS

(if e0 e1 e2)

If e0 evaluates to value strictly equal to false, then e2 otherwise e1. Note: The JavaScript becomes ((e0===false) ? e2 : e1)

(var x (y 3))

Binds x to undefined and y to 3.

More Repositories

1

sketching

A Racket library for creative drawings and animations. Inspired by Processing.
Racket
110
star
2

minipascal

MiniPascal implemented in Racket
Pascal
88
star
3

racket-cas

Simple computer algebra system
Racket
61
star
4

metapict

A graphics library for producing Racket picts in a MetaPost/TikZ style.
Racket
61
star
5

remacs

Emacs style editor written in Racket
Racket
60
star
6

web-tutorial

How to write web applications with Racket
Racket
50
star
7

racket-stories

Racket Stories is a "submit and vote" web site. This repo serves as an example of a small "in production" web-site written in Racket.
Racket
38
star
8

pyffi

Use Python from Racket
Racket
26
star
9

racket-poppler

Racket bindings for Poppler (library for reading and generating pdfs)
HTML
23
star
10

meta

Exploration of the inner workings of Racket
Racket
19
star
11

flappy-bird

A clone of the game Flappy Bird.
Racket
19
star
12

sci

Racket libraries for scientific computing
Racket
17
star
13

bracket

A computer algebra system (CAS) for high school students
Racket
13
star
14

super

Adds syntax to racket languages
Racket
11
star
15

6502

An emulator/assembler/disassmbler for 6502
Racket
9
star
16

bind

Bind: Let with binding clause transformers
HTML
8
star
17

control

Control Structures
Racket
8
star
18

little-helper

Search engine for full text searches in the Racket documentation
Scheme
8
star
19

breakout

A small breakout game in Racket
Racket
7
star
20

cairo

Racket bindings for Cairo (a 2d graphics library implemented in C)
Racket
6
star
21

space-invaders

Space Invaders
Racket
6
star
22

indiana

Ports of "Indiana" Scheme libraries
Racket
5
star
23

flmatrix

Matrices over floating points. Bindings for CBLAS and LAPACK
Racket
5
star
24

racket-highlight-for-github

Github syntax highlighting for Racket
Racket
5
star
25

mathbook

Scribble support for writing math books - MathJax and more
Racket
4
star
26

infix

Infix expression for Racket
Racket
4
star
27

Racket-Maxima

Use Maxima from Racket
4
star
28

nanopass

A Racket implementation of the nanopass framework for compiler writing
Racket
4
star
29

this-and-that

Roff
4
star
30

require-github

Experiments with require
Racket
4
star
31

racket-osx-libs

Source files and build instructions for the dynamic libraries used by Racket on OS X
C
4
star
32

dualshock4

Dualshock 4 interface for Racket on OS X
Racket
3
star
33

tutorials

Bits and pieces that will end up in tutorials
Racket
2
star
34

srfi-array

Implementation of SRFI 179 - Nonempty Intervals and Generalized Arrays
Racket
2
star
35

calcura

A Mathematica-inspired Computer Algebra System (CAS)
Racket
2
star
36

poppler-libs

Binaries for poppler built to work with the draw-<platform>-3 libraries
Racket
1
star
37

racketfest-2023-talk-sketching

The RacketFest 2023 talk on Sketching
Racket
1
star
38

triangle-solver

Triangle solver written in Whalesong (Racket)
1
star
39

rackos

Racket Cartridge for Redhat's OpenShift
Shell
1
star
40

disksort

Sort large files
Racket
1
star