sibilant-rails 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+