- 露水 lùshui
-
dew; ephemeral, transient, of short duration
The reference compiler and the standard library of the Lushui programming language and related tooling.
This project is under heavy development and it is not recommended for use outside of experimental non-production software. The language, the compiler API and its CLI have no stability guarantees whatsoever. Anything may change in a new version without notice. The majority of the language has not been implemented yet in the compiler, the latter contains quite a lot of bugs and the test suites are not that big yet.
The Lushui programming language is dependently typed, purely functional and eagerly evaluated. Modules are second-class citizens. Allocations are implicit and memory management is automatic.
The final design of the language is very much in flux.
Currently, there is no universe hierarchy (Type : Type
holds),
all functions may be partial and we support next to no type inference.
However, it’s planned to at some point feature a cumulative universe hierarchy,
to enforce the totality of functions by default (with a way to opt-out on a fine-grained level),
to type-check bidirectionally and
to support implicit parameters.
It’s planned to support
-
dependent case analysis / pattern matching
-
nominal record types
-
side effects via monads or algebraic effects (undecided ^^')
-
“type classes” via implicit record parameters
-
a deriving mechanism through a dependently-typed generics system
-
a coercion system for representationally equal types (with respect to memory layout)
-
C-FFI at run-time and at compile-time
-
opt-in laziness
-
abstract definitions by default (bindings in types that don’t reduce / aren’t normalized outside of their defining module / defined reach)
-
the option to compile with LLVM or Cranelift
@public @transparent
data Option A of
none
some (_: A)
use Option.(none, some)
@public
map 'A 'B (f: A -> B) (x: Option A): Option B =
case x of
none => none
some (let x) => some (f x)
use extern.core.(type.Type, nat.(Nat, +, *))
process (n: Option Nat): Option Nat =
map (for n => + n 1) n
@public @transparent
data Vector A: For (n: Nat) -> Type of
empty: Vector 0 A
prepend '(n: Nat)
(head: A)
(tail: Vector n A):
Vector (+ n 1) A
trait Monoid A of
empty: A
append: A -> A -> A
given sum: Monoid Nat of
empty = 0
append = +
given product: Monoid Nat of
empty = 1
append = *
duplicate 'A [Monoid A] (a: A): A =
Monoid.append a a
use extern.core.text.Text
record Person of
name: Text
age: Nat
jane: Person = {name = "Jane", age = 38}
name: Text = jane::name
For more, check out the source files found in test/ui
.
Feel free to open on-topic GitHub issues & discussions. You are welcome to contribute patches to this repository. However, keep in mind that I am developing this project for personal learning purposes and that I intend to further my skills by tackling big and challenging tasks entirely by myself.
The compiler is mainly written in Rust and
it uses Rust’s official package manager Cargo.
We require a nightly version of the Rust compiler rustc
.
For the exact version, see the rust-toolchain.toml
in the project root.
rustup
will pick it up automatically.
To build the Lushui compiler with all (Cargo) features, run:
cargo +nightly build --all-features
To show the help text (on Unix-like systems), execute:
./lushui -h
On Windows, use cargo +nightly run -- -h
.
Currently, the bash script ./lushui
also rebuilds the compiler if necessary
(no status info shown though during building) and
runs it afterwards.
To execute a Lushui source file (with the HIR interpreter which is the most feature-complete backend), run:
./lushui file run file.lushui
To run a Lushui package found in the current or in a parent folder, execute:
./lushui run
Use the following command (Unix-like systems only) to run all test suites:
./test/run
If you want to restrict yourself to UI tests, execute ./test/run ui
.
Basic language support (syntax highlighting and a rudimentary language server) is available as an extension. For Recnot files (a type of configuration files), we currently provide a separate extension. It’s planned to be integrated into the main extension at some point.
To build the language server, change into ./project/editors/vscode/fmease.lushui-0.0.1/
and type:
npm install
npm run compile
Then, copy or symlink the folder to ~/.vscode/extensions/
.
The compiler currently needs to be built with (Cargo) feature lsp
and added to the $PATH
as lushui-nightly
for the language server to work.
For Recnot language support (a configuration language), copy or symlink the folder ./project/editor/vscode/fmease.lushui-recnot-0.0.1
to ~/.vscode/extensions/
.
The LLVM backend is currently in the earliest of stages. You can only compile super simple programs.
First, compile the runtime system called boot
(part of core
).
This step only needs to be done once (unless you want to modify the system).
cargo build --release --package boot
This should create the file /target/release/libboot.a
(on Unix-like systems) necessary for compiling intrinsic functions.
Make sure that you have built / you are executing the compiler with the (Cargo) feature llvm
enabled.
Set the backend to llvm
via the --backend
option.
As hinted in the help text (./lushui -h
), you use ./lushui doc
(and variations) to generate (HTML) documentation.
To view it, just pass --open
.
By default, documentation comments are treated as plain text.
However, the goal is to make AsciiDoc the standard markup language.
Today, this is only opt-in via the unstable option -Z asciidoc
which requires Asciidoctor
to be installed and
available as asciidoctor
(a custom installation path is not supported at the moment).
Except as otherwise noted, the contents of this repository are licensed under the Apache License, Version 2.0 (see the license file). Some files include or are accompanied by explicit license notices.