Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Wright brothers bicycle

A Lo-to-JavaScript compiler, written in Node.js Build Status

This is a proof-of-concept compiler for the Lo programming language. It operates as a load-and-go compiler to compile, load, and run a Lo program within a Node environment.


Clone the repo then in the project root folder do:

$ npm install -g

To run the test suite

In the project root folder:

$ npm test


To compile and run a program

$ velo run <root module>

The root module of a Lo program must define a main service that takes two arguments: args and system, for example:

main is (args, system) {

    system.out.writeln <- "Hello, world!";

The first argument is the array of strings provided on the command line after the root module name (arguments before the root module name are handled by Velo). The second argument is the system API object, which contains all the authority available to the program.

To compile a program and dump the JavaScript to the console

$ velo dump <root module>

Module Bindings

Velo provides several built-in module namespaces.

JavaScript Built-In Objects

Velo maps the various JavaScript built-in objects to modules under the JS namespace, but omits any calls that depend on ambient authority, such as Math.random().

For example, this program uses the Math built-in object.

using JS::Math as Math;

main is (args, system) {

    system.out.writeln <- Math.E;



Scanning and parsing are handled by a parser generated by nearley; an AST is constructed from Lo construct objects.


Each Lo statement compiles to a node in a control flow graph that wraps a JavaScript AST. Some statements compile to specialized nodes, e.g. blocking requests, to enable them to wrap following statements in the code generation phase.

Code Generation

A code writer walks the control flow graph and generates JS, creating continuations as necessary to link logically sequential blocks across async requests.

Linking & loading

Compiled modules are linked and then loaded using Node's VM module to prevent access to JS or Node globals.


The runtime consists of Task.js, which implements the Lo task tree; Util.js which provides runtime library functions; and System.js which provides access to system functions such as I/O.

Testing Strategy

Parsing, code generation, and runtime methods are tested independently, as is the pipeline logic (linking and loading). To make sure this all adds up to Lo programs that actually do what they should, there are integration tests in the programs directory that read in a program, run it, and inspect the result.


Copyright (c) Seth Purcell

Licensed under Apache License v2.0 with Runtime Library Exception

See LICENSE.txt in the project root for license information.


A proof-of-concept Lo compiler targeting JavaScript







No releases published


No packages published