-
Notifications
You must be signed in to change notification settings - Fork 0
operators
You can define your own prefix, infix and postfix operators. Here's an example I've already added to the preamble:
fn factorial (n) {
let
fn h {
(0, a) { a }
(n, a) { h(n - 1, n * a) }
}
in
h(n, 1)
}
postfix 120 "!" factorial;
and an example:
$ ./cekf --exec='print 100!'
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
because every language should have a postfix factorial operator!
I've also removed special treatment for @
, @@
, prefix <
and prefix >
from the parser and put them
in the preamble as
infix right 90 "@" cons;
infix right 80 "@@" append;
prefix 55 "<" car;
prefix 55 ">" cdr;
The syntax is pretty self explanatory I think, the number is precedence and I'll need to document
the precedence of the core operators when they settle down but for now you can look in
src/pratt_parser.c
.
The quoted operator can be anything that doesn't include whitespace and doesn't start with a digit or an
open or close parenthesis (Unicode general category "Ps" or "Pe").
The semantics are also pretty self-evident, for example a @ b
gets transformed to cons(a, b)
so the
cons
in the infix declaration is just an expression that gets applied to its (two) arguments. Anything
that works in the place of a function can be used, specifically type constructors, macros and anonymous functions.
A few caveats:
- You can't redefine an existing operator with the same fixity.
- Because of the way parsing works you can't declare the same operator as both infix and postfix (the other two combinations, prefix-infix and prefix-postfix are fine).
- If you define an operator with the same name as an existing function it will mask the function (but can still be used as an operator).
- Because operator rewriting is a purely textual replacement at the point of use, the replacement will pick up whatever definition is current when the operator is invoked. This is more of a bug than a feature to be honest, and I'd very much like to fix it.
Next: Macros
CEKF(s) a.k.a. F Natural a.k.a F♮