atomy 0.1.1 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (172) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +13 -0
  3. data/LICENSE.md +201 -0
  4. data/bin/atomy +16 -133
  5. data/kernel/array.ay +6 -0
  6. data/kernel/atomy.ay +18 -0
  7. data/kernel/condition.ay +171 -271
  8. data/kernel/control-flow.ay +197 -192
  9. data/kernel/core.ay +120 -0
  10. data/kernel/data.ay +83 -39
  11. data/kernel/define.ay +84 -93
  12. data/kernel/doc.ay +282 -449
  13. data/kernel/dynamic.ay +25 -29
  14. data/kernel/file.ay +9 -0
  15. data/kernel/grammar.ay +267 -0
  16. data/kernel/hash.ay +17 -0
  17. data/kernel/interpolation.ay +59 -0
  18. data/kernel/io.ay +70 -244
  19. data/kernel/let-macro.ay +24 -0
  20. data/kernel/let-pattern.ay +24 -0
  21. data/kernel/loop.ay +80 -0
  22. data/kernel/mutation.ay +53 -0
  23. data/kernel/particles.ay +176 -39
  24. data/kernel/patterns.ay +527 -191
  25. data/kernel/pretty.ay +311 -277
  26. data/kernel/quotes.ay +29 -0
  27. data/kernel/range.ay +4 -0
  28. data/kernel/regexp.ay +23 -0
  29. data/kernel/repl.ay +83 -109
  30. data/kernel/stack-local.ay +21 -0
  31. data/lib/atomy.rb +37 -0
  32. data/lib/atomy/bootstrap.rb +256 -0
  33. data/lib/atomy/code/assign.rb +64 -0
  34. data/lib/atomy/code/block.rb +98 -0
  35. data/lib/atomy/code/class_variable.rb +17 -0
  36. data/lib/atomy/code/constant.rb +21 -0
  37. data/lib/atomy/code/define.rb +242 -0
  38. data/lib/atomy/code/define_function.rb +51 -0
  39. data/lib/atomy/code/define_method.rb +20 -0
  40. data/lib/atomy/code/false.rb +9 -0
  41. data/lib/atomy/code/instance_variable.rb +15 -0
  42. data/lib/atomy/code/integer.rb +13 -0
  43. data/lib/atomy/code/list.rb +17 -0
  44. data/lib/atomy/code/nil.rb +9 -0
  45. data/lib/atomy/code/pattern.rb +23 -0
  46. data/lib/atomy/code/pattern/and.rb +61 -0
  47. data/lib/atomy/code/pattern/quasi_quote.rb +185 -0
  48. data/lib/atomy/code/pattern/splat.rb +29 -0
  49. data/lib/atomy/code/pattern/wildcard.rb +37 -0
  50. data/lib/atomy/code/quasi_quote.rb +118 -0
  51. data/lib/atomy/code/quote.rb +13 -0
  52. data/lib/atomy/code/self.rb +9 -0
  53. data/lib/atomy/code/send.rb +110 -0
  54. data/lib/atomy/code/sequence.rb +23 -0
  55. data/lib/atomy/code/string_literal.rb +53 -0
  56. data/lib/atomy/code/symbol.rb +13 -0
  57. data/lib/atomy/code/true.rb +9 -0
  58. data/lib/atomy/code/undefined.rb +9 -0
  59. data/lib/atomy/code/variable.rb +17 -0
  60. data/lib/atomy/codeloader.rb +218 -0
  61. data/lib/atomy/compiler.rb +57 -0
  62. data/lib/atomy/errors.rb +54 -0
  63. data/lib/atomy/grammar.rb +2278 -0
  64. data/lib/atomy/locals.rb +75 -0
  65. data/lib/atomy/message_structure.rb +277 -0
  66. data/lib/atomy/method.rb +343 -0
  67. data/lib/atomy/module.rb +144 -0
  68. data/lib/atomy/node/constructable.rb +169 -0
  69. data/lib/atomy/node/equality.rb +113 -0
  70. data/lib/atomy/node/meta.rb +206 -0
  71. data/lib/atomy/node/pretty.rb +108 -0
  72. data/lib/atomy/parser.rb +21 -0
  73. data/lib/atomy/pattern.rb +26 -0
  74. data/lib/atomy/pattern/and.rb +59 -0
  75. data/lib/atomy/pattern/attribute.rb +16 -0
  76. data/lib/atomy/pattern/class_variable.rb +15 -0
  77. data/lib/atomy/pattern/equality.rb +42 -0
  78. data/lib/atomy/pattern/instance_variable.rb +15 -0
  79. data/lib/atomy/pattern/kind_of.rb +20 -0
  80. data/lib/atomy/pattern/or.rb +48 -0
  81. data/lib/atomy/pattern/quasi_quote.rb +164 -0
  82. data/lib/atomy/pattern/splat.rb +15 -0
  83. data/lib/atomy/pattern/wildcard.rb +18 -0
  84. data/lib/atomy/rubygems.rb +48 -0
  85. data/lib/atomy/version.rb +3 -0
  86. metadata +169 -134
  87. data/COPYING +0 -30
  88. data/README.md +0 -1
  89. data/kernel/block.ay +0 -30
  90. data/kernel/boot.ay +0 -10
  91. data/kernel/comparison.ay +0 -61
  92. data/kernel/concurrency.ay +0 -84
  93. data/kernel/cosmetics.ay +0 -3
  94. data/kernel/data-delta.ay +0 -105
  95. data/kernel/documentation.ay +0 -135
  96. data/kernel/errors.ay +0 -6
  97. data/kernel/format.ay +0 -13
  98. data/kernel/format/data.ay +0 -89
  99. data/kernel/format/formatter.ay +0 -345
  100. data/kernel/format/parser.ay +0 -13
  101. data/kernel/hashes.ay +0 -39
  102. data/kernel/namespaces.ay +0 -63
  103. data/kernel/node.ay +0 -48
  104. data/kernel/operators.ay +0 -28
  105. data/kernel/precision.ay +0 -148
  106. data/kernel/therie.ay +0 -204
  107. data/lib/ast/binary_send.rb +0 -44
  108. data/lib/ast/block.rb +0 -268
  109. data/lib/ast/constant.rb +0 -88
  110. data/lib/ast/internal/assign.rb +0 -19
  111. data/lib/ast/internal/block_pass.rb +0 -21
  112. data/lib/ast/internal/catch.rb +0 -247
  113. data/lib/ast/internal/class.rb +0 -30
  114. data/lib/ast/internal/class_variable.rb +0 -23
  115. data/lib/ast/internal/define.rb +0 -174
  116. data/lib/ast/internal/ensure.rb +0 -135
  117. data/lib/ast/internal/file.rb +0 -14
  118. data/lib/ast/internal/global_variable.rb +0 -20
  119. data/lib/ast/internal/if_then_else.rb +0 -24
  120. data/lib/ast/internal/instance_variable.rb +0 -17
  121. data/lib/ast/internal/let_macro.rb +0 -35
  122. data/lib/ast/internal/macro_quote.rb +0 -23
  123. data/lib/ast/internal/match.rb +0 -53
  124. data/lib/ast/internal/module.rb +0 -30
  125. data/lib/ast/internal/pattern.rb +0 -17
  126. data/lib/ast/internal/return.rb +0 -29
  127. data/lib/ast/internal/set.rb +0 -19
  128. data/lib/ast/internal/singleton_class.rb +0 -18
  129. data/lib/ast/internal/splat.rb +0 -14
  130. data/lib/ast/internal/when.rb +0 -24
  131. data/lib/ast/list.rb +0 -25
  132. data/lib/ast/macro.rb +0 -37
  133. data/lib/ast/node.rb +0 -599
  134. data/lib/ast/operator.rb +0 -21
  135. data/lib/ast/particle.rb +0 -13
  136. data/lib/ast/primitive.rb +0 -20
  137. data/lib/ast/quasi_quote.rb +0 -20
  138. data/lib/ast/quote.rb +0 -13
  139. data/lib/ast/send.rb +0 -104
  140. data/lib/ast/splice.rb +0 -32
  141. data/lib/ast/string.rb +0 -23
  142. data/lib/ast/unary.rb +0 -44
  143. data/lib/ast/unquote.rb +0 -45
  144. data/lib/ast/variable.rb +0 -64
  145. data/lib/atomy.kpeg.rb +0 -3995
  146. data/lib/code_loader.rb +0 -137
  147. data/lib/compiler/compiler.rb +0 -155
  148. data/lib/compiler/stages.rb +0 -81
  149. data/lib/formatter.kpeg.rb +0 -1394
  150. data/lib/macros.rb +0 -317
  151. data/lib/method.rb +0 -261
  152. data/lib/namespace.rb +0 -236
  153. data/lib/parser.rb +0 -28
  154. data/lib/patterns.rb +0 -276
  155. data/lib/patterns/any.rb +0 -21
  156. data/lib/patterns/attribute.rb +0 -59
  157. data/lib/patterns/block_pass.rb +0 -54
  158. data/lib/patterns/constant.rb +0 -33
  159. data/lib/patterns/default.rb +0 -44
  160. data/lib/patterns/head_tail.rb +0 -63
  161. data/lib/patterns/list.rb +0 -77
  162. data/lib/patterns/match.rb +0 -45
  163. data/lib/patterns/named.rb +0 -55
  164. data/lib/patterns/named_class.rb +0 -46
  165. data/lib/patterns/named_global.rb +0 -46
  166. data/lib/patterns/named_instance.rb +0 -46
  167. data/lib/patterns/particle.rb +0 -29
  168. data/lib/patterns/quasi_quote.rb +0 -184
  169. data/lib/patterns/quote.rb +0 -33
  170. data/lib/patterns/singleton_class.rb +0 -31
  171. data/lib/patterns/splat.rb +0 -57
  172. data/lib/util.rb +0 -37
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4a5ee90eba9d13582347f3eaf9ca4dc9df87f82d
4
+ data.tar.gz: 36535d41525bf8bf12e3149a43ec7fc42adc9b3b
5
+ SHA512:
6
+ metadata.gz: 2f1b3fcb454c9d0d98e1eb244c8b999d6db9b2bd9f4172058dbbd1ceada3ea8bd37f3d41a6fb4f2a6cf647514f9b67e066f44e9c9339cee57a9ea9aff98cdb57
7
+ data.tar.gz: 3eb67fcebe8d404c0acf13270e99c01604169d98222bfb979075630aaa6991d0940859eccbc7c14b1b6b6f06508834ae1d6b63431c206da30b5ba0657655fde5
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ group "test" do
6
+ gem "rspec"
7
+ end
8
+
9
+ group "development" do
10
+ gem "pry"
11
+ gem "benchmark-ips"
12
+ gem "rubinius-profiler"
13
+ end
data/LICENSE.md ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "{}"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright {yyyy} {name of copyright owner}
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
data/bin/atomy CHANGED
@@ -1,134 +1,17 @@
1
- #!/usr/bin/env rbx
2
-
3
- base = File.expand_path "../../lib/", __FILE__
4
- kernel = File.expand_path "../../kernel/", __FILE__
5
-
6
- require 'readline'
7
- require 'optparse'
8
-
9
- require base + "/macros"
10
- require base + "/method"
11
- require base + "/util"
12
- require base + "/namespace"
13
- require base + "/compiler/compiler"
14
- require base + "/compiler/stages"
15
- require base + "/parser"
16
- require base + "/patterns"
17
- require base + "/code_loader"
18
-
19
- def require_atomy(*as)
20
- before = Atomy::Namespace.get
21
- begin
22
- Atomy::CodeLoader.load_file *as
23
- ensure
24
- Atomy::Namespace.set(before)
25
- end
26
- end
27
-
28
- options = {}
29
-
30
- unless ARGV.empty? || ARGV[0][0] != ?-
31
- OptionParser.new do |o|
32
- o.banner = "usage: atomy [options]"
33
-
34
- o.on("-B", "--print-bytecode", "print out compiled bytecode") do |v|
35
- options[:debug] = v
36
- end
37
-
38
- o.on("-e", "--evaluate EXPR", "evaluate EXPR and print the result") do |v|
39
- options[:evaluate] = v
40
- end
41
-
42
- o.on("-s", "--before-start EXPR", "evaluate EXPR beforehand") do |v|
43
- options[:start] = v
44
- end
45
-
46
- o.on("-l", "--load FILE", "load FILENAME and start the REPL") do |v|
47
- options[:load] = v
48
- end
49
-
50
- o.on("-d", "--documentation DIR", "generate documentation with output to DIR") do |v|
51
- Atomy::CodeLoader.documentation = v
52
- end
53
-
54
- o.on_tail("-h", "--help", "show this message") do
55
- puts o
56
- exit
57
- end
58
- end.parse!
1
+ #!/usr/bin/env ruby
2
+ # vim: set ft=ruby
3
+
4
+ require "atomy"
5
+ require "atomy/bootstrap"
6
+ require "atomy/codeloader"
7
+ require "atomy/parser"
8
+ require "atomy/rubygems"
9
+
10
+ file, *_ = ARGV
11
+
12
+ if file
13
+ Atomy::CodeLoader.run_script(File.expand_path(file))
14
+ else
15
+ repl = Atomy::CodeLoader.require("repl")
16
+ repl.repl
59
17
  end
60
-
61
- a = Time.now
62
- puts "loading kernel"
63
- require_atomy(kernel + "/boot.ay")
64
- puts Time.now - a
65
-
66
- Atomy::Namespace.ensure(:user)
67
-
68
- def run_atomy(options)
69
- if str = options[:evaluate] || options[:start]
70
- $0 = "(eval)"
71
- res = Atomy::Compiler.evaluate(
72
- str,
73
- nil,
74
- "(eval)",
75
- 1,
76
- options[:debug]
77
- )
78
-
79
- if options[:evaluate]
80
- res.send(Atomy.namespaced("atomy", "write").to_sym)
81
- return
82
- end
83
- end
84
-
85
- if file = options[:load] || ARGV[0]
86
- $0 = file
87
- require_atomy(file, ARGV[0] ? :run : :load, options[:debug])
88
- return if ARGV[0]
89
- end
90
-
91
- if respond_to?(Atomy.namespaced("atomy", "repl").to_sym, true)
92
- send(Atomy.namespaced("atomy", "repl").to_sym, File.expand_path("~/.atomy_history"))
93
- else
94
- $stderr.puts("main REPL startup failed! here's a basic one:")
95
-
96
- history_file = File.expand_path("~/.atomy_history")
97
-
98
- if File.exists?(history_file)
99
- File.open(history_file, "r") do |f|
100
- f.readlines.each do |l|
101
- Readline::HISTORY << l.strip
102
- end
103
- end
104
- end
105
-
106
- begin
107
- sane_history = []
108
- while str = Readline.readline("> ")
109
- next if str.empty?
110
-
111
- sane_history << str
112
-
113
- begin
114
- res = Atomy::Compiler.evaluate str, TOPLEVEL_BINDING
115
- if res.respond_to?(:pretty)
116
- puts "=> #{res.pretty.render}"
117
- else
118
- puts "=> #{res.inspect}"
119
- end
120
- rescue StandardError => e
121
- puts "ERROR!"
122
- puts "#{e}:\n #{e.message}"
123
- puts e.backtrace
124
- end
125
- end
126
- ensure
127
- File.open(history_file, "a") do |f|
128
- f.puts(*sane_history)
129
- end
130
- end
131
- end
132
- end
133
-
134
- run_atomy(options)
data/kernel/array.ay ADDED
@@ -0,0 +1,6 @@
1
+ use(require("core"))
2
+ use(require("patterns"))
3
+
4
+ pattern(~x . ~ys): pattern(`[~x, *~ys])
5
+
6
+ macro(~x . ~ys): `([~x] + ~ys)
data/kernel/atomy.ay ADDED
@@ -0,0 +1,18 @@
1
+ export(
2
+ require("core")
3
+ require("patterns")
4
+ require("define")
5
+ require("loop")
6
+ require("data")
7
+ require("array")
8
+ require("quotes")
9
+ require("interpolation")
10
+ require("regexp")
11
+ require("hash")
12
+ require("dynamic")
13
+ require("condition")
14
+ require("particles")
15
+ require("range")
16
+ require("io")
17
+ require("control-flow")
18
+ require("file"))
data/kernel/condition.ay CHANGED
@@ -1,277 +1,177 @@
1
- namespace(atomy)
1
+ use(require("core"))
2
+ define = use(require("define"))
3
+ use(require("data"))
4
+ use(require("control-flow"))
5
+ use(require("interpolation"))
6
+ use(require("patterns"))
2
7
 
3
- title"Condition System"
8
+ use(require("dynamic"))
4
9
 
5
- doc"
6
- Rather than traditional exceptions, Atomy sports a condition/restart \
7
- system modeled on Common Lisp's design. The native Ruby exception handling \
8
- is available, but conditions and restarts are much more flexible.
9
- "
10
+ io = use(require("io"))
11
+ loaded-pretty = nil
12
+ fn(pretty): &loaded-pretty = (loaded-pretty || require("pretty"))
13
+
14
+ require("atomy/message_structure")
15
+
16
+ data(Handler(@callback, @rest)):
17
+ BaseHandler()
10
18
 
11
19
  -- registered handlers/restarts
12
- dynamic(handlers, [])
13
- dynamic(restarts, [])
20
+ const-set(.Handlers, dynamic(BaseHandler new))
21
+ const-set(.Restarts, dynamic([]))
22
+
23
+ fn(catcher(x)): ."restart:#{Atomy MessageStructure new(x) name}"
24
+
25
+ data(Restart(@name, @action))
26
+
27
+ def(Restart invoke(*args)):
28
+ throw(."restart:#{@name}", @action [*args])
29
+
30
+ data(Condition):
31
+ Error(@backtrace):
32
+ SimpleError(@value)
33
+ ExceptionError(@exception)
34
+ NoRestartError(@restart)
35
+ PortError(@port):
36
+ EndOfFile
37
+
38
+ Warning(@backtrace):
39
+ SimpleWarning(@value)
40
+
41
+ def(Condition name): class name
42
+
43
+ def(ExceptionError name): @exception class name
44
+
45
+ def(Condition message): inspect
46
+
47
+ def(SimpleError(s & String) message): s
48
+ def(SimpleError(v) message): pretty show(v)
49
+
50
+ def(SimpleWarning(s & String) message): s
51
+ def(SimpleWarning(v) message): pretty show(v)
52
+
53
+ def(ExceptionError message): @exception message
54
+
55
+ def(NoRestartError message): "unknown restart " + pretty show(@restart)
56
+
57
+ def(EndOfFile message): "unexpected end-of-file for " + pretty show(@port)
58
+
59
+
60
+ macro(~body bind: ~*handlers):
61
+ callback = `([signalled-condition]: signalled-condition match: ~*handlers)
62
+
63
+ `(with(Handlers = Handler new(~callback, ^Handlers)):
64
+ ~body rescue:
65
+ (e & StandardError): Self error(e))
66
+
67
+
68
+ macro(with-restarts(~*restarts): ~*body):
69
+ branches = restarts collect [`(~name: ~*body)]:
70
+ [name, `(do: ~*body)]
71
+
72
+ rs = branches collect [n, e]:
73
+ structure = Atomy MessageStructure new(n)
74
+
75
+ `(Restart new(
76
+ ~(Atomy Code Symbol new(structure name))
77
+ [~*(structure arguments)] &~(structure proc-argument || 'nil) { ~e }))
78
+
79
+ with =
80
+ branches reduce(`{ do { ~*body } rescue: (e & StandardError): Self error(e) })
81
+ [x, [name, _]]:
82
+ `{ catch(~(Atomy Code Symbol new(catcher(name)))) ~x }
83
+
84
+ `(with(Restarts = ([~*rs] + ^Restarts)) ~with)
85
+
86
+
87
+ def(restart(name, *args)):
88
+ ^Restarts each [r]:
89
+ when(r name == name):
90
+ r invoke(*args)
91
+
92
+ error(NoRestartError new(name))
14
93
 
15
- for-macro:
16
- catcher(x) :=
17
- Atomy::AST::Variable new(x line) $:
94
+
95
+ def(BaseHandler signal(_)): nil
96
+ def(Handler(callback, rest) signal(c)):
97
+ with(Handlers = rest):
98
+ callback [c]
99
+ rest signal(c)
100
+
101
+ def(signal(c)): ^Handlers signal(c)
102
+
103
+ def(error(x)):
104
+ e =
105
+ x match:
106
+ Exception:
107
+ ExceptionError new(x) tap [err]:
108
+ err backtrace = x locations
109
+
110
+ Error: x
111
+
112
+ _: SimpleError new(x)
113
+
114
+ unless(e backtrace):
115
+ e backtrace = Rubinius VM backtrace(1, true)
116
+
117
+ signal(e)
118
+
119
+ with-output-to(^(io ErrorPort)):
120
+ ^Debugger new(e) run
121
+
122
+
123
+ def(warning(x)):
124
+ with-restarts(muffle-warning: nil):
125
+ w =
18
126
  x match:
19
- Atomy::AST::Variable ->
20
- "restart:" + x name
21
-
22
- Atomy::AST::Send ->
23
- "restart:" + x method-name
24
-
25
- data(Object):
26
- Restart(@name, @action)
27
-
28
- Restart invoke(*args) :=
29
- throw(("restart:" + @name to-s) to-sym, @action [*args])
30
-
31
- symbols(signal, warning, error, restart)
32
-
33
- section("Conditions"):
34
- doc"
35
- Condition system hierarchy. You should subclass one of these to create \
36
- your own conditions.
37
- " for:
38
- data(Object):
39
- Condition:
40
- Error(@backtrace):
41
- SimpleError(@value)
42
- ExceptionError(@exception)
43
- NoRestartError(@name)
44
- PortError(@port):
45
- EndOfFile
46
-
47
- Warning(@backtrace):
48
- SimpleWarning(@value)
49
-
50
- doc"
51
- Get the name of a condition. By default, this will be the class name, \
52
- but you may override this for your own behaviour.
53
- " for:
54
- Condition name := class name
55
-
56
- ExceptionError name := @exception class name
57
-
58
- doc"
59
- A human-friendly message displayed for the condition. Override this.
60
- " for:
61
- Condition message := inspect
62
-
63
- SimpleError message := @value to-s
64
- ExceptionError message := @exception message
65
- SimpleWarning message := @value to-s
66
- NoRestartError message := "unknown restart " + @name show
67
- EndOfFile message := "unexpected end-of-file for " + @port show
68
-
69
-
70
- section("Handling"):
71
- doc"
72
- Invoke the \hl{name} restart, passing \hl{args} along to its callback.
73
-
74
- See \hl{with-restarts}.
75
- " spec {
76
- name is-a?(Symbol)
77
- => any
78
- } for {
79
- restart(name, *args) := do:
80
- ^restarts each [r]:
81
- when(r name == name):
82
- r invoke(*args)
83
-
84
- error(NoRestartError new(name))
85
- } examples:
86
- { with-restarts(foo -> 42):
87
- signal(#bar)
88
- } bind: #bar -> restart(#foo)
89
-
90
-
91
- doc"
92
- Register handlers for various signals for the duration of \hl{x}'s \
93
- execution.
94
-
95
- The body of \hl{y} is similar to \hl{match}; \hl{\italic{pattern} -> \
96
- \italic{body}}.
97
-
98
- The result is the result of \hl{body}.
99
- " spec {
100
- y contents all? [x]: x match { `(~_ -> ~_) -> true, _ -> false }
101
- => any
102
- } for {
103
- macro(body bind(&y)):
104
- names [a]:
105
- callback = `([~a]: ~a match: ~*(y contents))
106
- `(let(handlers = ^handlers + [~callback]):
107
- ~body rescue:
108
- (e: StandardError) -> error(e))
109
- } examples:
110
- { signal(#a) } bind: #a -> "got A!" print
111
- { signal(#b) } bind: #a -> "got A!" print
112
- { { signal(#a) } bind: #a -> "inner" print } bind: #a -> "outer" print
113
-
114
-
115
- doc"
116
- Register restarts available for the duration of \hl{body}'s execution.
117
-
118
- The \hl{restarts} should be in the form of \
119
- \hl{\italic{name}(*\italic{args}) -> \italic{body}}.
120
-
121
- The result is the result of \hl{body}.
122
- " spec {
123
- => any
124
- } for {
125
- macro(with-restarts(*restarts, &block)):
126
- rs = restarts collect [`(~n -> ~e)]:
127
- n match:
128
- Atomy::AST::Variable ->
129
- `(Restart new(#~n, { ~e }))
130
-
131
- Atomy::AST::Send -> do:
132
- name = Atomy::AST::Variable new(0, n method-name)
133
- `(Restart new(#~name, [~*(n arguments)] { ~e }))
134
-
135
- body =
136
- restarts reduce(
137
- `{ ~block rescue: (e: StandardError) -> error(e) }
138
- ) [x, `(~name -> ~_)]:
139
- `{ catch(#~catcher(name), &~x) }
140
-
141
- `(let(restarts = [~*rs] + ^restarts, &~body))
142
- } examples:
143
- { with-restarts(x -> 1, y -> 2):
144
- signal(#a)
145
- } bind: #a -> restart(#x)
146
-
147
- { with-restarts(x -> 1, y -> 2):
148
- signal(#a)
149
- } bind: #a -> restart(#y)
150
-
151
- { with-restarts(x(a) -> a * 7):
152
- signal(#a)
153
- } bind: #a -> restart(#x, 6)
154
-
155
-
156
- section("Signalling"):
157
- doc"
158
- Signal a value through all bound handlers, nearest-first, stopping when \
159
- a restart is invoked.
160
- " spec {
161
- => nil
162
- } for {
163
- signal(c) := do:
164
- ^handlers reverse-each [callback]:
165
- callback [c]
166
-
167
- nil
168
- } examples:
169
- signal(#foo)
170
- { signal(#foo) } bind: #foo -> "got foo" print
171
-
172
-
173
- doc"
174
- Like \hl{signal}, except that if no restart is invoked, the current \
175
- \hl{^debugger} is started.
176
-
177
- If the given value is not an \hl{Error}, it is wrapped in a \
178
- \hl{SimpleError}. If the value is a Ruby \hl{Exception}, it is wrapped \
179
- in an \hl{ExceptionError}.
180
- " spec {
181
- => _
182
- } for {
183
- error(x) := do:
184
- e =
185
- x match:
186
- Exception ->
187
- ExceptionError new(x) tap [err]:
188
- err backtrace = x locations
189
-
190
- Error ->
191
- x tap [err]:
192
- err backtrace = Rubinius::VM backtrace(0)
193
-
194
- _ ->
195
- SimpleError new(x) tap [err]:
196
- err backtrace = Rubinius::VM backtrace(0)
197
-
198
- signal(e)
199
-
200
- with-output-to(^error-port):
201
- ^debugger run(e)
202
- } examples:
203
- error("Oh no!")
204
- { error("Oh no!") } bind: Error -> "INCOMING" print
205
-
206
-
207
- doc"
208
- Like \hl{signal}, except that if no restart is invoked, the warning is \
209
- printed to \hl{^error-port}.
210
-
211
- If the given value is not a \hl{Warning}, it is wrapped in a \
212
- \hl{SimpleWarning}. Warning messages can be muffled by binding for \
213
- \hl{Warning} and invoking the \hl{#muffle-warning} restart.
214
- " spec {
215
- => nil
216
- } for {
217
- warning(x) :=
218
- with-restarts(muffle-warning -> nil):
219
- w =
220
- x match:
221
- Warning ->
222
- x tap [wrn]:
223
- wrn backtrace = Rubinius::VM backtrace(0)
224
-
225
- _ ->
226
- SimpleWarning new(x) tap [wrn]:
227
- wrn backtrace = Rubinius::VM backtrace(0)
228
-
229
- signal(w)
230
-
231
- with-output-to(^error-port):
232
- (w name + ": " + w message) print
233
-
234
- nil
235
- } examples:
236
- warning("Suspicious!")
237
- { warning("Quiet, you!") } bind: Warning -> restart(#muffle-warning)
238
-
239
-
240
- section("Debuggers"):
241
- doc"
242
- The default debugger. This will show the condition name, its message, \
243
- and let the user pick from the available restarts.
244
- " for:
245
- class(DefaultDebugger):
246
- class(<< self):
247
- define(show-error-banner(e)):
248
- ("-" * 78) print
249
- (e name + ": " + e message) each-line [l]:
250
- ("*** " + l) display
251
-
252
- "\n" display
253
-
254
- define(show-options-for(e)):
255
- when(^restarts empty?):
256
- exit(1)
257
-
258
- "\n" display
259
- "restarts:" print
260
- ^restarts each-with-index [r, i]:
261
- (" :" + i to-s + " -> " + r name to-s) print
262
-
263
- define(run(e)):
264
- show-error-banner(e)
265
-
266
- show-options-for(e)
267
-
268
- "!> " display
269
- ^restarts [gets to-i] invoke
270
-
271
- doc"
272
- The current debugger. \hl{run} will be called with the condition as an \
273
- argument.
274
- " spec {
275
- respond-to?(#run)
276
- } for:
277
- dynamic(debugger, DefaultDebugger)
127
+ Warning: x
128
+
129
+ _: SimpleWarning new(x)
130
+
131
+ w backtrace = Rubinius VM backtrace(1, true)
132
+
133
+ signal(w)
134
+
135
+ with-output-to(^(io ErrorPort)):
136
+ puts(i"#{w name}: #{w message}")
137
+
138
+ nil
139
+
140
+
141
+ data(DefaultDebugger(@error))
142
+
143
+ def(DefaultDebugger(e) show-banner):
144
+ puts("An error occurred:")
145
+
146
+ [msg, *desc] = e message to-s split("\n")
147
+
148
+ puts(i" #{msg} (#{e name})")
149
+
150
+ desc each [l]:
151
+ puts(l)
152
+
153
+ def(DefaultDebugger(e) show-restarts):
154
+ puts("")
155
+ puts("restarts:")
156
+ ^Restarts each-with-index [r, i]:
157
+ puts(i" :#{i} -> #{r name}")
158
+
159
+ def(DefaultDebugger(e) show-backtrace):
160
+ puts(Rubinius Backtrace backtrace(e backtrace) show)
161
+
162
+ def(DefaultDebugger(e) run):
163
+ show-banner
164
+
165
+ if(^Restarts empty?)
166
+ then:
167
+ puts("")
168
+ puts("Backtrace:")
169
+ show-backtrace
170
+ exit(1)
171
+ else:
172
+ show-restarts
173
+
174
+ print("!> ")
175
+ ^Restarts [gets to-i] invoke
176
+
177
+ const-set(.Debugger, dynamic(DefaultDebugger))