luxya
luxya copied to clipboard
Programming language with a tree-walking interpreter written in Rust©™.
luxya ✨
Luxya is a Lox-based programming language with a tree-walking interpreter written in Rust©™.

To download precompiled binaries for GNU/Linux and Windows visit the releases page!
- Lox-luxya differences
- Additions
- Syntax
- Backend
- Native functions
- Usage
- Examples
- Compilation and development
Lox-luxya differences
Additions:
- lists!; read more
- square bracket accessor (
[expression]); read more - grouping accessor (
.(expression)); read more - full object notation; read more
- chars; read more
- the modulo (
%) operator
Syntax differences:
- function declarations are expressions, rather than statements, so you can create anonymous (but not strictly) functions you want to use in-place:
function_name(10, a, fun () { print "callback" }) - introduced
letinstead ofvar, andconstfor immutable declarations if's,else's, andfor's body has to be a blockifs condition doesn't need to be a grouping (basically you can do:if true { ... })- although there is no type coercion, any value that's not strictly
truewill be treated asnot truewhen placed inif's orfor's condition for's initialization consists of three, not grouped fields (e.g.:for let i = 0; i < 10; i = i + 1 { ... })- there are no
whileloops, but you can achieve the same behaviour withfor(while true { ... }is the same asfor ; true; { ... }) - you can state an infinite loop by omitting every field:
for ;; {} init(Lox's constructor method) is namedconstructor- you cannot call an instance's
constructordirectly (constructors are only callable by usingClassname()orsuper()) - to call a superclass's constructor you need to call the
superkeyword, as you would a function - inheritance is done with the
extendskeyword, replacing the<syntax - chars, which you can read more about here
Backend differences:
- numbers are
IEEE 754-2008compliant (rust's f64 underneath) - no type coercion, no truthy nor falsy values
- no visitor pattern
- reference counting because there's no garbage collector to leverage
- shadowing of named values is permitted
Native functions:
You can find full list of native functions here
Usage
To run any script source run:
$ luxya <source>
To run in REPL mode (which is not yet finished):
$ luxya
Examples
for let i = 0; i < 10; i = i + 1 {
print i;
}
fun shout(text) {
print text + "!";
}
shout("hi");
class Language {
constructor(name) {
this.name = name;
}
say_language() {
print this.name;
}
}
class Luxya extends Language {
constructor() {
super("luxya");
}
say_language() {
print "✨✨✨";
super.say_language();
print "✨✨✨";
}
}
const luxya = Luxya();
luxya.say_language();
Compilation and development
The source comprises two parts:
- the
src/ast/*generated bytools/generate_ast.py - the rest
To get a release build you can use just:
$ just
Or use cargo:
$ cargo build --release --verbose
There are also a couple of useful dev commands like:
# run REPL in watch mode
$ just watch
# run the `sample_program.lux` in watch mode
# (script source overridable with sample_program_path in justfile)
$ just watch_sample
# run the `generate_ast.py` script with mypy checks in watch mode
# (script source overridable with generate_ast_path in justfile)
$ just watch_generate_ast