diff options
Diffstat (limited to 'global.lua')
-rw-r--r-- | global.lua | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/global.lua b/global.lua new file mode 100644 index 0000000..3805912 --- /dev/null +++ b/global.lua | |||
@@ -0,0 +1,141 @@ | |||
1 | --- lam.environment | ||
2 | |||
3 | local util = require "util" | ||
4 | local types = require("types") | ||
5 | |||
6 | if not table.unpack then table.unpack = unpack end | ||
7 | |||
8 | local global = { | ||
9 | -- constants | ||
10 | ["#t"] = true, | ||
11 | ["#f"] = false, | ||
12 | } | ||
13 | |||
14 | --- Types --- | ||
15 | |||
16 | for name, func in pairs(types) do | ||
17 | if name == "lamtype" then | ||
18 | global.type = func | ||
19 | else | ||
20 | global[name] = func | ||
21 | end | ||
22 | end | ||
23 | |||
24 | --- Basic functions --- | ||
25 | |||
26 | global.begin = function(...) | ||
27 | local xs = {...} | ||
28 | return xs[#xs] | ||
29 | end | ||
30 | |||
31 | global.car = util.car | ||
32 | global.cdr = util.cdr | ||
33 | |||
34 | global.list = function(...) return {...} end | ||
35 | |||
36 | --- Higher-order functions --- | ||
37 | |||
38 | global.apply = function(fn, ...) | ||
39 | local args = {...} | ||
40 | local last = args[#args] | ||
41 | assert(types.luatype(last) == "table", "Bad apply") | ||
42 | table.remove(args) | ||
43 | for _, v in ipairs(last) do | ||
44 | table.insert(args, v) | ||
45 | end | ||
46 | return fn(table.unpack(args)) | ||
47 | end | ||
48 | |||
49 | global.map = function(fn, list) | ||
50 | return util.map(fn, list) | ||
51 | end | ||
52 | |||
53 | --- Math --- | ||
54 | -- NOTE: we do not have the full numeric tower yet! | ||
55 | |||
56 | for name, func in pairs(math) do | ||
57 | global[name] = func | ||
58 | end | ||
59 | |||
60 | global["+"] = function (...) | ||
61 | return util.reduce({...}, 0, function (a, b) return a + b end) | ||
62 | end | ||
63 | |||
64 | global["-"] = function (...) | ||
65 | local args = {...} | ||
66 | if #args == 0 then | ||
67 | error("Too few arguments: need at least 1") | ||
68 | elseif #args == 1 then | ||
69 | return (-args[1]) | ||
70 | else | ||
71 | local result = args[1] | ||
72 | for v = 2, #args do | ||
73 | result = result - args[v] | ||
74 | end | ||
75 | return result | ||
76 | end | ||
77 | end | ||
78 | |||
79 | global["*"] = function (...) | ||
80 | local result = 1 | ||
81 | for _, v in ipairs({...}) do | ||
82 | if v == 0 then return 0 end | ||
83 | result = result * v | ||
84 | end | ||
85 | return result | ||
86 | end | ||
87 | |||
88 | global["/"] = function (...) | ||
89 | local args = {...} | ||
90 | if #args == 0 then | ||
91 | error("Too few arguments: need at least 1") | ||
92 | elseif #args == 1 then | ||
93 | if args[1] == 0 then error("Division by zero") end | ||
94 | return (1/args[1]) | ||
95 | else | ||
96 | local result = args[1] | ||
97 | for v = 2, #args do | ||
98 | if args[v] == 0 then error("Division by zero") end | ||
99 | result = result / args[v] | ||
100 | end | ||
101 | return result | ||
102 | end | ||
103 | end | ||
104 | |||
105 | global["="] = function (...) | ||
106 | for _, v in ipairs({...}) do | ||
107 | if not a == b then return false end | ||
108 | end | ||
109 | return true | ||
110 | end | ||
111 | |||
112 | global["<"] = function (...) | ||
113 | for _, v in ipairs({...}) do | ||
114 | if not a < b then return false end | ||
115 | end | ||
116 | return true | ||
117 | end | ||
118 | |||
119 | global["<="] = function (...) | ||
120 | for _, v in ipairs({...}) do | ||
121 | if not a <= b then return false end | ||
122 | end | ||
123 | return true | ||
124 | end | ||
125 | |||
126 | global[">"] = function (...) | ||
127 | for _, v in ipairs({...}) do | ||
128 | if not a > b then return false end | ||
129 | end | ||
130 | return true | ||
131 | end | ||
132 | |||
133 | global[">="] = function (...) | ||
134 | for _, v in ipairs({...}) do | ||
135 | if not a >= b then return false end | ||
136 | end | ||
137 | return true | ||
138 | end | ||
139 | |||
140 | --- | ||
141 | return global | ||