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
@@ -0,0 +1,108 @@
1
+ require "atomy/grammar"
2
+
3
+ module Atomy::Grammar::AST
4
+ class Sequence
5
+ def to_s
6
+ @nodes.join(", ")
7
+ end
8
+ end
9
+
10
+ class Number
11
+ def to_s
12
+ @value.to_s
13
+ end
14
+ end
15
+
16
+ class Literal
17
+ def to_s
18
+ @value.to_s
19
+ end
20
+ end
21
+
22
+ class Quote
23
+ def to_s
24
+ "'#@node"
25
+ end
26
+ end
27
+
28
+ class QuasiQuote
29
+ def to_s
30
+ "`#@node"
31
+ end
32
+ end
33
+
34
+ class Unquote
35
+ def to_s
36
+ "~#@node"
37
+ end
38
+ end
39
+
40
+ class Constant
41
+ def to_s
42
+ @text.to_s
43
+ end
44
+ end
45
+
46
+ class Word
47
+ def to_s
48
+ word = @text.to_s
49
+ word[0] + word[1..-1].tr("_", "-")
50
+ end
51
+ end
52
+
53
+ class Prefix
54
+ def to_s
55
+ "#@operator#@node"
56
+ end
57
+ end
58
+
59
+ class Postfix
60
+ def to_s
61
+ "#@node#@operator"
62
+ end
63
+ end
64
+
65
+ class Infix
66
+ def to_s
67
+ if @left
68
+ "(#@left #@operator #@right)"
69
+ else
70
+ "(#@operator #@right)"
71
+ end
72
+ end
73
+ end
74
+
75
+ class Block
76
+ def to_s
77
+ if @nodes.empty?
78
+ "{}"
79
+ else
80
+ "{ #{@nodes.join(", ")} }"
81
+ end
82
+ end
83
+ end
84
+
85
+ class List
86
+ def to_s
87
+ "[#{@nodes.join(", ")}]"
88
+ end
89
+ end
90
+
91
+ class Compose
92
+ def to_s
93
+ "(#@left #@right)"
94
+ end
95
+ end
96
+
97
+ class Apply
98
+ def to_s
99
+ "#@node(#{@arguments.join(", ")})"
100
+ end
101
+ end
102
+
103
+ class StringLiteral
104
+ def to_s
105
+ @value.inspect
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,21 @@
1
+ require "atomy/grammar"
2
+
3
+ module Atomy
4
+ module Parser
5
+ extend self
6
+
7
+ def parse_file(file)
8
+ parse_string(File.read(file))
9
+ end
10
+
11
+ def parse_string(source)
12
+ grammar = Atomy::Grammar.new(source)
13
+
14
+ grammar.raise_error unless grammar.parse
15
+
16
+ grammar.result
17
+ rescue KPeg::CompiledParser::ParseError => e
18
+ raise SyntaxError, e.to_s
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,26 @@
1
+ require "atomy/node/constructable"
2
+ require "rubinius/ast"
3
+
4
+ module Atomy
5
+ class Pattern
6
+ attr_accessor :from_node
7
+
8
+ def ===(v)
9
+ matches?(v)
10
+ end
11
+
12
+ def matches?(gen)
13
+ raise NotImplementedError
14
+ end
15
+
16
+ def target
17
+ raise NotImplementedError
18
+ end
19
+
20
+ def inline_matches?(gen)
21
+ gen.push_literal(self)
22
+ gen.swap
23
+ gen.send(:matches?, 1)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,59 @@
1
+ require "atomy/pattern"
2
+
3
+ class Atomy::Pattern
4
+ class And < self
5
+ attr_reader :a, :b
6
+
7
+ def initialize(a, b)
8
+ @a = a
9
+ @b = b
10
+ end
11
+
12
+ def matches?(val)
13
+ @a.matches?(val) && @b.matches?(val)
14
+ end
15
+
16
+ def inline_matches?(gen)
17
+ mismatch = gen.new_label
18
+ done = gen.new_label
19
+
20
+ # [value, value]
21
+ gen.dup
22
+
23
+ # [bool, value]
24
+ @a.inline_matches?(gen)
25
+
26
+ # [value]
27
+ gen.gif(mismatch)
28
+
29
+ # [bool]
30
+ @b.inline_matches?(gen)
31
+
32
+ # [bool]
33
+ gen.goto(done)
34
+
35
+ # [value]
36
+ mismatch.set!
37
+
38
+ # []
39
+ gen.pop
40
+
41
+ # [bool]
42
+ gen.push_false
43
+
44
+ # [bool]
45
+ done.set!
46
+ end
47
+
48
+ def assign(gen)
49
+ @a.assign(gen)
50
+ @b.assign(gen)
51
+ end
52
+
53
+ def target
54
+ a = @a.target
55
+ b = @b.target
56
+ a < b ? a : b
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,16 @@
1
+ require "atomy/pattern"
2
+
3
+ class Atomy::Pattern
4
+ class Attribute < self
5
+ attr_reader :receiver, :arguments
6
+
7
+ def initialize(receiver, arguments = [])
8
+ @receiver = receiver
9
+ @arguments = arguments
10
+ end
11
+
12
+ def matches?(_)
13
+ true
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ require "atomy/pattern"
2
+
3
+ class Atomy::Pattern
4
+ class ClassVariable < self
5
+ attr_reader :name
6
+
7
+ def initialize(name)
8
+ @name = name
9
+ end
10
+
11
+ def matches?(_)
12
+ true
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,42 @@
1
+ require "atomy/pattern"
2
+
3
+ class Atomy::Pattern
4
+ class Equality < self
5
+ attr_reader :value
6
+
7
+ def initialize(value)
8
+ @value = value
9
+ end
10
+
11
+ def matches?(val)
12
+ @value == val
13
+ end
14
+
15
+ def inline_matches?(gen)
16
+ push_value(gen)
17
+ gen.swap
18
+ gen.send(:==, 1)
19
+ end
20
+
21
+ def target
22
+ @value.class
23
+ end
24
+
25
+ private
26
+
27
+ def push_value(gen)
28
+ case @value
29
+ when true
30
+ gen.push_true
31
+ when false
32
+ gen.push_false
33
+ when nil
34
+ gen.push_nil
35
+ when Integer
36
+ gen.push_int(@value)
37
+ else
38
+ gen.push_literal(@value)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,15 @@
1
+ require "atomy/pattern"
2
+
3
+ class Atomy::Pattern
4
+ class InstanceVariable < self
5
+ attr_reader :name
6
+
7
+ def initialize(name)
8
+ @name = name
9
+ end
10
+
11
+ def matches?(_)
12
+ true
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,20 @@
1
+ require "atomy/pattern"
2
+ require "atomy/pattern/wildcard"
3
+
4
+ class Atomy::Pattern
5
+ class KindOf < self
6
+ attr_reader :klass
7
+
8
+ def initialize(klass)
9
+ @klass = klass
10
+ end
11
+
12
+ def matches?(val)
13
+ val.kind_of?(@klass)
14
+ end
15
+
16
+ def target
17
+ @klass
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,48 @@
1
+ require "atomy/pattern"
2
+
3
+ class Atomy::Pattern
4
+ class Or < self
5
+ attr_reader :a, :b
6
+
7
+ def initialize(a, b)
8
+ @a = a
9
+ @b = b
10
+ end
11
+
12
+ def matches?(val)
13
+ @a.matches?(val) || @b.matches?(val)
14
+ end
15
+
16
+ def inline_matches?(gen)
17
+ match = gen.new_label
18
+ done = gen.new_label
19
+
20
+ # [value, value]
21
+ gen.dup
22
+
23
+ # [bool, value]
24
+ @a.inline_matches?(gen)
25
+
26
+ # [value]
27
+ gen.git(match)
28
+
29
+ # [bool]
30
+ @b.inline_matches?(gen)
31
+
32
+ # [bool]
33
+ gen.goto(done)
34
+
35
+ # [value]
36
+ match.set!
37
+
38
+ # []
39
+ gen.pop
40
+
41
+ # [bool]
42
+ gen.push_true
43
+
44
+ # [bool]
45
+ done.set!
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,164 @@
1
+ require "atomy/pattern"
2
+
3
+ require "atomy/node/meta"
4
+ require "atomy/pattern/equality"
5
+
6
+
7
+ class Atomy::Pattern
8
+ class QuasiQuote < self
9
+ attr_reader :node
10
+
11
+ def self.patterns_through(mod, node)
12
+ constructor = Constructor.new(mod)
13
+ constructor.go(node)
14
+ end
15
+
16
+ def self.make(mod, node)
17
+ new(mod.evaluate(patterns_through(mod, node)))
18
+ end
19
+
20
+ def initialize(node)
21
+ @node = node
22
+ end
23
+
24
+ def matches?(val)
25
+ MatchWalker.new.go(@node, val)
26
+ end
27
+
28
+ private
29
+
30
+ class Walker
31
+ def initialize
32
+ @depth = 0
33
+ end
34
+
35
+ def go(x)
36
+ x.accept(self)
37
+ end
38
+
39
+ def visit_quasiquote(qq)
40
+ @depth += 1
41
+ visit(qq)
42
+ ensure
43
+ @depth -= 1
44
+ end
45
+
46
+ def visit_unquote(x)
47
+ @depth -= 1
48
+
49
+ if @depth == 0
50
+ unquote(x)
51
+ else
52
+ visit(x)
53
+ end
54
+ ensure
55
+ @depth += 1
56
+ end
57
+
58
+ def unquote(_)
59
+ raise NotImplementedError
60
+ end
61
+
62
+ def push_literal(x)
63
+ case x
64
+ when Array
65
+ x.each { |v| push_literal(v) }
66
+ @gen.make_array(x.size)
67
+ when String
68
+ @gen.push_literal(x)
69
+ @gen.string_dup
70
+ else
71
+ @gen.push_literal(x)
72
+ end
73
+ end
74
+
75
+ def unsplat(pats)
76
+ if pats.last.is_a?(Atomy::Grammar::AST::Unquote) && \
77
+ pats.last.node.is_a?(Atomy::Pattern::Splat)
78
+ [pats[0..-2], pats[-1]]
79
+ else
80
+ [pats, nil]
81
+ end
82
+ end
83
+ end
84
+
85
+ class Constructor < Walker
86
+ def initialize(mod)
87
+ super()
88
+
89
+ @module = mod
90
+ end
91
+
92
+ def go(x)
93
+ x.accept(self)
94
+ end
95
+
96
+ def visit(x)
97
+ x.through do |v|
98
+ go(v)
99
+ end
100
+ end
101
+
102
+ def unquote(x)
103
+ x.through do |p|
104
+ @module.pattern(p)
105
+ end
106
+ end
107
+ end
108
+
109
+ class MatchWalker
110
+ def go(a, b)
111
+ if a.is_a?(Atomy::Pattern)
112
+ a.matches?(b)
113
+ elsif b.is_a?(a.class)
114
+ a.each_attribute do |attr, val|
115
+ return false unless val == b.send(attr)
116
+ end
117
+
118
+ a.each_child do |attr, val|
119
+ theirval = b.send(attr)
120
+
121
+ if val.is_a?(Array) # TODO test that theirval is an array too
122
+ return false unless go_array(val, theirval)
123
+ else
124
+ return false unless go(val, b.send(attr))
125
+ end
126
+ end
127
+
128
+ true
129
+ else
130
+ false
131
+ end
132
+ end
133
+
134
+ def go_array(as, bs)
135
+ splat = nil
136
+ req_size = 0
137
+ as.each do |a|
138
+ if a.is_a?(Atomy::Pattern::Splat)
139
+ splat = a
140
+ break
141
+ end
142
+
143
+ req_size += 1
144
+ end
145
+
146
+ if splat
147
+ return false unless bs.size >= req_size
148
+ else
149
+ return false unless bs.size == req_size
150
+ end
151
+
152
+ req_size.times do |i|
153
+ return false unless go(as[i], bs[i])
154
+ end
155
+
156
+ if splat
157
+ return false unless splat.matches?(bs[req_size..-1])
158
+ end
159
+
160
+ true
161
+ end
162
+ end
163
+ end
164
+ end