Escaping assignment, more docs, fix not
This commit is contained in:
parent
128224a97a
commit
8e6a04536a
95
README.md
95
README.md
|
@ -44,12 +44,11 @@ Unlike Fennel, we do not implement implicit return semantics, and early returns
|
|||
Sorry Phil.
|
||||
|
||||
### q
|
||||
Defines a terra quotation, compiling down to the ` `` ` operator if given one argument, and
|
||||
Defines a terra quotation, compiling down to the `` ` `` operator if given one argument, and
|
||||
`quote` / `end` if given more than one.
|
||||
|
||||
```fennel
|
||||
(fn inc [x] (q (+ x 1))) ; compiles to: function(x) `(x + 1) end
|
||||
|
||||
```
|
||||
|
||||
### Type syntax
|
||||
|
@ -125,7 +124,7 @@ a function call, but there is a shortened form using `$` to match the tuple inst
|
|||
#### Escaping
|
||||
Arbitrary Fennel expressions can be evaluated in a type-compilation context using Fennel's `,` prefix,
|
||||
which is normally used by macros. If you need to re-enter a type-compilation context after escaping,
|
||||
you'll need to nest a call to `ttype`. (I'm considering using ` `` ` for this purpose, but I might have
|
||||
you'll need to nest a call to `ttype`. (I'm considering using `` ` `` for this purpose, but I might have
|
||||
it consistently mean "create a quote" everywhere. Not sure.)
|
||||
|
||||
```fennel
|
||||
|
@ -136,6 +135,17 @@ it consistently mean "create a quote" everywhere. Not sure.)
|
|||
|
||||
### 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
|
||||
```fennel
|
||||
(var name initial-value) ; compiles to: var name = initial-value
|
||||
|
@ -145,13 +155,78 @@ Define a local variable named `var`, and set its initial value to `initial-value
|
|||
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.
|
||||
|
||||
#### 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.
|
||||
#### assignment
|
||||
```fennel
|
||||
(set varname value) ; compiles to: varname = value
|
||||
(set struct.field value) ; compiles to: struct.field = value
|
||||
(tset struct (getfield) value) ; compiles to: struct.[getfield()] = value
|
||||
```
|
||||
|
||||
#### field access
|
||||
```fennel
|
||||
struct.field ; compiles to: struct.field
|
||||
(struct.func) ; compiles to: struct.func()
|
||||
(obj:method) ; compiles to: obj:method()
|
||||
(. struct (getfield)) ; compiles to: struct.[getfield()]
|
||||
(: obj (getmethod)) ; compiles to: struct:[getmethod()]()
|
||||
```
|
||||
|
||||
#### cast
|
||||
```fennel
|
||||
(cast type expr)
|
||||
```
|
||||
Cast an expression `expr` to the type `type`.
|
||||
|
||||
```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 [])
|
||||
(cast [int] voidptr) ; compiles to: ([&int]voidptr)
|
||||
(cast [int8] (C.malloc (* (sizeof int8) 16))) ; compiles to: ([&int8]C.malloc(sizeof(int8) * 16))
|
||||
```
|
||||
|
||||
#### tuple literal
|
||||
`$` can be used to create a tuple.
|
||||
|
||||
```fennel
|
||||
($ 5 2.5 :hello) ; compiles to: { 5, 2.5, "hello" }
|
||||
(var pair ($ int int) ($ 5 10)) ; compiles to: var pair : { int, int } = { 5, 10 }
|
||||
```
|
||||
|
||||
#### struct literal
|
||||
A fennel key-value table literal is interpreted as an anonymous struct literal.
|
||||
If you "call" a struct type with a struct literal, it will coerce it to the given
|
||||
type.
|
||||
|
||||
```fennel
|
||||
(local Complex (ttype {real float imag float}))
|
||||
; compiles to:
|
||||
; local Complex = struct { real : float, imag : float }
|
||||
|
||||
(def [: Complex] (return (Complex { real 5 imag 1 })))
|
||||
; compiles to:
|
||||
; terra (): Complex
|
||||
; return Complex({ real = 5, imag = 1 })
|
||||
; end
|
||||
```
|
||||
|
||||
#### Primitive operators
|
||||
|
||||
| Fennel | Terra | Meaning |
|
||||
| ------------ | ------------ | ----------------------------------- |
|
||||
| `(+ x y)` | `x + y` | add x and y |
|
||||
| `(- x y)` | `x - y` | subtract y from x |
|
||||
| `(/ x y)` | `x / y` | divide x by y |
|
||||
| `(* x y)` | `x * y` | multiply x and y |
|
||||
| `(% x y)` | `x % y` | x modulo y |
|
||||
| `(< x y)` | `x < y` | x is less than y |
|
||||
| `(<= x y)` | `x <= y` | x is less than or equal to y |
|
||||
| `(= x y)` | `x == y` | x is equal to y |
|
||||
| `(not= x y)` | `x ~= y` | x is not equal to y |
|
||||
| `(> x y)` | `x > y` | x is greater than y |
|
||||
| `(>= x y)` | `x >= y` | x is greater than or equal to y |
|
||||
| `(and x y)` | `x and y` | x AND y (boolean or bitwise) |
|
||||
| `(or x y)` | `x or y` | x OR y (boolean or bitwise) |
|
||||
| `(not x)` | `not x` | NOT x (boolean or bitwise) |
|
||||
| `(^ x y)` | `x ^ y` | x XOR y (bitwise) |
|
||||
| `(<< x y)` | `x << y` | arithmetic shift x left by y bits |
|
||||
| `(>> x y)` | `x >> y` | arithmetic shift x right by y bits |
|
||||
|
||||
#### Fennel escaping
|
||||
|
|
31
go.fnl
31
go.fnl
|
@ -1,23 +1,18 @@
|
|||
(local fennel (require :fennel))
|
||||
(import-macros {: def : q : ttype : static : unterra : untype} :terra)
|
||||
|
||||
(local N (static int 5))
|
||||
(print N)
|
||||
(fn inc [x]
|
||||
(print "calling inc" x)
|
||||
(q (+ ,x 1)))
|
||||
|
||||
(local Complex (ttype {real float imag float}))
|
||||
(print (unterra
|
||||
(def [x int]
|
||||
(set N (+ N x))
|
||||
(return N))))
|
||||
(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)))
|
||||
|
||||
(local addN (def [x int]
|
||||
(set N (+ N x))
|
||||
(return N)))
|
||||
|
||||
(print addN)
|
||||
(print (N:get) (addN 3) (N:get))
|
||||
|
||||
; (local inc (def [x [int]] (return [x N])))
|
||||
; (print (inc 5))
|
||||
(let [result (thing)]
|
||||
(print result result.real result.imag (get-real result))
|
||||
(set-real result 10)
|
||||
(print (get-real result)))
|
||||
|
|
14
terra.fnl
14
terra.fnl
|
@ -193,13 +193,23 @@
|
|||
(fn def-infix [fnlop luaop]
|
||||
(tset forms fnlop (fn [[left right] scope]
|
||||
(.. "(" (comp.expr left scope) " " luaop " " (comp.expr right scope) ")"))))
|
||||
(each [_ op (ipairs [:+ :- :* :/ :% :< :<= :> :>= :and :or :not :^ :<< :>>])]
|
||||
(each [_ op (ipairs [:+ :- :* :/ :% :< :<= :> :>= :and :or :^ :<< :>>])]
|
||||
(def-infix op op))
|
||||
(def-infix := :==)
|
||||
(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) ")"))
|
||||
(fn forms.tset [args scope]
|
||||
(let [iright (length args)
|
||||
right (. args iright)]
|
||||
(tset args iright nil)
|
||||
(.. ((. forms ".") args scope) " = (" (comp.expr right scope) ")")))
|
||||
|
||||
(tset forms "." (fn [[struct & fields] scope]
|
||||
(.. (comp.expr struct scope) (commasep fields #(.. ".[" (scope:expr $1) "]") ""))))
|
||||
(tset forms ":" (fn [[obj field & args] scope]
|
||||
(.. (comp.expr obj scope) ":[" (scope:expr field) "](" (commasep args #(comp.expr $1 scope)) ")")))
|
||||
|
||||
(fn comp.quote [stmts scope]
|
||||
(if (= (length stmts) 1) (.. "`(" (comp.expr (. stmts 1) scope) ")")
|
||||
|
|
Loading…
Reference in a new issue