sibilant 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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)))