|
|
|
@ -32,26 +32,138 @@ are similar to m4/cpp. I'm a fan of homoiconicity, and this provides both a fami |
|
|
|
|
delightfully simple syntax. note that it doesn't actually function like a lisp under the |
|
|
|
|
hood: there's no cons, for instance. no church numerals either, so it isn't pure(tm). |
|
|
|
|
|
|
|
|
|
examples: |
|
|
|
|
demonstrative examples: |
|
|
|
|
|
|
|
|
|
<=== |
|
|
|
|
:comments are pre-processed (i.e. ignored) when the `:` character starts |
|
|
|
|
: a line. for this example page, multi-line comments will have an extra |
|
|
|
|
: space before continuation of the text. |
|
|
|
|
|
|
|
|
|
:the identifier `hello` will henceforth expand to "world" |
|
|
|
|
(def hello "world") |
|
|
|
|
|
|
|
|
|
(def hello (+ "goodbye, " hello "!!")) |
|
|
|
|
:this sets `hello`'s expansion to the following (executed in steps): |
|
|
|
|
|
|
|
|
|
: (+ "goodbye, " hello "!!") |
|
|
|
|
|
|
|
|
|
:then `hello` gets expanded to its set value, "world"... |
|
|
|
|
: (+ "goodbye, " "world" "!!") |
|
|
|
|
|
|
|
|
|
:then the `+` builtin executes, using "goodbye, ", "world", and "!!" as |
|
|
|
|
: parameters, which concatenates them |
|
|
|
|
:finally, we end up with |
|
|
|
|
: "goodbye, world!!" |
|
|
|
|
:which `hello` will henceforth expand to |
|
|
|
|
|
|
|
|
|
===> |
|
|
|
|
- |
|
|
|
|
|
|
|
|
|
<=== |
|
|
|
|
:define the identifier `spit-raw` to a lambda expansion that |
|
|
|
|
: takes one argument (`cunny`) |
|
|
|
|
(def spit-raw (lambda (cunny) |
|
|
|
|
(w "/dev/fd/1" cunny))) |
|
|
|
|
:it writes the passed argument to /dev/fd/1, a.k.a STDOUT |
|
|
|
|
|
|
|
|
|
:define another lambda expansion, this time converting |
|
|
|
|
: the parameter to a string via `conv`, then appending a |
|
|
|
|
: newline escape to the parameter and ising it to call |
|
|
|
|
: `split-raw` |
|
|
|
|
(def spit (lambda (cunny) |
|
|
|
|
(spit-raw (+ (conv string cunny) "\n")))) |
|
|
|
|
|
|
|
|
|
:a final lambda expansion, here defining `thesis` as an lambda |
|
|
|
|
: process that prints a particular string |
|
|
|
|
(def thesis (lambda () |
|
|
|
|
(spit |
|
|
|
|
"this language belongs to makise kurisu. there are many like it, but this one is hers."))) |
|
|
|
|
|
|
|
|
|
:here `thesis` gets expanded to its lambda expression, |
|
|
|
|
: which itself expands a `split` to it's lambda expression, |
|
|
|
|
: which finally expands a `spit-raw` and executes the whole |
|
|
|
|
: assembly from the ground up, printing the string to STDOUT. |
|
|
|
|
(thesis) |
|
|
|
|
===> |
|
|
|
|
this language belongs to makise kurisu. there are many like it, but this one is hers. |
|
|
|
|
|
|
|
|
|
<=== |
|
|
|
|
(def a (id "desu")) |
|
|
|
|
(spit |
|
|
|
|
("lol swej" (+ 9000 1) a)) |
|
|
|
|
:use our ability to pass code around for the creation of a recursive looping macro |
|
|
|
|
:here it counts down while expanding more copies of itself (recursion), until it |
|
|
|
|
: is fully expanded and the last `cond` returns `false`. then it executes from the |
|
|
|
|
: ground up, calling `statement` each time -- effectively calling it once for |
|
|
|
|
: each value of the counter. |
|
|
|
|
(def loop (lambda (min i statement) |
|
|
|
|
(all |
|
|
|
|
statement |
|
|
|
|
(cond (= i min) |
|
|
|
|
false |
|
|
|
|
(loop min (- i 1) (id statement)))))) |
|
|
|
|
|
|
|
|
|
:use the loop macro to define another macro executing a statementfor each item in |
|
|
|
|
: a list |
|
|
|
|
(def each |
|
|
|
|
(lambda (it action) |
|
|
|
|
(loop 0 (- (length it) 1) |
|
|
|
|
(id all |
|
|
|
|
(def item (at i it)) |
|
|
|
|
action)))) |
|
|
|
|
|
|
|
|
|
:define a modulo operation recursively |
|
|
|
|
(def % (lambda (a m) |
|
|
|
|
(cond (== m a) |
|
|
|
|
0 |
|
|
|
|
(cond (< m a) |
|
|
|
|
(% (- a m) m) |
|
|
|
|
(- a 0))))) |
|
|
|
|
===> |
|
|
|
|
|
|
|
|
|
<=== |
|
|
|
|
:call our loop macro, passing the loop range (from 0 to 100 inclusive) and the statement |
|
|
|
|
:since the statement is being called in the macro scope, `i` successfully expands |
|
|
|
|
: to the current value of the counter |
|
|
|
|
(loop 0 100 |
|
|
|
|
(id spit (cond (% i 15) (cond (% i 5) (cond (% i 3) i "fizz") "buzz") "fizzbuzz"))) |
|
|
|
|
:the statement is wrapped in a call to the id function, preventing it from being executed |
|
|
|
|
: before getting to the macro |
|
|
|
|
===> |
|
|
|
|
lol swej 9001.0 desu |
|
|
|
|
fizzbuzz |
|
|
|
|
1.0 |
|
|
|
|
2.0 |
|
|
|
|
fizz |
|
|
|
|
4.0 |
|
|
|
|
buzz |
|
|
|
|
fizz |
|
|
|
|
7.0 |
|
|
|
|
8.0 |
|
|
|
|
fizz |
|
|
|
|
buzz |
|
|
|
|
11.0 |
|
|
|
|
fizz |
|
|
|
|
13.0 |
|
|
|
|
14.0 |
|
|
|
|
fizzbuzz |
|
|
|
|
16.0 |
|
|
|
|
17.0 |
|
|
|
|
|
|
|
|
|
[...] |
|
|
|
|
|
|
|
|
|
fizz |
|
|
|
|
97.0 |
|
|
|
|
98.0 |
|
|
|
|
fizz |
|
|
|
|
buzz |
|
|
|
|
|
|
|
|
|
<=== |
|
|
|
|
(spit "how old are you? > ") |
|
|
|
|
(def age (conv number (input))) |
|
|
|
|
(spit |
|
|
|
|
(cond (> age 18) |
|
|
|
|
"adult (hag)" |
|
|
|
|
"not adult (uoh)")) |
|
|
|
|
=='9' STDIN=> |
|
|
|
|
not adult (uoh) |
|
|
|
|
:define a variable, `moeblob`, that expands to a list |
|
|
|
|
(def moeblob ("moe" "moe~" "kyun!!")) |
|
|
|
|
:iterate over said list, passing each item to a statement |
|
|
|
|
:the statement is only executed in the scope of the macro, so `item` expands to the |
|
|
|
|
: actual value of each item. since `item` is defined passing the statement to `loop`, |
|
|
|
|
: we could actually use `i` as well! |
|
|
|
|
(each moeblob |
|
|
|
|
(id spit item)) |
|
|
|
|
===> |
|
|
|
|
moe |
|
|
|
|
moe~ |
|
|
|
|
kyun!! |