Fix function pointer syntax, booleans, return multivals
This commit is contained in:
parent
8e6a04536a
commit
eafe21c6db
43
README.md
43
README.md
|
@ -102,13 +102,14 @@ auto-convert `-` to `_` at least.
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Function pointers
|
#### Function pointers
|
||||||
Function pointer types are defined with the `->` form, which accepts two arguments - a sequence
|
Function pointer types are defined with the `->` form, which a variable number of types as arguments.
|
||||||
of types representing the input parameter types, and a sequence of types representing the return
|
Similar to `def`, you can put a `:` in your argument list to delineate between input parameters and
|
||||||
value. Actually this kind of sucks, I think we should use the same syntax as `def`. I'll probably
|
output types. Unlike `def`, if no `:` is present it is assumed that the function does not return a value,
|
||||||
change this. But this is how it works right now:
|
as inference is not possible.
|
||||||
|
|
||||||
```fennel
|
```fennel
|
||||||
(local callback (ttype (-> [[int] int] [int]))) ; compiles to: local callback = { &int, int } -> { int }
|
(local callback (ttype (-> [int] int : int))) ; compiles to: local callback = { &int, int } -> { int }
|
||||||
|
(local callback (ttype (-> float))) ; compiles to: local callback = { float } -> {}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Tuples
|
#### Tuples
|
||||||
|
@ -135,17 +136,6 @@ it consistently mean "create a quote" everywhere. Not sure.)
|
||||||
|
|
||||||
### Terra syntax
|
### Terra syntax
|
||||||
|
|
||||||
#### Pointers and arrays
|
|
||||||
Dereferencing a pointer or accessing an element in an array uses the same syntax as defining a pointer
|
|
||||||
or array type - the Fennel sequence literal. To take a reference to a value, you can use the `&` form.
|
|
||||||
|
|
||||||
```fennel
|
|
||||||
(def [ptr [int]] (return [ptr])) ; compiles to: terra (ptr : &int) return @ptr end
|
|
||||||
(def [arr [int 8]] (return [arr 5])) ; compiles to: terra (arr : int[8]) return arr[5] end
|
|
||||||
(def [nested [[int]]] (return [nested 0 3])) ; compiles to: terra (nested : &&int) return nested[0][3] end
|
|
||||||
(def [ptr [int] : [int]] (return (& [ptr 1]))) ; compiles to: terra (ptr : &int): &int return &ptr[1] end
|
|
||||||
```
|
|
||||||
|
|
||||||
#### var
|
#### var
|
||||||
```fennel
|
```fennel
|
||||||
(var name initial-value) ; compiles to: var name = initial-value
|
(var name initial-value) ; compiles to: var name = initial-value
|
||||||
|
@ -162,6 +152,18 @@ syntax for _not_ initalizing the variable on declaration.
|
||||||
(tset struct (getfield) value) ; compiles to: struct.[getfield()] = value
|
(tset struct (getfield) value) ; compiles to: struct.[getfield()] = value
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Pointers and arrays
|
||||||
|
Dereferencing a pointer or accessing an element in an array uses the same syntax as defining a pointer
|
||||||
|
or array type - the Fennel sequence literal. To take a reference to a value, you can use the `&` form.
|
||||||
|
|
||||||
|
```fennel
|
||||||
|
(def [ptr [int]] (return [ptr])) ; compiles to: terra (ptr : &int) return @ptr end
|
||||||
|
(def [arr [int 8]] (return [arr 5])) ; compiles to: terra (arr : int[8]) return arr[5] end
|
||||||
|
(def [nested [[int]]] (return [nested 0 3])) ; compiles to: terra (nested : &&int) return nested[0][3] end
|
||||||
|
(def [nested [[int]]] (return [[nested] 3])) ; compiles to: terra (nested : &&int) return (@nested)[3] end
|
||||||
|
(def [ptr [int] : [int]] (return (& [ptr 1]))) ; compiles to: terra (ptr : &int): &int return &ptr[1] end
|
||||||
|
```
|
||||||
|
|
||||||
#### field access
|
#### field access
|
||||||
```fennel
|
```fennel
|
||||||
struct.field ; compiles to: struct.field
|
struct.field ; compiles to: struct.field
|
||||||
|
@ -229,4 +231,13 @@ type.
|
||||||
| `(<< x y)` | `x << y` | arithmetic shift x left by y bits |
|
| `(<< x y)` | `x << y` | arithmetic shift x left by y bits |
|
||||||
| `(>> x y)` | `x >> y` | arithmetic shift x right by y bits |
|
| `(>> x y)` | `x >> y` | arithmetic shift x right by y bits |
|
||||||
|
|
||||||
|
#### return
|
||||||
|
Terra functions can return multiple values, or none. Returns must be explicitly
|
||||||
|
written with the `return` form.
|
||||||
|
|
||||||
|
```fennel
|
||||||
|
(def [: int] (return 5)) ; compiles to: terra (): { int } return 5 end
|
||||||
|
(def [: float float] (return -1.5 1.5)) ; compiles to: terra (): { float float } return -1.5, 1.5 end
|
||||||
|
```
|
||||||
|
|
||||||
#### Fennel escaping
|
#### Fennel escaping
|
||||||
|
|
4
go.fnl
4
go.fnl
|
@ -16,3 +16,7 @@
|
||||||
(print result result.real result.imag (get-real result))
|
(print result result.real result.imag (get-real result))
|
||||||
(set-real result 10)
|
(set-real result 10)
|
||||||
(print (get-real result)))
|
(print (get-real result)))
|
||||||
|
|
||||||
|
(print (unterra
|
||||||
|
(def [: int bool] (return 5 true))
|
||||||
|
))
|
||||||
|
|
41
terra.fnl
41
terra.fnl
|
@ -59,7 +59,7 @@
|
||||||
result)
|
result)
|
||||||
:expr (fn [self expr]
|
:expr (fn [self expr]
|
||||||
(if (and (sym? expr) (not (multi-sym? expr))) (self:env-ref expr)
|
(if (and (sym? expr) (not (multi-sym? expr))) (self:env-ref expr)
|
||||||
(= (type expr) :number) (tostring expr)
|
(or (= (type expr) :number) (= (type expr) :boolean)) (tostring expr)
|
||||||
(= expr nil) :nil
|
(= expr nil) :nil
|
||||||
(let [name (safesym :inline-expr)
|
(let [name (safesym :inline-expr)
|
||||||
arglist (sequence)
|
arglist (sequence)
|
||||||
|
@ -113,7 +113,7 @@
|
||||||
(where symbol (sym? symbol))
|
(where symbol (sym? symbol))
|
||||||
(scope:reference symbol)
|
(scope:reference symbol)
|
||||||
|
|
||||||
(where lit (or (= (type lit) :string) (= (type lit) :number) (= (type lit) :nil)))
|
(where lit (or (= (type lit) :string) (= (type lit) :number) (= (type lit) :nil) (= (type lit) :boolean)))
|
||||||
(scope:expr lit)
|
(scope:expr lit)
|
||||||
|
|
||||||
_ (error (.. "Failed to parse expression: " (view form)))))
|
_ (error (.. "Failed to parse expression: " (view form)))))
|
||||||
|
@ -152,13 +152,29 @@
|
||||||
|
|
||||||
_ (error (.. "Invalid field name: " (view name)))))
|
_ (error (.. "Invalid field name: " (view name)))))
|
||||||
|
|
||||||
|
(fn find-ival [tbl pred]
|
||||||
|
(var ival nil)
|
||||||
|
(each [i val (ipairs tbl)]
|
||||||
|
(when (pred val) (set ival i)))
|
||||||
|
ival)
|
||||||
|
|
||||||
|
(fn split-arglist [arglist]
|
||||||
|
(let [iarg-return-sep (find-ival arglist #(and (sym? $1) (= (tostring $1) ":")))
|
||||||
|
in (icollect [i arg (ipairs arglist) &until (= i iarg-return-sep)] arg)
|
||||||
|
out (when (not= iarg-return-sep nil) (icollect [i arg (ipairs arglist)] (when (> i iarg-return-sep) arg)))]
|
||||||
|
(values in out)))
|
||||||
|
|
||||||
(fn arglist-type [arglist scope] (.. "{ " (commasep (or arglist []) #(comp.type $1 scope)) " }"))
|
(fn arglist-type [arglist scope] (.. "{ " (commasep (or arglist []) #(comp.type $1 scope)) " }"))
|
||||||
(tset type-constructors :-> (fn [[in out] scope] (.. (arglist-type in scope) " -> " (arglist-type out scope))))
|
(tset type-constructors :-> (fn [argtyps scope]
|
||||||
|
(let [(in out) (split-arglist argtyps)]
|
||||||
|
(.. (arglist-type in scope) " -> " (arglist-type (or out []) scope)))))
|
||||||
(tset type-constructors :& (fn [[typ] scope] (.. :& (comp.type typ scope))))
|
(tset type-constructors :& (fn [[typ] scope] (.. :& (comp.type typ scope))))
|
||||||
(tset type-constructors :$ (fn [typs scope] (.. "tuple(" (commasep typs #(comp.type $1 scope)) ")")))
|
(tset type-constructors :$ (fn [typs scope] (.. "tuple(" (commasep typs #(comp.type $1 scope)) ")")))
|
||||||
(fn type-constructors.unquote [[expr] scope] (scope:expr expr))
|
(fn type-constructors.unquote [[expr] scope] (scope:expr expr))
|
||||||
|
|
||||||
(fn forms.rawterra [[text] scope] text)
|
(fn forms.raw-escape [[text] scope] text)
|
||||||
|
(fn type-constructors.raw-escape [[text] scope] text)
|
||||||
|
|
||||||
(fn forms.var [defn scope]
|
(fn forms.var [defn scope]
|
||||||
(case defn
|
(case defn
|
||||||
[name typ initval] (.. "var " (scope:addlocal name) " : " (comp.type typ scope) " = " (comp.expr initval scope))
|
[name typ initval] (.. "var " (scope:addlocal name) " : " (comp.type typ scope) " = " (comp.expr initval scope))
|
||||||
|
@ -167,22 +183,15 @@
|
||||||
(fn forms.do [stmts scope]
|
(fn forms.do [stmts scope]
|
||||||
(scope:with #(block :do stmts :end scope #(comp.expr $1 scope))))
|
(scope:with #(block :do stmts :end scope #(comp.expr $1 scope))))
|
||||||
|
|
||||||
(fn find-ival [tbl pred]
|
|
||||||
(var ival nil)
|
|
||||||
(each [i val (ipairs tbl)]
|
|
||||||
(when (pred val) (set ival i)))
|
|
||||||
ival)
|
|
||||||
|
|
||||||
(fn forms.def [[arglist & stmts] scope]
|
(fn forms.def [[arglist & stmts] scope]
|
||||||
(scope:with #(let [iarg-return-sep (find-ival arglist #(and (sym? $1) (= (tostring $1) ":")))
|
(scope:with #(let [(in out) (split-arglist arglist)
|
||||||
argpairs (fcollect [i 1 (length arglist) 2 &until (= i iarg-return-sep)]
|
argpairs (fcollect [i 1 (length in) 2] {:name (. in i) :type (. in (+ i 1))})
|
||||||
{:name (. arglist i) :type (. arglist (+ i 1))})
|
rettyp (if out (.. ": { " (commasep out #(comp.type $1 scope)) " }") "")
|
||||||
rettyps (when iarg-return-sep (icollect [i typ (ipairs arglist)] (when (> i iarg-return-sep) typ)))
|
|
||||||
rettyp (if rettyps (.. ": { " (commasep rettyps #(comp.type $1 scope)) " }") "")
|
|
||||||
argdefs (commasep argpairs #(.. (scope:addlocal $1.name) " : " (comp.type $1.type scope)))]
|
argdefs (commasep argpairs #(.. (scope:addlocal $1.name) " : " (comp.type $1.type scope)))]
|
||||||
(block (.. "terra (" argdefs ")" rettyp) stmts :end scope #(comp.expr $1 scope)))))
|
(block (.. "terra (" argdefs ")" rettyp) stmts :end scope #(comp.expr $1 scope)))))
|
||||||
|
|
||||||
(fn forms.return [[expr] scope] (.. "return " (comp.expr expr scope)))
|
(fn forms.return [vals scope] (.. "return " (commasep vals #(comp.expr $1 scope))))
|
||||||
|
|
||||||
(fn forms.cast [[typ expr] scope]
|
(fn forms.cast [[typ expr] scope]
|
||||||
(.. "([" (comp.type typ scope)"](" (comp.expr expr scope) "))"))
|
(.. "([" (comp.type typ scope)"](" (comp.expr expr scope) "))"))
|
||||||
(fn forms.unquote [[expr] scope] (.. "([" (scope:expr expr) "])"))
|
(fn forms.unquote [[expr] scope] (.. "([" (scope:expr expr) "])"))
|
||||||
|
|
Loading…
Reference in a new issue