Last active 18 hours ago

capitalex's Avatar capitalex revised this gist 18 hours ago. Go to revision

1 file changed, 179 insertions

dsl3.lua(file created)

@@ -0,0 +1,179 @@
1 + local function eval (prog, env)
2 + local env = env or {}
3 + local last
4 + for _, fn in ipairs (prog) do
5 + last = fn (env)
6 + end
7 + return last
8 + end
9 +
10 + local function force (env)
11 + return function (x)
12 + if type (x) == "function" then
13 + x = x (env)
14 + end
15 + return x
16 + end
17 + end
18 +
19 + local function keywords_for (apply)
20 + return function (word_list)
21 + local keywords = {}
22 + for _, word in ipairs (word_list) do
23 + keywords[word] = apply
24 + end
25 + return setmetatable (keywords, {__call = function (t, ...)
26 + return apply(...)
27 + end})
28 + end
29 + end
30 +
31 + local function default (apply)
32 + return function (operations)
33 + return setmetatable (operations, {__call = function (t, ...)
34 + return apply (...)
35 + end})
36 + end
37 + end
38 +
39 + local function let (var)
40 + local _let = function (val)
41 + return function (env)
42 + env[force (env) (var)] = force (env) (val)
43 + end
44 + end
45 + return keywords_for (_let) { "equal", "be" }
46 + end
47 +
48 + local function get (var)
49 + return function (env)
50 + return env[force (env) (var)]
51 + end
52 + end
53 +
54 + local function add (x)
55 + local _add = function (y)
56 + return function (env)
57 + return force (env) (x) + force (env) (y)
58 + end
59 + end
60 + return keywords_for (_add) { "to", "with" }
61 + end
62 +
63 + local function subtract (x)
64 + local _sub = function (y)
65 + return function (env)
66 + return force (env) (x) - force (env) (y)
67 + end
68 + end
69 +
70 + return default (_sub) {
71 + from = function (y)
72 + return function (env)
73 + return force (env) (y) - force (env) (x)
74 + end
75 + end,
76 +
77 + with = _sub
78 + }
79 + end
80 +
81 + local function show (val)
82 + local _show = function (env)
83 + print (force (env) (val))
84 + end
85 +
86 + return _show
87 + end
88 +
89 + local function is (a)
90 + local _equals = function (b)
91 + return function (env)
92 + return force (env) (a) == force (env) (b)
93 + end
94 + end
95 +
96 + return default (_equals) {
97 + greater_than = function (b)
98 + return function (env)
99 + return force (env) (a) > force (env) (b)
100 + end
101 + end,
102 + less_than = function (b)
103 + return function (env)
104 + return force (env) (a) < force (env) (b)
105 + end
106 + end,
107 + }
108 + end
109 +
110 + local function when (cond)
111 + local _when_true = function (when_true)
112 + local _when_false = function (when_false)
113 + return function (env)
114 + if force (env) (cond) then
115 + return eval (when_true, env)
116 + else
117 + return eval (when_false, env)
118 + end
119 + end
120 + end
121 + return { otherwise = _when_false }
122 + end
123 + return _when_true
124 + end
125 +
126 + local function seed_rand ()
127 + math.randomseed (os.time ())
128 + end
129 +
130 + local function rand ()
131 + return math.random ()
132 + end
133 +
134 + local function return_with (value)
135 + return function (env)
136 + return value
137 + end
138 + end
139 +
140 + local function define (name)
141 + return function (bindings)
142 + return function (body)
143 + return function (env)
144 + env[force (env) (name)] = { bindings, body }
145 + end
146 + end
147 + end
148 + end
149 +
150 + local function call (name)
151 + return function (args)
152 + return function (env)
153 + local call_env = setmetatable({}, {__index = env})
154 + local bindings, body = env[name][1], env[name][2]
155 + for i, binding in ipairs (bindings) do
156 + call_env[binding] = force (env) (args[i])
157 + end
158 + return eval (body, call_env)
159 + end
160 + end
161 + end
162 +
163 + print
164 + eval {
165 + define "fib" { "n" } {
166 + when (is (get "n") .less_than (1)) {
167 + return_with (0) ;
168 + } .otherwise {
169 + when (is (get "n") (1)) {
170 + return_with (1)
171 + } .otherwise {
172 + let "n1" .equal (subtract (1) .from (get "n")) ;
173 + let "n2" .equal (subtract (2) .from (get "n")) ;
174 + add (call "fib" {get "n1"}) .with (call "fib" {get "n2"}) ;
175 + }
176 + }
177 + } ;
178 + show (call "fib" { 10 }) ;
179 + }

capitalex's Avatar capitalex revised this gist 1 day ago. Go to revision

1 file changed, 6 insertions, 1 deletion

dsl2.lua

@@ -106,6 +106,10 @@ local function when (cond)
106 106 return _when
107 107 end
108 108
109 + local function seed_rand ()
110 + math.randomseed (os.time ())
111 + end
112 +
109 113 local function rand ()
110 114 return math.random ()
111 115 end
@@ -116,8 +120,9 @@ local function return_with (value)
116 120 end
117 121 end
118 122
119 - math.randomseed (os.time ())
123 +
120 124 eval {
125 + seed_rand ;
121 126 show (
122 127 when (is (rand) .greater_than (0.5)) {
123 128 show "Wow! The value was..." ;

capitalex's Avatar capitalex revised this gist 1 day ago. Go to revision

1 file changed, 130 insertions

dsl2.lua(file created)

@@ -0,0 +1,130 @@
1 + local function eval (prog, env)
2 + local env = env or {}
3 + local last
4 + for _, fn in ipairs (prog) do
5 + last = fn (env)
6 + end
7 + return last
8 + end
9 +
10 + local function force (env)
11 + return function (x)
12 + if type (x) == "function" then
13 + x = x (env)
14 + end
15 + return x
16 + end
17 + end
18 +
19 + local function keywords_for (apply)
20 + return function (word_list)
21 + local keywords = {}
22 + for _, word in ipairs (word_list) do
23 + keywords[word] = apply
24 + end
25 + return setmetatable (keywords, {__call = function (t, ...)
26 + return apply(...)
27 + end})
28 + end
29 + end
30 +
31 + local function default (apply)
32 + return function (operations)
33 + return setmetatable (operations, {__call = function (t, ...)
34 + return apply (...)
35 + end})
36 + end
37 + end
38 +
39 + local function let (var)
40 + local _let = function (val)
41 + return function (env)
42 + env[force (env) (var)] = force (env) (val)
43 + end
44 + end
45 + return keywords_for (_let) { "equal", "be" }
46 + end
47 +
48 + local function get (var)
49 + return function (env)
50 + return env[force (env) (var)]
51 + end
52 + end
53 +
54 + local function add (x)
55 + local _add = function (y)
56 + return function (env)
57 + return force (env) (x) + force (env) (y)
58 + end
59 + end
60 + return keywords_for (_add) { "to", "with" }
61 + end
62 +
63 + local function show (val)
64 + local _show = function (env)
65 + print (force (env) (val))
66 + end
67 +
68 + return _show
69 + end
70 +
71 + local function is (a)
72 + local _equals = function (b)
73 + return function (env)
74 + return force (env) (a) == force (env) (b)
75 + end
76 + end
77 +
78 + return default (_equals) {
79 + greater_than = function (b)
80 + return function (env)
81 + return force (env) (a) > force (env) (b)
82 + end
83 + end,
84 + less_than = function (b)
85 + return function (env)
86 + return force (env) (a) < force (env) (b)
87 + end
88 + end,
89 + }
90 + end
91 +
92 + local function when (cond)
93 + local _when = function (when_true)
94 + local _when_false = function (when_false)
95 + return function (env)
96 + if force (env) (cond) then
97 + return eval (when_true, env)
98 + else
99 + return eval (when_false, env)
100 + end
101 + end
102 + end
103 +
104 + return keywords_for (_when_false) { "otherwise" }
105 + end
106 + return _when
107 + end
108 +
109 + local function rand ()
110 + return math.random ()
111 + end
112 +
113 + local function return_with (value)
114 + return function (env)
115 + return value
116 + end
117 + end
118 +
119 + math.randomseed (os.time ())
120 + eval {
121 + show (
122 + when (is (rand) .greater_than (0.5)) {
123 + show "Wow! The value was..." ;
124 + return_with "High :>" ;
125 + } .otherwise {
126 + show "Damn, the value was..." ;
127 + return_with "Low :<" ;
128 + }
129 + )
130 + }

capitalex's Avatar capitalex revised this gist 1 day ago. Go to revision

1 file changed, 73 insertions

dsl.lua(file created)

@@ -0,0 +1,73 @@
1 + local function eval (prog)
2 + local env = {}
3 + for _, fn in ipairs (prog) do
4 + fn (env)
5 + end
6 + end
7 +
8 + local function keywords_for (apply)
9 + return function (word_list)
10 + local keywords = {}
11 + for _, word in ipairs (word_list) do
12 + keywords[word] = apply
13 + end
14 + return setmetatable (keywords, {__call = function (t, ...) return apply(...) end})
15 + end
16 + end
17 +
18 + local function let (var)
19 + local _let = function (val)
20 + return function (env)
21 + if type (val) == "function" then
22 + val = val (env)
23 + end
24 + env[var] = val
25 + end
26 + end
27 + return keywords_for (_let) { "equal", "be" }
28 + end
29 +
30 + local function get (var)
31 + return function (env)
32 + return env[var]
33 + end
34 + end
35 +
36 + local function add (x)
37 + local _add = function (y)
38 + return function (env)
39 + if type (x) == "function" then
40 + x = x (env)
41 + end
42 +
43 + if type (y) == "function" then
44 + y = y (env)
45 + end
46 + if type (y) == "table" then
47 + print (next(y))
48 + end
49 + return x + y
50 + end
51 + end
52 + return keywords_for (_add) { "to", "with" }
53 + end
54 +
55 + local function show (val)
56 + local _show = function (env)
57 + if type (val) == "function" then
58 + val = val (env)
59 + end
60 +
61 + print (val)
62 + end
63 +
64 + return _show
65 + end
66 +
67 + eval {
68 + let "x" .equal (1) ;
69 + let "y" .be (2) ;
70 + let "z" (3) ;
71 + show (add (get "x") .to (get "y")) ;
72 + show (add (get "y") .with (get "z")) ;
73 + }
Newer Older