tuple destructuring
This commit is contained in:
parent
f86b7ba60b
commit
6b5035c111
26
README.md
26
README.md
|
@ -4,6 +4,18 @@ An experiment in combining [Fennel](https://fennel-lang.org) and [Terra](https:/
|
|||
## Rationale
|
||||
Idk, seemed cool
|
||||
|
||||
## Goals and Non-Goals
|
||||
At its core are a few a largely non-opinionated macros that directly expose the functionality
|
||||
that is only available through Terra's custom syntax. Terra code is not necessarily meant to
|
||||
read like Fennel or have the same semantics. Early returns are fine, all variables are mutable,
|
||||
break and continue and imperative loops are the norm.
|
||||
|
||||
Ideally it would be possible to build a much cleaner set of macros on top of these base macros.
|
||||
But the goal isn't to design a nice low-level language, it's to expose a powerful compilation
|
||||
target. It's assumed that if you want to take advantage of Terra, it's probably because you
|
||||
want to do horrible code-generation tricks. Hosting it inside Fennel simply makes it more
|
||||
comfortable to do so.
|
||||
|
||||
## Usage
|
||||
At the top of your file, include the following:
|
||||
```fennel
|
||||
|
@ -179,15 +191,25 @@ it consistently mean "create a quote" everywhere. Not sure.)
|
|||
```fennel
|
||||
(var name initial-value) ; compiles to: var name = initial-value
|
||||
(var name type initial-value) ; compiles to: var name : type = initial-value
|
||||
(var (name1 name2) val1 val2) ; compiles to: var name1, name2 = val1, val2
|
||||
(var {name1 type1 name2 type2} val1 val2) ; compiles to: var name1 : type1, name2 : type2 = val1, val2
|
||||
(var {undefined type}) ; compiles to: var undefined : type
|
||||
```
|
||||
Define a local variable named `var`, and set its initial value to `initial-value`. You can
|
||||
manually specify a `type`, or you can let terra infer it from `initial-value`. There is no
|
||||
syntax for _not_ initalizing the variable on declaration.
|
||||
manually specify a `type`, or you can let terra infer it from `initial-value`. Both forms
|
||||
require `initial-value` to be provided.
|
||||
|
||||
You can define multiple type-inferred variables at once with the `(name1 name2)` syntax, and
|
||||
multiple explicitly-typed variables with the `{name1 type1 name2 type2}` syntax. Both of those
|
||||
forms accept any number of initial values. If no values are provided, the variables are left
|
||||
uninitialized. If one value is passed, Terra will treat it as a tuple destructuring. Otherwise
|
||||
you should probably pass the same number of values as names.
|
||||
|
||||
#### assignment
|
||||
```fennel
|
||||
(set varname value) ; compiles to: varname = value
|
||||
(set struct.field value) ; compiles to: struct.field = value
|
||||
(set (field1 field2) tuple) ; compiles to: field1, field2 = tuple
|
||||
(tset struct (getfield) value) ; compiles to: struct.[getfield()] = value
|
||||
```
|
||||
|
||||
|
|
11
terra.fnl
11
terra.fnl
|
@ -180,7 +180,15 @@
|
|||
(fn type-constructors.raw-escape [[text] scope] text)
|
||||
|
||||
(fn forms.var [defn scope]
|
||||
(fn rvaluelist [initvals]
|
||||
(if (> (length initvals) 0)
|
||||
(.. " = " (commasep initvals #(comp.expr $1 scope)))
|
||||
""))
|
||||
(case defn
|
||||
(where [names & initvals] (list? names))
|
||||
(.. "var " (commasep names #(scope:addlocal $1)) (rvaluelist initvals))
|
||||
(where [nametyps & initvals] (kv-table? nametyps))
|
||||
(.. "var " (kvcommasep nametyps #(.. (scope:addlocal $1) " : " (comp.type $2 scope))) (rvaluelist initvals))
|
||||
[name typ initval] (.. "var " (scope:addlocal name) " : " (comp.type typ scope) " = " (comp.expr initval scope))
|
||||
[name initval] (.. "var " (scope:addlocal name) " = " (comp.expr initval scope))))
|
||||
|
||||
|
@ -214,7 +222,8 @@
|
|||
(def-infix :not= "~=")
|
||||
(fn forms.not [[expr] scope] (.. "not (" (comp.expr expr scope) ")"))
|
||||
(fn forms.set [[left right] scope]
|
||||
(.. (comp.expr left scope) " = (" (comp.expr right scope) ")"))
|
||||
(if (list? left) (.. (commasep left #(comp.expr $1 scope)) " = (" (comp.expr right scope) ")")
|
||||
(.. (comp.expr left scope) " = (" (comp.expr right scope) ")")))
|
||||
(fn forms.tset [args scope]
|
||||
(let [iright (length args)
|
||||
right (. args iright)]
|
||||
|
|
Loading…
Reference in a new issue