sibilant-rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,7 @@
1
+ require 'sibilant/tilt/template'
2
+
3
+ begin
4
+ gem 'haml-rails'
5
+ require 'sibilant/haml/filter'
6
+ rescue Gem::LoadError
7
+ end
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
+