Compare commits

..

9 Commits

  1. 22
      lib.py
  2. 1
      lib/aids.klambda
  3. 20
      lib/kokoro.klambda
  4. 6
      lib/math.klambda
  5. 138
      readme.txt
  6. 6
      test.klambda

@ -3,7 +3,7 @@
# t. cirno
def execute(program):
import traceback, copy
import traceback, copy, sys
from functools import reduce
def _execute(ctx, ids):
import sys, functools
@ -62,11 +62,16 @@ def execute(program):
subs = _fixarr(list(map(lambda a: _execute(a, lids), ctx)))
if ctx[0][1][0] == "$":
return subs
if ctx[0][1][0] == ".":
return _execute(subs[1:], lids)
elif ctx[0] == _ident("miracle"):
return _box(getattr(eval(_destr(subs[1])), _destr(subs[2]))(*[(i if type(i) == type([]) else i[1]) for i in _fixarr(subs[3])]))
elif ctx[0] == _ident("r"):
return ("string", open(_destr(subs[1]), "r").read(int(subs[2][1])))
elif ctx[0] == _ident("w"):
open(_destr(subs[1]), "w").write(_destr(subs[2]))
return subs[2]
elif ctx[0] == _ident("def"):
ids[ctx[1]] = subs[2]
return ids[ctx[1]]
@ -78,8 +83,6 @@ def execute(program):
return reduce(lambda a, b: (a[0], a[1]*b[1]), subs[1:])
elif ctx[0] == _ident("/"):
return reduce(lambda a, b: (a[0], a[1]/b[1]), subs[1:])
elif ctx[0] == _ident("%"):
return (subs[1][0], subs[1][1]%subs[2][1])
elif ctx[0] == _ident("=="):
return ("number", 1.0 if subs[1] == subs[2] else 0.0)
elif ctx[0] == _ident("="):
@ -89,6 +92,13 @@ def execute(program):
elif ctx[0] == _ident("<"):
return ("number", 1.0 if subs[1][1] < subs[2][1] else 0.0)
elif ctx[0] == _ident("conv"):
if subs[1][1] == "number":
return (subs[1][1], float(subs[2][1]))
elif subs[1][1] == "string":
return (subs[1][1], str(subs[2][1] if not isinstance(subs[2], list) else subs[2]))
elif subs[1][1] == "identifier":
return (subs[1][1], str(subs[2][1]))
return (subs[1][1], float(subs[2][1]) if subs[1][1] == "number" else str(subs[2][1]))
elif ctx[0] == _ident("all"):
ret = _execute(subs[1], lids)
@ -115,6 +125,8 @@ def execute(program):
return list(
map(lambda a: _execute(a, lids), ctx)
)
elif ctx[0] == "string":
return (ctx[0], ctx[1].replace('\\n', '\n').replace('\\t', '\t'))
return ctx
idspace = {}

@ -6,3 +6,4 @@ INCLUDE:./lists.klambda
INCLUDE:./kokoro.klambda
INCLUDE:./booleans.klambda
INCLUDE:./string.klambda
INCLUDE:./math.klambda

@ -1,11 +1,19 @@
INCLUDE:./loop.klambda
(def spit-raw (lambda (cunny)
(w "/dev/fd/1" cunny)))
(def spit (lambda (cunny)
(miracle
"__import__('builtins')" "print" (id cunny))))
(spit-raw (+ (conv string cunny) "\n"))))
(def prettyspit-lst (lambda (lst-cunny)
(each lst-cunny
(id spit-raw (+ (conv string item) " ")))))
(def input (lambda ()
(miracle
"__import__('builtins')" "input" (""))))
(r "/dev/fd/0" 20)))
(def thesis (lambda ()
(spit
("this language belongs to makise kurisu. there are many like it, but this one is hers."))))
DEFINE:<3:(thesis)
"this language belongs to makise kurisu. there are many like it, but this one is hers.")))
(def <3 thesis)

@ -0,0 +1,6 @@
(def % (lambda (a m)
(cond (== m a)
0
(cond (< m a)
(% (- a m) m)
(- a 0)))))

@ -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!!

@ -1,12 +1,12 @@
INCLUDE:./lib/aids.klambda
(def a (id (id "desu")))
(spit
(prettyspit-lst
("lol swej" (+ 9000 1) a))
(spit (cond (= "10" (+ 1 9)) "same" "not same"))
(cond ("", (+ 0 1))
(id spit "one")
(id spit "zero"))
(spit "one")
(spit "zero"))
(spit "how old are you? > ")
(def age (conv number (input)))

Loading…
Cancel
Save