myco 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/lib/myco/bootstrap/add_method.rb +38 -0
  3. data/lib/myco/bootstrap/component.rb +43 -21
  4. data/lib/myco/bootstrap/find_constant.rb +73 -25
  5. data/lib/myco/bootstrap/instance.rb +96 -25
  6. data/lib/myco/bootstrap/meme.rb +18 -12
  7. data/lib/myco/bootstrap/tuple.rb +13 -0
  8. data/lib/myco/bootstrap/undefined.rb +9 -0
  9. data/lib/myco/bootstrap/void.rb +5 -4
  10. data/lib/myco/bootstrap.my +24 -13
  11. data/lib/myco/bootstrap.my.rb +41 -4
  12. data/lib/myco/bootstrap.rb +4 -0
  13. data/lib/myco/code_loader.rb +11 -9
  14. data/lib/myco/code_tools/AST/Block.my.rb +2 -2
  15. data/lib/myco/code_tools/AST/ConstantAccess.my.rb +4 -4
  16. data/lib/myco/code_tools/AST/ConstantAssignment.my.rb +4 -4
  17. data/lib/myco/code_tools/AST/Invoke.my +1 -1
  18. data/lib/myco/code_tools/AST/Invoke.my.rb +1 -1
  19. data/lib/myco/code_tools/AST/Node.my +2 -4
  20. data/lib/myco/code_tools/AST/Node.my.rb +3 -3
  21. data/lib/myco/code_tools/AST/PipeOperator.my.rb +1 -1
  22. data/lib/myco/code_tools/AST/ToRuby.my.rb +8 -8
  23. data/lib/myco/code_tools/AST/misc.my.rb +1 -1
  24. data/lib/myco/code_tools/Parser.my +8 -15
  25. data/lib/myco/code_tools/Parser.my.rb +8 -14
  26. data/lib/myco/code_tools/parser/MycoBuilder.my +3 -4
  27. data/lib/myco/code_tools/parser/MycoBuilder.my.rb +5 -6
  28. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeHelpers.my +8 -4
  29. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeHelpers.my.rb +5 -5
  30. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeInstructions.my +2 -2
  31. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeInstructions.my.rb +12 -12
  32. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeParser.my +54 -44
  33. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeParser.my.rb +69 -83
  34. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Grammar.my +18 -8
  35. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Grammar.my.rb +24 -10
  36. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Machine.my.rb +1 -1
  37. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Parser.my +1 -1
  38. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Parser.my.rb +1 -2
  39. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Patterns.my +1 -1
  40. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Patterns.my.rb +1 -1
  41. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Processor.my +3 -3
  42. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Processor.my.rb +5 -6
  43. data/lib/myco/code_tools/parser/pegleromyces/spec/BasicSpec.my +35 -0
  44. data/lib/myco/code_tools/parser/pegleromyces/spec/BasicSpec.my.rb +35 -0
  45. data/lib/myco/code_tools/parser/pegleromyces/spec/Builder.test.my +10 -0
  46. data/lib/myco/code_tools/parser/pegleromyces/spec/Builder.test.my.rb +9 -0
  47. data/lib/myco/code_tools/parser/pegleromyces/spec/BytecodeInstructions.test.my +10 -0
  48. data/lib/myco/code_tools/parser/pegleromyces/spec/BytecodeInstructions.test.my.rb +9 -0
  49. data/lib/myco/code_tools/parser/pegleromyces/spec/BytecodeParser.test.my +81 -0
  50. data/lib/myco/code_tools/parser/pegleromyces/spec/BytecodeParser.test.my.rb +209 -0
  51. data/lib/myco/code_tools/parser/pegleromyces/spec/Constructions.test.my +229 -0
  52. data/lib/myco/code_tools/parser/pegleromyces/spec/Constructions.test.my.rb +663 -0
  53. data/lib/myco/code_tools/parser/pegleromyces/spec/Grammar.test.my +10 -0
  54. data/lib/myco/code_tools/parser/pegleromyces/spec/Grammar.test.my.rb +9 -0
  55. data/lib/myco/code_tools/parser/pegleromyces/spec/Instructions.test.my +10 -0
  56. data/lib/myco/code_tools/parser/pegleromyces/spec/Instructions.test.my.rb +9 -0
  57. data/lib/myco/code_tools/parser/pegleromyces/spec/Machine.test.my +13 -0
  58. data/lib/myco/code_tools/parser/pegleromyces/spec/Machine.test.my.rb +20 -0
  59. data/lib/myco/code_tools/parser/pegleromyces/spec/Parser.test.my +54 -0
  60. data/lib/myco/code_tools/parser/pegleromyces/spec/Parser.test.my.rb +215 -0
  61. data/lib/myco/code_tools/parser/pegleromyces/spec/Patterns.test.my +156 -0
  62. data/lib/myco/code_tools/parser/pegleromyces/spec/Patterns.test.my.rb +334 -0
  63. data/lib/myco/code_tools/parser/pegleromyces/spec/Processor.test.my +10 -0
  64. data/lib/myco/code_tools/parser/pegleromyces/spec/Processor.test.my.rb +9 -0
  65. data/lib/myco/code_tools/parser/pegleromyces/spec/run.my +20 -0
  66. data/lib/myco/code_tools/parser/pegleromyces/spec/run.my.rb +16 -0
  67. data/lib/myco/core/BasicDecorators.my +19 -11
  68. data/lib/myco/core/BasicDecorators.my.rb +24 -20
  69. data/lib/myco/core/BasicObject.my +12 -7
  70. data/lib/myco/core/BasicObject.my.rb +50 -44
  71. data/lib/myco/core/Category.my +12 -2
  72. data/lib/myco/core/Category.my.rb +15 -7
  73. data/lib/myco/core/Decorator.my +1 -1
  74. data/lib/myco/core/Decorator.my.rb +8 -10
  75. data/lib/myco/core/FileToplevel.my +3 -3
  76. data/lib/myco/core/FileToplevel.my.rb +4 -6
  77. data/lib/myco/core/Object.my +7 -10
  78. data/lib/myco/core/Object.my.rb +11 -17
  79. data/lib/myco/core/Ruby.my +6 -0
  80. data/lib/myco/core/Ruby.my.rb +16 -0
  81. data/lib/myco/core/Switch.my +1 -1
  82. data/lib/myco/core/Switch.my.rb +1 -1
  83. data/lib/myco/core.my +4 -0
  84. data/lib/myco/core.my.rb +7 -0
  85. data/lib/myco/dev/call_sites.rb +39 -0
  86. data/lib/myco/dev/counter.rb +26 -0
  87. data/lib/myco/dev.rb +3 -0
  88. data/lib/myco/eval.rb +1 -1
  89. data/lib/myco/tools/BasicCommand.my.rb +1 -1
  90. data/lib/myco/version.rb +1 -1
  91. data/lib/myco.rb +2 -3
  92. metadata +53 -20
  93. data/lib/myco/bootstrap/evaluator.rb +0 -58
@@ -0,0 +1,20 @@
1
+
2
+ ::Myco::Component.new([::Myco::FileToplevel], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
3
+ .tap { |__c__| __c__.__last__ = __c__.component_eval {(::Myco::Component.new([::Myco.find_constant(:BasicSpec)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
4
+ .tap { |__c__| __c__.__last__ = __c__.component_eval {(
5
+ declare_meme(:name, [], nil, ::Myco.cscope.dup) { |*| ("Machine")}
6
+ declare_meme(:new_machine, [], nil, ::Myco.cscope.dup) { |*| (::Myco::Component.new([::Myco.find_constant(:Machine)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
7
+ .tap { |__c__| __c__.__last__ = __c__.component_eval {nil}}.instance)}
8
+ __category__(:tests).component_eval {(
9
+ declare_meme(:"starts pointing to instruction 0", [[:it, []]], nil, ::Myco.cscope.dup) { |*| (self.assert_equal(
10
+ self.new_machine.ip,
11
+ 0
12
+ ))}
13
+ declare_meme(:"starts pointing to string index 0", [[:it, []]], nil, ::Myco.cscope.dup) { |*| (self.assert_equal(
14
+ self.new_machine.idx,
15
+ 0
16
+ ))}
17
+ declare_meme(:"starts with an empty stack", [[:it, []]], nil, ::Myco.cscope.dup) { |*| (self.assert(self.new_machine.stack.__send__(:empty?)))}
18
+ declare_meme(:"starts with no captures", [[:it, []]], nil, ::Myco.cscope.dup) { |*| (self.assert(self.new_machine.captures.__send__(:empty?)))}
19
+ )}
20
+ )}}.instance)}}.instance
@@ -0,0 +1,54 @@
1
+
2
+ BasicSpec {
3
+ name: "Parser"
4
+
5
+ new_parser: Parser { }
6
+
7
+ basic_grammar: Grammar {
8
+ c: character_classes
9
+
10
+ [character_classes]
11
+ upper: range('A','Z')
12
+ lower: range('a','z') / str('_')
13
+ num: range('0','9')
14
+ alpha: upper / lower
15
+ spc: set(" \t\r\f\v")
16
+
17
+ [rules]
18
+ rule root: expr[:root]
19
+ rule expr: (array / assign / constant / ident / float / integer)
20
+
21
+ rule sepd_expr: r(c.spc.* + str(',') + c.spc.* + integer[:n0]) { n0 }
22
+ rule array: r(str('[') + expr[:n0] + sepd_expr.*[:nrest] + str(']'))
23
+ { [n0, *nrest] }
24
+
25
+ rule constant: r((c.upper + c.alpha.*)[:text]) { [:constant, text.to_sym] }
26
+ rule ident: r((c.lower + c.alpha.*)[:text]) { [:ident, text.to_sym] }
27
+ rule integer: r((str('-').- + c.num.+)[:text]) { [:integer, text.to_i] }
28
+ rule float: r((str('-').- + c.num.+ + str('.') + c.num.+)[:text])
29
+ { [:float, text.to_f] }
30
+
31
+ rule assign_lhs: (constant / ident)
32
+ rule assign_rhs: expr
33
+ rule assign: r(assign_lhs[:lhs] + c.spc.* + str('=') + c.spc.* +
34
+ assign_rhs[:rhs]) { [:assign, lhs, rhs] }
35
+ }
36
+
37
+ [tests]
38
+
39
+ it "can parse from a basic grammar": {
40
+ parser = new_parser
41
+ parser.grammar = basic_grammar
42
+
43
+ examples = [
44
+ "xyz", [:ident, :xyz]
45
+ "_foo = -88.8", [:assign, [:ident, :"_foo"], [:float, -88.8]]
46
+ "Foo_BAR=5", [:assign, [:constant, :"Foo_BAR"], [:integer, 5]]
47
+ "[99, 99]", [[:integer, 99], [:integer, 99]]
48
+ ]
49
+
50
+ examples.each_slice(2) |input, output| {
51
+ assert_equal(parser.parse(input).result.fetch(:root), output)
52
+ }
53
+ }
54
+ }
@@ -0,0 +1,215 @@
1
+
2
+ ::Myco::Component.new([::Myco::FileToplevel], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
3
+ .tap { |__c__| __c__.__last__ = __c__.component_eval {(::Myco::Component.new([::Myco.find_constant(:BasicSpec)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
4
+ .tap { |__c__| __c__.__last__ = __c__.component_eval {(
5
+ declare_meme(:name, [], nil, ::Myco.cscope.dup) { |*| ("Parser")}
6
+ declare_meme(:new_parser, [], nil, ::Myco.cscope.dup) { |*| (::Myco::Component.new([::Myco.find_constant(:Parser)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
7
+ .tap { |__c__| __c__.__last__ = __c__.component_eval {nil}}.instance)}
8
+ declare_meme(:basic_grammar, [], nil, ::Myco.cscope.dup) { |*| (::Myco::Component.new([::Myco.find_constant(:Grammar)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
9
+ .tap { |__c__| __c__.__last__ = __c__.component_eval {(
10
+ declare_meme(:c, [], nil, ::Myco.cscope.dup) { |*| (self.character_classes)}
11
+ __category__(:character_classes).component_eval {(
12
+ declare_meme(:upper, [], nil, ::Myco.cscope.dup) { |*| (self.range(
13
+ "A",
14
+ "Z"
15
+ ))}
16
+ declare_meme(:lower, [], nil, ::Myco.cscope.dup) { |*| (self.range(
17
+ "a",
18
+ "z"
19
+ ).__send__(
20
+ :/,
21
+ self.str("_")
22
+ ))}
23
+ declare_meme(:num, [], nil, ::Myco.cscope.dup) { |*| (self.range(
24
+ "0",
25
+ "9"
26
+ ))}
27
+ declare_meme(:alpha, [], nil, ::Myco.cscope.dup) { |*| (self.upper.__send__(
28
+ :/,
29
+ self.lower
30
+ ))}
31
+ declare_meme(:spc, [], nil, ::Myco.cscope.dup) { |*| (self.set(" \t\r\f\v"))}
32
+ )}
33
+ __category__(:rules).component_eval {(
34
+ declare_meme(:root, [[:rule, []]], nil, ::Myco.cscope.dup) { |*| (self.expr.__send__(
35
+ :[],
36
+ :root
37
+ ))}
38
+ declare_meme(:expr, [[:rule, []]], nil, ::Myco.cscope.dup) { |*| (self.array.__send__(
39
+ :/,
40
+ self.assign
41
+ ).__send__(
42
+ :/,
43
+ self.constant
44
+ ).__send__(
45
+ :/,
46
+ self.ident
47
+ ).__send__(
48
+ :/,
49
+ self.float
50
+ ).__send__(
51
+ :/,
52
+ self.integer
53
+ ))}
54
+ declare_meme(:sepd_expr, [[:rule, []]], nil, ::Myco.cscope.dup) { |*| (self.r(self.c.spc.__send__(:*).__send__(
55
+ :+,
56
+ self.str(",")
57
+ ).__send__(
58
+ :+,
59
+ self.c.spc.__send__(:*)
60
+ ).__send__(
61
+ :+,
62
+ self.integer.__send__(
63
+ :[],
64
+ :n0
65
+ )
66
+ )) { || (self.__send__(:n0))})}
67
+ declare_meme(:array, [[:rule, []]], nil, ::Myco.cscope.dup) { |*| (self.r(self.str("[").__send__(
68
+ :+,
69
+ self.expr.__send__(
70
+ :[],
71
+ :n0
72
+ )
73
+ ).__send__(
74
+ :+,
75
+ self.sepd_expr.__send__(:*).__send__(
76
+ :[],
77
+ :nrest
78
+ )
79
+ ).__send__(
80
+ :+,
81
+ self.str("]")
82
+ )) { || ([
83
+ self.__send__(:n0),
84
+ *self.nrest
85
+ ])})}
86
+ declare_meme(:constant, [[:rule, []]], nil, ::Myco.cscope.dup) { |*| (self.r(self.c.upper.__send__(
87
+ :+,
88
+ self.c.alpha.__send__(:*)
89
+ ).__send__(
90
+ :[],
91
+ :text
92
+ )) { || ([
93
+ :constant,
94
+ self.text.to_sym
95
+ ])})}
96
+ declare_meme(:ident, [[:rule, []]], nil, ::Myco.cscope.dup) { |*| (self.r(self.c.lower.__send__(
97
+ :+,
98
+ self.c.alpha.__send__(:*)
99
+ ).__send__(
100
+ :[],
101
+ :text
102
+ )) { || ([
103
+ :ident,
104
+ self.text.to_sym
105
+ ])})}
106
+ declare_meme(:integer, [[:rule, []]], nil, ::Myco.cscope.dup) { |*| (self.r(self.str("-").__send__(:-).__send__(
107
+ :+,
108
+ self.c.num.__send__(:+)
109
+ ).__send__(
110
+ :[],
111
+ :text
112
+ )) { || ([
113
+ :integer,
114
+ self.text.to_i
115
+ ])})}
116
+ declare_meme(:float, [[:rule, []]], nil, ::Myco.cscope.dup) { |*| (self.r(self.str("-").__send__(:-).__send__(
117
+ :+,
118
+ self.c.num.__send__(:+)
119
+ ).__send__(
120
+ :+,
121
+ self.str(".")
122
+ ).__send__(
123
+ :+,
124
+ self.c.num.__send__(:+)
125
+ ).__send__(
126
+ :[],
127
+ :text
128
+ )) { || ([
129
+ :float,
130
+ self.text.to_f
131
+ ])})}
132
+ declare_meme(:assign_lhs, [[:rule, []]], nil, ::Myco.cscope.dup) { |*| (self.constant.__send__(
133
+ :/,
134
+ self.ident
135
+ ))}
136
+ declare_meme(:assign_rhs, [[:rule, []]], nil, ::Myco.cscope.dup) { |*| (self.expr)}
137
+ declare_meme(:assign, [[:rule, []]], nil, ::Myco.cscope.dup) { |*| (self.r(self.assign_lhs.__send__(
138
+ :[],
139
+ :lhs
140
+ ).__send__(
141
+ :+,
142
+ self.c.spc.__send__(:*)
143
+ ).__send__(
144
+ :+,
145
+ self.str("=")
146
+ ).__send__(
147
+ :+,
148
+ self.c.spc.__send__(:*)
149
+ ).__send__(
150
+ :+,
151
+ self.assign_rhs.__send__(
152
+ :[],
153
+ :rhs
154
+ )
155
+ )) { || ([
156
+ :assign,
157
+ self.lhs,
158
+ self.rhs
159
+ ])})}
160
+ )}
161
+ )}}.instance)}
162
+ __category__(:tests).component_eval {(declare_meme(:"can parse from a basic grammar", [[:it, []]], nil, ::Myco.cscope.dup) { |*| (
163
+ parser = self.new_parser
164
+ parser.__send__(
165
+ :grammar=,
166
+ self.basic_grammar
167
+ )
168
+ examples = [
169
+ "xyz",
170
+ [
171
+ :ident,
172
+ :xyz
173
+ ],
174
+ "_foo = -88.8",
175
+ [
176
+ :assign,
177
+ [
178
+ :ident,
179
+ :_foo
180
+ ],
181
+ [
182
+ :float,
183
+ -88.8
184
+ ]
185
+ ],
186
+ "Foo_BAR=5",
187
+ [
188
+ :assign,
189
+ [
190
+ :constant,
191
+ :Foo_BAR
192
+ ],
193
+ [
194
+ :integer,
195
+ 5
196
+ ]
197
+ ],
198
+ "[99, 99]",
199
+ [
200
+ [
201
+ :integer,
202
+ 99
203
+ ],
204
+ [
205
+ :integer,
206
+ 99
207
+ ]
208
+ ]
209
+ ]
210
+ examples.each_slice(2) { |input, output| (self.assert_equal(
211
+ parser.parse(input).result.fetch(:root),
212
+ output
213
+ ))}
214
+ )})}
215
+ )}}.instance)}}.instance
@@ -0,0 +1,156 @@
1
+
2
+ BasicSpec {
3
+ name: "Patterns"
4
+
5
+ new_pattern: Patterns::Base { }
6
+ var shorthand: Patterns::ShorthandMethods { }
7
+
8
+ [tests]
9
+
10
+ it "knows its name": {
11
+ assert_equal(new_pattern.name, :new_pattern)
12
+ }
13
+
14
+ it "creates a NegativePredicate with the '!' unary operator": {
15
+ a = new_pattern
16
+ b = !a
17
+ assert_is_a(b, Patterns::NegativePredicate)
18
+ assert_equal(b.inner, a)
19
+ }
20
+
21
+ it "creates a PositivePredicate with two uses of the '!' unary operator": {
22
+ a = new_pattern
23
+ b = !!a
24
+ assert_is_a(b, Patterns::PositivePredicate)
25
+ assert_equal(b.inner, a)
26
+ }
27
+
28
+ it "creates a NegativePredicate with three uses of the '!' unary operator": {
29
+ a = new_pattern
30
+ b = !!!a
31
+ assert_is_a(b, Patterns::NegativePredicate)
32
+ assert_equal(b.inner, a)
33
+ }
34
+
35
+ it "creates an OrderedChoice with the '/' operator": {
36
+ a = new_pattern
37
+ b = new_pattern
38
+ c = a / b
39
+ assert_is_a(c, Patterns::OrderedChoice)
40
+ assert_equal(c.first, a)
41
+ assert_equal(c.second, b)
42
+ }
43
+
44
+ it "interprets a series of OrderedChoices as a right-associative tree": {
45
+ a = new_pattern
46
+ b = new_pattern
47
+ c = new_pattern
48
+ d = new_pattern
49
+ e = a / b / c / d
50
+ assert_is_a(e, Patterns::OrderedChoice)
51
+ assert_is_a(e.second, Patterns::OrderedChoice)
52
+ assert_is_a(e.second.second, Patterns::OrderedChoice)
53
+ assert_equal(e.first, a)
54
+ assert_equal(e.second.first, b)
55
+ assert_equal(e.second.second.first, c)
56
+ assert_equal(e.second.second.second, d)
57
+ }
58
+
59
+ it "creates a Concatenation with the '+' operator": {
60
+ a = new_pattern
61
+ b = new_pattern
62
+ c = a + b
63
+ assert_is_a(c, Patterns::Concatenation)
64
+ assert_equal(c.first, a)
65
+ assert_equal(c.second, b)
66
+ }
67
+
68
+ it "interprets a series of Concatenations as a right-associative tree": {
69
+ a = new_pattern
70
+ b = new_pattern
71
+ c = new_pattern
72
+ d = new_pattern
73
+ e = a + b + c + d
74
+ assert_is_a(e, Patterns::Concatenation)
75
+ assert_is_a(e.second, Patterns::Concatenation)
76
+ assert_is_a(e.second.second, Patterns::Concatenation)
77
+ assert_equal(e.first, a)
78
+ assert_equal(e.second.first, b)
79
+ assert_equal(e.second.second.first, c)
80
+ assert_equal(e.second.second.second, d)
81
+ }
82
+
83
+ it "creates a OneOrMore with the '+' operator used as a 'suffix' call": {
84
+ a = new_pattern
85
+ b = a.+
86
+ assert_is_a(b, Patterns::OneOrMore)
87
+ assert_equal(b.inner, a)
88
+
89
+ # This is implemented as a special case but should act the same
90
+ a = (new_pattern + new_pattern)
91
+ b = a.+
92
+ assert_is_a(b, Patterns::OneOrMore)
93
+ assert_equal(b.inner, a)
94
+ }
95
+
96
+ it "creates a ZeroOrOne with the '-' operator used as a 'suffix' call": {
97
+ a = new_pattern
98
+ b = a.-
99
+ assert_is_a(b, Patterns::ZeroOrOne)
100
+ assert_equal(b.inner, a)
101
+ }
102
+
103
+ it "creates a ZeroOrMore with the '*' operator used as a 'suffix' call": {
104
+ a = new_pattern
105
+ b = a.*
106
+ assert_is_a(b, Patterns::ZeroOrMore)
107
+ assert_equal(b.inner, a)
108
+ }
109
+
110
+ it "creates a NamedCapture with the '[]' operator, given a capture name": {
111
+ a = new_pattern
112
+ b = a[:foo]
113
+ assert_is_a(b, Patterns::NamedCapture)
114
+ assert_equal(b.inner, a)
115
+ assert_equal(b.name, :foo)
116
+ }
117
+
118
+ it "creates an AnyCharacter with the 'any' shorthand method": {
119
+ a = shorthand.any
120
+ assert_is_a(a, Patterns::AnyCharacter)
121
+ }
122
+
123
+ it "creates a Character with the 'char' shorthand method": {
124
+ a = shorthand.char('x')
125
+ assert_is_a(a, Patterns::Character)
126
+ assert_equal(a.code, 120)
127
+ }
128
+
129
+ it "creates a CharacterString with the 'str' shorthand method": {
130
+ a = shorthand.str('xyz')
131
+ assert_is_a(a, Patterns::CharacterString)
132
+ assert_equal(a.codes, [120,121,122])
133
+ }
134
+
135
+ it "creates a CharacterSet with the 'set' shorthand method": {
136
+ a = shorthand.set('xyz')
137
+ assert_is_a(a, Patterns::CharacterSet)
138
+ assert_equal(a.codes, [120,121,122])
139
+ }
140
+
141
+ it "creates a CharacterRange with the 'range' shorthand method": {
142
+ a = shorthand.range('x','z')
143
+ assert_is_a(a, Patterns::CharacterRange)
144
+ assert_equal(a.start, 120)
145
+ assert_equal(a.stop, 122)
146
+ }
147
+
148
+ it "creates a Reduction with the 'r' shorthand method": {
149
+ a_proc = Proc.new { }
150
+ a = new_pattern
151
+ b = shorthand.r(a, &a_proc)
152
+ assert_is_a(b, Patterns::Reduction)
153
+ assert_equal(b.inner, a)
154
+ assert_equal(b.block, a_proc)
155
+ }
156
+ }