apricot 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 (62) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.ruby-version +1 -1
  4. data/.travis.yml +1 -0
  5. data/Gemfile.lock +229 -11
  6. data/README.md +46 -29
  7. data/Rakefile +1 -1
  8. data/apricot.gemspec +7 -3
  9. data/benchmarks/factorial.rb +51 -0
  10. data/benchmarks/interpolate.rb +20 -0
  11. data/bin/apricot +5 -23
  12. data/examples/bot.apr +1 -4
  13. data/examples/cinch-bot.apr +3 -3
  14. data/examples/sinatra.apr +9 -0
  15. data/kernel/core.apr +124 -75
  16. data/kernel/repl.apr +37 -0
  17. data/lib/apricot.rb +7 -26
  18. data/lib/apricot/boot.rb +24 -0
  19. data/lib/apricot/code_loader.rb +108 -0
  20. data/lib/apricot/compiler.rb +265 -32
  21. data/lib/apricot/generator.rb +10 -3
  22. data/lib/apricot/identifier.rb +25 -10
  23. data/lib/apricot/list.rb +28 -41
  24. data/lib/apricot/macroexpand.rb +14 -8
  25. data/lib/apricot/misc.rb +2 -1
  26. data/lib/apricot/namespace.rb +20 -3
  27. data/lib/apricot/{parser.rb → reader.rb} +221 -194
  28. data/lib/apricot/repl.rb +67 -24
  29. data/lib/apricot/ruby_ext.rb +27 -16
  30. data/lib/apricot/scopes.rb +159 -0
  31. data/lib/apricot/seq.rb +43 -1
  32. data/lib/apricot/special_forms.rb +16 -695
  33. data/lib/apricot/special_forms/def.rb +32 -0
  34. data/lib/apricot/special_forms/do.rb +23 -0
  35. data/lib/apricot/special_forms/dot.rb +112 -0
  36. data/lib/apricot/special_forms/fn.rb +342 -0
  37. data/lib/apricot/special_forms/if.rb +31 -0
  38. data/lib/apricot/special_forms/let.rb +8 -0
  39. data/lib/apricot/special_forms/loop.rb +10 -0
  40. data/lib/apricot/special_forms/quote.rb +9 -0
  41. data/lib/apricot/special_forms/recur.rb +26 -0
  42. data/lib/apricot/special_forms/try.rb +146 -0
  43. data/lib/apricot/variables.rb +65 -0
  44. data/lib/apricot/version.rb +1 -1
  45. data/spec/compiler_spec.rb +53 -450
  46. data/spec/fn_spec.rb +206 -0
  47. data/spec/list_spec.rb +1 -1
  48. data/spec/reader_spec.rb +349 -0
  49. data/spec/spec_helper.rb +40 -4
  50. data/spec/special_forms_spec.rb +203 -0
  51. metadata +99 -133
  52. data/lib/apricot/ast.rb +0 -3
  53. data/lib/apricot/ast/identifier.rb +0 -111
  54. data/lib/apricot/ast/list.rb +0 -99
  55. data/lib/apricot/ast/literals.rb +0 -240
  56. data/lib/apricot/ast/node.rb +0 -45
  57. data/lib/apricot/ast/scopes.rb +0 -147
  58. data/lib/apricot/ast/toplevel.rb +0 -66
  59. data/lib/apricot/ast/variables.rb +0 -64
  60. data/lib/apricot/printers.rb +0 -12
  61. data/lib/apricot/stages.rb +0 -60
  62. data/spec/parser_spec.rb +0 -312
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0295d0651dd359754c9580022c471cd7ba23c4e6
4
+ data.tar.gz: fac2f3950287af5573cdd62b2aed0d583da8a31c
5
+ SHA512:
6
+ metadata.gz: a3354fab2b0c27a994730be6aaf88220095b8d35638bbfc413a85b5e08c790b71f1c28927c1de4ec6708d11c6de8ec131f4d7b6644d1c3999ed9304a614b1969
7
+ data.tar.gz: 814994187ebb326df71597fc548d98b1dd7f409bbacc0e43d3435d342de4b5eea44770cca42625cb7392df843b9bfa4b09f0ebd8153b8c1bb43dff2bad4bf0c1
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
1
  *.rbc
2
2
  .rbx
3
3
  *.gem
4
+ coverage
@@ -1 +1 @@
1
- rbx-head
1
+ rubinius
@@ -5,3 +5,4 @@ rvm:
5
5
  notifications:
6
6
  webhooks:
7
7
  - http://rcmp.tenthbit.net/
8
+ - http://rcmp.tenthbit.net/irc.freenode.net/apricot
@@ -2,25 +2,243 @@ PATH
2
2
  remote: .
3
3
  specs:
4
4
  apricot (0.0.1)
5
+ rubysl (~> 2.0)
5
6
 
6
7
  GEM
7
8
  remote: https://rubygems.org/
8
9
  specs:
9
- diff-lcs (1.2.1)
10
- rake (10.0.3)
11
- rspec (2.13.0)
12
- rspec-core (~> 2.13.0)
13
- rspec-expectations (~> 2.13.0)
14
- rspec-mocks (~> 2.13.0)
15
- rspec-core (2.13.0)
16
- rspec-expectations (2.13.0)
10
+ diff-lcs (1.2.4)
11
+ ffi2-generators (0.1.1)
12
+ minitest (4.7.5)
13
+ psych (2.0.1)
14
+ racc (1.4.9)
15
+ rake (10.1.0)
16
+ rspec (2.14.1)
17
+ rspec-core (~> 2.14.0)
18
+ rspec-expectations (~> 2.14.0)
19
+ rspec-mocks (~> 2.14.0)
20
+ rspec-core (2.14.5)
21
+ rspec-expectations (2.14.3)
17
22
  diff-lcs (>= 1.1.3, < 2.0)
18
- rspec-mocks (2.13.0)
23
+ rspec-mocks (2.14.3)
24
+ rubysl (2.0.7)
25
+ minitest (~> 4.5)
26
+ psych (~> 2.0)
27
+ racc (~> 1.4)
28
+ rubysl-abbrev (~> 2.0)
29
+ rubysl-base64 (~> 2.0)
30
+ rubysl-benchmark (~> 2.0)
31
+ rubysl-bigdecimal (~> 2.0)
32
+ rubysl-cgi (~> 2.0)
33
+ rubysl-cgi-session (~> 2.0)
34
+ rubysl-cmath (~> 2.0)
35
+ rubysl-complex (~> 2.0)
36
+ rubysl-continuation (~> 2.0)
37
+ rubysl-coverage (~> 2.0)
38
+ rubysl-csv (~> 2.0)
39
+ rubysl-curses (~> 2.0)
40
+ rubysl-date (~> 2.0)
41
+ rubysl-delegate (~> 2.0)
42
+ rubysl-digest (~> 2.0)
43
+ rubysl-drb (~> 2.0)
44
+ rubysl-e2mmap (~> 2.0)
45
+ rubysl-english (~> 2.0)
46
+ rubysl-enumerator (~> 2.0)
47
+ rubysl-erb (~> 2.0)
48
+ rubysl-etc (~> 2.0)
49
+ rubysl-expect (~> 2.0)
50
+ rubysl-fcntl (~> 2.0)
51
+ rubysl-fiber (~> 2.0)
52
+ rubysl-fileutils (~> 2.0)
53
+ rubysl-find (~> 2.0)
54
+ rubysl-forwardable (~> 2.0)
55
+ rubysl-getoptlong (~> 2.0)
56
+ rubysl-gserver (~> 2.0)
57
+ rubysl-io-console (~> 2.0)
58
+ rubysl-io-nonblock (~> 2.0)
59
+ rubysl-io-wait (~> 2.0)
60
+ rubysl-ipaddr (~> 2.0)
61
+ rubysl-irb (~> 2.0)
62
+ rubysl-json (~> 2.0)
63
+ rubysl-logger (~> 2.0)
64
+ rubysl-mathn (~> 2.0)
65
+ rubysl-matrix (~> 2.0)
66
+ rubysl-mkmf (~> 2.0)
67
+ rubysl-monitor (~> 2.0)
68
+ rubysl-mutex_m (~> 2.0)
69
+ rubysl-net-ftp (~> 2.0)
70
+ rubysl-net-http (~> 2.0)
71
+ rubysl-net-imap (~> 2.0)
72
+ rubysl-net-pop (~> 2.0)
73
+ rubysl-net-protocol (~> 2.0)
74
+ rubysl-net-smtp (~> 2.0)
75
+ rubysl-net-telnet (~> 2.0)
76
+ rubysl-nkf (~> 2.0)
77
+ rubysl-observer (~> 2.0)
78
+ rubysl-open-uri (~> 2.0)
79
+ rubysl-open3 (~> 2.0)
80
+ rubysl-openssl (~> 2.0)
81
+ rubysl-optparse (~> 2.0)
82
+ rubysl-ostruct (~> 2.0)
83
+ rubysl-pathname (~> 2.0)
84
+ rubysl-prettyprint (~> 2.0)
85
+ rubysl-prime (~> 2.0)
86
+ rubysl-profile (~> 2.0)
87
+ rubysl-profiler (~> 2.0)
88
+ rubysl-pstore (~> 2.0)
89
+ rubysl-pty (~> 2.0)
90
+ rubysl-rational (~> 2.0)
91
+ rubysl-readline (~> 2.0)
92
+ rubysl-resolv (~> 2.0)
93
+ rubysl-rexml (~> 2.0)
94
+ rubysl-rinda (~> 2.0)
95
+ rubysl-ripper (~> 2.0)
96
+ rubysl-rss (~> 2.0)
97
+ rubysl-scanf (~> 2.0)
98
+ rubysl-securerandom (~> 2.0)
99
+ rubysl-set (~> 2.0)
100
+ rubysl-shellwords (~> 2.0)
101
+ rubysl-singleton (~> 2.0)
102
+ rubysl-socket (~> 2.0)
103
+ rubysl-stringio (~> 2.0)
104
+ rubysl-strscan (~> 2.0)
105
+ rubysl-syslog (~> 2.0)
106
+ rubysl-tempfile (~> 2.0)
107
+ rubysl-test-unit (~> 2.0)
108
+ rubysl-thread (~> 2.0)
109
+ rubysl-thwait (~> 2.0)
110
+ rubysl-time (~> 2.0)
111
+ rubysl-timeout (~> 2.0)
112
+ rubysl-tmpdir (~> 2.0)
113
+ rubysl-tracer (~> 2.0)
114
+ rubysl-tsort (~> 2.0)
115
+ rubysl-un (~> 2.0)
116
+ rubysl-uri (~> 2.0)
117
+ rubysl-weakref (~> 2.0)
118
+ rubysl-webrick (~> 2.0)
119
+ rubysl-xmlrpc (~> 2.0)
120
+ rubysl-yaml (~> 2.0)
121
+ rubysl-zlib (~> 2.0)
122
+ rubysl-abbrev (2.0.2)
123
+ rubysl-base64 (2.0.0)
124
+ rubysl-benchmark (2.0.0)
125
+ rubysl-bigdecimal (2.0.2)
126
+ rubysl-cgi (2.0.0)
127
+ rubysl-cgi-session (2.0.0)
128
+ rubysl-cmath (2.0.0)
129
+ rubysl-complex (2.0.0)
130
+ rubysl-continuation (2.0.0)
131
+ rubysl-coverage (2.0.3)
132
+ rubysl-csv (2.0.1)
133
+ rubysl-english (~> 2.0)
134
+ rubysl-curses (2.0.0)
135
+ rubysl-date (2.0.5)
136
+ rubysl-delegate (2.0.0)
137
+ rubysl-digest (2.0.2)
138
+ rubysl-drb (2.0.1)
139
+ rubysl-e2mmap (2.0.0)
140
+ rubysl-english (2.0.0)
141
+ rubysl-enumerator (2.0.0)
142
+ rubysl-erb (2.0.0)
143
+ rubysl-etc (2.0.3)
144
+ ffi2-generators (~> 0.1)
145
+ rubysl-expect (2.0.0)
146
+ rubysl-fcntl (2.0.4)
147
+ ffi2-generators (~> 0.1)
148
+ rubysl-fiber (2.0.0)
149
+ rubysl-fileutils (2.0.2)
150
+ rubysl-find (2.0.0)
151
+ rubysl-forwardable (2.0.0)
152
+ rubysl-getoptlong (2.0.0)
153
+ rubysl-gserver (2.0.0)
154
+ rubysl-socket (~> 2.0)
155
+ rubysl-thread (~> 2.0)
156
+ rubysl-io-console (2.0.0)
157
+ rubysl-io-nonblock (2.0.0)
158
+ rubysl-io-wait (2.0.0)
159
+ rubysl-ipaddr (2.0.0)
160
+ rubysl-irb (2.0.3)
161
+ rubysl-e2mmap (~> 2.0)
162
+ rubysl-mathn (~> 2.0)
163
+ rubysl-readline (~> 2.0)
164
+ rubysl-thread (~> 2.0)
165
+ rubysl-tracer (~> 2.0)
166
+ rubysl-json (2.0.2)
167
+ rubysl-logger (2.0.0)
168
+ rubysl-mathn (2.0.0)
169
+ rubysl-matrix (2.1.0)
170
+ rubysl-e2mmap (~> 2.0)
171
+ rubysl-mkmf (2.0.1)
172
+ rubysl-fileutils (~> 2.0)
173
+ rubysl-shellwords (~> 2.0)
174
+ rubysl-monitor (2.0.0)
175
+ rubysl-mutex_m (2.0.0)
176
+ rubysl-net-ftp (2.0.1)
177
+ rubysl-net-http (2.0.4)
178
+ rubysl-cgi (~> 2.0)
179
+ rubysl-erb (~> 2.0)
180
+ rubysl-singleton (~> 2.0)
181
+ rubysl-net-imap (2.0.1)
182
+ rubysl-net-pop (2.0.1)
183
+ rubysl-net-protocol (2.0.1)
184
+ rubysl-net-smtp (2.0.1)
185
+ rubysl-net-telnet (2.0.0)
186
+ rubysl-nkf (2.0.0)
187
+ rubysl-observer (2.0.0)
188
+ rubysl-open-uri (2.0.0)
189
+ rubysl-open3 (2.0.0)
190
+ rubysl-openssl (2.0.0)
191
+ rubysl-optparse (2.0.1)
192
+ rubysl-shellwords (~> 2.0)
193
+ rubysl-ostruct (2.0.4)
194
+ rubysl-pathname (2.0.0)
195
+ rubysl-prettyprint (2.0.1)
196
+ rubysl-prime (2.0.0)
197
+ rubysl-profile (2.0.0)
198
+ rubysl-profiler (2.0.1)
199
+ rubysl-pstore (2.0.0)
200
+ rubysl-pty (2.0.1)
201
+ rubysl-rational (2.0.1)
202
+ rubysl-readline (2.0.2)
203
+ rubysl-resolv (2.0.0)
204
+ rubysl-rexml (2.0.1)
205
+ rubysl-rinda (2.0.0)
206
+ rubysl-ripper (2.0.0)
207
+ rubysl-rss (2.0.0)
208
+ rubysl-scanf (2.0.0)
209
+ rubysl-securerandom (2.0.0)
210
+ rubysl-set (2.0.1)
211
+ rubysl-shellwords (2.0.0)
212
+ rubysl-singleton (2.0.0)
213
+ rubysl-socket (2.0.0)
214
+ rubysl-stringio (2.0.0)
215
+ rubysl-strscan (2.0.0)
216
+ rubysl-syslog (2.0.1)
217
+ ffi2-generators (~> 0.1)
218
+ rubysl-tempfile (2.0.0)
219
+ rubysl-test-unit (2.0.1)
220
+ minitest (~> 4.7)
221
+ rubysl-thread (2.0.2)
222
+ rubysl-thwait (2.0.0)
223
+ rubysl-time (2.0.2)
224
+ rubysl-timeout (2.0.0)
225
+ rubysl-tmpdir (2.0.0)
226
+ rubysl-tracer (2.0.0)
227
+ rubysl-tsort (2.0.1)
228
+ rubysl-un (2.0.0)
229
+ rubysl-fileutils (~> 2.0)
230
+ rubysl-optparse (~> 2.0)
231
+ rubysl-uri (2.0.0)
232
+ rubysl-weakref (2.0.0)
233
+ rubysl-webrick (2.0.0)
234
+ rubysl-xmlrpc (2.0.0)
235
+ rubysl-yaml (2.0.0)
236
+ rubysl-zlib (2.0.0)
19
237
 
20
238
  PLATFORMS
21
239
  ruby
22
240
 
23
241
  DEPENDENCIES
24
242
  apricot!
25
- rake (~> 10.0.3)
26
- rspec (~> 2.13.0)
243
+ rake (~> 10.1.0)
244
+ rspec (~> 2.14.0)
data/README.md CHANGED
@@ -1,37 +1,34 @@
1
- # Apricot [![Build Status](https://secure.travis-ci.org/programble/apricot.png?branch=master)](http://travis-ci.org/programble/apricot) [![Dependency Status](https://gemnasium.com/programble/apricot.png?travis)](https://gemnasium.com/programble/apricot)
1
+ # Apricot [![Gem Version](https://badge.fury.io/rb/apricot.png)](http://badge.fury.io/rb/apricot) [![Build Status](https://secure.travis-ci.org/apricot-lang/apricot.png?branch=master)](http://travis-ci.org/apricot-lang/apricot) [![Dependency Status](https://gemnasium.com/apricot-lang/apricot.png?travis)](https://gemnasium.com/apricot-lang/apricot)
2
2
 
3
- A Clojure-like Lisp on Rubinius.
3
+ A Clojure-like Lisp on [Rubinius](http://rubini.us/).
4
4
 
5
5
  Try to contain your excitement, please.
6
6
 
7
7
 
8
- ## Setup
9
- To get Apricot up and running, make sure you have Rubinius and Bundler
10
- installed. The easiest way to get Rubinius is with [RVM](https://rvm.io/).
11
- Whenever you are using Apricot you need to be running Rubinius in Ruby 1.9
12
- mode. We make this easy in the Apricot repository with the `.ruby-version`
13
- file which RVM automatically reads to figure out which Ruby to switch to.
8
+ ## Install
9
+
10
+ First of all, you're going to need Rubinius. I recommend installing the latest
11
+ Rubinius with Ruby 1.9-mode default from [RVM](https://rvm.io/).
14
12
 
15
13
  ``` sh
16
14
  $ rvm install rbx-head --1.9
17
- $ rvm use rbx-head
18
- $ gem install bundler
19
- $ bundle
15
+ $ rvm use rbx
16
+ $ gem install apricot
20
17
  ```
21
18
 
19
+ To use Apricot you must be running Rubinius in Ruby 1.9 mode.
20
+
21
+
22
22
  ## The REPL
23
- Apricot provides a nice read-eval-print-loop with line editing, history,
24
- tab-completion, and some interesting commands like `!bytecode`. To enter the
25
- REPL just run:
26
23
 
27
- ``` sh
28
- $ bin/apricot
29
- ```
24
+ Apricot provides an awesome read-eval-print-loop with line editing, history,
25
+ tab-completion, and some interesting commands like `!bytecode`. To enter the
26
+ REPL just run `apricot`.
30
27
 
31
- Once in the repl you can ask for help by using `!help` and you can exit with
32
- `!exit`. See the documentation of any function with `(doc <name>)`. Play
33
- around, read `kernel/core.apr` and try out our functions, and make some of
34
- your own. Experiment. Tell us what you think!
28
+ Once in the repl you can get help with `!help` or use `(doc <name>)` to see
29
+ the documentation of any function or macro. Play around, read
30
+ `kernel/core.apr` and try out our functions, and make some of your own.
31
+ Experiment. Tell us what you think!
35
32
 
36
33
  ``` clojure
37
34
  apr> (+ 1 2 3)
@@ -54,28 +51,48 @@ comp
54
51
  => nil
55
52
  ```
56
53
 
54
+
57
55
  ## Hello World
56
+
58
57
  So you want to put your program in a file and not type it into the REPL? Sure:
59
58
 
60
59
  ``` sh
61
60
  $ cat hello.apr
62
- (puts "Hello, world!")
63
- $ bin/apricot hello.apr
61
+ (println "Hello, world!")
62
+ $ apricot hello.apr
64
63
  Hello, world!
65
64
  ```
66
65
 
66
+
67
+ ## Development
68
+
69
+ If you want to hack on Apricot, first install Rubinius as explained above.
70
+ When you `cd` to the Apricot git repo, RVM should automatically switch to
71
+ Rubinius thanks to the `.ruby-version` file. Now install and run Bundler:
72
+
73
+ ``` sh
74
+ $ gem install bundler
75
+ $ bundle
76
+ ```
77
+
78
+ You're all set. Run the tests with `rake` and run the bleeding edge REPL with
79
+ `ruby -Ilib bin/apricot`. Similarily, use `irb -Ilib -rapricot` for an IRB
80
+ session with Apricot loaded.
81
+
82
+
67
83
  ## Contact / Bug Reports
68
- Come visit us on [freenode](http://freenode.net/) in the #apricot channel, or
69
- drop one of us an email. Please send your bug reports to the GitHub
70
- [issue tracker](https://github.com/programble/apricot/issues). They will be
71
- greatly appreciated!
84
+
85
+ If you have any questions don't hesitate to email us or visit us in `#apricot`
86
+ on [freenode](http://freenode.net/) (we are `curtism` and `tsion`). And we'd
87
+ really appreciate it if you opened bug reports on the GitHub [issue
88
+ tracker](https://github.com/programble/apricot/issues)!
72
89
 
73
90
 
74
91
  ## License
75
92
 
76
- Copyright (c) 2012-2013, Curtis McEnroe <programble@gmail.com>
93
+ Copyright (c) 2012-2013, Curtis McEnroe \<programble@gmail.com>
77
94
 
78
- Copyright (c) 2012-2013, Scott Olson <scott@scott-olson.org>
95
+ Copyright (c) 2012-2013, Scott Olson \<scott@scott-olson.org>
79
96
 
80
97
  Permission to use, copy, modify, and/or distribute this software for any
81
98
  purpose with or without fee is hereby granted, provided that the above
data/Rakefile CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'bundler/setup'
2
- require 'rspec/core'
2
+ require 'bundler/gem_tasks'
3
3
  require 'rspec/core/rake_task'
4
4
 
5
5
  RSpec::Core::RakeTask.new(:spec) do |spec|
@@ -6,7 +6,7 @@ Gem::Specification.new do |s|
6
6
  s.version = Apricot::VERSION
7
7
  s.authors = ["Curtis McEnroe", "Scott Olson"]
8
8
  s.email = ["programble@gmail.com", "scott@scott-olson.org"]
9
- s.homepage = "https://github.com/programble/apricot"
9
+ s.homepage = "https://github.com/apricot-lang/apricot"
10
10
  s.license = "ISC"
11
11
  s.summary = "A Clojure-like programming language on Rubinius"
12
12
  s.description = "A compiler for a Clojure-like programming language on the Rubinius VM"
@@ -16,7 +16,11 @@ Gem::Specification.new do |s|
16
16
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
17
  s.require_paths = ["lib"]
18
18
 
19
- s.add_development_dependency "rake", "~> 10.0.3"
20
- s.add_development_dependency "rspec", "~> 2.13.0"
19
+ s.add_dependency "rubysl", "~> 2.0"
20
+
21
+ s.add_development_dependency "rake", "~> 10.1.0"
22
+ s.add_development_dependency "rspec", "~> 2.14.0"
23
+ #s.add_development_dependency "simplecov", "~> 0.7.0"
24
+ #s.add_development_dependency "rubinius-coverage", "~> 2.0"
21
25
  end
22
26
 
@@ -0,0 +1,51 @@
1
+ $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
2
+ require 'apricot'
3
+
4
+ begin
5
+ require 'benchmark/ips'
6
+ rescue LoadError
7
+ $stderr.puts "The benchmark-ips gem is not installed."
8
+ exit 1
9
+ end
10
+
11
+ ruby_loop = lambda do |n|
12
+ cnt = n
13
+ acc = 1
14
+
15
+ while cnt > 0
16
+ acc *= cnt
17
+ cnt -= 1
18
+ end
19
+
20
+ acc
21
+ end
22
+
23
+ apricot_loop = Apricot::Compiler.eval <<CODE
24
+ (fn [n]
25
+ (loop [n n acc 1]
26
+ (if (pos? n)
27
+ (recur (dec n) (* n acc))
28
+ acc)))
29
+ CODE
30
+
31
+ ruby_reduce = lambda do |n|
32
+ (1..n).reduce(1, :*)
33
+ end
34
+
35
+ apricot_reduce_1 = Apricot::Compiler.eval <<CODE
36
+ (fn [n] (.reduce (Range. 1 n) 1 :*))
37
+ CODE
38
+
39
+ apricot_reduce_2 = Apricot::Compiler.eval <<CODE
40
+ (fn [n] (reduce * (Range. 1 n)))
41
+ CODE
42
+
43
+ n = 100
44
+
45
+ Benchmark.ips do |x|
46
+ x.report("ruby loop") { ruby_loop.call(n) }
47
+ x.report("apricot loop") { apricot_loop.call(n) }
48
+ x.report("ruby reduce") { ruby_reduce.call(n) }
49
+ x.report("apricot reduce 1") { apricot_reduce_1.call(n) }
50
+ x.report("apricot reduce 2") { apricot_reduce_2.call(n) }
51
+ end