sibilant 0.0.1 → 0.0.2

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.
Files changed (47) hide show
  1. data/README.md +8 -4
  2. data/js/sibilant/.gitignore +4 -0
  3. data/js/sibilant/.travis.yml +6 -0
  4. data/js/sibilant/LICENSE +20 -0
  5. data/js/sibilant/README.md +70 -0
  6. data/js/sibilant/bin/sibilant +3 -0
  7. data/js/sibilant/cli-help +79 -0
  8. data/js/sibilant/include/functional.sibilant +57 -0
  9. data/js/sibilant/include/macros.sibilant +374 -0
  10. data/js/sibilant/include/node.sibilant +2 -0
  11. data/js/sibilant/lib/browser.js +685 -0
  12. data/js/sibilant/lib/cli.js +153 -0
  13. data/js/sibilant/lib/options.js +232 -0
  14. data/js/sibilant/lib/repl.js +78 -0
  15. data/js/sibilant/lib/sibilant.js +688 -0
  16. data/js/sibilant/misc/sibilant-mode.el +129 -0
  17. data/js/sibilant/package.json +19 -0
  18. data/js/sibilant/package.sibilant +16 -0
  19. data/js/sibilant/public/index.html +502 -0
  20. data/js/sibilant/public/javascripts/browser.js +685 -0
  21. data/js/sibilant/public/javascripts/jquery-ui.js +392 -0
  22. data/js/sibilant/public/javascripts/jquery.js +154 -0
  23. data/js/sibilant/public/javascripts/macros.sibilant +374 -0
  24. data/js/sibilant/public/javascripts/sibilant.info.sibilant +77 -0
  25. data/js/sibilant/public/sass/_mixins.sass +98 -0
  26. data/js/sibilant/public/sass/sibilant.sass +156 -0
  27. data/js/sibilant/public/stylesheets/Anonymous_Pro-webfont.eot +0 -0
  28. data/js/sibilant/public/stylesheets/Anonymous_Pro-webfont.svg +241 -0
  29. data/js/sibilant/public/stylesheets/Anonymous_Pro-webfont.ttf +0 -0
  30. data/js/sibilant/public/stylesheets/Anonymous_Pro-webfont.woff +0 -0
  31. data/js/sibilant/public/stylesheets/sibilant.css +166 -0
  32. data/js/sibilant/src/browser.sibilant +45 -0
  33. data/js/sibilant/src/cli.sibilant +93 -0
  34. data/js/sibilant/src/core.sibilant +338 -0
  35. data/js/sibilant/src/options.sibilant +65 -0
  36. data/js/sibilant/src/repl.sibilant +59 -0
  37. data/js/sibilant/src/sibilant.sibilant +78 -0
  38. data/js/sibilant/test/defvar.sibilant +5 -0
  39. data/js/sibilant/test/includeFile1.sibilant +1 -0
  40. data/js/sibilant/test/includeFile2.sibilant +1 -0
  41. data/js/sibilant/test/node.sibilant +10 -0
  42. data/js/sibilant/test/slice.sibilant +3 -0
  43. data/js/sibilant/test/test.sibilant +464 -0
  44. data/js/sibilant/test/testHelper.sibilant +80 -0
  45. data/lib/sibilant/version.rb +1 -1
  46. data/sibilant.gemspec +3 -1
  47. metadata +44 -1
data/README.md CHANGED
@@ -4,18 +4,20 @@
4
4
  # Sibilant Ruby Gem
5
5
 
6
6
  This is a ruby wrapper for the sibilant compiler, which is written in
7
- javascript. Instead of depending on ExecJS, it expects to find NodeJS
8
- available on the path as node. Sibilant doesn't need to be installed.
7
+ javascript. It expects to find NodeJS available on the path as node.
8
+ Sibilant doesn't need to be installed.
9
9
 
10
10
  # Tilt support
11
11
 
12
- Providing sibilant code inside of a [tilt](https://github.com/rtomayko/tilt/) environment is provided by
12
+ [Tilt](https://github.com/rtomayko/tilt/) support is provided by `sibilant/tilt`:
13
13
 
14
14
  require 'sibilant/tilt'
15
15
  Tilt['test.sibilant'].new { "(+ 1 2 3)" }.render #=> '(1 + 2 + 3)'
16
16
 
17
17
  # Sinatra
18
18
 
19
+ [Sinatra](http://sinatrarb.com) support is provided by `sibilant/sinatra`:
20
+
19
21
  require 'sinatra'
20
22
  require 'sibilant/sinatra'
21
23
  helpers Sinatra::Sibilant
@@ -24,7 +26,9 @@ Providing sibilant code inside of a [tilt](https://github.com/rtomayko/tilt/) en
24
26
  #./views/templated.sibilant
25
27
  get('/templated.js') { sibilant :templated }
26
28
 
27
- ## When it's ready, here's how you'll install it
29
+ ## How to install
30
+
31
+ First, you'll need [NodeJS](http://nodejs.org/) installed.
28
32
 
29
33
  Add this line to your application's Gemfile:
30
34
 
@@ -0,0 +1,4 @@
1
+ public/.sass-cache
2
+ lib/core.js
3
+ tmp/*
4
+ *.swp
@@ -0,0 +1,6 @@
1
+ language: node_js
2
+ node_js:
3
+ - "0.11"
4
+ - "0.10"
5
+ - "0.8"
6
+ - "0.6"
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Jacob Rothstein
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,70 @@
1
+ [![Build Status](https://travis-ci.org/jbr/sibilant.png?branch=master)](https://travis-ci.org/jbr/sibilant)
2
+
3
+ # Sibilant
4
+
5
+ - Sibilant is a language that is parsed by javascript and compiles to
6
+ javascript.
7
+ - Sibilant is inspired by lisp and follows many lisp conventions,
8
+ although it is still relatively close to the underlying javascript.
9
+ - Macros can be defined in sibilant and included at compile time.
10
+ - Sibilant is entirely written in sibilant and can recompile itself.
11
+
12
+ ## Language Priorities
13
+
14
+ - Prefer verbose names to abbreviations by default.
15
+ - Avoid line noise. Prefer established punctuation semantics from
16
+ natural languages and common programming languages (eg commas come
17
+ after things and mean a pause or separation).
18
+ - Prefer readable and idiomatic javascript output, which necessitates
19
+ sticking fairly closely to javascript semantics. Switching cost from
20
+ sibilant to directly editing the output javascript should be low.
21
+ - Prefer expressions to statements. This is the most notable exception
22
+ to the adherance to idiomatic javascript. Self-executing functions
23
+ are used extensively to this end.
24
+ - Allow as much of the language to be modified in-source as
25
+ possible. This includes the ability to rename/remove/redefine all
26
+ keywords and macros.
27
+ - Any language constructs that do not output readable javascript
28
+ should be opt-in.
29
+ - Add language features slowly, and only when there's a real use
30
+ case. Don't blindly implement Lisp features without reasoning
31
+ through the need.
32
+ - Provide tools to simplify avoidance of repetition.
33
+
34
+ ## Try it before you install
35
+
36
+ [sibilantjs.info](http://sibilantjs.info) includes an in-browser
37
+ as-you-type sibilant compiler and tutorial, so you can get a sense of
38
+ the language without leaving your browser.
39
+
40
+ ## Installation
41
+
42
+ First, install [node.js](http://nodejs.org) [
43
+ [github](http://github.com/ry/node) ] and [npm](http://npmjs.org) [
44
+ [github](http://github.com/isaacs/npm) ]. Then, it's as simple as:
45
+
46
+ $ npm install sibilant -g
47
+ $ sibilant --help
48
+
49
+ ## Learning the language and examples
50
+
51
+ The most up to date documentation will always be
52
+ [sibilantjs.info](http://sibilantjs.info) which includes an
53
+ as-you-type in-browser sibilant compiler. Check out [sibilant itself,
54
+ which is written 100% in
55
+ sibilant](http://github.com/jbr/sibilant/tree/master/src) to get a
56
+ sense of what's possible.
57
+
58
+ ## How to get involved or learn more
59
+
60
+ Send a blank email to
61
+ [sibilant@librelist.com](mailto:sibilant@librelist.com) to join the
62
+ mailing list. Add any bugs or feature requests to the
63
+ [issues](http://github.com/jbr/sibilant/issues) page or email the
64
+ list. Happy hacking, have fun!
65
+
66
+ ## License
67
+
68
+ Sibilant is released under the [MIT
69
+ license](http://github.com/jbr/sibilant/blob/master/LICENSE)
70
+ ([wikipedia](http://en.wikipedia.org/wiki/MIT_License)).
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ require ('./../lib/cli')
@@ -0,0 +1,79 @@
1
+ Hi there! Thanks for installing sibilant.
2
+ Please leave feedback on github issues (http://github.com/jbr/sibilant/issues)
3
+
4
+ The current commandline options are
5
+ --------------------------------------------------------------------------------
6
+
7
+ -v / --version Print out a version string and exit
8
+
9
+ -h / --help This message
10
+
11
+ --repl / [no args] Sibilant interactive command prompt
12
+
13
+ --eval [optional STRING] / -e [optional STRING]
14
+ Evaluate STRING if provided, otherwise evaluate STDIN.
15
+ This is the same as -x -i [optional STRING]
16
+
17
+ --execute / -x This is a flag. Execute input files in order supplied.
18
+
19
+ --output DIR / -o DIR Output input files to this dir, replacing .sibilant with .js.
20
+
21
+ --input [optional STRING / -i [optional STRING]
22
+ Interpret optional string as sibilant code. If the execute
23
+ flag is set, execute this code. If STRING is not provided,
24
+ read STDIN.
25
+
26
+ --file FILE / -f FILE / FILE
27
+ Add this file to the input files. If the execute flag is
28
+ set, input files will be executed. If an output dir is
29
+ specified, each file will be written to that dir.
30
+ Otherwise, each file will be written to STDOUT.
31
+
32
+
33
+ To pass arguments to an executed file, append them after a \"--\", as follows
34
+ $ sibilant -x myfile.sibilant -- --arg-for-my-program=stuff
35
+
36
+ myfile.sibilant will see process.argv as
37
+ [ 'sibilant', 'myfile.sibilant', '--arg-for-my-program=stuff' ]
38
+
39
+ --------------------------------------------------------------------------------
40
+
41
+ Examples
42
+
43
+ to compile sibilant
44
+ $ git clone git://github.com/jbr/sibilant.git
45
+ $ npm link .
46
+ $ sibilant src/*.sibilant -o lib
47
+ $ sibilant -x test/test.sibilant # you're now running a sibilant you just compiled.
48
+
49
+ to compile one file to stdout
50
+ $ sibilant test/test.sibilant
51
+
52
+ to compile a file to a directory
53
+ $ sibilant test/test.sibilant -o . # put test.js here
54
+ or
55
+ $ sibilant --file test/test.sibilant --output .
56
+
57
+ to run a file
58
+ $ sibilant -x test/test.sibilant
59
+
60
+ to enter the repl
61
+ $ sibilant
62
+ or
63
+ $ sibilant --repl
64
+
65
+ to see how something will translate to js,
66
+ $ sibilant -i "(console.log (+ 2 2))"
67
+ console.log((2 + 2));
68
+
69
+ to execute a quick snippet,
70
+ $ sibilant -e "(console.log (+ 2 2))" # this is the same as -x -i
71
+ 4
72
+
73
+ to translate STDIN,
74
+ $ echo "(console.log 'hello 'world)" | sibilant -i
75
+ console.log("hello", "world");
76
+
77
+ to execute sibilant code on STDIN,
78
+ $ echo "console.log 'hello 'world)" | sibilant -e # or sibilant -x -i
79
+ hello world
@@ -0,0 +1,57 @@
1
+ (defun bulk-map (arr fn)
2
+ (defvar index 0
3
+ group-size fn.length
4
+ ret-arr [])
5
+
6
+ (while (< index arr.length)
7
+ (send ret-arr push
8
+ (apply fn (send arr slice
9
+ index (+ index group-size))))
10
+ (incr-by index group-size))
11
+ ret-arr)
12
+
13
+ (defun inject (start items fn)
14
+ (defvar value start)
15
+ (when (list? items)
16
+ (each (item index) items
17
+ (setf value (fn value item index))))
18
+ value)
19
+
20
+ (defun map (items fn)
21
+ (inject [] items
22
+ (lambda (collector item index)
23
+ (send collector push (fn item index))
24
+ collector)))
25
+
26
+ (defun select (items fn)
27
+ (inject [] items
28
+ (lambda (collector item index)
29
+ (when (fn item index)
30
+ (send collector push item))
31
+ collector)))
32
+
33
+ (defun detect (items fn)
34
+ (defvar return-item undefined
35
+ index 0
36
+ items items)
37
+
38
+ (until (or (= items.length index) return-item)
39
+ (when (fn (get items index) index)
40
+ (setf return-item (get items index)))
41
+ (incr index)))
42
+
43
+ (defun reject (items fn)
44
+ (defvar args [ items fn ])
45
+ (select items (thunk (not (apply fn arguments)))))
46
+
47
+ (defun compact (arr)
48
+ (select arr (lambda (item)
49
+ (as-boolean item))))
50
+
51
+ (defun flatten (&rest items)
52
+ (inject [] items
53
+ (lambda (collector item)
54
+ (collector.concat
55
+ (if (list? item)
56
+ (apply flatten item)
57
+ item)))))
@@ -0,0 +1,374 @@
1
+ (defmacro cons (first rest)
2
+ (macros.send (macros.list first) 'concat rest))
3
+
4
+ (defmacro join (glue arr)
5
+ (concat "(" (translate arr) ").join(" (translate glue) ")"))
6
+
7
+ (defmacro list (&rest args)
8
+ (concat "[ " (join ", " (map args translate)) " ]"))
9
+
10
+ (defmacro get (arr i) (concat "(" (translate arr) ")[" (translate i) "]"))
11
+
12
+ (defmacro + (&rest args)
13
+ (concat "(" (join " + " (map args translate)) ")"))
14
+ (defmacro - (&rest args)
15
+ (concat "(" (join " - " (map args translate)) ")"))
16
+ (defmacro * (&rest args)
17
+ (concat "(" (join " * " (map args translate)) ")"))
18
+ (defmacro / (&rest args)
19
+ (concat "(" (join " / " (map args translate)) ")"))
20
+ (defmacro or (&rest args)
21
+ (concat "(" (join " || " (map args translate)) ")"))
22
+ (defmacro and (&rest args)
23
+ (concat "(" (join " && " (map args translate)) ")"))
24
+ (defmacro mod (&rest args)
25
+ (concat "(" (join " % " (map args translate)) ")"))
26
+
27
+
28
+
29
+ (defmacro infix-comparator (comparator args)
30
+ (concat "("
31
+ (join " && "
32
+ (map (args.slice 0 -1)
33
+ (lambda (item index)
34
+ (concat item
35
+ " " comparator " "
36
+ (get args (+ 1 index))))))
37
+ ")"))
38
+
39
+ (defmacro > (&rest args) (macros.infix-comparator ">" (map args translate)))
40
+ (defmacro < (&rest args) (macros.infix-comparator "<" (map args translate)))
41
+ (defmacro <= (&rest args) (macros.infix-comparator "<=" (map args translate)))
42
+ (defmacro >= (&rest args) (macros.infix-comparator ">=" (map args translate)))
43
+ (defmacro != (&rest args) (macros.infix-comparator "!==" (map args translate)))
44
+
45
+ (defmacro pow (base exponent)
46
+ (macros.call "Math.pow" base exponent))
47
+
48
+ (defmacro incr-by (item increment)
49
+ (concat (translate item) " += " (translate increment)))
50
+
51
+ (defmacro incr (item)
52
+ (concat "((" (translate item) ")++)"))
53
+
54
+ (defmacro decr (item)
55
+ (concat "((" (translate item) ")--)"))
56
+
57
+ (defmacro set (arr &rest kv-pairs)
58
+ (join "\n" (bulk-map kv-pairs
59
+ (lambda (k v)
60
+ (concat "(" (translate arr) ")"
61
+ "[" (translate k) "] = " (translate v) ";")))))
62
+
63
+ (defmacro send (object method &rest args)
64
+ (concat (translate object) "." (translate method)
65
+ "(" (join ", " (map args translate)) ")"))
66
+
67
+ (defmacro new (fn)
68
+ (concat "(new " (translate fn) ")"))
69
+
70
+ (defmacro regex (string &optional glim)
71
+ ((get macros 'new) (macros.call "RegExp" string (or glim "undefined"))))
72
+
73
+ (defmacro timestamp ()
74
+ (concat "\"" (send (new (-date)) to-string) "\""))
75
+
76
+ (defmacro comment (&rest contents)
77
+ (map contents
78
+ (lambda (item)
79
+ (join "\n" (map (send (translate item) split "\n")
80
+ (lambda (line) (concat "// " line)))))))
81
+
82
+ (defmacro meta (body)
83
+ (eval (translate body)))
84
+
85
+ (defmacro apply (fn arglist)
86
+ (macros.send fn 'apply 'undefined arglist))
87
+
88
+ (defmacro zero? (item)
89
+ ((get macros "=") (translate item) 0))
90
+
91
+ (defmacro empty? (arr)
92
+ (concat "((" (translate arr) ").length === 0)"))
93
+
94
+ (defmacro odd? (number)
95
+ ((get macros "!=") 0
96
+ (macros.mod (translate number) 2)))
97
+
98
+ (defmacro even? (number)
99
+ ((get macros "=") 0
100
+ (macros.mod (translate number) 2)))
101
+
102
+
103
+ (defmacro function? (thing)
104
+ (concat "typeof(" (translate thing) ") === 'function'"))
105
+
106
+ (defmacro undefined? (thing)
107
+ (concat "typeof(" (translate thing) ") === 'undefined'"))
108
+
109
+ (defmacro defined? (thing)
110
+ (concat "typeof(" (translate thing) ") !== 'undefined'"))
111
+
112
+ (defmacro number? (thing)
113
+ (concat "typeof(" (translate thing) ") === 'number'"))
114
+
115
+ (defmacro first (arr) (macros.get arr 0))
116
+ (defmacro second (arr) (macros.get arr 1))
117
+ (defmacro third (arr) (macros.get arr 2))
118
+ (defmacro fourth (arr) (macros.get arr 3))
119
+ (defmacro fifth (arr) (macros.get arr 4))
120
+ (defmacro sixth (arr) (macros.get arr 5))
121
+ (defmacro seventh (arr) (macros.get arr 6))
122
+ (defmacro eighth (arr) (macros.get arr 7))
123
+ (defmacro ninth (arr) (macros.get arr 8))
124
+
125
+ (defmacro rest (arr)
126
+ (macros.send arr 'slice 1))
127
+
128
+ (defmacro length (arr)
129
+ (macros.get arr "\"length\""))
130
+
131
+ (defmacro last (arr)
132
+ (macros.get (macros.send arr 'slice -1) 0))
133
+
134
+ (defmacro if (arg truebody falsebody)
135
+ (concat
136
+ "(function() {"
137
+ (indent (concat
138
+ "if (" (translate arg) ") {"
139
+ (indent (macros.progn truebody))
140
+ "} else {"
141
+ (indent (macros.progn falsebody))
142
+ "}"))
143
+ "})()"))
144
+
145
+ (defmacro defvar (&rest pairs)
146
+ (as-statement
147
+ (concat "var "
148
+ (join ",\n "
149
+ (bulk-map pairs
150
+ (lambda (name value)
151
+ (concat (translate name) " = "
152
+ (translate value)))))
153
+ ";")))
154
+
155
+ (defmacro = (first-thing &rest other-things)
156
+ (defvar translated-first-thing (translate first-thing))
157
+ (concat "("
158
+ (join " &&\n "
159
+ (map other-things
160
+ (lambda (thing)
161
+ (concat translated-first-thing
162
+ " === "
163
+ (translate thing)))))
164
+ ")"))
165
+
166
+
167
+ (defmacro string? (thing)
168
+ (concat "typeof(" (translate thing) ") === \"string\""))
169
+
170
+ (defmacro list? (thing)
171
+ (defvar translated (concat "(" (translate thing) ")"))
172
+ (concat translated " && "
173
+ translated ".constructor.name === \"Array\""))
174
+
175
+
176
+ (defmacro when (arg &rest body)
177
+ (concat
178
+ "(function() {"
179
+ (indent (concat
180
+ "if (" (translate arg) ") {"
181
+ (indent (apply macros.progn body))
182
+ "}"))
183
+ "})()"))
184
+
185
+
186
+
187
+ (defmacro not (exp)
188
+ (concat "(!" (translate exp) ")"))
189
+
190
+ (defmacro slice (arr start &optional end)
191
+ (macros.send (translate arr) "slice" start end))
192
+
193
+ (defmacro inspect (&rest args)
194
+ (join " + \"\\n\" + "
195
+ (map args
196
+ (lambda (arg)
197
+ (concat "\"" arg ":\" + " (translate arg))))))
198
+
199
+ (defmacro each (item array &rest body)
200
+ (macros.send (translate array) 'for-each
201
+ (apply macros.lambda (cons item body))))
202
+
203
+
204
+ (defmacro setf (&rest args)
205
+ (join "\n"
206
+ (bulk-map args (lambda (name value)
207
+ (as-statement (concat (translate name) " = "
208
+ (translate value)))))))
209
+
210
+
211
+ (defmacro macro-list ()
212
+ (concat "["
213
+ (indent (join ",\n"
214
+ (map (-object.keys macros)
215
+ macros.quote)))
216
+ "]"))
217
+
218
+ (defmacro macroexpand (name)
219
+ (defvar macro (get macros (translate name)))
220
+ (if macro
221
+ (concat "// macro: " name "\n" (send macro to-string))
222
+ "undefined"))
223
+
224
+ (defmacro throw (&rest string)
225
+ (concat "throw new Error (" (join " " (map string translate)) ")"))
226
+
227
+ (defmacro as-boolean (expr)
228
+ (concat "(!!(" (translate expr) "))"))
229
+
230
+ (defmacro chain (object &rest calls)
231
+ (concat (translate object) " // chain"
232
+ (indent (join "\n"
233
+ (map calls
234
+ (lambda (call, index)
235
+ (defvar method (first call))
236
+ (defvar args (rest call))
237
+ (concat "." (translate method)
238
+ "(" (join ", " (map args translate)) ")")))))))
239
+
240
+ (defmacro try (tryblock catchblock)
241
+ (concat
242
+ "(function() {"
243
+ (indent (concat
244
+ "try {"
245
+ (indent (macros.progn tryblock))
246
+ "} catch (e) {"
247
+ (indent (macros.progn catchblock))
248
+ "}"))
249
+ "})()"))
250
+
251
+
252
+ (defmacro while (condition &rest block)
253
+ (macros.scoped
254
+ (macros.defvar '**return-value**)
255
+ (concat "while (" (translate condition) ") {"
256
+ (indent (macros.setf '**return-value**
257
+ (apply macros.scoped block))))
258
+ "}"
259
+ '**return-value**))
260
+
261
+ (defmacro until (condition &rest block)
262
+ (apply (get macros 'while)
263
+ (cons ['not condition] block)))
264
+
265
+
266
+ (defmacro thunk (&rest args)
267
+ (apply macros.lambda (cons [] args)))
268
+
269
+ (defmacro keys (obj)
270
+ (macros.call "Object.keys" (translate obj)))
271
+
272
+ (defmacro delete (&rest objects)
273
+ (join "\n" (map objects (lambda (obj)
274
+ (concat "delete " (translate obj) ";")))))
275
+
276
+ (defmacro delmacro (macro-name)
277
+ (delete (get macros (translate macro-name)))
278
+ "")
279
+
280
+ (defmacro alias-macro (current-macro-name desired-macro-name)
281
+ (defvar current-macro-name (translate current-macro-name)
282
+ desired-macro-name (translate desired-macro-name))
283
+ (set macros desired-macro-name (get macros current-macro-name))
284
+ "")
285
+
286
+ (defmacro rename-macro (current-macro-name desired-macro-name)
287
+ (macros.alias-macro current-macro-name desired-macro-name)
288
+ (macros.delmacro current-macro-name)
289
+ "")
290
+
291
+ (defmacro defhash (name &rest pairs)
292
+ (macros.defvar name (apply macros.hash pairs)))
293
+
294
+ (defmacro arguments ()
295
+ "(Array.prototype.slice.apply(arguments))")
296
+
297
+ (defmacro scoped (&rest body)
298
+ (macros.call (apply macros.thunk body)))
299
+
300
+ (defmacro each-key (as obj &rest body)
301
+ (concat "(function() {"
302
+ (indent
303
+ (concat "for (var " (translate as) " in " (translate obj) ") "
304
+ (apply macros.scoped body)
305
+ ";"))
306
+ "})();"))
307
+
308
+ (defmacro match? (regexp string)
309
+ (macros.send string 'match regexp))
310
+
311
+ (defmacro switch (obj &rest cases)
312
+
313
+ ;; the complexity of this macro indicates there's a problem
314
+ ;; I'm not quite sure where to fix this, but it has to do with quoting.
315
+ (defvar lines (list (concat "switch(" (translate obj) ") {")))
316
+ (each (case-def) cases
317
+ (defvar case-name (first case-def))
318
+ (when (and (list? case-name)
319
+ (= (first case-name) 'quote))
320
+ (defvar second (second case-name))
321
+ (setf case-name (if (list? second)
322
+ (map second macros.quote)
323
+ (macros.quote second))))
324
+
325
+ (defvar case-string
326
+ (if (list? case-name)
327
+ (join "\n" (map case-name (lambda (c)
328
+ (concat "case " (translate c) ":"))))
329
+ (if (= 'default case-name) "default:"
330
+ (concat "case " (translate case-name) ":"))))
331
+
332
+ (lines.push (concat case-string
333
+ (indent (apply macros.progn (case-def.slice 1))))))
334
+
335
+ ;; the following two lines are to get the whitespace right
336
+ ;; this is necessary because switches are indented weird
337
+ (set lines (- lines.length 1)
338
+ (chain (get lines (- lines.length 1)) (concat "}")))
339
+
340
+ (concat "(function() {" (apply indent lines) "})()"))
341
+
342
+
343
+ (defmacro if-else (&rest args)
344
+ (concat "(function() {"
345
+ (indent
346
+ (join " else "
347
+ (bulk-map args
348
+ (lambda (cond val)
349
+ (if (undefined? val)
350
+ (concat "{" (indent (macros.progn cond)) "}")
351
+ (concat "if (" (translate cond) ") {"
352
+ (indent (macros.progn val))
353
+ "}"))))))
354
+ "})()"))
355
+
356
+ (defmacro let (args &optional body)
357
+ (concat "let (" (bulk-map args
358
+ (lambda (h k v)
359
+ (concat (translate k) " = " (translate v))))
360
+ (if (undefined? body) ");"
361
+ (concat ") {" (indent (translate body)) "}"))))
362
+
363
+ (defmacro instance-of? (item type)
364
+ (concat "(" (translate item) " instanceof " (translate type) ")"))
365
+
366
+ (defmacro slice (list &optional begin &optional end)
367
+ (concat "Array.prototype.slice.call(" (translate list)
368
+ ", " (or (translate begin) 0)
369
+ (if (defined? end) (concat ", " (translate end) ")") ")")))
370
+
371
+ (defmacro ternary (cond if-true if-false)
372
+ (concat "(" (translate cond) ") ? "
373
+ (translate if-true) " : "
374
+ (translate if-false)))
@@ -0,0 +1,2 @@
1
+ (defmacro on (thing event &rest args-and-body)
2
+ (macros.send thing 'on (macros.quote event) (apply macros.lambda args-and-body)))