diff options
Diffstat (limited to 'core.lua')
-rw-r--r-- | core.lua | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/core.lua b/core.lua new file mode 100644 index 0000000..e8ad42b --- /dev/null +++ b/core.lua | |||
@@ -0,0 +1,75 @@ | |||
1 | --- lam.core --- core procedures | ||
2 | |||
3 | local m = {} | ||
4 | local type = require "type" | ||
5 | local isa, null = type.isa, type.null | ||
6 | local math = math | ||
7 | |||
8 | local function fold (kons, knil, r) | ||
9 | if r == null then | ||
10 | return knil | ||
11 | else | ||
12 | local step, early_return = kons(r[1], knil) | ||
13 | if early_return then return step end | ||
14 | return fold(kons, step, r[2]) | ||
15 | end | ||
16 | end | ||
17 | |||
18 | m.env = { -- all functions here take R, which is the list of arguments | ||
19 | ------- numbers | ||
20 | ["number?"] = function (r) return isa(r[1], "number") end, | ||
21 | ["="] = | ||
22 | function (r) | ||
23 | local function go (a, b) | ||
24 | if a ~= b then return false, 1 end | ||
25 | return b | ||
26 | end | ||
27 | return fold(go, r[1], r[2]) and true | ||
28 | end, | ||
29 | ["<"] = | ||
30 | function (r) | ||
31 | local function go (a, b) | ||
32 | if a >= b then return false, 1 end | ||
33 | return b | ||
34 | end | ||
35 | return fold(go, r[1], r[2]) and true | ||
36 | end, | ||
37 | [">"] = | ||
38 | function (r) | ||
39 | local function go (a, b) | ||
40 | if a <= b then return false, 1 end | ||
41 | return b | ||
42 | end | ||
43 | return fold(go, r[1], r[2]) and true | ||
44 | end, | ||
45 | ["<="] = function (r) return not m.env[">"](r) end, | ||
46 | [">="] = function (r) return not m.env["<"](r) end, | ||
47 | ------- math | ||
48 | ["+"] = | ||
49 | function (r) | ||
50 | return fold(function (a, b) return a + b end, 0, r) | ||
51 | end, | ||
52 | ["-"] = | ||
53 | function (r) | ||
54 | if r == null then return -1 end | ||
55 | if r[2] == null then return (- r[1]) end | ||
56 | return fold(function (a, b) return a-b end, r[1], r[2]) | ||
57 | end, | ||
58 | ["*"] = | ||
59 | function (r) | ||
60 | local function go (a, b) | ||
61 | if a == 0 or b == 0 then return 0, 1 end | ||
62 | return a * b | ||
63 | end | ||
64 | return fold(go, 1, r) | ||
65 | end, | ||
66 | ["/"] = | ||
67 | function (r) | ||
68 | if r == null then error("Wrong arity") end | ||
69 | if r[2] == null then return (1 / r[1]) end | ||
70 | return fold(function (a, b) return a/b end, r[1], r[2]) | ||
71 | end, | ||
72 | } | ||
73 | |||
74 | -------- | ||
75 | return m | ||