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