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.
Installation
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
Usage
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;
};
Implementation
Parsing
Scanning and parsing are handled by a parser generated by nearley; an AST is constructed from Lo construct objects.
Compilation
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.
Runtime
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.
License
Copyright (c) Seth Purcell
Licensed under Apache License v2.0 with Runtime Library Exception
See LICENSE.txt in the project root for license information.