Ecosyste.ms: Awesome

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

Awesome Lists | Featured Topics | Projects

https://github.com/you-win/gdlisp

A Lisp-style language implemented in GDScript.
https://github.com/you-win/gdlisp

gdscript godot lisp scheme

Last synced: 2 months ago
JSON representation

A Lisp-style language implemented in GDScript.

Awesome Lists containing this project

README

        

# GDLisp
A Lisp-style language and REPL written using GDScript and Godot 3.3.

## Quickstart
Run the main scene. Start writing Lisp-style stuff.

## Integration into Godot games/apps
Take the `gdlisp.gd` file and drop it into your project. Create a new `gdlisp` object.

A dictionary of initialization variables can be passed as an argument (e.g. `var gdlisp = GDLISP.new({"some-identifier": myobject})`). If you want to be able to modify objects from GDLisp, these initialization variables must be some sort of reference (i.e. not a primitive).

Call `gdlisp.parse_string('(print "hello world"))` to start execution. The `parse_string` method will return an array of return values, depending on how many root S-expressions were passed.

## Motivation
It seemed like a cool idea at the time. I also wanted to write a language that had goto statements in it. [This website was a big help for the initial interpreter.](https://norvig.com/lispy.html). I tried to avoid referencing any explicit Make a Lisp (MAL) implementations.

## Implementation notes
- Arrays and Dictionaries are wrapped in the GDLArray and GDLDictionary classes respectively. This was done so that `set`/`get` can be called on Arrays and Dictionaries in GDLisp.

## TODO
- finish implementing macros
- finish implementing a way to access lists and tables
- allow for compilation to GDScript
- self host the interpreter

## Syntax

### Define a variable `(def )`
Creates a variable in the current scope and sets it to the specified value. Can shadow outer variables if used in an inner scope.

The below example will set variable `x` to value `0` in the current scope.

`(def x 0)`

### Update a variable `(= )`
Finds a variable in the current or any outer scope (in that order) and sets it to the specified value.

The below example will set variable `x` to value `10`.

`(= x 10)`

### Create a list `[ ... ]` or `(list ... )`
Creates and returns a list with the specified values. An empty list can be created if no values are specified.

The below example creates a list with the values `1`, `2`, and `3` and stores it in variable `x`.

`(def x [1 2 3])`

### Create a table `{ ... }` or `(table ...)`
Creates and returns a table (aka a dictionary) with the specified values. An empty table can be created if no values are specified.

The below example creates a table with the key/value pair `"hello": "world"` and stores it in variable `x`.

`(def x { "hello" "world" })`

### Create a lambda expression `(lam [] ...)`
Creates and returns a lambda expression that takes the specified parameters and runs the specified expressions. A lambda expression does not need any parameters but must have at least 1 expression.

The below example creates a lambda expression and assigns it to the variable `double`. The lambda expression is then used to double the value `2`. The returned value will equal `4`.

```
(def double (lam [ x ] (+ x x)))

(double 2)
```

### Create a macro `(macro [] ...)`
Not yet implemented.

### Call a method from a raw value `(raw ...)`
Gets an object and calls the `callv` function on it.

### If statements `(if )`
Evaluates the condition and selects an expression to execute.

The below example checks to see if 1 is less than 2. If this is true, the `double` lambda expression will be executed, otherwise the built-in `print` function will be called.

`(if (< 1 2) (double 1) (print "this is not possible"))`

### While statements `(while ...)`
Executes the given expressions while the condition is true. There must be at least 1 expression to execute.

The below example creates and increments a variable `x` from 0 to 5.

```
(def x 0)
(while (<= x 5) (= x (+ x 1)))
```

### Do block `(do ...)`
Executes the given expressions. There must be at least 1 expression to execute. Do blocks create an implicit inner scope.

The below example creates a variable `x` and sets it equal to `0`. Then the do block will shadow the variable `x` and set it equal to `10`. Outside of the do block, the built-in function `print` will print the value of `x`, which will be `0`.

```
(def x 0)
(do (def x 10))
(print x)
```

### Label `(label )`
Not yet implemented.
Marks the current expression as a `goto` location.

### Goto `(goto )`
Not yet implemented.
Moves execution to the specified `label`. The `label` must be in the same scope or an outer scope. If the `label` has not be interpreted yet, then the interpreter will conduct a breadth-first search for the `label`.