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
@@ -0,0 +1,129 @@
1
+ ;;; sibilant-mode.el --- Major mode for Sibilant Lisp
2
+
3
+ ;; I should mention that I looked at clojure-mode
4
+ ;; (https://github.com/jochu/clojure-mode) when writing this.
5
+
6
+ (require 'cl)
7
+
8
+ (defgroup sibilant-mode nil
9
+ "A mode for Sibilant Lisp"
10
+ :prefix "sibilant-mode-"
11
+ :group 'applications)
12
+
13
+ (defvar sibilant-mode-map
14
+ (let ((map (make-sparse-keymap)))
15
+ (set-keymap-parent map lisp-mode-shared-map)
16
+ (define-key map (kbd "RET") 'reindent-then-newline-and-indent)
17
+ map)
18
+ "Keymap for Sibilant mode. Inherits from `lisp-mode-shared-map'.")
19
+
20
+ (defvar sibilant-mode-syntax-table
21
+ (let ((table (copy-syntax-table emacs-lisp-mode-syntax-table)))
22
+ (modify-syntax-entry ?: "." table)
23
+ (modify-syntax-entry ?, "." table)
24
+ (modify-syntax-entry ?\{ "(}" table)
25
+ (modify-syntax-entry ?\} "){" table)
26
+ (modify-syntax-entry ?\[ "(]" table)
27
+ (modify-syntax-entry ?\] ")[" table)
28
+ (modify-syntax-entry ?/ "|" table)
29
+ table))
30
+
31
+ ;;;###autoload
32
+ (defun sibilant-mode ()
33
+ "Major mode for editing Sibilant code - similar to Lisp mode."
34
+ (interactive)
35
+ (kill-all-local-variables)
36
+ (use-local-map sibilant-mode-map)
37
+ (setq major-mode 'sibilant-mode)
38
+ (setq mode-name "Sibilant")
39
+ (lisp-mode-variables nil)
40
+
41
+ (set-syntax-table sibilant-mode-syntax-table)
42
+
43
+ (set (make-local-variable 'lisp-indent-function)
44
+ 'sibilant-indent-function)
45
+
46
+ (sibilant-mode-font-lock-setup)
47
+
48
+ (run-mode-hooks 'sibilant-mode-hook))
49
+
50
+ (defun sibilant-mode-font-lock-setup ()
51
+ "Configures font-lock for editing Sibilant code."
52
+ (interactive)
53
+ (setq font-lock-defaults
54
+ '(sibilant-font-lock-keywords)))
55
+
56
+ (defconst sibilant-font-lock-keywords
57
+ '(("(\\(defun\\|defmacro\\)[ \t\n\r]+\\([[:alnum:].-]+[?!]?\\)[ \t\r\n]+(\\(.*?\\))"
58
+ (1 font-lock-keyword-face)
59
+ (2 font-lock-function-name-face)
60
+ (3 font-lock-variable-name-face))
61
+ ("(\\(lambda\\)[[:space:]]+(\\(.*?\\))"
62
+ (1 font-lock-keyword-face)
63
+ (2 font-lock-variable-name-face))
64
+ ("(\\(defvar\\|setf?\\)[ \r\n\t]+\\([[:alnum:].-]+[?!]?\\)"
65
+ (1 font-lock-keyword-face)
66
+ (2 font-lock-variable-name-face))
67
+ ("(\\(thunk\\|if\\|when\\|apply\\|concat\\|throw\\|switch\\|each\\|chain\\|try\\|progn\\|call\\|default\\)[ \t\r\n)]+"
68
+ (1 font-lock-builtin-face))
69
+ ("&[[:alnum:]]+" . font-lock-keyword-face)
70
+ ("'[[:alnum:].-]+[?!]?" . font-lock-string-face)
71
+ ("(\\([[:alnum:].-]+[?!]?\\)" (1 font-lock-constant-face nil t))
72
+ ))
73
+
74
+
75
+ (defun sibilant-indent-function (indent-point state)
76
+ (let ((normal-indent (current-column)))
77
+ (goto-char (1+ (elt state 1)))
78
+ (parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t)
79
+ (let ((function (buffer-substring (point)
80
+ (progn (forward-sexp 1) (point))))
81
+ (open-paren (elt state 1))
82
+ method)
83
+
84
+ (setq method (get (intern-soft function) 'sibilant-indent-function))
85
+
86
+ (cond
87
+ ((member (char-after open-paren) '(?\[ ?\{))
88
+ (goto-char open-paren)
89
+ (+ 2 (current-column)))
90
+
91
+ ((eq method 'defun)
92
+ (lisp-indent-defform state indent-point))
93
+
94
+ ((integerp method)
95
+ (lisp-indent-specform method state indent-point normal-indent))
96
+
97
+ (method
98
+ (funcall method indent-point state))))))
99
+
100
+
101
+ (defun put-sibilant-indent (sym indent)
102
+ (put sym 'sibilant-indent-function indent))
103
+
104
+ (defmacro define-sibilant-indent (&rest kvs)
105
+ `(progn
106
+ ,@(mapcar (lambda (x) `(put-sibilant-indent
107
+ (quote ,(first x)) ,(second x))) kvs)))
108
+
109
+ (define-sibilant-indent
110
+ (lambda 'defun)
111
+ (defun 'defun)
112
+ (defmacro 'defun)
113
+ (if 1)
114
+ (when 1)
115
+ (while 1)
116
+ (try 0)
117
+ (switch 1)
118
+ (progn 0)
119
+ (scoped 0)
120
+ (for 1)
121
+ (chain 1)
122
+ (each 2)
123
+ (thunk 0))
124
+
125
+ ;;;###autoload
126
+ (add-to-list 'auto-mode-alist '("\\.sib\\(?:ilant\\)?$" . sibilant-mode))
127
+
128
+ (provide 'sibilant-mode)
129
+ ;;; sibilant-mode.el ends here
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "sibilant",
3
+ "version": "0.1.3",
4
+ "keywords": [ "lisp", "javascript", "language" ],
5
+ "description": "javascript with a lisp",
6
+ "contributors": [ "Jacob Rothstein <hi@jbr.me> (http://jbr.me)", "Matthew Phillips (http://www.matthewphillips.info/)", "Yuest Wang (http://yue.st/)", "Lyndon Tremblay (http://www.hoovy.org)", "David Sargeant (https://github.com/dubiousdavid)" ],
7
+ "repositories": {
8
+ "type": "git",
9
+ "url": "http://github.com/jbr/sibilant.git"
10
+ },
11
+ "bugs": {
12
+ "mail": "sibilant@librelist.com",
13
+ "url": "http://github.com/jbr/sibilant/issues"
14
+ },
15
+ "bin": { "sibilant": "./bin/sibilant" },
16
+ "main": "./lib/sibilant",
17
+ "scripts": { "test": "node ./bin/sibilant test/test.sibilant -x" }
18
+ }
19
+
@@ -0,0 +1,16 @@
1
+ { 'name 'sibilant
2
+ 'version "0.1.3"
3
+ 'keywords '(lisp javascript language)
4
+ 'description "javascript with a lisp"
5
+ 'contributors [ "Jacob Rothstein <hi@jbr.me> (http://jbr.me)"
6
+ "Matthew Phillips (http://www.matthewphillips.info/)"
7
+ "Yuest Wang (http://yue.st/)"
8
+ "Lyndon Tremblay (http://www.hoovy.org)"
9
+ "David Sargeant (https://github.com/dubiousdavid)" ]
10
+ 'repositories { 'type 'git
11
+ 'url "http://github.com/jbr/sibilant.git" }
12
+ 'bugs { 'mail "sibilant@librelist.com"
13
+ 'url "http://github.com/jbr/sibilant/issues" }
14
+ 'bin { 'sibilant "./bin/sibilant" }
15
+ 'main "./lib/sibilant"
16
+ 'scripts { 'test "node ./bin/sibilant test/test.sibilant -x" }}
@@ -0,0 +1,502 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <script src="/javascripts/jquery.js"></script>
5
+ <script src="/javascripts/jquery-ui.js"></script>
6
+ <script src="/javascripts/macros.sibilant" type="text/sibilant"></script>
7
+ <script src="/javascripts/sibilant.info.sibilant" type="text/sibilant"></script>
8
+ <script src="/javascripts/browser.js"></script>
9
+ <link rel="stylesheet" href="/stylesheets/sibilant.css"/>
10
+ <title>Sibilant: Javascript with a lisp</title>
11
+ <script type="text/javascript">
12
+ var _gaq = _gaq || [];
13
+ _gaq.push(['_setAccount', 'UA-17635250-1']);
14
+ _gaq.push(['_trackPageview']);
15
+
16
+ (function() {
17
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
18
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
19
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
20
+ })();
21
+ </script>
22
+ </head>
23
+ <body>
24
+ <header>
25
+ <h1>SibilantJS</h1>
26
+ <h2>stuff</h2>
27
+ <div id="controls">
28
+ <a id="prev" href="#">Previous</a>
29
+ <a id="next" href="#">Next</a>
30
+ </div>
31
+ </header>
32
+
33
+ <a id="fork-me-on-github" href="http://github.com/jbr/sibilant">
34
+ <span>Fork me on github</span>
35
+ </a>
36
+
37
+ <div id="left">
38
+ <textarea name="content">
39
+ </textarea>
40
+ </div>
41
+
42
+ <div id="right">
43
+ <pre id="output">
44
+ </pre>
45
+ </div>
46
+
47
+
48
+ <script id="welcome" language="sibilant/example" data-title="Welcome">
49
+ ; Welcome to the sibilant tutorial.
50
+ ; Sibilant code and comments will
51
+ ; appear in the left column and
52
+ ; the equivalent javascript will
53
+ ; be generated by your browser
54
+ ; in the right column.
55
+ ;
56
+ ;
57
+ ; You can edit the sibilant code
58
+ ; at any time to see how the js
59
+ ; changes.
60
+ ;
61
+ ;
62
+ ; Press the next button
63
+ ; to begin.
64
+ </script>
65
+
66
+ <script id="numbers-and-strings"
67
+ language="sibilant/example"
68
+ data-title="Literals: Numbers & Strings">
69
+ <![CDATA[
70
+ ; Numbers should look pretty familiar
71
+ ;
72
+ 5
73
+ 10.5
74
+ -100.5
75
+ ;
76
+ ; Use commas for readability
77
+ ;
78
+ 1,000,000.00
79
+ ;
80
+ ; Strings start and end
81
+ ; with a double quote.
82
+ ;
83
+ "hello world"
84
+ "he said to them \"hello\""
85
+ "multiline strings
86
+ are allowed"
87
+ ]]>
88
+ </script>
89
+
90
+ <script id="literal-variables"
91
+ language="sibilant/example"
92
+ data-title="Literals: Variable names">
93
+ <![CDATA[
94
+ "Variable names may include letters,
95
+ the period (.) and the hyphen (-).
96
+ Lower case letters are idiomatic.
97
+ They may end with a question mark (?) or with a
98
+ bang (!). They may start with a sigil ($)."
99
+
100
+ simple
101
+ multi-word-variable-name
102
+ is-this-thing-on?
103
+ save!
104
+ variable-number-5
105
+ $jquery
106
+ JSON
107
+
108
+ ]]>
109
+ </script>
110
+
111
+
112
+ <script id="quoting"
113
+ language="sibilant/example"
114
+ data-title="Quoting">
115
+ <![CDATA[
116
+ ; Sibilant supports quoting
117
+ ; with the single quote (').
118
+ ; Anything that is a legal
119
+ ; variable name can be
120
+ ; quoted, as well as lists.
121
+
122
+ 'a
123
+ 'this-is-a-multi-word-quote
124
+ '(a b c d e)
125
+
126
+ ; This is equivalent to:
127
+ ;
128
+ (quote a)
129
+ (quote this-is-a-multi-word-quote)
130
+ (quote (a b c d e))
131
+ ]]>
132
+ </script>
133
+
134
+
135
+ <script id="lists"
136
+ language="sibilant/example"
137
+ data-title="Lists">
138
+ <![CDATA[
139
+ ; Lists are made with the list macro
140
+ ; and can be nested infinitely.
141
+ ; A list translates to a javascript
142
+ ; array.
143
+
144
+ (list hello
145
+ '(q r s)
146
+ (list foo bar baz))
147
+
148
+ ; [ a b c ] is a shortcut for (list a b c)
149
+
150
+ [ a 'b 'c (this-is 'still-sibilant) ]
151
+
152
+ ]]>
153
+ </script>
154
+
155
+ <script id="hashes"
156
+ language="sibilant/example"
157
+ data-title="Hashes/Objects">
158
+ <![CDATA[
159
+ ; Sibilant supports javascript
160
+ ; hash-objects by way of the
161
+ ; hash macro:
162
+ (hash key-one value-one
163
+ key-two value-two)
164
+
165
+ (hash a b c d e f)
166
+
167
+ ; { a b } is a shortcut for (hash a b)
168
+ { a 'b c (+ 1 2 3) }
169
+ </script>
170
+
171
+
172
+ <script id="defining-variables"
173
+ language="sibilant/example"
174
+ data-title="Defining Variables">
175
+ <![CDATA[
176
+ ; Define a variable with the defvar
177
+ ; macro. This translates directly
178
+ ; to the var keyword in javascript.
179
+
180
+ (defvar foo 35)
181
+ (defvar wibble "test")
182
+ (defvar bar '(multi word array))
183
+
184
+ (defvar var1 val1
185
+ var2 val2)
186
+
187
+ ; To modify an existing variable,
188
+ ; use setf.
189
+
190
+ (setf foo 10)
191
+ (setf a 1
192
+ b 2)
193
+ ]]>
194
+ </script>
195
+
196
+
197
+ <script id="functions"
198
+ language="sibilant/example"
199
+ data-title="Defining Functions">
200
+ <![CDATA[
201
+ (defun alert-hello (planet-name)
202
+ (defvar message (concat "hello " planet-name))
203
+ (alert message)
204
+ message)
205
+
206
+ (defvar my-message (alert-hello 'world))
207
+ ; my-message is now "hello world"
208
+ ]]>
209
+ </script>
210
+
211
+ <script id="variable-count-arguments"
212
+ language="sibilant/example"
213
+ data-title="Variable count arguments">
214
+ <![CDATA[
215
+ (defun alert-each-argument(&rest my-arguments)
216
+ (each (arg) my-arguments (alert arg)))
217
+
218
+ (alert-each-argument 'hello 'world 'foo)
219
+ ]]>
220
+ </script>
221
+
222
+ <script id="optional-arguments"
223
+ language="sibilant/example"
224
+ data-title="Optional arguments">
225
+ <![CDATA[
226
+ ; Optional arguments are specified with
227
+ ; &optional. If there are fewer than the
228
+ ; total number of possible arguments,
229
+ ; optional arguments are skipped. If
230
+ ; there are several, they are filled
231
+ ; from left to right.
232
+
233
+ (defun has-optional-arg (&optional optional-arg
234
+ mandatory-arg)
235
+ (when (defined? optional-argument)
236
+ (alert "optional provided"))
237
+ mandatory-arg)
238
+
239
+ (has-optional-arg "only one arg")
240
+ (has-optional-arg true "return value")
241
+ ]]>
242
+ </script>
243
+
244
+
245
+ <script id="lambdas"
246
+ language="sibilant/example"
247
+ data-title="Lambdas">
248
+ <![CDATA[
249
+ ; (lambda) works much like (defun)
250
+ ; This example uses Node's async
251
+ ; readfile
252
+
253
+ (defvar fs (require 'fs))
254
+
255
+ (fs.read-file "path/to/file"
256
+ (lambda (error content)
257
+ (alert (or error content))))
258
+ ]]>
259
+ </script>
260
+
261
+
262
+ <script id="when"
263
+ data-title="When"
264
+ language="sibilant/example">
265
+ <![CDATA[
266
+ ; `when` is the simplest conditional.
267
+ ; It only considers the true case.
268
+ ; `when` will return the value of the
269
+ ; last statement
270
+
271
+ (defvar this-will-be-true (when (= 5 (+ 3 2))
272
+ (alert "we've got a five")
273
+ (post-to-twitter "three and two is five")
274
+ true))
275
+ ]]>
276
+ </script>
277
+
278
+ <script id="if" data-title="If"
279
+ language="sibilant/example">
280
+ <![CDATA[
281
+ ; `if` is like `when` with an "else."
282
+ (defvar a-or-b (if (< 0.5 (-math.random)) 'a 'b))
283
+
284
+ ; Unlike when, cases may only be a single
285
+ ; statement. Use progn to execute several
286
+ ; statements.
287
+
288
+ (defvar a-or-b
289
+ (if (< 0.5 (-math.random))
290
+ (progn
291
+ (log "random was more than 0.5")
292
+ 'a)
293
+ (progn
294
+ (log "random was less than 0.5")
295
+ 'b)))
296
+ ]]>
297
+ </script>
298
+
299
+ <script id="switch"
300
+ data-title="Switch"
301
+ language="sibilant/example">
302
+ <![CDATA[
303
+ ; Switch allows you to check a variable
304
+ ; against any number of possible values.
305
+
306
+ (defvar comment (switch month-name
307
+ ('january
308
+ (increment year)
309
+ "happy new year!")
310
+ ('(february march) "still pretty cold")
311
+ ('april "expect showers")
312
+ ("may" "flowers!")
313
+ ('(june july august)
314
+ (enjoy 'sunshine)
315
+ 'summer)
316
+ ('(september october) "leaves change")
317
+ ('(november december) "getting chilly")
318
+ (default
319
+ (record-unexpected-month month-name)
320
+ "I didn't recognize that")))
321
+
322
+ ]]>
323
+ </script>
324
+
325
+ <script id="iteration-with-each"
326
+ data-title="Iteration with each"
327
+ language="sibilant/example">
328
+ <![CDATA[
329
+ ; To iterate over an array, use the each
330
+ ; macro.
331
+
332
+ (defvar list '(a b c d e))
333
+ (each (letter) list
334
+ (when (= "C" (letter.to-upper-case))
335
+ (console.log "this was a c"))
336
+ (console.log letter))
337
+
338
+ ]]>
339
+ </script>
340
+
341
+ <script id="while"
342
+ data-title="While"
343
+ language="sibilant/example">
344
+ <![CDATA[
345
+ (defvar wall-bottle-count 99)
346
+
347
+ (defun take-one-down ()
348
+ (decr wall-bottle-count)
349
+ the-bottle)
350
+
351
+ (while (> wall-bottle-count 0)
352
+ (defvar bottle (take-one-down))
353
+ (each (person) room
354
+ (while (not (empty? bottle))
355
+ (sip bottle))))
356
+
357
+ ]]>
358
+ </script>
359
+
360
+ <script id="chain"
361
+ data-title="Chaining function calls"
362
+ language="sibilant/example">
363
+ <![CDATA[
364
+ ; It is often idiomatic in javascript libraries
365
+ ; to chain function calls. Here's how that looks
366
+ ; in sibilant:
367
+
368
+ (chain ($ ".some.random#tag")
369
+ (show)
370
+ (css { background-color 'red })
371
+ (animate { width 100 })
372
+ (click (lambda (evt)
373
+ (chain ($ this)
374
+ (hide)
375
+ (data 'clicked true))
376
+ true)))
377
+ ]]>
378
+ </script>
379
+
380
+ <script id="macro-intro"
381
+ data-title="Sibilant is mostly macros"
382
+ language="sibilant/example">
383
+ <![CDATA[
384
+ "Now we're getting into advanced stuff.
385
+ Go get a cup of tea or some fresh air.
386
+ I'll be here when you get back.
387
+
388
+ The real power of sibilant is the ability
389
+ to define (and redefine) macros, extending
390
+ the language. All constructs can be
391
+ redefined. This includes core language
392
+ features like +, lambda, if, defun, defvar,
393
+ and even defmacro itself.
394
+
395
+ Defining macros is as easy as defining
396
+ functions, but modify the interpreter
397
+ instead of outputting compiled js.
398
+ Most of sibilant is defined like this:
399
+
400
+ http://http://j.mp/sibilantmacros"
401
+
402
+ ]]>
403
+ </script>
404
+
405
+ <script id="defining-macros"
406
+ data-title="Defining your own macros"
407
+ language="sibilant/example">
408
+ <![CDATA[
409
+ "As an example, let's say you want to
410
+ add a ternary conditional macro to sibilant.
411
+ Let's call it 'cond'."
412
+
413
+ (defmacro cond (cond true-value false-value)
414
+ (concat (translate cond) " ? "
415
+ (translate true-value) " : "
416
+ (translate false-value) ";"))
417
+
418
+ (cond (< 0.5 (-math.random)) 'yep 'nah)
419
+
420
+ ; once removed, cond is just a function call
421
+ (delmacro cond)
422
+ (cond (< 0.5 (-math.random)) 'yep 'nah)
423
+ ]]>
424
+ </script>
425
+
426
+
427
+ <script id="redefining-macros"
428
+ data-title="Redefining existing macros"
429
+ language="sibilant/example">
430
+ <![CDATA[
431
+ ; All macros can be redefined, and
432
+ ; most of sibilant is macros.
433
+
434
+ ; Let's say we want to add newlines
435
+ ; after the commas in a list if
436
+ ; there are more than two items.
437
+
438
+ (defmacro list (&rest args)
439
+ (concat "["
440
+ (if (> 3 args.length)
441
+ (concat " "
442
+ (join ", " (map args translate)) " ")
443
+ (indent (join ",\n" (map args translate))))
444
+ "]"))
445
+
446
+ (list a b)
447
+ (list a b c)
448
+ ]]>
449
+ </script>
450
+
451
+ <script id="macroexpand"
452
+ data-title="Expanding macros"
453
+ language="sibilant/example">
454
+ <![CDATA[
455
+ ; Want to find out how a macro is
456
+ ; defined in js? Try macroexpand.
457
+
458
+ (macroexpand if)
459
+
460
+ (macroexpand defined?)
461
+
462
+ (macroexpand first)
463
+
464
+ ]]>
465
+ </script>
466
+
467
+
468
+ <script id="macro-list"
469
+ data-title="Listing available macros"
470
+ language="sibilant/example">
471
+ <![CDATA[
472
+ ; use macro-list to find out what
473
+ ; macros are available
474
+
475
+ (macro-list)
476
+ ]]>
477
+ </script>
478
+
479
+ <script id="json"
480
+ data-title="JSON is valid sibilant"
481
+ language="sibilant/example">
482
+ <![CDATA[
483
+ "Example from http://www.json.org/example.html:"
484
+
485
+ {"menu": {
486
+ "id": "file",
487
+ "value": "File",
488
+ "popup": {
489
+ "menuitem": [
490
+ {"value": "New", "onclick": "CreateNewDoc()"},
491
+ {"value": "Open", "onclick": "OpenDoc()"},
492
+ {"value": "Close", "onclick": "CloseDoc()"}
493
+ ]
494
+ }
495
+ }}
496
+ ]]>
497
+ </script>
498
+
499
+
500
+
501
+ </body>
502
+ </html>