An open API service indexing awesome lists of open source software.

https://github.com/franeklubi/luxya

Programming language with a tree-walking interpreter written in Rust©™.
https://github.com/franeklubi/luxya

interpreted-programming-language interpreter lox lox-language programming-language programming-languages rust tree tree-walk-interpreter tree-walker

Last synced: 10 months ago
JSON representation

Programming language with a tree-walking interpreter written in Rust©™.

Awesome Lists containing this project

README

          

# luxya ✨

Luxya is a [Lox](https://github.com/munificent/craftinginterpreters)-based programming language with a tree-walking interpreter *written in Rust©™*.

![luxya logo](./assets/luxya_logo.png)

To download precompiled binaries for GNU/Linux and Windows visit the [releases](https://github.com/franeklubi/luxya/releases) page!

---
* [Lox-luxya differences](#lox-luxya-differences)
* [Additions](#additions)
* [Syntax](#syntax-differences)
* [Backend](#backend-differences)
* [Native functions](#native-functions)
* [Usage](#usage)
* [Examples](#examples)
* [Compilation and development](#compilation-and-development)
---

## Lox-luxya differences
### [Additions](./doc/additions.md):
- **lists!**; [read more](./doc/additions.md#lists)
- square bracket accessor (`[expression]`); [read more](./doc/additions.md#square-bracket-accessor)
- grouping accessor (`.(expression)`); [read more](./doc/additions.md#grouping-accessor)
- full object notation; [read more](./doc/additions.md#objects)
- chars; [read more](./doc/additions.md#chars)
- 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 `let` instead of `var`, and `const` for immutable declarations
- `if`'s, `else`'s, and `for`'s body has to be a block
- `if`s 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 `true` will be treated as `not true` when placed in `if`'s or `for`'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 `while` loops, but you can achieve the same behaviour with `for` (`while true { ... }` is the same as `for ; true; { ... }`)
- you can state an infinite loop by omitting every field: `for ;; {}`
- `init` (Lox's constructor method) is named `constructor`
- you cannot call an instance's `constructor` directly (`constructor`s are only callable by using `Classname()` or `super()`)
- to call a superclass's constructor you need to call the `super` keyword, as you would a function
- inheritance is done with the `extends` keyword, replacing the `<` syntax
- chars, which you can read more about [here](./doc/additions.md#chars)

### Backend differences:
- numbers are `IEEE 754-2008` compliant (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](./doc/native_functions.md)

## Usage
To run any script source run:
```sh
$ luxya
```

To run in REPL mode (which is not yet finished):
```sh
$ luxya
```

## Examples
```lux
for let i = 0; i < 10; i = i + 1 {
print i;
}
```
```lux
fun shout(text) {
print text + "!";
}

shout("hi");
```
```lux
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 by `tools/generate_ast.py`
- the rest

To get a release build you can use `just`:
```sh
$ just
```
Or use cargo:
```sh
$ cargo build --release --verbose
```

There are also a couple of useful dev commands like:
```sh
# 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
```