https://github.com/devnote-dev/clip
Toy/experimental interpreted scripting language
https://github.com/devnote-dev/clip
Last synced: 8 months ago
JSON representation
Toy/experimental interpreted scripting language
- Host: GitHub
- URL: https://github.com/devnote-dev/clip
- Owner: devnote-dev
- License: mpl-2.0
- Created: 2023-06-27T18:12:13.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2023-07-21T18:35:28.000Z (over 2 years ago)
- Last Synced: 2025-03-30T19:13:25.014Z (10 months ago)
- Language: Rust
- Homepage:
- Size: 75.2 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Clip
A toy programming language for me to learn and explore compilers/the compilation process/compiler internals/etc.
## Installing
1. Clone the repo
2. `cargo install`
3. `cargo build -r` (optional: this will build to `./target/release`)
## Using
You can run the interpreter via `cargo run -- run ` or start the REPL with just `cargo run -- repl`.
## Syntax
The language can be best described as lisp without the parentheses, everything is declared and read left to right. Comments are declared using `#` unlike lisp — semicolons actually have meaning (they are delimiters, as they should be).
### Variables
Variables can be assigned and reassigned using `=`:
```
= foo 24
= foo "bar"
```
### Data types
There are primitive data types such as integers, floats, strings and booleans as per usual. However, there is no _explicit_ `null`. Instead, `null` is represented via an empty expression `()` (also known as "unit" in some actual languages).
### Operators
> **Note**
> Operators will only compare arguments of the same type, except for `==` with `()`.
| Definition | Description |
| -------------- | ------------------------------------------------------------------------------------ |
| `== a b ...` | Equality: checks if `a` is equal to any of the other arguments. |
| `> a b ...` | Comparison: checks if `a` is greater than any of the other arguments. |
| `>= a b ...` | Comparison: checks if `a` is greater than or equal to any of the other arguments. |
| `< a b ...` | Comparison: checks if `a` is less than any of the other arguments. |
| `<= a b ...` | Comparison: checks if `a` is less than or equal to any of the other arguments. |
| `+ a b ...` | Addition: adds all the arguments sequentially. |
| `- a ...` | Subtraction: subtracts all the arguments sequentially. Negates if there is only one. |
| `* a b ...` | Multiplication: multiplies all the arguments sequentially. |
| `/ a b ...` | Division: divides all the arguments sequentially. |
| `&& a b ...` | Logic And: checks if all arguments are _truthy_. |
| `\|\| a b ...` | Logic Or: checks if at least one argument is _truthy_. |
| `! a` | Inverse: gets the inverse value of `a`. Only works for boolean values. |
There is no explicit `!=` (not equal) operator because this can be achieved by combining the inverse and equals operators:
```
# works the same
! == 2 4 # boolean : true
```
### Functions
Functions can be declared using braces. A function's return type is inferred from last expression in the function block. To call a function, simply specify provide the arguments after the function name. If the function doesn't take any arguments, it can be called with `()`.
```
= random { 42 }
random () # integer : 42
```
Function parameters can be defined in brackets following the opening brace:
```
= add { [a b] + a b }
add 2 3 # integer : 5
```
Note that calling a function that has a singular argument with `()` still works:
```
= is_null { [a] == a () }
is_null () # boolean : true
```
Because of this rule, this allows functions to be passed around as arguments:
```
= sum_numbers { [fn] fn 2 4 6 }
= add { [a b c] + a b c }
= subtract { [a b c] - a b c }
sum_numbers add # integer : 12
sum_numbers subtract # integer : -8
```
Alternatively, you can pass in a function literal directly (i.e. closures) but this may not be a permanent feature:
```
sum_numbers { [a b c] + a b c } # integer : 12
```
## Control Flow
Control flow in the form of `if` and `else` statements is possible (chained `else-if` statements coming soon). Here's fibonacci (it actually works):
```
= fib { [n]
if < n 2 {
1
} else {
+ (fib - n 2) (fib - n 1)
}
}
fib 12 # integer : 233
```
## Development
- Control statements (`for`)
- Module management (`import`, `export`)
- Method calls
- Data types (`object`, `init`)
- Function type signatures
- Error management (`error`, `catch`)
- Null safety
- Separation of interpretation and compilation
This repository is managed under the Mozilla Public License v2.
© 2023 devnote-dev