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.
- data/README.md +8 -4
- data/js/sibilant/.gitignore +4 -0
- data/js/sibilant/.travis.yml +6 -0
- data/js/sibilant/LICENSE +20 -0
- data/js/sibilant/README.md +70 -0
- data/js/sibilant/bin/sibilant +3 -0
- data/js/sibilant/cli-help +79 -0
- data/js/sibilant/include/functional.sibilant +57 -0
- data/js/sibilant/include/macros.sibilant +374 -0
- data/js/sibilant/include/node.sibilant +2 -0
- data/js/sibilant/lib/browser.js +685 -0
- data/js/sibilant/lib/cli.js +153 -0
- data/js/sibilant/lib/options.js +232 -0
- data/js/sibilant/lib/repl.js +78 -0
- data/js/sibilant/lib/sibilant.js +688 -0
- data/js/sibilant/misc/sibilant-mode.el +129 -0
- data/js/sibilant/package.json +19 -0
- data/js/sibilant/package.sibilant +16 -0
- data/js/sibilant/public/index.html +502 -0
- data/js/sibilant/public/javascripts/browser.js +685 -0
- data/js/sibilant/public/javascripts/jquery-ui.js +392 -0
- data/js/sibilant/public/javascripts/jquery.js +154 -0
- data/js/sibilant/public/javascripts/macros.sibilant +374 -0
- data/js/sibilant/public/javascripts/sibilant.info.sibilant +77 -0
- data/js/sibilant/public/sass/_mixins.sass +98 -0
- data/js/sibilant/public/sass/sibilant.sass +156 -0
- data/js/sibilant/public/stylesheets/Anonymous_Pro-webfont.eot +0 -0
- data/js/sibilant/public/stylesheets/Anonymous_Pro-webfont.svg +241 -0
- data/js/sibilant/public/stylesheets/Anonymous_Pro-webfont.ttf +0 -0
- data/js/sibilant/public/stylesheets/Anonymous_Pro-webfont.woff +0 -0
- data/js/sibilant/public/stylesheets/sibilant.css +166 -0
- data/js/sibilant/src/browser.sibilant +45 -0
- data/js/sibilant/src/cli.sibilant +93 -0
- data/js/sibilant/src/core.sibilant +338 -0
- data/js/sibilant/src/options.sibilant +65 -0
- data/js/sibilant/src/repl.sibilant +59 -0
- data/js/sibilant/src/sibilant.sibilant +78 -0
- data/js/sibilant/test/defvar.sibilant +5 -0
- data/js/sibilant/test/includeFile1.sibilant +1 -0
- data/js/sibilant/test/includeFile2.sibilant +1 -0
- data/js/sibilant/test/node.sibilant +10 -0
- data/js/sibilant/test/slice.sibilant +3 -0
- data/js/sibilant/test/test.sibilant +464 -0
- data/js/sibilant/test/testHelper.sibilant +80 -0
- data/lib/sibilant/version.rb +1 -1
- data/sibilant.gemspec +3 -1
- 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>
|