myco 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/myco/bootstrap/find_constant.rb +4 -11
- data/lib/myco/code_loader.rb +2 -1
- data/lib/myco/code_tools/AST/ConstantAccess.my +47 -3
- data/lib/myco/code_tools/AST/ConstantAccess.my.rb +13 -9
- data/lib/myco/code_tools/AST/ConstantAssignment.my +1 -5
- data/lib/myco/code_tools/AST/ConstantAssignment.my.rb +3 -9
- data/lib/myco/code_tools/AST/ToRuby.my +5 -2
- data/lib/myco/code_tools/AST/ToRuby.my.rb +7 -3
- data/lib/myco/code_tools/AST.my +1 -0
- data/lib/myco/code_tools/AST.my.rb +9 -1
- data/lib/myco/code_tools/Parser.my +24 -0
- data/lib/myco/code_tools/Parser.my.rb +25 -0
- data/lib/myco/code_tools/parser/MycoBuilder.my +67 -0
- data/lib/myco/code_tools/parser/MycoBuilder.my.rb +99 -0
- data/lib/myco/code_tools/parser/MycoCharacterClasses.my +20 -0
- data/lib/myco/code_tools/parser/MycoCharacterClasses.my.rb +56 -0
- data/lib/myco/code_tools/parser/MycoGrammar.my +564 -0
- data/lib/myco/code_tools/parser/MycoGrammar.my.rb +1851 -0
- data/lib/myco/code_tools/parser/MycoTokens.my +78 -0
- data/lib/myco/code_tools/parser/MycoTokens.my.rb +170 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Builder.my +4 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Builder.my.rb +5 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeHelpers.my +142 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeHelpers.my.rb +181 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeInstructions.my +420 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeInstructions.my.rb +415 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeParser.my +137 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeParser.my.rb +237 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Constructions.my +183 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Constructions.my.rb +370 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Grammar.my +65 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Grammar.my.rb +83 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Instructions.my +139 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Instructions.my.rb +284 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Machine.my +37 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Machine.my.rb +24 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Parser.my +42 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Parser.my.rb +52 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Patterns.my +123 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Patterns.my.rb +164 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Processor.my +236 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Processor.my.rb +339 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces.my +15 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces.my.rb +14 -0
- data/lib/myco/code_tools.rb +1 -1
- data/lib/myco/version.rb +1 -1
- data/lib/myco.rb +2 -0
- metadata +44 -25
- data/lib/myco/code_tools/parser/peg_parser.rb +0 -7182
- data/lib/myco/code_tools/parser.rb +0 -39
@@ -0,0 +1,370 @@
|
|
1
|
+
|
2
|
+
::Myco::Component.new([::Myco::FileToplevel], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
3
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {(::Myco.cscope.for_method_definition.const_set(:Constructions, ::Myco::Component.new([::Myco.find_constant(:EmptyObject)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
4
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {(
|
5
|
+
::Myco.cscope.for_method_definition.const_set(:Base, ::Myco::Component.new([::Myco.find_constant(:BasicObject)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
6
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {nil}})
|
7
|
+
.tap { |__c__| __c__.__name__ = :Base }
|
8
|
+
::Myco.cscope.for_method_definition.const_set(:UnaryBase, ::Myco::Component.new([::Myco.find_constant(:Base)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
9
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {(declare_meme(:inner, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil})}})
|
10
|
+
.tap { |__c__| __c__.__name__ = :UnaryBase }
|
11
|
+
::Myco.cscope.for_method_definition.const_set(:BinaryBase, ::Myco::Component.new([::Myco.find_constant(:Base)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
12
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {(
|
13
|
+
declare_meme(:first, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil}
|
14
|
+
declare_meme(:second, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil}
|
15
|
+
)}})
|
16
|
+
.tap { |__c__| __c__.__name__ = :BinaryBase }
|
17
|
+
::Myco.cscope.for_method_definition.const_set(:AnyCharacter, ::Myco::Component.new([::Myco.find_constant(:Base)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
18
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {nil}})
|
19
|
+
.tap { |__c__| __c__.__name__ = :AnyCharacter }
|
20
|
+
::Myco.cscope.for_method_definition.const_set(:Character, ::Myco::Component.new([::Myco.find_constant(:Base)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
21
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {(declare_meme(:code, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil})}})
|
22
|
+
.tap { |__c__| __c__.__name__ = :Character }
|
23
|
+
::Myco.cscope.for_method_definition.const_set(:CharacterString, ::Myco::Component.new([::Myco.find_constant(:Base)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
24
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {(declare_meme(:codes, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil})}})
|
25
|
+
.tap { |__c__| __c__.__name__ = :CharacterString }
|
26
|
+
::Myco.cscope.for_method_definition.const_set(:CharacterSet, ::Myco::Component.new([::Myco.find_constant(:Base)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
27
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {(declare_meme(:codes, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil})}})
|
28
|
+
.tap { |__c__| __c__.__name__ = :CharacterSet }
|
29
|
+
::Myco.cscope.for_method_definition.const_set(:CharacterRange, ::Myco::Component.new([::Myco.find_constant(:Base)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
30
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {(
|
31
|
+
declare_meme(:start, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil}
|
32
|
+
declare_meme(:stop, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil}
|
33
|
+
)}})
|
34
|
+
.tap { |__c__| __c__.__name__ = :CharacterRange }
|
35
|
+
::Myco.cscope.for_method_definition.const_set(:NegativePredicate, ::Myco::Component.new([::Myco.find_constant(:UnaryBase)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
36
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {nil}})
|
37
|
+
.tap { |__c__| __c__.__name__ = :NegativePredicate }
|
38
|
+
::Myco.cscope.for_method_definition.const_set(:PositivePredicate, ::Myco::Component.new([::Myco.find_constant(:UnaryBase)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
39
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {nil}})
|
40
|
+
.tap { |__c__| __c__.__name__ = :PositivePredicate }
|
41
|
+
::Myco.cscope.for_method_definition.const_set(:OneOrMore, ::Myco::Component.new([::Myco.find_constant(:UnaryBase)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
42
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {nil}})
|
43
|
+
.tap { |__c__| __c__.__name__ = :OneOrMore }
|
44
|
+
::Myco.cscope.for_method_definition.const_set(:ZeroOrOne, ::Myco::Component.new([::Myco.find_constant(:UnaryBase)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
45
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {nil}})
|
46
|
+
.tap { |__c__| __c__.__name__ = :ZeroOrOne }
|
47
|
+
::Myco.cscope.for_method_definition.const_set(:ZeroOrMore, ::Myco::Component.new([::Myco.find_constant(:UnaryBase)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
48
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {nil}})
|
49
|
+
.tap { |__c__| __c__.__name__ = :ZeroOrMore }
|
50
|
+
::Myco.cscope.for_method_definition.const_set(:OrderedChoice, ::Myco::Component.new([::Myco.find_constant(:BinaryBase)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
51
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {nil}})
|
52
|
+
.tap { |__c__| __c__.__name__ = :OrderedChoice }
|
53
|
+
::Myco.cscope.for_method_definition.const_set(:Concatenation, ::Myco::Component.new([::Myco.find_constant(:BinaryBase)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
54
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {nil}})
|
55
|
+
.tap { |__c__| __c__.__name__ = :Concatenation }
|
56
|
+
::Myco.cscope.for_method_definition.const_set(:NamedCapture, ::Myco::Component.new([::Myco.find_constant(:UnaryBase)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
57
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {(declare_meme(:captargs, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil})}})
|
58
|
+
.tap { |__c__| __c__.__name__ = :NamedCapture }
|
59
|
+
::Myco.cscope.for_method_definition.const_set(:NamedTextCapture, ::Myco::Component.new([::Myco.find_constant(:UnaryBase)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
60
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {(declare_meme(:captargs, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil})}})
|
61
|
+
.tap { |__c__| __c__.__name__ = :NamedTextCapture }
|
62
|
+
::Myco.cscope.for_method_definition.const_set(:NamedTokenCapture, ::Myco::Component.new([::Myco.find_constant(:UnaryBase)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
63
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {(declare_meme(:captargs, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil})}})
|
64
|
+
.tap { |__c__| __c__.__name__ = :NamedTokenCapture }
|
65
|
+
::Myco.cscope.for_method_definition.const_set(:Reduction, ::Myco::Component.new([::Myco.find_constant(:UnaryBase)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
66
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {(declare_meme(:captargs, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil})}})
|
67
|
+
.tap { |__c__| __c__.__name__ = :Reduction }
|
68
|
+
::Myco.find_constant(:Patterns)::UnaryBase.component_eval {(declare_meme(:construct, [], nil, ::Myco.cscope.dup) { |*| (self.construct_type.new({:inner => self.inner.construct}))})}
|
69
|
+
::Myco.find_constant(:Patterns)::BinaryBase.component_eval {(declare_meme(:construct, [], nil, ::Myco.cscope.dup) { |*| (self.construct_type.new({
|
70
|
+
:first => self.first.construct,
|
71
|
+
:second => self.second.construct
|
72
|
+
}))})}
|
73
|
+
::Myco.find_constant(:Patterns)::AnyCharacter.component_eval {(declare_meme(:construct, [], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:AnyCharacter).new)})}
|
74
|
+
::Myco.find_constant(:Patterns)::Character.component_eval {(declare_meme(:construct, [], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:Character).new({:code => self.code}))})}
|
75
|
+
::Myco.find_constant(:Patterns)::CharacterString.component_eval {(declare_meme(:construct, [], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:CharacterString).new({:codes => self.codes}))})}
|
76
|
+
::Myco.find_constant(:Patterns)::CharacterSet.component_eval {(declare_meme(:construct, [], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:CharacterSet).new({:codes => self.codes}))})}
|
77
|
+
::Myco.find_constant(:Patterns)::CharacterRange.component_eval {(declare_meme(:construct, [], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:CharacterRange).new({
|
78
|
+
:start => self.start,
|
79
|
+
:stop => self.stop
|
80
|
+
}))})}
|
81
|
+
::Myco.find_constant(:Patterns)::NegativePredicate.component_eval {(declare_meme(:construct_type, [], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:NegativePredicate))})}
|
82
|
+
::Myco.find_constant(:Patterns)::PositivePredicate.component_eval {(declare_meme(:construct_type, [], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:PositivePredicate))})}
|
83
|
+
::Myco.find_constant(:Patterns)::OneOrMore.component_eval {(declare_meme(:construct_type, [], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:OneOrMore))})}
|
84
|
+
::Myco.find_constant(:Patterns)::ZeroOrOne.component_eval {(declare_meme(:construct_type, [], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:ZeroOrOne))})}
|
85
|
+
::Myco.find_constant(:Patterns)::ZeroOrMore.component_eval {(declare_meme(:construct_type, [], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:ZeroOrMore))})}
|
86
|
+
::Myco.find_constant(:Patterns)::OrderedChoice.component_eval {(declare_meme(:construct_type, [], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:OrderedChoice))})}
|
87
|
+
::Myco.find_constant(:Patterns)::Concatenation.component_eval {(declare_meme(:construct_type, [], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:Concatenation))})}
|
88
|
+
::Myco.find_constant(:Patterns)::NamedCapture.component_eval {(declare_meme(:construct, [], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:NamedCapture).new({
|
89
|
+
:inner => self.inner.construct,
|
90
|
+
:captargs => [self.name]
|
91
|
+
}))})}
|
92
|
+
::Myco.find_constant(:Patterns)::NamedTextCapture.component_eval {(declare_meme(:construct, [], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:NamedTextCapture).new({
|
93
|
+
:inner => self.inner.construct,
|
94
|
+
:captargs => [self.name]
|
95
|
+
}))})}
|
96
|
+
::Myco.find_constant(:Patterns)::NamedTokenCapture.component_eval {(declare_meme(:construct, [], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:NamedTokenCapture).new({
|
97
|
+
:inner => self.inner.construct,
|
98
|
+
:captargs => [self.name]
|
99
|
+
}))})}
|
100
|
+
::Myco.find_constant(:Patterns)::Reduction.component_eval {(declare_meme(:construct, [], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:Reduction).new({
|
101
|
+
:inner => self.inner.construct,
|
102
|
+
:captargs => [
|
103
|
+
self.code,
|
104
|
+
*self.args
|
105
|
+
]
|
106
|
+
}))})}
|
107
|
+
::Myco.find_constant(:AnyCharacter).component_eval {(declare_meme(:sequence, [], nil, ::Myco.cscope.dup) { |*| ([[
|
108
|
+
:any,
|
109
|
+
1
|
110
|
+
]])})}
|
111
|
+
::Myco.find_constant(:Character).component_eval {(declare_meme(:sequence, [], nil, ::Myco.cscope.dup) { |*| ([[
|
112
|
+
:char,
|
113
|
+
self.code
|
114
|
+
]])})}
|
115
|
+
::Myco.find_constant(:CharacterString).component_eval {(declare_meme(:sequence, [], nil, ::Myco.cscope.dup) { |*| (self.codes.map { |code| ([
|
116
|
+
:char,
|
117
|
+
code
|
118
|
+
])})})}
|
119
|
+
::Myco.find_constant(:CharacterSet).component_eval {(
|
120
|
+
declare_meme(:sequence, [], nil, ::Myco.cscope.dup) { |*| ([[
|
121
|
+
:charset,
|
122
|
+
self.table
|
123
|
+
]])}
|
124
|
+
declare_meme(:table, [], nil, ::Myco.cscope.dup) { |*| (self.codes.map { |code| ([
|
125
|
+
code,
|
126
|
+
true
|
127
|
+
])}.to_h)}
|
128
|
+
)}
|
129
|
+
::Myco.find_constant(:CharacterRange).component_eval {(declare_meme(:sequence, [], nil, ::Myco.cscope.dup) { |*| ([[
|
130
|
+
:charrange,
|
131
|
+
self.start,
|
132
|
+
self.stop
|
133
|
+
]])})}
|
134
|
+
::Myco.find_constant(:NegativePredicate).component_eval {(declare_meme(:sequence, [], nil, ::Myco.cscope.dup) { |*| (
|
135
|
+
a = self.inner.sequence
|
136
|
+
[
|
137
|
+
[
|
138
|
+
:choice,
|
139
|
+
a.size.__send__(
|
140
|
+
:+,
|
141
|
+
2
|
142
|
+
)
|
143
|
+
],
|
144
|
+
*a,
|
145
|
+
[:fail_twice]
|
146
|
+
]
|
147
|
+
)})}
|
148
|
+
::Myco.find_constant(:PositivePredicate).component_eval {(declare_meme(:sequence, [], nil, ::Myco.cscope.dup) { |*| (
|
149
|
+
a = self.inner.sequence
|
150
|
+
size = a.size
|
151
|
+
[
|
152
|
+
[
|
153
|
+
:choice,
|
154
|
+
size.__send__(
|
155
|
+
:+,
|
156
|
+
4
|
157
|
+
)
|
158
|
+
],
|
159
|
+
[
|
160
|
+
:choice,
|
161
|
+
size.__send__(
|
162
|
+
:+,
|
163
|
+
1
|
164
|
+
)
|
165
|
+
],
|
166
|
+
*a,
|
167
|
+
[
|
168
|
+
:commit,
|
169
|
+
1
|
170
|
+
],
|
171
|
+
[:fail]
|
172
|
+
]
|
173
|
+
)})}
|
174
|
+
::Myco.find_constant(:OneOrMore).component_eval {(
|
175
|
+
declare_meme(:inlaid, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil}
|
176
|
+
declare_meme(:sequence, [], nil, ::Myco.cscope.dup) { |*| (
|
177
|
+
one = self.inner.sequence
|
178
|
+
::Myco.branch_op(:"&&", self.inlaid) {one = one.__send__(
|
179
|
+
:+,
|
180
|
+
self.inlaid
|
181
|
+
)}
|
182
|
+
or_more = ::Myco.find_constant(:ZeroOrMore).new({
|
183
|
+
:inner => self.inner,
|
184
|
+
:inlaid => self.inlaid
|
185
|
+
}).sequence
|
186
|
+
[
|
187
|
+
*one,
|
188
|
+
*or_more
|
189
|
+
]
|
190
|
+
)}
|
191
|
+
)}
|
192
|
+
::Myco.find_constant(:ZeroOrOne).component_eval {(declare_meme(:sequence, [], nil, ::Myco.cscope.dup) { |*| (
|
193
|
+
a = self.inner.sequence
|
194
|
+
[
|
195
|
+
[
|
196
|
+
:choice,
|
197
|
+
a.size.__send__(
|
198
|
+
:+,
|
199
|
+
2
|
200
|
+
)
|
201
|
+
],
|
202
|
+
*a,
|
203
|
+
[
|
204
|
+
:commit,
|
205
|
+
1
|
206
|
+
]
|
207
|
+
]
|
208
|
+
)})}
|
209
|
+
::Myco.find_constant(:ZeroOrMore).component_eval {(
|
210
|
+
declare_meme(:inlaid, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil}
|
211
|
+
declare_meme(:sequence, [], nil, ::Myco.cscope.dup) { |*| (self.switch(
|
212
|
+
self.inner,
|
213
|
+
:is_a?
|
214
|
+
).when(::Myco.find_constant(:CharacterSet)) { || ([[
|
215
|
+
:span,
|
216
|
+
self.inner.table
|
217
|
+
]])}.else { || (
|
218
|
+
a = self.inner.sequence
|
219
|
+
::Myco.branch_op(:"&&", self.inlaid) {a = a.__send__(
|
220
|
+
:+,
|
221
|
+
self.inlaid
|
222
|
+
)}
|
223
|
+
size = a.size
|
224
|
+
[
|
225
|
+
[
|
226
|
+
:choice,
|
227
|
+
size.__send__(
|
228
|
+
:+,
|
229
|
+
2
|
230
|
+
)
|
231
|
+
],
|
232
|
+
*a,
|
233
|
+
[
|
234
|
+
:partial_commit,
|
235
|
+
size.__send__(
|
236
|
+
:*,
|
237
|
+
-1
|
238
|
+
)
|
239
|
+
]
|
240
|
+
]
|
241
|
+
)}.output)}
|
242
|
+
)}
|
243
|
+
::Myco.find_constant(:OrderedChoice).component_eval {(declare_meme(:sequence, [], nil, ::Myco.cscope.dup) { |*| (
|
244
|
+
a = self.first.sequence
|
245
|
+
b = self.second.sequence
|
246
|
+
[
|
247
|
+
[
|
248
|
+
:choice,
|
249
|
+
a.size.__send__(
|
250
|
+
:+,
|
251
|
+
2
|
252
|
+
)
|
253
|
+
],
|
254
|
+
*a,
|
255
|
+
[
|
256
|
+
:commit,
|
257
|
+
b.size.__send__(
|
258
|
+
:+,
|
259
|
+
1
|
260
|
+
)
|
261
|
+
],
|
262
|
+
*b
|
263
|
+
]
|
264
|
+
)})}
|
265
|
+
::Myco.find_constant(:Concatenation).component_eval {(declare_meme(:sequence, [], nil, ::Myco.cscope.dup) { |*| ([
|
266
|
+
*self.first.sequence,
|
267
|
+
*self.second.sequence
|
268
|
+
])})}
|
269
|
+
::Myco.find_constant(:NamedCapture).component_eval {(declare_meme(:sequence, [], nil, ::Myco.cscope.dup) { |*| (::Myco.branch_op(:"??", ::Myco.branch_op(:"&?", ::Myco.branch_op(:"||", self.inner.__send__(
|
270
|
+
:is_a?,
|
271
|
+
::Myco.find_constant(:OneOrMore)
|
272
|
+
)) {self.inner.__send__(
|
273
|
+
:is_a?,
|
274
|
+
::Myco.find_constant(:ZeroOrMore)
|
275
|
+
)}) {(
|
276
|
+
self.inner.__send__(
|
277
|
+
:inlaid=,
|
278
|
+
[[
|
279
|
+
:capture,
|
280
|
+
[
|
281
|
+
:m_split,
|
282
|
+
self.captargs
|
283
|
+
]
|
284
|
+
]]
|
285
|
+
)
|
286
|
+
a = self.inner.sequence
|
287
|
+
[
|
288
|
+
[
|
289
|
+
:capture,
|
290
|
+
[:m_start]
|
291
|
+
],
|
292
|
+
*a,
|
293
|
+
[
|
294
|
+
:capture,
|
295
|
+
[
|
296
|
+
:m_end,
|
297
|
+
self.captargs
|
298
|
+
]
|
299
|
+
]
|
300
|
+
]
|
301
|
+
)}) {(
|
302
|
+
a = self.inner.sequence
|
303
|
+
[
|
304
|
+
[
|
305
|
+
:capture,
|
306
|
+
[:c_start]
|
307
|
+
],
|
308
|
+
*a,
|
309
|
+
[
|
310
|
+
:capture,
|
311
|
+
[
|
312
|
+
:c_end,
|
313
|
+
self.captargs
|
314
|
+
]
|
315
|
+
]
|
316
|
+
]
|
317
|
+
)})})}
|
318
|
+
::Myco.find_constant(:NamedTextCapture).component_eval {(declare_meme(:sequence, [], nil, ::Myco.cscope.dup) { |*| (
|
319
|
+
a = self.inner.sequence
|
320
|
+
[
|
321
|
+
[
|
322
|
+
:capture,
|
323
|
+
[:s_start]
|
324
|
+
],
|
325
|
+
*a,
|
326
|
+
[
|
327
|
+
:capture,
|
328
|
+
[
|
329
|
+
:s_end,
|
330
|
+
self.captargs
|
331
|
+
]
|
332
|
+
]
|
333
|
+
]
|
334
|
+
)})}
|
335
|
+
::Myco.find_constant(:NamedTokenCapture).component_eval {(declare_meme(:sequence, [], nil, ::Myco.cscope.dup) { |*| (
|
336
|
+
a = self.inner.sequence
|
337
|
+
[
|
338
|
+
[
|
339
|
+
:capture,
|
340
|
+
[:t_start]
|
341
|
+
],
|
342
|
+
*a,
|
343
|
+
[
|
344
|
+
:capture,
|
345
|
+
[
|
346
|
+
:t_end,
|
347
|
+
self.captargs
|
348
|
+
]
|
349
|
+
]
|
350
|
+
]
|
351
|
+
)})}
|
352
|
+
::Myco.find_constant(:Reduction).component_eval {(declare_meme(:sequence, [], nil, ::Myco.cscope.dup) { |*| (
|
353
|
+
a = self.inner.sequence
|
354
|
+
[
|
355
|
+
[
|
356
|
+
:capture,
|
357
|
+
[:r_start]
|
358
|
+
],
|
359
|
+
*a,
|
360
|
+
[
|
361
|
+
:capture,
|
362
|
+
[
|
363
|
+
:r_end,
|
364
|
+
self.captargs
|
365
|
+
]
|
366
|
+
]
|
367
|
+
]
|
368
|
+
)})}
|
369
|
+
)}})
|
370
|
+
.tap { |__c__| __c__.__name__ = :Constructions })}}.instance
|
@@ -0,0 +1,65 @@
|
|
1
|
+
|
2
|
+
Grammar < BasicObject, Patterns::ShorthandMethods {
|
3
|
+
|
4
|
+
Rule < Patterns::UnaryBase {
|
5
|
+
construct_rule: inner.construct
|
6
|
+
construct: RuleReference.new(name:name)
|
7
|
+
}
|
8
|
+
|
9
|
+
RuleReference < Constructions::UnaryBase {
|
10
|
+
var name
|
11
|
+
sequence: [[:call, name]]
|
12
|
+
bytecode: |m| m.call(name)
|
13
|
+
bytecode_can_capture: true
|
14
|
+
}
|
15
|
+
|
16
|
+
var rule_table: ::Hash.new
|
17
|
+
|
18
|
+
# Force evaluation of the rule tree in a way that
|
19
|
+
# doesn't get stuck in an infinite recursion.
|
20
|
+
construct_all_rules: {
|
21
|
+
rules.root.construct_rule
|
22
|
+
seen_keys = []
|
23
|
+
loop {
|
24
|
+
new_keys = rule_table.keys - seen_keys
|
25
|
+
new_keys.empty? && break
|
26
|
+
new_keys.each |key| {
|
27
|
+
rule_table[key].construct_rule
|
28
|
+
seen_keys.push(key)
|
29
|
+
}
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
[decorators]
|
34
|
+
|
35
|
+
# TODO: streamline syntax for this definition to make it more intuitive
|
36
|
+
token: Decorator {
|
37
|
+
apply: |meme| {
|
38
|
+
orig_meme = meme.dup
|
39
|
+
meme.body = Proc.new { orig_meme.result.token(:"t_"meme.name"") }
|
40
|
+
}
|
41
|
+
[transforms]
|
42
|
+
cache: true
|
43
|
+
}
|
44
|
+
|
45
|
+
var rule: Decorator {
|
46
|
+
apply: |meme| {
|
47
|
+
name = meme.name
|
48
|
+
# TODO: use some kind of Decorator#wrap mechanism instead
|
49
|
+
meme.target.declare_meme(name, [:var]) {
|
50
|
+
outer_self = self
|
51
|
+
rule = Rule {
|
52
|
+
name: name
|
53
|
+
inner: meme.result_for(outer_self)
|
54
|
+
}
|
55
|
+
rule_table[name] = rule
|
56
|
+
rule
|
57
|
+
}
|
58
|
+
}
|
59
|
+
[transforms]
|
60
|
+
expose: false # Exposing the original meme would overwrite the wrapped one
|
61
|
+
}
|
62
|
+
|
63
|
+
[rules]
|
64
|
+
rule root: Patterns::AnyCharacter.new.*
|
65
|
+
}
|
@@ -0,0 +1,83 @@
|
|
1
|
+
|
2
|
+
::Myco::Component.new([::Myco::FileToplevel], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
3
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {(::Myco.cscope.for_method_definition.const_set(:Grammar, ::Myco::Component.new([
|
4
|
+
::Myco.find_constant(:BasicObject),
|
5
|
+
::Myco.find_constant(:Patterns)::ShorthandMethods
|
6
|
+
], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
7
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {(
|
8
|
+
::Myco.cscope.for_method_definition.const_set(:Rule, ::Myco::Component.new([::Myco.find_constant(:Patterns)::UnaryBase], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
9
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {(
|
10
|
+
declare_meme(:construct_rule, [], nil, ::Myco.cscope.dup) { |*| (self.inner.construct)}
|
11
|
+
declare_meme(:construct, [], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:RuleReference).new({:name => self.name}))}
|
12
|
+
)}})
|
13
|
+
.tap { |__c__| __c__.__name__ = :Rule }
|
14
|
+
::Myco.cscope.for_method_definition.const_set(:RuleReference, ::Myco::Component.new([::Myco.find_constant(:Constructions)::UnaryBase], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
15
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {(
|
16
|
+
declare_meme(:name, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil}
|
17
|
+
declare_meme(:sequence, [], nil, ::Myco.cscope.dup) { |*| ([[
|
18
|
+
:call,
|
19
|
+
self.name
|
20
|
+
]])}
|
21
|
+
declare_meme(:bytecode, [], nil, ::Myco.cscope.dup) { |m| (m.call(self.name))}
|
22
|
+
declare_meme(:bytecode_can_capture, [], nil, ::Myco.cscope.dup) { |*| (true)}
|
23
|
+
)}})
|
24
|
+
.tap { |__c__| __c__.__name__ = :RuleReference }
|
25
|
+
declare_meme(:rule_table, [[:var, []]], nil, ::Myco.cscope.dup) { |*| (::Hash.new)}
|
26
|
+
declare_meme(:construct_all_rules, [], nil, ::Myco.cscope.dup) { |*| (
|
27
|
+
self.rules.root.construct_rule
|
28
|
+
seen_keys = []
|
29
|
+
self.loop { || (
|
30
|
+
new_keys = self.rule_table.keys.__send__(
|
31
|
+
:-,
|
32
|
+
seen_keys
|
33
|
+
)
|
34
|
+
::Myco.branch_op(:"&&", new_keys.__send__(:empty?)) {self.__send__(:break)}
|
35
|
+
new_keys.each { |key| (
|
36
|
+
self.rule_table.__send__(
|
37
|
+
:[],
|
38
|
+
key
|
39
|
+
).construct_rule
|
40
|
+
seen_keys.push(key)
|
41
|
+
)}
|
42
|
+
)}
|
43
|
+
)}
|
44
|
+
__category__(:decorators).component_eval {(
|
45
|
+
declare_meme(:token, [], nil, ::Myco.cscope.dup) { |*| (::Myco::Component.new([::Myco.find_constant(:Decorator)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
46
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {(
|
47
|
+
declare_meme(:apply, [], nil, ::Myco.cscope.dup) { |meme| (
|
48
|
+
orig_meme = meme.dup
|
49
|
+
meme.__send__(
|
50
|
+
:body=,
|
51
|
+
::Myco.find_constant(:Proc).new { || (orig_meme.result.token(:"t_#{meme.name}"))}
|
52
|
+
)
|
53
|
+
)}
|
54
|
+
__category__(:transforms).component_eval {(declare_meme(:cache, [], nil, ::Myco.cscope.dup) { |*| (true)})}
|
55
|
+
)}}.instance)}
|
56
|
+
declare_meme(:rule, [[:var, []]], nil, ::Myco.cscope.dup) { |*| (::Myco::Component.new([::Myco.find_constant(:Decorator)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
57
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {(
|
58
|
+
declare_meme(:apply, [], nil, ::Myco.cscope.dup) { |meme| (
|
59
|
+
name = meme.name
|
60
|
+
meme.target.declare_meme(
|
61
|
+
name,
|
62
|
+
[:var]
|
63
|
+
) { || (
|
64
|
+
outer_self = self
|
65
|
+
rule = ::Myco::Component.new([::Myco.find_constant(:Rule)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
|
66
|
+
.tap { |__c__| __c__.__last__ = __c__.component_eval {(
|
67
|
+
declare_meme(:name, [], nil, ::Myco.cscope.dup) { |*| (name)}
|
68
|
+
declare_meme(:inner, [], nil, ::Myco.cscope.dup) { |*| (meme.result_for(outer_self))}
|
69
|
+
)}}.instance
|
70
|
+
self.rule_table.__send__(
|
71
|
+
:[]=,
|
72
|
+
name,
|
73
|
+
rule
|
74
|
+
)
|
75
|
+
rule
|
76
|
+
)}
|
77
|
+
)}
|
78
|
+
__category__(:transforms).component_eval {(declare_meme(:expose, [], nil, ::Myco.cscope.dup) { |*| (false)})}
|
79
|
+
)}}.instance)}
|
80
|
+
)}
|
81
|
+
__category__(:rules).component_eval {(declare_meme(:root, [[:rule, []]], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:Patterns)::AnyCharacter.new.__send__(:*))})}
|
82
|
+
)}})
|
83
|
+
.tap { |__c__| __c__.__name__ = :Grammar })}}.instance
|
@@ -0,0 +1,139 @@
|
|
1
|
+
|
2
|
+
Instructions < EmptyObject {
|
3
|
+
|
4
|
+
##
|
5
|
+
# Basic Instructions
|
6
|
+
|
7
|
+
# Test the character pointed to by the current index into the subject.
|
8
|
+
# Continue if the character |code| is equal, otherwise fail.
|
9
|
+
char: |code|
|
10
|
+
(subject.at(idx) == code)
|
11
|
+
&? (self.ip = ip + 1; self.idx = idx + 1)
|
12
|
+
?? (self.ip = null) # failure
|
13
|
+
|
14
|
+
# Move the instruction pointer forward by |label| instructions.
|
15
|
+
jump: |label|
|
16
|
+
self.ip = ip + label
|
17
|
+
|
18
|
+
# Create a backtrack entry on the stack, pointing |label| instructions ahead.
|
19
|
+
choice: |label| {
|
20
|
+
stack.push([ip + label, idx, captures.dup])
|
21
|
+
self.ip = ip + 1
|
22
|
+
}
|
23
|
+
|
24
|
+
# Push two-part return address onto the stack and goto start of |new_ipk|
|
25
|
+
call: |new_ipk| {
|
26
|
+
stack.push([ip+1, ipk])
|
27
|
+
self.ip = 0
|
28
|
+
self.ipk = new_ipk
|
29
|
+
}
|
30
|
+
|
31
|
+
# Return from a call by popping the return address and jumping to it.
|
32
|
+
# It is assumed that the top of the stack is a return address from a :call.
|
33
|
+
return: {
|
34
|
+
addr = stack.pop
|
35
|
+
addr &? (
|
36
|
+
self.ipk = addr.pop
|
37
|
+
self.ip = addr.pop
|
38
|
+
true
|
39
|
+
) ?? finish
|
40
|
+
}
|
41
|
+
|
42
|
+
# Pop and discard the backtrack entry from the stack and jump to |label|.
|
43
|
+
# It is assumed that the top of the stack is a backtrack entry from a :choice.
|
44
|
+
commit: |label| {
|
45
|
+
stack.pop
|
46
|
+
self.ip = ip + label
|
47
|
+
}
|
48
|
+
|
49
|
+
# Note the current subject index and the given metadata for post-processing.
|
50
|
+
capture: |metadata| {
|
51
|
+
captures.push([idx, metadata])
|
52
|
+
self.ip = ip + 1
|
53
|
+
}
|
54
|
+
|
55
|
+
# Pop the backtrack entry off the stack and copy the state from it,
|
56
|
+
# effectively pursuing the alternative posed by the last :choice.
|
57
|
+
handle_fail:
|
58
|
+
self.stack.empty?
|
59
|
+
&? ErrorCondition.new
|
60
|
+
?? (
|
61
|
+
entry = stack.pop
|
62
|
+
size = entry.size
|
63
|
+
size == 3 &? ( # backtrack
|
64
|
+
self.captures = entry.pop
|
65
|
+
self.idx = entry.pop
|
66
|
+
self.ip = entry.pop
|
67
|
+
true
|
68
|
+
) ?? ( # return and mark fail
|
69
|
+
size == 2 &? (
|
70
|
+
self.ipk = entry.pop
|
71
|
+
self.ip = null
|
72
|
+
) ?? ErrorCondition.new
|
73
|
+
)
|
74
|
+
)
|
75
|
+
|
76
|
+
# Signal a successful match at the end of the complete pattern
|
77
|
+
finish:
|
78
|
+
self.ip = true
|
79
|
+
|
80
|
+
##
|
81
|
+
# Optimized Instructions
|
82
|
+
#
|
83
|
+
# These instructions could be expressed in terms of the Basic Instructions,
|
84
|
+
# but are more efficiently executed if given special implementations.
|
85
|
+
|
86
|
+
# Like char, but accept any char whose code is a valid key in |table|
|
87
|
+
charset: |table|
|
88
|
+
(code=subject.at(idx); code && table.key?(code))
|
89
|
+
&? (self.ip = ip + 1; self.idx = idx + 1)
|
90
|
+
?? (self.ip = null) # failure
|
91
|
+
|
92
|
+
# Like char, but accept any char whose code is between |start| and |stop|
|
93
|
+
charrange: |start, stop|
|
94
|
+
(code=subject.at(idx); code && code>=start && code<=stop)
|
95
|
+
&? (self.ip = ip + 1; self.idx = idx + 1)
|
96
|
+
?? (self.ip = null) # failure
|
97
|
+
|
98
|
+
# (Kleene star applied to a charset)
|
99
|
+
span: |table| loop {
|
100
|
+
(code=subject.at(idx); code && table.key?(code))
|
101
|
+
&? (self.idx = idx + 1)
|
102
|
+
?? (self.ip = ip + 1; break)
|
103
|
+
}
|
104
|
+
|
105
|
+
# Match any character, |count| number of times.
|
106
|
+
any: |count|
|
107
|
+
(self.idx + count > subject.size)
|
108
|
+
&? (self.ip = null; true) # failure
|
109
|
+
?? (
|
110
|
+
self.ip = ip + 1
|
111
|
+
self.idx = idx + count
|
112
|
+
)
|
113
|
+
|
114
|
+
# Update the state for the backtrack entry on the top of the stack
|
115
|
+
# but don't change the fail address; then jump to |label|.
|
116
|
+
partial_commit: |label| {
|
117
|
+
entry = stack.pop
|
118
|
+
stack.push([entry.first, idx, captures.dup])
|
119
|
+
self.ip = ip + label
|
120
|
+
}
|
121
|
+
|
122
|
+
# Pop the backtrack entry and restore state but jump to |label|
|
123
|
+
# instead of jumping to the popped fail address.
|
124
|
+
back_commit: |label| {
|
125
|
+
entry = stack.pop
|
126
|
+
self.captures = entry.pop
|
127
|
+
self.idx = entry.pop
|
128
|
+
self.ip = ip + label
|
129
|
+
}
|
130
|
+
|
131
|
+
# Pop a backtrack entry off the stack and discard it, then fail.
|
132
|
+
fail_twice: {
|
133
|
+
self.stack.empty?
|
134
|
+
&? ErrorCondition.new
|
135
|
+
?? stack.pop
|
136
|
+
handle_fail
|
137
|
+
}
|
138
|
+
|
139
|
+
}
|