apricot 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/.gitignore +3 -0
  2. data/.rspec +1 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +7 -0
  5. data/Gemfile +6 -0
  6. data/Gemfile.lock +26 -0
  7. data/README.md +90 -0
  8. data/Rakefile +9 -0
  9. data/apricot.gemspec +22 -0
  10. data/bin/apricot +58 -0
  11. data/examples/bot.apr +23 -0
  12. data/examples/cinch-bot.apr +12 -0
  13. data/examples/hanoi.apr +10 -0
  14. data/examples/hello.apr +1 -0
  15. data/examples/plot.apr +28 -0
  16. data/examples/quine.apr +1 -0
  17. data/kernel/core.apr +928 -0
  18. data/lib/apricot/ast/identifier.rb +111 -0
  19. data/lib/apricot/ast/list.rb +99 -0
  20. data/lib/apricot/ast/literals.rb +240 -0
  21. data/lib/apricot/ast/node.rb +45 -0
  22. data/lib/apricot/ast/scopes.rb +147 -0
  23. data/lib/apricot/ast/toplevel.rb +66 -0
  24. data/lib/apricot/ast/variables.rb +64 -0
  25. data/lib/apricot/ast.rb +3 -0
  26. data/lib/apricot/compiler.rb +55 -0
  27. data/lib/apricot/cons.rb +27 -0
  28. data/lib/apricot/errors.rb +38 -0
  29. data/lib/apricot/generator.rb +15 -0
  30. data/lib/apricot/identifier.rb +91 -0
  31. data/lib/apricot/list.rb +96 -0
  32. data/lib/apricot/macroexpand.rb +47 -0
  33. data/lib/apricot/misc.rb +11 -0
  34. data/lib/apricot/namespace.rb +59 -0
  35. data/lib/apricot/parser.rb +541 -0
  36. data/lib/apricot/printers.rb +12 -0
  37. data/lib/apricot/repl.rb +254 -0
  38. data/lib/apricot/ruby_ext.rb +254 -0
  39. data/lib/apricot/seq.rb +44 -0
  40. data/lib/apricot/special_forms.rb +735 -0
  41. data/lib/apricot/stages.rb +60 -0
  42. data/lib/apricot/version.rb +3 -0
  43. data/lib/apricot.rb +30 -0
  44. data/spec/compiler_spec.rb +499 -0
  45. data/spec/identifier_spec.rb +58 -0
  46. data/spec/list_spec.rb +96 -0
  47. data/spec/parser_spec.rb +312 -0
  48. data/spec/spec_helper.rb +10 -0
  49. metadata +188 -0
data/kernel/core.apr ADDED
@@ -0,0 +1,928 @@
1
+ ; The core apricot library
2
+
3
+ (ns Apricot::Core)
4
+
5
+ ; Basics
6
+
7
+ (def raise Kernel/raise)
8
+
9
+ ; Needed in defn, will redefine with documentation later.
10
+ (def list
11
+ (fn list [& items]
12
+ (.to_list items)))
13
+
14
+ ; Needed in defn, will redefine with documentation later.
15
+ (def concat
16
+ (fn concat [& colls]
17
+ (.to_list (.reduce (.map colls | :to_a) [] :+))))
18
+
19
+ (def defn
20
+ (fn defn [name & body]
21
+ (let [doc-string (if (.is_a? (.first body) String)
22
+ (.shift body))
23
+ metadata (if (.is_a? (.first body) Hash)
24
+ (.shift body)
25
+ {})
26
+ arglists (if (.is_a? (.first body) Array)
27
+ (list (.first body))
28
+ (.to_list
29
+ (.map body | #(if (.is_a? % Apricot::List)
30
+ (.first %)))))
31
+ f (.intern Apricot::Identifier (.gensym Apricot))]
32
+ (list 'let [f (concat (list 'fn name) body)]
33
+ (list 'def name f)
34
+ (list '.apricot_meta=
35
+ f
36
+ (.merge! {:name (list 'quote name)
37
+ :doc doc-string
38
+ :arglists (list 'quote arglists)}
39
+ metadata))
40
+ f))))
41
+ (.apricot_meta=
42
+ defn
43
+ {:name 'defn
44
+ :doc "Define a new function."
45
+ :arglists '([name doc-string? metadata? [params ...] body]
46
+ [name doc-string? metadata? ([params ...] body) ...+])
47
+ :macro true})
48
+
49
+ (defn defmacro
50
+ "Like defn, but the resulting function name is declared as a macro and will
51
+ be used as a macro by the compiler when it is called."
52
+ {:arglists '([name doc-string? metadata? [params ...] body]
53
+ [name doc-string? metadata? ([params ...] body) ...+])
54
+ :macro true}
55
+ [name & body]
56
+ (let [f (.intern Apricot::Identifier (.gensym Apricot))]
57
+ (list 'let [f (concat (list 'defn name) body)]
58
+ (list '.store (list '.apricot_meta f) :macro true)
59
+ f)))
60
+
61
+ (defn list
62
+ "Create a new list containing the items."
63
+ [& items] (.to_list items))
64
+
65
+ (defn concat
66
+ "Concatenate the items in the supplied colls into a single list."
67
+ [& colls] (.to_list (.reduce (.map colls | :to_a) [] :+)))
68
+
69
+ (defn array
70
+ "Create a new array containing the items."
71
+ [& items] items)
72
+
73
+ (defn set
74
+ "Create a new set containing the items."
75
+ [& items] (Set. items))
76
+
77
+ (defn hash
78
+ "Create a new hash map from the items. The items are interpreted as a list of
79
+ key/value pairs so there must be an even number of them."
80
+ [& items]
81
+ (if (.even? (.length items))
82
+ (let [h {}]
83
+ (.each_slice items 2 | #(.store h %1 %2))
84
+ h)
85
+ (raise ArgumentError "hash requires an even number of arguments")))
86
+
87
+ (defn cons
88
+ "Return a new list where head is the first element and tail is the rest."
89
+ [head tail] (Apricot::Cons. head tail))
90
+
91
+ (defn apply
92
+ "Applies fn f to the argument list formed by prepending intervening
93
+ arguments to args."
94
+ ([f args]
95
+ (.apricot_call f & args))
96
+ ([f x & args]
97
+ (.apricot_call f & (cons x (.concat args (.pop args))))))
98
+
99
+ ;; At this point everything is defined that syntax quote requires
100
+
101
+ (defn identifier
102
+ "Return an identifier with the given name."
103
+ [name] (.intern Apricot::Identifier name))
104
+
105
+ (defn symbol
106
+ "Return a symbol with the given name."
107
+ [name] (.to_sym name))
108
+
109
+ (defn gensym
110
+ "Return a new identifier with a unique name. If a prefix string is supplied,
111
+ the name is prefix__# where # is some unique number. If prefix is not
112
+ supplied, the prefix is 'g'."
113
+ [[prefix "g"]]
114
+ (identifier (.gensym Apricot prefix)))
115
+
116
+ (defn require
117
+ "Require the given Ruby files. Works just like using Ruby's 'require' on
118
+ each of the arguments."
119
+ [& files]
120
+ ; (. Kernel require %) does not call the Rubygems custom require for some
121
+ ; reason, so we use this method. (MAIN is the special toplevel object).
122
+ (.each files | #(. MAIN send :require %)))
123
+
124
+ (defn str
125
+ "With no args, return the empty string. With one arg x, return x converted
126
+ to a string. With more than one arg, return the concatenation of the str
127
+ values of the args."
128
+ ([] "")
129
+ ([x] (.apricot_str x))
130
+ ([x & args]
131
+ (.reduce args (.apricot_str x) | #(.concat %1 (.apricot_str %2)))))
132
+
133
+ (defn print
134
+ "Print the object(s) to standard output."
135
+ [& args] (Kernel/print (apply str args)))
136
+
137
+ (defn println
138
+ "Print the object(s) followed by a newline at the end to standard output."
139
+ [& args] (Kernel/puts (apply str args)))
140
+
141
+ (def macroexpand Apricot/macroexpand)
142
+ (def macroexpand-1 Apricot/macroexpand_1)
143
+
144
+ ; Type predicates
145
+
146
+ (defn instance?
147
+ "Test if x is an instance of class c. Return true or false."
148
+ [c x] (.is_a? x c))
149
+
150
+ (defn module?
151
+ "Return true if x is an instance of Module."
152
+ [x] (instance? Module x))
153
+
154
+ (defn class?
155
+ "Return true if x is an instance of Class."
156
+ [x] (instance? Class x))
157
+
158
+ (defn seq?
159
+ "Return true if x is an instance of an Apricot::Seq class."
160
+ [x] (instance? Apricot::Seq x))
161
+
162
+ (defn array?
163
+ "Return true if x is an instance of Array."
164
+ [x] (instance? Array x))
165
+
166
+ (defn list?
167
+ "Return true if x is an instance of Apricot::List."
168
+ [x] (instance? Apricot::List x))
169
+
170
+ (defn hash?
171
+ "Return true if x is an instance of Hash."
172
+ [x] (instance? Hash x))
173
+
174
+ (defn set?
175
+ "Return true if x is an instance of Set."
176
+ [x] (instance? Set x))
177
+
178
+ (defn string?
179
+ "Return true if x is an instance of String."
180
+ [x] (instance? String x))
181
+
182
+ (defn regexp?
183
+ "Return true if x is an instance of Regexp."
184
+ [x] (instance? Regexp x))
185
+
186
+ (defn identifier?
187
+ "Return true if x is an instance of Apricot::Identifier."
188
+ [x] (instance? Apricot::Identifier x))
189
+
190
+ (defn symbol?
191
+ "Return true if x is an instance of Symbol."
192
+ [x] (instance? Symbol x))
193
+
194
+ (defn number?
195
+ "Return true if x is an instance of Numeric."
196
+ [x] (instance? Numeric x))
197
+
198
+ (defn ratio?
199
+ "Return true if x is an instance of Rational."
200
+ [x] (instance? Rational x))
201
+
202
+ (defn integer?
203
+ "Return true if x is an instance of Integer."
204
+ [x] (instance? Integer x))
205
+
206
+ (defn fixnum?
207
+ "Return true if x is an instance of Fixnum."
208
+ [x] (instance? Fixnum x))
209
+
210
+ (defn bignum?
211
+ "Return true if x is an instance of Bignum."
212
+ [x] (instance? Bignum x))
213
+
214
+ (defn float?
215
+ "Return true if x is an instance of Float."
216
+ [x] (instance? Float x))
217
+
218
+ (defn complex?
219
+ "Return true if x is an instance of Complex."
220
+ [x] (instance? Complex x))
221
+
222
+ (defn range?
223
+ "Return true if x is an instance of Range."
224
+ [x] (instance? Range x))
225
+
226
+ (defn comparable?
227
+ "Return true if x is an instance of a Comparable class."
228
+ [x] (instance? Comparable x))
229
+
230
+ (defn enumerable?
231
+ "Return true if x is an instance of an Enumerable class."
232
+ [x] (instance? Enumerable x))
233
+
234
+ ; Basic logic predicates, functions, and macros
235
+
236
+ (defn nil?
237
+ "Return true if x is nil, false otherwise."
238
+ [x] (.nil? x))
239
+
240
+ (defn true?
241
+ "Return true if x is the value true, false otherwise."
242
+ [x] (.equal? x true))
243
+
244
+ (defn false?
245
+ "Return true if x is the value false, false otherwise."
246
+ [x] (.equal? x false))
247
+
248
+ (defn not
249
+ "Return true if x is logical false, false otherwise."
250
+ [x] (if x false true))
251
+
252
+ (defmacro and
253
+ "Evaluate exprs one at a time, from left to right. If a form returns logical
254
+ false (nil or false), return that value and don't evaluate any of the other
255
+ expressions, otherwise return the value of the last expr. (and) returns
256
+ true."
257
+ ([] true)
258
+ ([x] x)
259
+ ([x & more]
260
+ `(let [and# ~x]
261
+ (if and# (and ~@more) and#))))
262
+
263
+ (defmacro or
264
+ "Evaluate exprs one at a time, from left to right. If a form returns a
265
+ logical true value, return that value and don't evaluate any of the other
266
+ expressions, otherwise return the value of the last expression. (or) returns
267
+ nil."
268
+ ([] nil)
269
+ ([x] x)
270
+ ([x & more]
271
+ `(let [or# ~x]
272
+ (if or# or# (or ~@more)))))
273
+
274
+ ; Collection functions
275
+
276
+ (defn seq
277
+ "Returns a seq on the collection. If the collection is empty, returns nil.
278
+ (seq nil) returns nil."
279
+ [coll] (.to_seq coll))
280
+
281
+ (defn first
282
+ "Return the first item in the collection. Call seq on the argument. If coll
283
+ is nil, return nil."
284
+ [coll] (.first (seq coll)))
285
+
286
+ (defn rest
287
+ "Return a possibly empty seq of the items after the first. Call seq on the
288
+ argument."
289
+ [coll] (.rest (seq coll)))
290
+
291
+ (defn next
292
+ "Return a seq of the items after the first. Call seq on the argument. If
293
+ there are no more items, return nil."
294
+ [coll] (.next (seq coll)))
295
+
296
+ (defn empty?
297
+ "Return true if coll has no items - same as (not (seq coll)). Please use the
298
+ idiom (seq x) rather than (not (empty? x))"
299
+ [coll] (not (seq coll)))
300
+
301
+ (defn second
302
+ "Same as (first (next coll))."
303
+ [coll] (first (next coll)))
304
+
305
+ (defn ffirst
306
+ "Same as (first (first coll))."
307
+ [coll] (first (first coll)))
308
+
309
+ (defn nfirst
310
+ "Same as (next (first coll))."
311
+ [coll] (next (first coll)))
312
+
313
+ (defn fnext
314
+ "Same as (first (next coll))."
315
+ [coll] (first (next coll)))
316
+
317
+ (defn last
318
+ "Return the last item in coll."
319
+ [coll] (.last coll))
320
+
321
+ (defn butlast [coll]
322
+ "Return all but the last item in coll."
323
+ (if (empty? coll)
324
+ []
325
+ (.take coll (. (.count coll) - 1))))
326
+
327
+ (defn nth
328
+ "Return the value at the given index in coll. If the index is out of bounds,
329
+ return not-found if it is supplied. Otherwise raise an exception."
330
+ ([coll index]
331
+ (.fetch coll index))
332
+ ([coll index not-found]
333
+ (.fetch coll index not-found)))
334
+
335
+ (defn count
336
+ "Return the number of items in coll."
337
+ [coll] (.count coll))
338
+
339
+ (defn take
340
+ "Return the first n items in coll."
341
+ [n coll] (.take coll n))
342
+
343
+ (defn drop
344
+ "Return all but the first n items in coll."
345
+ [n coll] (.drop coll n))
346
+
347
+ (defn reverse
348
+ "Return the items in coll in reverse order."
349
+ [coll] (.reverse coll))
350
+
351
+ (defn map
352
+ "Return an array consisting of the result of applying f to the set of first
353
+ items of each coll, followed by applying f to the set of second items in
354
+ each coll, until any one of the colls is exhausted. Any remaining items in
355
+ other colls are exhausted. Function f should accept number-of-colls
356
+ arguments."
357
+ ([f coll]
358
+ (.map coll | f))
359
+ ([f coll & colls]
360
+ (.map (.zip coll & colls) | #(apply f %))))
361
+
362
+ (defn reduce
363
+ "f should be a function of 2 arguments. If val is not supplied, return the
364
+ result of applying f to the first 2 items in coll, then applying f to that
365
+ result and the 3rd item, etc. If coll contains no items, f must accept no
366
+ arguments as well, and reduce returns the result of calling f with no
367
+ arguments. If coll has only 1 item, it is returned and f is not called. If
368
+ val is supplied, return the result of applying f to val and the first item
369
+ in coll, then applying f to that result and the 2nd item, etc. If coll
370
+ contains no items, return val and f is not called."
371
+ ([f coll]
372
+ (if (empty? coll)
373
+ (f)
374
+ (.reduce coll | f)))
375
+ ([f val coll]
376
+ (.reduce coll val | f)))
377
+
378
+ (defn contains?
379
+ "Return true if val is present in the given collection, otherwise return
380
+ false. Note that for hashes this checks for a key."
381
+ [coll val]
382
+ (.include? coll val))
383
+
384
+ ; Hash map functions
385
+ (defn get
386
+ "Return the value mapped to key, not-found or nil if key not present."
387
+ ([map key]
388
+ (.fetch map key nil))
389
+ ([map key not-found]
390
+ (.fetch map key not-found)))
391
+
392
+ (defn keys
393
+ "Return an array of the map's keys."
394
+ [map] (.keys map))
395
+
396
+ (defn vals
397
+ "Return an array of the map's values."
398
+ [map] (.values map))
399
+
400
+ ; Number predicates and functions
401
+
402
+ (defn zero?
403
+ "Return true if num is zero, false otherwise."
404
+ {:inline (fn [x] `(.zero? ~x))}
405
+ [x] (.zero? x))
406
+
407
+ (defn pos?
408
+ "Return true if num is greater than zero, false otherwise."
409
+ {:inline (fn [x] `(. ~x > 0))}
410
+ [x] (. x > 0))
411
+
412
+ (defn neg?
413
+ "Return true if num is less than zero, false otherwise."
414
+ {:inline (fn [x] `(. ~x < 0))}
415
+ [x] (. x < 0))
416
+
417
+ (defn even?
418
+ "Return true if num is even, false otherwise."
419
+ {:inline (fn [x] `(.even? ~x))}
420
+ [x] (.even? x))
421
+
422
+ (defn odd?
423
+ "Return true if num is odd, false otherwise."
424
+ {:inline (fn [x] `(.odd? ~x))}
425
+ [x] (.odd? x))
426
+
427
+ (defn nary-inline
428
+ {:private true}
429
+ [op]
430
+ (fn
431
+ ([x y] `(. ~x ~op ~y))
432
+ ([x y & more]
433
+ (.reduce more
434
+ `(. ~x ~op ~y)
435
+ | (fn [a b] `(. ~a ~op ~b))))))
436
+
437
+ (defn +
438
+ "Return the sum of nums. (+) returns 0."
439
+ {:inline (fn
440
+ ([] 0)
441
+ ([x] x)
442
+ ([x & more] (apply (nary-inline '+) x more)))}
443
+ ([] 0)
444
+ ([x] x)
445
+ ([x y] (.+ x y))
446
+ ([x y & more]
447
+ (.reduce more (.+ x y) :+)))
448
+
449
+ (defn *
450
+ "Return the product of nums. (*) returns 1."
451
+ {:inline (fn
452
+ ([] 1)
453
+ ([x] x)
454
+ ([x & more] (apply (nary-inline '*) x more)))}
455
+ ([] 1)
456
+ ([x] x)
457
+ ([x y] (.* x y))
458
+ ([x y & more]
459
+ (.reduce more (.* x y) :*)))
460
+
461
+ (defn -
462
+ "If no ys are supplied, return the negation of x, otherwise subtract the ys
463
+ from x and return the result."
464
+ {:inline (fn
465
+ ([x] `(. ~x -@))
466
+ ([x & more] (apply (nary-inline '-) x more)))
467
+ :inline-arities #(. % > 0)}
468
+ ([x] (. x -@)) ; Ruby's horribly named -@ method is the negation operator
469
+ ([x y] (.- x y))
470
+ ([x y & more]
471
+ (.reduce more (.- x y) :-)))
472
+
473
+ (defn /
474
+ "If no denominators are supplied, return 1/numerator, otherwise return
475
+ numerator divided by all of the denominators."
476
+ {:inline (fn
477
+ ([x] `(. 1 quo ~x))
478
+ ([x & more] (apply (nary-inline 'quo) x more)))
479
+ :inline-arities #(. % > 0)}
480
+ ([x] (.quo 1 x))
481
+ ([x y] (.quo x y))
482
+ ([x y & more]
483
+ (.reduce more (.quo x y) :quo)))
484
+
485
+ (defn quot
486
+ "Return quotient of dividing numerator by denominator."
487
+ [num div] (.truncate (.fdiv num div)))
488
+
489
+ (defn rem
490
+ "Return remainder of dividing numerator by denominator."
491
+ [num div] (.remainder num div))
492
+
493
+ (defn mod
494
+ "Return the modulus of num and div. Truncates toward negative infinity."
495
+ [num div] (.modulo num div))
496
+
497
+ (defn pow
498
+ "Return num raised to the exponent exp."
499
+ [num exp] (.** num exp))
500
+
501
+ (defn int
502
+ "Coerce to integer."
503
+ [x] (.to_i x))
504
+
505
+ (defn float
506
+ "Coerce to floating point."
507
+ [x] (.to_f x))
508
+
509
+ (def ratio Kernel/Rational)
510
+
511
+ (defn inc
512
+ "Return a number one greater than x."
513
+ {:inline (fn [x] `(. ~x + 1))}
514
+ [x] (. x + 1))
515
+
516
+ (defn dec
517
+ "Return a number one less than x."
518
+ {:inline (fn [x] `(. ~x - 1))}
519
+ [x] (. x - 1))
520
+
521
+ ; Equality and inequality
522
+
523
+ (defn identical?
524
+ "Test if the two arguments are the same object."
525
+ [x y] (.equal? x y))
526
+
527
+ (defn =
528
+ "Return true if all of the arguments are equal, otherwise false. (=) returns
529
+ true."
530
+ ([x] true)
531
+ ([x y] (. x == y))
532
+ ([x y & more]
533
+ (and
534
+ (. x == y)
535
+ (.all? more | #(. x == %)))))
536
+
537
+ (defn not=
538
+ "Return true if any of the arguments are not equal, otherwise false. (not=
539
+ returns false. Same as (not (= x y ...))."
540
+ ([x] false)
541
+ ([x y] (. x != y))
542
+ ([x y & more]
543
+ (not (apply = x y more))))
544
+
545
+ (defn compare
546
+ "Return a negative number, zero, or a positive number when x is logically
547
+ 'less than', 'equal to', or 'greater than' y, respectively."
548
+ [x y] (. x <=> y))
549
+
550
+ (defn >
551
+ "Return true if nums are in monotonically decreasing order, otherwise false."
552
+ ([x] true)
553
+ ([x y] (. x > y))
554
+ ([x y & more]
555
+ (and
556
+ (. x > y)
557
+ (.all? (.each_cons (cons y more) 2) | #(. %1 > %2)))))
558
+
559
+ (defn <
560
+ "Return true if nums are in monotonically increasing order, otherwise false."
561
+ ([x] true)
562
+ ([x y] (. x < y))
563
+ ([x y & more]
564
+ (and
565
+ (. x < y)
566
+ (.all? (.each_cons (cons y more) 2) | #(. %1 < %2)))))
567
+
568
+ (defn >=
569
+ "Return true if nums are in monotonically non-increasing order, otherwise
570
+ false."
571
+ ([x] true)
572
+ ([x y] (. x >= y))
573
+ ([x y & more]
574
+ (and
575
+ (. x >= y)
576
+ (.all? (.each_cons (cons y more) 2) | #(. %1 >= %2)))))
577
+
578
+ (defn <=
579
+ "Return true if nums are in monotonically non-decreasing order, otherwise
580
+ false."
581
+ ([x] true)
582
+ ([x y] (. x <= y))
583
+ ([x y & more]
584
+ (and
585
+ (. x <= y)
586
+ (.all? (.each_cons (cons y more) 2) | #(. %1 <= %2)))))
587
+
588
+ (defn max
589
+ "Return the greatest of the arguments."
590
+ ([x] x)
591
+ ([x & more]
592
+ (.max (cons x more))))
593
+
594
+ (defn min
595
+ "Return the least of the arguments."
596
+ ([x] x)
597
+ ([x & more]
598
+ (.min (cons x more))))
599
+
600
+ ; Bitwise operations
601
+
602
+ (defn bit-not
603
+ "Return the bitwise complement of x (ie. flip all the bits)."
604
+ [x] (. x #|~|)) ; Use arbitrary identifier syntax since ~ is a special char
605
+
606
+ (defn bit-and
607
+ "Return the bitwise and of the arguments."
608
+ ([x y] (. x & y))
609
+ ([x y & more]
610
+ (.reduce more (. x & y) | #(. %1 & %2))))
611
+
612
+ (defn bit-or
613
+ "Return the bitwise or of the arguments."
614
+ ([x y] (. x | y))
615
+ ([x y & more]
616
+ (.reduce more (. x | y) | #(. %1 | %2))))
617
+
618
+ (defn bit-xor
619
+ "Return the bitwise exclusive or of the arguments."
620
+ ([x y] (. x ^ y))
621
+ ([x y & more]
622
+ (.reduce more (. x ^ y) | #(. %1 ^ %2))))
623
+
624
+ (defn bit-and-not
625
+ "Return the bitwise and of the first argument and the bitwise complement of
626
+ all arguments after the first."
627
+ ([x y] (bit-and x (bit-not y)))
628
+ ([x y & more]
629
+ (.reduce more (bit-and x (bit-not y)) | #(bit-and %1 (bit-not %2)))))
630
+
631
+ (defn bit-shift-left
632
+ "Return the bitwise shift left of x by n bits."
633
+ [x n] (. x << n))
634
+
635
+ (defn bit-shift-right
636
+ "Return the bitwise shift right of x by n bits."
637
+ [x n] (. x >> n))
638
+
639
+ (defn bit-clear
640
+ "Return x with the bit at index n set to 0."
641
+ [x n] (bit-and-not x (bit-shift-left 1 n)))
642
+
643
+ (defn bit-set
644
+ "Return x with the bit at index n set to 1."
645
+ [x n] (bit-or x (bit-shift-left 1 n)))
646
+
647
+ (defn bit-flip
648
+ "Return x with the bit at index n flipped from its previous value."
649
+ [x n] (bit-xor x (bit-shift-left 1 n)))
650
+
651
+ (defn bit-test
652
+ "Return true if the bit at index n is 1, otherwise false."
653
+ [x n] (not= 0 (bit-and x (bit-shift-left 1 n))))
654
+
655
+ ; Functional programming functions
656
+ (defn complement
657
+ "Take a fn f and return a fn that takes the same arguments as f, has the
658
+ same effects, if any, and returns the opposite truth value."
659
+ [f]
660
+ (fn
661
+ ([] (not (f)))
662
+ ([x] (not (f x)))
663
+ ([x y] (not (f x y)))
664
+ ([x y & zs] (not (apply f x y zs)))))
665
+
666
+ (defn constantly
667
+ "Return a function that takes any number of arguments and returns x."
668
+ [x] (fn [& args] x))
669
+
670
+ (defn identity
671
+ "Return the argument."
672
+ [x] x)
673
+
674
+ ; TODO: Stole this from Clojure. It probably isn't as efficient as it could be
675
+ ; in Apricot.
676
+ (defn comp
677
+ "Take a set of functions and return a fn that is the composition of those
678
+ fns. The returned fn takes a variable number of args, applies the rightmost
679
+ of fns to the args, the next fn (right-to-left) to the result, etc."
680
+ ([] identity)
681
+ ([f] f)
682
+ ([f g]
683
+ (fn
684
+ ([] (f (g)))
685
+ ([x] (f (g x)))
686
+ ([x y] (f (g x y)))
687
+ ([x y z] (f (g x y z)))
688
+ ([x y z & args] (f (apply g x y z args)))))
689
+ ([f g h]
690
+ (fn
691
+ ([] (f (g (h))))
692
+ ([x] (f (g (h x))))
693
+ ([x y] (f (g (h x y))))
694
+ ([x y z] (f (g (h x y z))))
695
+ ([x y z & args] (f (g (apply h x y z args))))))
696
+ ([f1 f2 f3 & fs]
697
+ (let [fs (reverse (apply list f1 f2 f3 fs))]
698
+ (fn [& args]
699
+ (loop [ret (apply (first fs) args) fs (next fs)]
700
+ (if fs
701
+ (recur ((first fs) ret) (next fs))
702
+ ret))))))
703
+
704
+ (defn partial
705
+ "Take a function f and fewer than the normal arguments to f, and return a fn
706
+ that takes a variable number of additional args. When called, the returned
707
+ function calls f with args + additional args."
708
+ ([f] f)
709
+ ([f arg1]
710
+ (fn [& args] (apply f arg1 args)))
711
+ ([f arg1 arg2]
712
+ (fn [& args] (apply f arg1 arg2 args)))
713
+ ([f arg1 arg2 arg3]
714
+ (fn [& args] (apply f arg1 arg2 arg3 args)))
715
+ ([f arg1 arg2 arg3 & more]
716
+ (fn [& args] (apply f arg1 arg2 arg3 (concat more args)))))
717
+
718
+ ; Useful macros
719
+
720
+ (defmacro when
721
+ "Evaluate test. If logical true, evaluate body in an implicit do."
722
+ [test & body]
723
+ `(if ~test (do ~@body)))
724
+
725
+ (defmacro when-not
726
+ "Evaluate test. If logical false, evaluate body in an implicit do."
727
+ [test & body]
728
+ `(if ~test nil (do ~@body)))
729
+
730
+ (defmacro ..
731
+ "form => method-name or (method-name args*)
732
+
733
+ Expands into a method send (.) of the first method on the first argument,
734
+ followed by the next method on the result, etc. For instance:
735
+
736
+ (.. \"one two three\" split reverse (join \" \"))
737
+
738
+ expands to:
739
+
740
+ (. (. (. \"one two three\" split) reverse) (join \" \"))
741
+
742
+ but is easier to write, read, and understand."
743
+ ([x form]
744
+ `(. ~x ~form))
745
+ ([x form & more]
746
+ `(.. (. ~x ~form) ~@more)))
747
+
748
+ (defmacro ->
749
+ "Thread the expr through the forms. Insert x as the second item in the first
750
+ form, making a list of it if it is not a list already. If there are more
751
+ forms, insert the first form as the second item in second form, etc."
752
+ ([x] x)
753
+ ([x form]
754
+ (if (seq? form)
755
+ `(~(first form) ~x ~@(next form))
756
+ (list form x)))
757
+ ([x form & more]
758
+ `(-> (-> ~x ~form) ~@more)))
759
+
760
+ (defmacro ->>
761
+ "Thread the expr through the forms. Insert x as the last item in the first
762
+ form, making a list of it if it is not a list already. If there are more
763
+ forms, insert the first form as the last item in second form, etc."
764
+ ([x] x)
765
+ ([x form]
766
+ (if (seq? form)
767
+ `(~(first form) ~@(next form) ~x)
768
+ (list form x)))
769
+ ([x form & more]
770
+ `(->> (->> ~x ~form) ~@more)))
771
+
772
+ (defmacro if-let
773
+ "bindings => var test
774
+
775
+ If test is true, evaluate then with var bound to the value of test,
776
+ otherwise yield else."
777
+ [bindings then [else nil]]
778
+ `(let [temp# ~(bindings 1)]
779
+ (if temp#
780
+ (let [~(bindings 0) temp#]
781
+ ~then)
782
+ ~else)))
783
+
784
+ (defmacro cond
785
+ "Take a set of test/expr pairs. Evaluate each test one at a time. If a test
786
+ returns logical true, evaluate and return the value of the corresponding
787
+ expr and don't evaluate any of the other tests or exprs. (cond) returns
788
+ nil."
789
+ [& clauses]
790
+ (when-not (even? (count clauses))
791
+ (raise ArgumentError "cond requires an even number of forms"))
792
+ (when-not (empty? clauses)
793
+ `(if ~(first clauses)
794
+ ~(second clauses)
795
+ (cond ~@(drop 2 clauses)))))
796
+
797
+ (defmacro case
798
+ "when => [expr ...+] expr
799
+ else => expr
800
+
801
+ Works like Ruby's case/when syntax (uses the === method).
802
+
803
+ Example:
804
+ (case x
805
+ [Array] \"x is an array\"
806
+ [String Symbol] \"x is a string or symbol\"
807
+ [1 2] \"x is equal to 1 or 2\"
808
+ \"x is unknown\")"
809
+ {:arglists '([x when ... else?])}
810
+ [x & forms]
811
+ (let [else (if (odd? (count forms))
812
+ (.pop forms))
813
+ val (gensym "case")
814
+ expand (fn expand [& forms]
815
+ (if (seq forms)
816
+ `(if (or ~@(map (fn [test] `(. ~test === ~val))
817
+ (first forms)))
818
+ ~(second forms)
819
+ ~(apply expand (drop 2 forms)))
820
+ else))]
821
+ `(let [~val ~x]
822
+ ~(apply expand forms))))
823
+
824
+ (defmacro doto
825
+ "Evaluate x then call all of the methods and functions with the value of x
826
+ supplied at the front of the given arguments. The forms are evaluated in
827
+ order. Return x.
828
+
829
+ (doto (Hash.) (.store :a 1) (.store :b 2)) ;=> {:a 1, :b 2}"
830
+ [x & forms]
831
+ (let [gx (gensym "doto")]
832
+ `(let [~gx ~x]
833
+ ~@(map (fn [f]
834
+ (if (seq? f)
835
+ `(~(first f) ~gx ~@(rest f))
836
+ `(~f ~gx)))
837
+ forms)
838
+ ~gx)))
839
+
840
+ ; Miscellaneous (to be sorted)
841
+
842
+ (defn eval
843
+ "Evaluate the form data structure (not text!) and return the result."
844
+ [form] (Apricot::Compiler/eval_form form))
845
+
846
+ (defmacro each [binding & body]
847
+ `(.each ~(last binding)
848
+ | (fn [~(first binding)] ~@body)))
849
+
850
+ (defmacro while-let [binding & body]
851
+ `(loop []
852
+ (let ~binding
853
+ (when ~(first binding)
854
+ ~@body
855
+ (recur)))))
856
+
857
+ ; Structs
858
+
859
+ (defmacro defstruct [name & fields]
860
+ `(def ~name (Struct. ~@(map symbol fields))))
861
+
862
+ ; Macros for defining Ruby classes and methods
863
+
864
+ (defmacro defmethod [target name & body]
865
+ `(.send ~target :define_method ~(symbol name) | (fn ~name ~@body)))
866
+
867
+ (defmacro defclass
868
+ ([name]
869
+ `(def ~name (Class.)))
870
+ ([name superclass]
871
+ `(def ~name (Class. ~superclass))))
872
+
873
+ ; Metadata
874
+
875
+ (defn meta
876
+ "Return the metadata of obj."
877
+ [obj] (.apricot_meta obj))
878
+
879
+ ; Documentation
880
+
881
+ (defn doc
882
+ "Print the documentation for the given function or macro."
883
+ [f]
884
+ (let [m (meta f)]
885
+ (println "-------------------------")
886
+ (println (m :name))
887
+ (println (m :arglists))
888
+ (if (m :macro)
889
+ (println "Macro"))
890
+ (println " " (m :doc))))
891
+
892
+ ; REPL Utilities
893
+
894
+ (defn decode
895
+ "Print the Rubinius bytecode for the given Proc or Method."
896
+ [f]
897
+ (case f
898
+ [Proc] (Kernel/puts (.. f block compiled_code decode))
899
+ [Method] (Kernel/puts (.. f executable decode))
900
+ (raise (str "Don't know how to decode " (.inspect f)))))
901
+
902
+ (defmacro time
903
+ "Evaluate the forms in body and return the time it took."
904
+ [& body]
905
+ `(do
906
+ (require "benchmark")
907
+ (.realtime Benchmark | (fn [] ~@body))))
908
+
909
+ (defmacro benchmark-ips
910
+ "clause => [label form ...]
911
+
912
+ Measure how many times per second each of the clause's bodies can be
913
+ executed. Output is organized using the given label strings.
914
+
915
+ This requires the benchmark-ips gem:
916
+ gem install benchmark-ips"
917
+ [& clauses]
918
+ (let [bm (gensym)
919
+ make-report (fn [clause]
920
+ `(.report ~bm ~(first clause) | (fn [] ~@(rest clause))))
921
+ reports (map make-report clauses)]
922
+ `(do
923
+ (try
924
+ (require "benchmark/ips")
925
+ (.ips Benchmark | (fn [~bm] ~@reports))
926
+ (rescue [_ LoadError]
927
+ (raise "benchmark-ips requires the benchmark-ips gem")))
928
+ nil)))