Oli language parser and compiler for node and the browser
Language version | 0.1 |
Stage | beta |
About
Multi-purpose high level Oli language parser and compiler for node.js and the browser, which implements the latest language specification
Oli.js provides a general parsing infraestructure to be integrated and consumed from other applications that uses the Oli syntax for specific purposes, like parsing own DSL
Aditionally it provides a rich featured high and intermediate level programmatic API and a rich command-line interface
Note: it's still a beta implementation! A full compiler re-designing process is pending
Features
- Powerful parser based on parsing grammar expressions
- Smart compiler with smart type inference
- Detailed parsing errors
- Runs on node.js and the browser
- High and intermediate level featured API
- Featured command-line interface
- Heavily tested with high coverage
- No third party dependencies
- Official language specification implementation
- Good performance (run
grunt bench
)
Installation
Node.js
$ npm install oli
For CLI usage only, it's recommented you install it as global package
$ npm install -g oli
Browser
$ bower install oli
Or load the script remotely (just for testing or development)
Then you can create script tags with text/oli
MIME type
It will automatically fetch and parse the oli sources and make it available from oli.scripts
.
To disable the automatic parsing, just add data-ignore
attribute in the script tag
Environments
- Node.js >= 0.8.0
- Chrome
- Firefox
- Safari >= 5
- Opera >= 11.6
- IE >= 9
Milestones
- Parser
- Top-down parsing (based on PEG strategy)
- AST
- Configurable parsing options
- Errors
- Unicode expressions
- [*] Indentation based parsing
- Compiler
- AST walker
- Memory register
- Intermediate code transpiler
- Code generator
- [*] Errors
- [_] Interpreter
- [_] Optimiser
- [_] Event-driven
- Interfaces
- API
- CLI
- REPL
- Serializer
- [_] JSON to Oli
- [_] Concret Syntax Tree to Oli
- Engines
- Node.js
- Browsers
- [?] Rhino
Upcoming features
There are important features in Oli language spec 0.2. You can see the future features discussion here
A summary about most important features that will be implemented
- Interpolated code expressions (oli/#3)
- Generic helper functions (random, string format, date format...)
- Helpers functions extension via API
- Block scope references (oli/#18)
- Indentation-based parsing (oli/#5)
- Date as first-class primitive type (oli/#2)
Command-line interface
Usage: oli [options] path/to/file.oli
Options:
-h, --help output usage information
-V, --version output the version number
-p, --parse parse and return the result as JSON
-t, --tokens parse and return a collection of the tokens as JSON
-o, --output <file> write output into a file instead of stdout
-a, --ast return the parsed AST serialized as JSON
-i, --in-line parse in-line argument as string
-d, --indent <size> JSON output indent size. Default to 2
-s, --stdin Read source from stdin
-r, --repl use the interactive read-eval-print loop interface
Examples:
$ oli file.oli > file.result.json
$ oli file.oli -o file.result.json
$ oli --ast file.oli
$ oli --tokens file.oli
$ oli --in-line "hello: oli!" > result.json
$ oli -s < file.oli
REPL
Run $ oli
without arguments to play with the REPL interface
$ oli
Oli experimental REPL interface
Type "examples" to see code examples
oli> - oli, rules, yes
Programmatic API
Example
Require the module
var oli = require('oli')
Simple parsing
var code = 'message: - hello, oli!'try var result = oli catch e console consoleconsole // => { message: [ "hello", "oli!" ] } }
Binding a custom context to the compiler
var code = 'directory: *env.HOME'var result = oli
parse(code, options)
Alias: transpile
Return: mixed
Parse and process the given code performing an end-to-end compilation and return the final result, that will be usually an object with the equivalent scheme tree equivalent representation of the Oli source code
ast(code, options)
Alias: parseAST
Return: object
This is the most low-level API method. It returns an object that represent the parsed abstract-syntax tree
Note: AST node types or tree data structures can change between minor versions, as the parser is still beta. Please be aware with that in order to prevent possible inconsistencies if your implementation is coupled to the parsed AST
parseMeta(code, options)
Alias: meta
Return: mixed
Parse a given code and return an intermediate resultant object tree structure which includes
meta data such as block operators, block expressions, references and attributes prefixed with $$
compile(ast)
Alias: run
Return: mixed
Process the given AST and return the compilation result.
tokens(code, options)
Alias: parseTokens
Return: array
Returns a one-level objects collection with the existent tokens in the given code
load(path, callback)
Context: browser
Performs an asynchronous XHR request and pass to the callback the response body as plain text.
It will throw an Error
exception if cannot perform the request
oli
oli.Compiler(ast, options)
The compiler perform a side-by-side code transformation and generation given an AST tree. It creates a new memory context and uses the tranformer and generator in order to proceed with the compilation
Once you create an instance of the object, you need to call
the compile()
method in order to perform the compilation
oli.Compiler.transformer(ast, memoryContext)
This method performs an AST traversal walk transforming each node and returning an intermediate-level simplified object tree
oli.Compiler.generator(obj, memoryContext)
Takes the intermediate object from the trasnformation process and performs the final code generator. It takes the responsabilities of the interpreter, data mutation and final code generation
oli.Compiler.nodes
An object with the AST node type transformer functions
Options
meta
Type: boolean
Default: false
Return an intermediate level object with metadata properties. This is useful when you need to process an intermediate object that includes tokens, operators, expressions and more, instead of process a cutted resultant object
loc
Type: boolean
Default: false
locals
Type: object
Default: null
Set of local variables context to be passed to the compilation sandbox
Errors
oli.js provides detailed errors. Usually it will be throwed as exception
Types
- SyntaxError
- CompileError
- TypeError
- ReferenceError
Members
Each error object instance will have the following members
- message
- fullMessage
- line
- column
- offset
- expect (SyntaxError only)
- found (SyntaxError only)
Contributing
Wanna help? Cool! It will be really apreciated :)
You must add new test cases for any new feature or refactor you do, always following the same design/code patterns that already exist
Tests specs are completely written in LiveScript language. Take a look to the language documentation if you are new with it. You should follow the LiveScript language conventions defined in the coding style guide
Development
Only node.js and Grunt are required for development
Clone/fork this repository
$ git clone https://github.com/oli-lang/oli-js.git && cd oli-js
Install package dependencies
$ npm install
Run tests
$ npm test
Run benchmarks
grunt bench
Coding zen mode
$ grunt dev [--force]
Cyclomatic complexibility report
$ grunt plato
Browser sources bundle
$ grunt build
Release a new version
$ grunt release
License
Copyright (c) Tomas Aparicio
Released under the MIT license