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

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

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