Undefined function defs and if statements
This commit is contained in:
parent
eafe21c6db
commit
7560aac500
31
README.md
31
README.md
|
@ -18,15 +18,15 @@ I could maybe be persuaded to make `def` work like `fn` and optionally define a
|
|||
eh, whatever.
|
||||
|
||||
### def
|
||||
Defines a function, compiling down to the `terra` keyword.
|
||||
Defines a function, compiling down to the `terra` keyword. Can also be used to create an undefined
|
||||
function, if called with no statements.
|
||||
|
||||
Syntax:
|
||||
```fennel
|
||||
; syntax:
|
||||
(def [argname1 argtype1 argname2 argtype2... : rettype1 rettype2...] statement...)
|
||||
```
|
||||
(def [argtype1 argtype2... : rettype1 rettype2...])
|
||||
|
||||
Simple example:
|
||||
```fennel
|
||||
; examples:
|
||||
(local add (def [x int y int : int]
|
||||
(return (+ x y))))
|
||||
|
||||
|
@ -36,10 +36,31 @@ Simple example:
|
|||
; end
|
||||
|
||||
(add 1 2) ; returns 3
|
||||
|
||||
(local iseven (def [uint32 : bool]))
|
||||
(local isodd (def [n uint32 : bool]
|
||||
(if (= n 0)
|
||||
(return true)
|
||||
(return (iseven (- n 1))))))
|
||||
(iseven:adddefinition (def [n uint32 : bool]
|
||||
(if (= n 0)
|
||||
(return false)
|
||||
(return (isodd (- n 1))))))
|
||||
|
||||
; compiles to:
|
||||
; local terra iseven :: { uint32 } -> { bool }
|
||||
; local isodd = terra(n : uint32) : { bool }
|
||||
; if n == 0 then return true else return iseven(n - 1) end
|
||||
; end
|
||||
; iseven:adddefinition(terra(n : uint32) : { bool }
|
||||
; if n == 0 then return false else return isodd(n - 1) end
|
||||
; end)
|
||||
```
|
||||
|
||||
To define a function as returning "void", simply end the argument list with a `:`.
|
||||
To make terra infer the return type, do not include a `:` in the argument list at all.
|
||||
Undefined functions can't have their return types inferred.
|
||||
|
||||
Unlike Fennel, we do not implement implicit return semantics, and early returns are A-OK.
|
||||
Sorry Phil.
|
||||
|
||||
|
|
31
go.fnl
31
go.fnl
|
@ -1,22 +1,15 @@
|
|||
(local fennel (require :fennel))
|
||||
(import-macros {: def : q : ttype : static : unterra : untype} :terra)
|
||||
|
||||
(local Complex (ttype {real float imag float}))
|
||||
(print (unterra
|
||||
(def [: Complex] (return (Complex { real 5 imag 1 })))
|
||||
))
|
||||
(print (unterra
|
||||
(def [c Complex r float] (tset c :real r))
|
||||
))
|
||||
(local thing (def [: Complex] (return (Complex { real 5 imag 1 }))))
|
||||
(local get-real (def [val Complex] (return (. val :real))))
|
||||
(local set-real (def [c [Complex] r float] (tset c :real r)))
|
||||
|
||||
(let [result (thing)]
|
||||
(print result result.real result.imag (get-real result))
|
||||
(set-real result 10)
|
||||
(print (get-real result)))
|
||||
|
||||
(print (unterra
|
||||
(def [: int bool] (return 5 true))
|
||||
))
|
||||
(local iseven (def [uint32 : bool]))
|
||||
(local isodd (def [n uint32 : bool]
|
||||
(if (= n 0)
|
||||
(return true)
|
||||
(return (iseven (- n 1))))))
|
||||
(iseven:adddefinition (def [n uint32 : bool]
|
||||
(if (= n 0)
|
||||
(return false)
|
||||
(return (isodd (- n 1))))))
|
||||
(print iseven)
|
||||
(print (iseven 5) (isodd 5))
|
||||
(print (iseven 6) (isodd 6))
|
||||
|
|
20
terra.fnl
20
terra.fnl
|
@ -184,11 +184,13 @@
|
|||
(scope:with #(block :do stmts :end scope #(comp.expr $1 scope))))
|
||||
|
||||
(fn forms.def [[arglist & stmts] scope]
|
||||
(if (> (length stmts) 0)
|
||||
(scope:with #(let [(in out) (split-arglist arglist)
|
||||
argpairs (fcollect [i 1 (length in) 2] {:name (. in i) :type (. in (+ i 1))})
|
||||
rettyp (if out (.. ": { " (commasep out #(comp.type $1 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))))
|
||||
(.. "(function () local terra anonfn :: " ((. type-constructors "->") arglist scope) " return anonfn end)()")))
|
||||
|
||||
(fn forms.return [vals scope] (.. "return " (commasep vals #(comp.expr $1 scope))))
|
||||
|
||||
|
@ -220,6 +222,22 @@
|
|||
(tset forms ":" (fn [[obj field & args] scope]
|
||||
(.. (comp.expr obj scope) ":[" (scope:expr field) "](" (commasep args #(comp.expr $1 scope)) ")")))
|
||||
|
||||
(fn forms.if [params scope]
|
||||
(let [has-else? (= (% (length params) 2) 1)
|
||||
ilast (if has-else? (length params) (- (length params) 1))
|
||||
ielse (when has-else? ilast)
|
||||
clauses (fcollect [i 1 (length params) 2]
|
||||
(if (= i ielse)
|
||||
{:pre (indent :else scope)
|
||||
:post :end
|
||||
:clause (. params i)}
|
||||
{:pre (.. (if (= i 1) :if (indent :elseif scope)) " " (comp.expr (. params i) scope) " then")
|
||||
:post (if (= i ilast) :end "")
|
||||
:clause (. params (+ i 1))}))
|
||||
blocks (icollect [_ clause (ipairs clauses)]
|
||||
(scope:with #(block clause.pre [clause.clause] clause.post scope #(comp.expr $1 scope))))]
|
||||
(table.concat blocks "\n")))
|
||||
|
||||
(fn comp.quote [stmts scope]
|
||||
(if (= (length stmts) 1) (.. "`(" (comp.expr (. stmts 1) scope) ")")
|
||||
(.. "quote\n" (commasep stmts #(comp.expr $1 scope)) "\nend")))
|
||||
|
|
Loading…
Reference in a new issue