or
and
if
var
..
:
:=
1.3Caveats
8.18
top
← prev up next →

GDLispπŸ”— i

(require gdlisp ) package: gdlisp

GDLisp is a lisp dialect that compiles to GDScript.

(print"Hello,world!")

Produces (when run):

print("Hello,world!")

1OverviewπŸ”— i

GDLisp is a way to write script files for the Godot engine without actually writing (directly) in the scripting language it provides.

The main benefits this provides is that you can write macros and (hopefully) enter into Lisp game jams. Also you don’t have to deal with semantic whitespace.

1.1The GDLisp scriptπŸ”— i

A GDLisp script has the following grammar:

program = top-level-stmt...
top-level-stmt = escape-stmt
| top-class-stmt
escape-stmt = (require require-spec...)
| (module module-body...)
top-class-stmt = (class-name name)
| class-stmt
class-stmt = (extends parent-name)
| stmt

Where escape-stmts are put directly into the surrounding module, and top-class-stmts are interpreted as a GDLisp class.

Statements and expressions have the following grammar:

stmt = (definemaybe-var-prefixbinding)
| (var maybe-var-prefixbinding)
|
(definemaybe-static(name-idfunc-param...)
body-expr...+)
|
(func maybe-static(name-idfunc-param...)
body-expr...+)
|
(class name-id
class-stmt...)
| (signal name-id)
| (beginstmt...)
| stmt-expr
func-param = name-id
| [binding]
maybe-var-prefix =
| export
| (export export-arg...)
maybe-static =
| static
binding = name-id
| name-id: type-id
| name-id: type-iddefault-expr
| name-id:= default-expr
expr = (beginbody-expr...)
| variable-id
| (.-field-nametarget-expr)
| (.method-nametarget-exprmethod-arg-expr...)
| (function-exprfunction-arg-expr...)
| literal-expr
| special-expr
literal-expr = [list-element-expr...]
| {kv-pair...}
special-expr = cond-expr
| let-expr
| recur-expr
| match-expr
| for-expr
kv-pair = key-exprval-expr
body-expr = (definebinding)
| expr
cond-expr =
(cond
[pred-exprthen-body-expr...+]...
maybe-else-clause)
maybe-else-clause =
| [elseelse-body-expr...+]
let-expr =
(letmaybe-let-name
(binding...)
body-expr...+)
maybe-let-name =
| name-id
recur-expr = (recurrecur-target-idarg-expr...)
match-expr =
(match target-expr
[match-patternbody-expr...+]
...)
match-pattern = (or subpattern...);where subpattern has no (var _) patterns
| subpattern
subpattern = constant-pattern
| variable-id
| _
| (var name-id)
| [subpattern...]
| [subpattern..... ]
| {kv-pattern...}
| {kv-pattern..... }
kv-pattern = constant-patternsubpattern
constant-pattern = constant-number
| constant-string
| constant-boolean
for-expr =
(for([name-idtarget-expr])
body-expr...+)

Syntax transformers are expanded (roughly) as usual.

1.2BindingsπŸ”— i

syntax

or

syntax

and

syntax

if

syntax

when

Analogous to the equivalent bindings from racket/base.

syntax

class-name

syntax

extends

syntax

export

syntax

match

syntax

var

syntax

signal

syntax

func

syntax

static

syntax

class

syntax

..

syntax

:

syntax

:=

syntax

#%gdscript

These have transformer bindings that prohibit them from being used outside of their context.

1.3CaveatsπŸ”— i

There are a few caveats and things to note about GDLisp.

1.3.1Name manglingπŸ”— i

Racket identifiers used as variables are mangled before being emitted as GDScript, so they are valid GDScript identifiers. Most notably, hyphens ("-") are converted to underscores ("_"). Names that mangle to the same identifier will conflict. This does also mean that macros which introduce variable bindings are unhygienic. Use (gensym) if you need a name which doesn’t conflict.

top
← prev up next →

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /