sibilant-rails 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/sibilant-rails.rb +7 -0
- data/lib/sibilant.rb +37 -0
- data/lib/sibilant/haml/filter.rb +16 -0
- data/lib/sibilant/tilt/template.rb +20 -0
- data/lib/source/include/functional.sibilant +411 -0
- data/lib/source/include/macros.sibilant +411 -0
- data/lib/source/lib/browser.js +644 -0
- metadata +106 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a058f375123b339531b523a539b892921a88e2d3
|
4
|
+
data.tar.gz: b2e9e2659f977f1b6758af6c6affd0c3d021d6c9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5c3e5337b8d3e03868b6bb1d648552161c43769493224af73ee4806f2d48093ca9ac35e537583e7eed3f954e48054ac4f2f94f4e899bc812fcb4f58a71e6810f
|
7
|
+
data.tar.gz: 14b0a252e405896eb23431c0ae0268ef98318865e2b7cda86dc343edccbfccc8165ba9696cea1651ded7c66e6951320bbedb44dbdd2b9a712668e10cd6644489
|
data/lib/sibilant.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'execjs'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Sibilant
|
5
|
+
@@context = nil
|
6
|
+
|
7
|
+
def self.compile(source)
|
8
|
+
self.context.call("sibilant.translateAll", source)
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
def self.source_dir
|
13
|
+
@@source_path ||= ENV['SIBILANT_SOURCE_PATH'] || File.join(File.expand_path(File.dirname(__FILE__)), 'source')
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.source_path(source)
|
17
|
+
File.join(self.source_dir, source)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.context
|
21
|
+
if @@context.nil?
|
22
|
+
browser = open(self.source_path("lib/browser.js")).read
|
23
|
+
functional = open(self.source_path("include/functional.sibilant")).read
|
24
|
+
macros = open(self.source_path("include/macros.sibilant")).read
|
25
|
+
|
26
|
+
source = <<-src
|
27
|
+
#{browser};
|
28
|
+
sibilant.translateAll.apply(sibilant, #{::JSON.generate([functional])});
|
29
|
+
sibilant.translateAll.apply(sibilant, #{::JSON.generate([macros])});
|
30
|
+
src
|
31
|
+
|
32
|
+
@@context = ExecJS.compile(source)
|
33
|
+
end
|
34
|
+
|
35
|
+
@@context
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'haml-rails'
|
2
|
+
require 'sibilant'
|
3
|
+
|
4
|
+
module Haml::FIlters
|
5
|
+
module Sibilant
|
6
|
+
include Haml::Filters::Base
|
7
|
+
|
8
|
+
def render(text)
|
9
|
+
return <<-src
|
10
|
+
<script type="text/javascript">
|
11
|
+
#{::Sibilant.compile(text)}
|
12
|
+
</script>
|
13
|
+
src
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'sibilant'
|
2
|
+
require 'sprockets'
|
3
|
+
require 'tilt'
|
4
|
+
|
5
|
+
module Sibilant
|
6
|
+
module Tilt
|
7
|
+
class Template < ::Tilt::Template
|
8
|
+
self.default_mime_type = 'application/javascript'
|
9
|
+
|
10
|
+
def prepare
|
11
|
+
end
|
12
|
+
|
13
|
+
def evaluate(scope, locals, &block)
|
14
|
+
@output ||= Sibilant.compile(data)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
::Sprockets.register_engine '.sibilant', Template
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,411 @@
|
|
1
|
+
(macro join (glue arr)
|
2
|
+
(concat "(" (translate arr) ").join(" (translate glue) ")"))
|
3
|
+
|
4
|
+
|
5
|
+
(macro send (object method &rest args)
|
6
|
+
(concat (translate object) "." (translate method)
|
7
|
+
"(" (join ", " (map args translate)) ")"))
|
8
|
+
|
9
|
+
(macro apply (fn arglist)
|
10
|
+
(macros.send fn 'apply 'undefined arglist))
|
11
|
+
|
12
|
+
(macro list (&rest args)
|
13
|
+
(concat "[ " (join ", " (map args translate)) " ]"))
|
14
|
+
|
15
|
+
(macro cons (first rest)
|
16
|
+
(macros.send (macros.list first) 'concat rest))
|
17
|
+
|
18
|
+
(macro append (list &rest additional)
|
19
|
+
(macros.send list 'concat (apply macros.list additional)))
|
20
|
+
|
21
|
+
(macro get (obj &rest keys)
|
22
|
+
(concat "(" (translate obj) ")"
|
23
|
+
(join "" (map keys (lambda (key)
|
24
|
+
(concat "[" (translate key) "]"))))))
|
25
|
+
|
26
|
+
(macro + (&rest args)
|
27
|
+
(concat "(" (join " + " (map args translate)) ")"))
|
28
|
+
(macro - (&rest args)
|
29
|
+
(concat "(" (join " - " (map args translate)) ")"))
|
30
|
+
(macro * (&rest args)
|
31
|
+
(concat "(" (join " * " (map args translate)) ")"))
|
32
|
+
(macro / (&rest args)
|
33
|
+
(concat "(" (join " / " (map args translate)) ")"))
|
34
|
+
(macro or (&rest args)
|
35
|
+
(concat "(" (join " || " (map args translate)) ")"))
|
36
|
+
(macro and (&rest args)
|
37
|
+
(concat "(" (join " && " (map args translate)) ")"))
|
38
|
+
(macro mod (&rest args)
|
39
|
+
(concat "(" (join " % " (map args translate)) ")"))
|
40
|
+
|
41
|
+
(macro join (&optional glue arr) ;redefined because join and or are mutually dependent
|
42
|
+
(concat "(" (translate arr) ").join(" (or (translate glue) "\"\"") ")"))
|
43
|
+
|
44
|
+
(macro infix-comparator (comparator args)
|
45
|
+
(concat "("
|
46
|
+
(join " && "
|
47
|
+
(map (args.slice 0 -1)
|
48
|
+
(lambda (item index)
|
49
|
+
(concat item
|
50
|
+
" " comparator " "
|
51
|
+
(get args (+ 1 index))))))
|
52
|
+
")"))
|
53
|
+
|
54
|
+
(macro > (&rest args) (macros.infix-comparator ">" (map args translate)))
|
55
|
+
(macro < (&rest args) (macros.infix-comparator "<" (map args translate)))
|
56
|
+
(macro <= (&rest args) (macros.infix-comparator "<=" (map args translate)))
|
57
|
+
(macro >= (&rest args) (macros.infix-comparator ">=" (map args translate)))
|
58
|
+
(macro != (&rest args) (macros.infix-comparator "!==" (map args translate)))
|
59
|
+
|
60
|
+
(macro pow (base exponent)
|
61
|
+
(macros.call "Math.pow" base exponent))
|
62
|
+
|
63
|
+
(macro incr-by (item increment)
|
64
|
+
(concat (translate item) " += " (translate increment)))
|
65
|
+
|
66
|
+
(macro incr (item)
|
67
|
+
(concat "((" (translate item) ")++)"))
|
68
|
+
|
69
|
+
(macro decr (item)
|
70
|
+
(concat "((" (translate item) ")--)"))
|
71
|
+
|
72
|
+
(macro set (arr &rest kv-pairs)
|
73
|
+
(join "\n" (bulk-map kv-pairs
|
74
|
+
(lambda (k v)
|
75
|
+
(concat "(" (translate arr) ")"
|
76
|
+
"[" (translate k) "] = " (translate v) ";")))))
|
77
|
+
|
78
|
+
(macro new (&rest args)
|
79
|
+
(concat "(new " (apply macros.call args) ")"))
|
80
|
+
|
81
|
+
(macro regex (string &optional glim)
|
82
|
+
(call (get macros 'new) 'RegExp string (or glim 'undefined)))
|
83
|
+
|
84
|
+
(macro timestamp ()
|
85
|
+
(concat "\"" (send (new Date) to-string) "\""))
|
86
|
+
|
87
|
+
(macro comment (&rest contents)
|
88
|
+
(map contents
|
89
|
+
(lambda (item)
|
90
|
+
(join "\n" (map (send (translate item) split "\n")
|
91
|
+
(lambda (line) (concat "// " line)))))))
|
92
|
+
|
93
|
+
(macro meta (body)
|
94
|
+
(eval (translate body)))
|
95
|
+
|
96
|
+
(macro zero? (item)
|
97
|
+
((get macros "=") (translate item) 0))
|
98
|
+
|
99
|
+
(macro empty? (arr)
|
100
|
+
(concat "((" (translate arr) ").length === 0)"))
|
101
|
+
|
102
|
+
(macro odd? (number)
|
103
|
+
((get macros "!=") 0
|
104
|
+
(macros.mod (translate number) 2)))
|
105
|
+
|
106
|
+
(macro even? (number)
|
107
|
+
((get macros "=") 0
|
108
|
+
(macros.mod (translate number) 2)))
|
109
|
+
|
110
|
+
|
111
|
+
(macro typeof (thing) (+ "typeof " (translate thing)))
|
112
|
+
|
113
|
+
(macro function? (thing)
|
114
|
+
((get macros "=") (macros.typeof thing) "'function'"))
|
115
|
+
|
116
|
+
(macro undefined? (thing)
|
117
|
+
((get macros "=") (macros.typeof thing) "'undefined'"))
|
118
|
+
|
119
|
+
(macro defined? (thing)
|
120
|
+
((get macros "!=") (macros.typeof thing) "'undefined'"))
|
121
|
+
|
122
|
+
(macro number? (thing)
|
123
|
+
((get macros "=") (macros.typeof thing) "'number'"))
|
124
|
+
|
125
|
+
(macro first (arr) (macros.get arr 0))
|
126
|
+
(macro second (arr) (macros.get arr 1))
|
127
|
+
(macro third (arr) (macros.get arr 2))
|
128
|
+
(macro fourth (arr) (macros.get arr 3))
|
129
|
+
(macro fifth (arr) (macros.get arr 4))
|
130
|
+
(macro sixth (arr) (macros.get arr 5))
|
131
|
+
(macro seventh (arr) (macros.get arr 6))
|
132
|
+
(macro eighth (arr) (macros.get arr 7))
|
133
|
+
(macro ninth (arr) (macros.get arr 8))
|
134
|
+
|
135
|
+
(macro rest (arr)
|
136
|
+
(macros.send arr 'slice 1))
|
137
|
+
|
138
|
+
(macro length (arr)
|
139
|
+
(macros.get arr "\"length\""))
|
140
|
+
|
141
|
+
(macro last (arr)
|
142
|
+
(macros.get (macros.send arr 'slice -1) 0))
|
143
|
+
|
144
|
+
(macro if (arg truebody falsebody)
|
145
|
+
(concat
|
146
|
+
"(function() {"
|
147
|
+
(indent (concat
|
148
|
+
"if (" (translate arg) ") {"
|
149
|
+
(indent (macros.progn truebody))
|
150
|
+
"} else {"
|
151
|
+
(indent (macros.progn falsebody))
|
152
|
+
"}"))
|
153
|
+
"})()"))
|
154
|
+
|
155
|
+
(macro defvar (&rest pairs)
|
156
|
+
(as-statement
|
157
|
+
(concat "var "
|
158
|
+
(join ",\n "
|
159
|
+
(bulk-map pairs
|
160
|
+
(lambda (name value)
|
161
|
+
(concat (translate name) " = "
|
162
|
+
(translate value)))))
|
163
|
+
";")))
|
164
|
+
|
165
|
+
(macro = (first-thing &rest other-things)
|
166
|
+
(defvar translated-first-thing (translate first-thing))
|
167
|
+
(concat "("
|
168
|
+
(join " &&\n "
|
169
|
+
(map other-things
|
170
|
+
(lambda (thing)
|
171
|
+
(concat translated-first-thing
|
172
|
+
" === "
|
173
|
+
(translate thing)))))
|
174
|
+
")"))
|
175
|
+
|
176
|
+
|
177
|
+
(macro string? (thing)
|
178
|
+
(concat "typeof(" (translate thing) ") === \"string\""))
|
179
|
+
|
180
|
+
(macro list? (thing)
|
181
|
+
(defvar translated (concat "(" (translate thing) ")"))
|
182
|
+
(concat translated " && "
|
183
|
+
translated ".constructor.name === \"Array\""))
|
184
|
+
|
185
|
+
|
186
|
+
(macro when (arg &rest body)
|
187
|
+
(concat
|
188
|
+
"(function() {"
|
189
|
+
(indent (concat
|
190
|
+
"if (" (translate arg) ") {"
|
191
|
+
(indent (apply macros.progn body))
|
192
|
+
"}"))
|
193
|
+
"})()"))
|
194
|
+
|
195
|
+
(macro unless (condition &rest body)
|
196
|
+
(apply macros.when (cons ['not condition] body)))
|
197
|
+
|
198
|
+
(macro not (exp)
|
199
|
+
(concat "(!" (translate exp) ")"))
|
200
|
+
|
201
|
+
(macro slice (arr start &optional end)
|
202
|
+
(macros.send (translate arr) "slice" start end))
|
203
|
+
|
204
|
+
(macro inspect (&rest args)
|
205
|
+
(join " + \"\\n\" + "
|
206
|
+
(map args
|
207
|
+
(lambda (arg)
|
208
|
+
(concat "\"" arg ":\" + " (translate arg))))))
|
209
|
+
|
210
|
+
(macro each (item array &rest body)
|
211
|
+
(macros.send (translate array) 'for-each
|
212
|
+
(apply macros.lambda (cons item body))))
|
213
|
+
|
214
|
+
|
215
|
+
(macro setf (&rest args)
|
216
|
+
(join "\n"
|
217
|
+
(bulk-map args (lambda (name value)
|
218
|
+
(as-statement (concat (translate name) " = "
|
219
|
+
(translate value)))))))
|
220
|
+
|
221
|
+
|
222
|
+
(macro macro-list ()
|
223
|
+
(concat "["
|
224
|
+
(indent (join ",\n"
|
225
|
+
(map (-object.keys macros)
|
226
|
+
macros.quote)))
|
227
|
+
"]"))
|
228
|
+
|
229
|
+
(macro macroexpand (name)
|
230
|
+
(defvar macro (get macros (translate name)))
|
231
|
+
(if macro
|
232
|
+
(concat "// macro: " name "\n" (send macro to-string))
|
233
|
+
"undefined"))
|
234
|
+
|
235
|
+
(macro throw (&rest string)
|
236
|
+
(concat "throw new Error (" (join " " (map string translate)) ")"))
|
237
|
+
|
238
|
+
(macro as-boolean (expr)
|
239
|
+
(concat "(!!(" (translate expr) "))"))
|
240
|
+
|
241
|
+
(macro chain (object &rest calls)
|
242
|
+
(if (= 0 calls.length) (translate object)
|
243
|
+
(if (= 1 calls.length) (apply macros.send (cons object (first calls)))
|
244
|
+
(concat (translate object)
|
245
|
+
(indent (join "\n"
|
246
|
+
(map calls (lambda (call index)
|
247
|
+
(concat "." (translate (first call))
|
248
|
+
"(" (join ", " (map (rest call) translate)) ")")))))))))
|
249
|
+
|
250
|
+
(macro chainable (&rest names)
|
251
|
+
(each (name) names
|
252
|
+
(macros.macro name ['target "&rest" 'calls]
|
253
|
+
['apply 'macros.chain ['cons ['macros.call ['quote name] 'target] 'calls]])))
|
254
|
+
|
255
|
+
(macro try (tryblock catchblock)
|
256
|
+
(concat
|
257
|
+
"(function() {"
|
258
|
+
(indent (concat
|
259
|
+
"try {"
|
260
|
+
(indent (macros.progn tryblock))
|
261
|
+
"} catch (e) {"
|
262
|
+
(indent (macros.progn catchblock))
|
263
|
+
"}"))
|
264
|
+
"})()"))
|
265
|
+
|
266
|
+
|
267
|
+
(macro while (condition &rest block)
|
268
|
+
(macros.scoped
|
269
|
+
(macros.defvar '**return-value**)
|
270
|
+
(concat "while (" (translate condition) ") {"
|
271
|
+
(indent (macros.setf '**return-value**
|
272
|
+
(apply macros.scoped block))))
|
273
|
+
"}"
|
274
|
+
'**return-value**))
|
275
|
+
|
276
|
+
(macro until (condition &rest block)
|
277
|
+
(apply (get macros 'while)
|
278
|
+
(cons ['not condition] block)))
|
279
|
+
|
280
|
+
|
281
|
+
(macro thunk (&rest args)
|
282
|
+
(apply macros.lambda (cons [] args)))
|
283
|
+
|
284
|
+
(macro keys (obj)
|
285
|
+
(macros.call "Object.keys" (translate obj)))
|
286
|
+
|
287
|
+
(macro delete (&rest objects)
|
288
|
+
(join "\n" (map objects (lambda (obj)
|
289
|
+
(concat "delete " (translate obj) ";")))))
|
290
|
+
|
291
|
+
(macro delmacro (macro-name)
|
292
|
+
(delete (get macros (translate macro-name)))
|
293
|
+
"")
|
294
|
+
|
295
|
+
(macro alias-macro (current-macro-name desired-macro-name)
|
296
|
+
(defvar current-macro-name (translate current-macro-name)
|
297
|
+
desired-macro-name (translate desired-macro-name))
|
298
|
+
(set macros desired-macro-name (get macros current-macro-name))
|
299
|
+
"")
|
300
|
+
|
301
|
+
(macro rename-macro (current-macro-name desired-macro-name)
|
302
|
+
(macros.alias-macro current-macro-name desired-macro-name)
|
303
|
+
(macros.delmacro current-macro-name)
|
304
|
+
"")
|
305
|
+
|
306
|
+
(macro defhash (name &rest pairs)
|
307
|
+
(macros.defvar name (apply macros.hash pairs)))
|
308
|
+
|
309
|
+
(macro arguments ()
|
310
|
+
"(Array.prototype.slice.apply(arguments))")
|
311
|
+
|
312
|
+
(macro scoped (&rest body)
|
313
|
+
(macros.call (apply macros.thunk body)))
|
314
|
+
|
315
|
+
(macro each-key (as obj &rest body)
|
316
|
+
(concat "(function() {"
|
317
|
+
(indent
|
318
|
+
(concat "for (var " (translate as) " in " (translate obj) ") "
|
319
|
+
(apply macros.scoped body)
|
320
|
+
";"))
|
321
|
+
"})();"))
|
322
|
+
|
323
|
+
(macro match? (regexp string)
|
324
|
+
(macros.send string 'match regexp))
|
325
|
+
|
326
|
+
(macro switch (obj &rest cases)
|
327
|
+
|
328
|
+
;; the complexity of this macro indicates there's a problem
|
329
|
+
;; I'm not quite sure where to fix this, but it has to do with quoting.
|
330
|
+
(defvar lines (list (concat "switch(" (translate obj) ") {")))
|
331
|
+
(each (case-def) cases
|
332
|
+
(defvar case-name (first case-def))
|
333
|
+
(when (and (list? case-name)
|
334
|
+
(= (first case-name) 'quote))
|
335
|
+
(defvar second (second case-name))
|
336
|
+
(setf case-name (if (list? second)
|
337
|
+
(map second macros.quote)
|
338
|
+
(macros.quote second))))
|
339
|
+
|
340
|
+
(defvar case-string
|
341
|
+
(if (list? case-name)
|
342
|
+
(join "\n" (map case-name (lambda (c)
|
343
|
+
(concat "case " (translate c) ":"))))
|
344
|
+
(if (= 'default case-name) "default:"
|
345
|
+
(concat "case " (translate case-name) ":"))))
|
346
|
+
|
347
|
+
(lines.push (concat case-string
|
348
|
+
(indent (apply macros.progn (case-def.slice 1))))))
|
349
|
+
|
350
|
+
;; the following two lines are to get the whitespace right
|
351
|
+
;; this is necessary because switches are indented weird
|
352
|
+
(set lines (- lines.length 1)
|
353
|
+
(chain (get lines (- lines.length 1)) (concat "}")))
|
354
|
+
|
355
|
+
(concat "(function() {" (apply indent lines) "})()"))
|
356
|
+
|
357
|
+
|
358
|
+
(macro if-else (&rest args)
|
359
|
+
(concat "(function() {"
|
360
|
+
(indent
|
361
|
+
(join " else "
|
362
|
+
(bulk-map args
|
363
|
+
(lambda (cond val)
|
364
|
+
(if (undefined? val)
|
365
|
+
(concat "{" (indent (macros.progn cond)) "}")
|
366
|
+
(concat "if (" (translate cond) ") {"
|
367
|
+
(indent (macros.progn val))
|
368
|
+
"}"))))))
|
369
|
+
"})()"))
|
370
|
+
|
371
|
+
(macro let (args &optional body)
|
372
|
+
(concat "let (" (bulk-map args
|
373
|
+
(lambda (h k v)
|
374
|
+
(concat (translate k) " = " (translate v))))
|
375
|
+
(if (undefined? body) ");"
|
376
|
+
(concat ") {" (indent (translate body)) "}"))))
|
377
|
+
|
378
|
+
(macro instance-of? (item type)
|
379
|
+
(concat "(" (translate item) " instanceof " (translate type) ")"))
|
380
|
+
|
381
|
+
(macro slice (list &optional begin &optional end)
|
382
|
+
(concat "Array.prototype.slice.call(" (translate list)
|
383
|
+
", " (or (translate begin) 0)
|
384
|
+
(if (defined? end) (concat ", " (translate end) ")") ")")))
|
385
|
+
|
386
|
+
(macro ternary (cond if-true if-false)
|
387
|
+
(concat "(" (translate cond) ") ? "
|
388
|
+
(translate if-true) " : "
|
389
|
+
(translate if-false)))
|
390
|
+
|
391
|
+
|
392
|
+
(macro includes? (list item)
|
393
|
+
(call (get macros "!=") -1 (macros.send list 'index-of item)))
|
394
|
+
|
395
|
+
(macro excludes? (list item)
|
396
|
+
(call (get macros "=") -1 (macros.send list 'index-of item)))
|
397
|
+
|
398
|
+
(macro exists? (thing)
|
399
|
+
(call (get macros "and")
|
400
|
+
(macros.defined? thing)
|
401
|
+
(call (get macros "!=") thing 'null)))
|
402
|
+
|
403
|
+
;;new style
|
404
|
+
(alias-macro lambda #)
|
405
|
+
(alias-macro thunk #>)
|
406
|
+
(alias-macro defvar var)
|
407
|
+
(alias-macro progn do)
|
408
|
+
(alias-macro setf assign)
|
409
|
+
(alias-macro defun def)
|
410
|
+
(alias-macro delmacro delete-macro)
|
411
|
+
|