reg 0.4.6
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +510 -0
- data/README +404 -0
- data/assert.rb +31 -0
- data/calc.reg +73 -0
- data/forward_to.rb +49 -0
- data/item_thattest.rb +47 -0
- data/numberset.rb +200 -0
- data/parser.txt +188 -0
- data/philosophy.txt +72 -0
- data/reg.gemspec +27 -0
- data/reg.rb +33 -0
- data/regarray.rb +675 -0
- data/regarrayold.rb +477 -0
- data/regbackref.rb +126 -0
- data/regbind.rb +74 -0
- data/regcase.rb +78 -0
- data/regcore.rb +379 -0
- data/regdeferred.rb +134 -0
- data/reggrid.csv +2 -1
- data/regguide.txt +416 -0
- data/reghash.rb +318 -0
- data/regitem_that.rb +146 -0
- data/regknows.rb +63 -0
- data/reglogic.rb +195 -0
- data/reglookab.rb +94 -0
- data/regold.rb +75 -0
- data/regpath.rb +74 -0
- data/regposition.rb +68 -0
- data/regprogress.rb +1067 -0
- data/regreplace.rb +114 -0
- data/regsugar.rb +230 -0
- data/regtest.rb +1075 -0
- data/regvar.rb +76 -0
- data/trace.rb +45 -0
- metadata +83 -0
data/reghash.rb
ADDED
@@ -0,0 +1,318 @@
|
|
1
|
+
|
2
|
+
=begin copyright
|
3
|
+
reg - the ruby extended grammar
|
4
|
+
Copyright (C) 2005 Caleb Clausen
|
5
|
+
|
6
|
+
This library is free software; you can redistribute it and/or
|
7
|
+
modify it under the terms of the GNU Lesser General Public
|
8
|
+
License as published by the Free Software Foundation; either
|
9
|
+
version 2.1 of the License, or (at your option) any later version.
|
10
|
+
|
11
|
+
This library is distributed in the hope that it will be useful,
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14
|
+
Lesser General Public License for more details.
|
15
|
+
|
16
|
+
You should have received a copy of the GNU Lesser General Public
|
17
|
+
License along with this library; if not, write to the Free Software
|
18
|
+
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
19
|
+
=end
|
20
|
+
|
21
|
+
|
22
|
+
require 'forward_to'
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
module Reg
|
27
|
+
|
28
|
+
class Hash
|
29
|
+
include Reg
|
30
|
+
attr :others
|
31
|
+
|
32
|
+
def initialize(hashdat=nil)
|
33
|
+
@matchers={}
|
34
|
+
@literals={}
|
35
|
+
@others=nil
|
36
|
+
hashdat or return
|
37
|
+
hashdat.key?(OB) and @others=hashdat.delete(OB)
|
38
|
+
hashdat.each {|key,val|
|
39
|
+
if Reg.interesting_matcher? key
|
40
|
+
Fixed===key and key=key.unwrap
|
41
|
+
@matchers[key]=val
|
42
|
+
else
|
43
|
+
Equals===key and key=key.unwrap
|
44
|
+
@literals[key]=val
|
45
|
+
end
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def Hash.[](*args); new(*args); end
|
50
|
+
|
51
|
+
def matches_class; ::Hash end
|
52
|
+
|
53
|
+
def ordered
|
54
|
+
pairs=[]
|
55
|
+
@literals.each{|k,v| pairs<< Pair[k,v] }
|
56
|
+
@matchers.each{|k,v| pairs<< Pair[k,v] }
|
57
|
+
pairs<<Pair[OB,@others] if @others
|
58
|
+
return +pairs
|
59
|
+
end
|
60
|
+
|
61
|
+
def subregs;
|
62
|
+
@literals.keys + @literals.values +
|
63
|
+
@matchers.keys + @matchers.values +
|
64
|
+
(@others==nil ? [OB,@others] : [])
|
65
|
+
end
|
66
|
+
|
67
|
+
def inspect
|
68
|
+
result=[]
|
69
|
+
result<<@literals.inspect.sub(/.(.*)./, "\\1") unless @literals.empty?
|
70
|
+
result<<@matchers.inspect.sub(/.(.*)./, "\\1") unless @matchers.empty?
|
71
|
+
result<<"OB=>#{@others.inspect}" if defined? @others and @others!=nil
|
72
|
+
return "+{#{result.join(", ")}}"
|
73
|
+
end
|
74
|
+
|
75
|
+
def -@ #make object matcher
|
76
|
+
Rob(@literals.merge(@matchers).merge(OB=>@others))
|
77
|
+
end
|
78
|
+
|
79
|
+
def ===(other)
|
80
|
+
matchedliterals={}
|
81
|
+
matchedmatchers={}
|
82
|
+
other.each_pair{|key,val|
|
83
|
+
#literals get a chance first
|
84
|
+
@literals.key? key and
|
85
|
+
if (@literals[key]===val)
|
86
|
+
matchedliterals[key]=true
|
87
|
+
next
|
88
|
+
else
|
89
|
+
return
|
90
|
+
end
|
91
|
+
|
92
|
+
#now try more general matchers
|
93
|
+
saw_matcher=nil
|
94
|
+
@matchers.each_pair{|mkey,mval|
|
95
|
+
if mkey===key
|
96
|
+
return unless (mval===val)
|
97
|
+
saw_matcher=matchedmatchers[mkey]=true
|
98
|
+
break
|
99
|
+
end
|
100
|
+
}
|
101
|
+
|
102
|
+
|
103
|
+
#last of all, try the catchall
|
104
|
+
saw_matcher or @others===val or return
|
105
|
+
}
|
106
|
+
@literals.each_pair{|k,v| matchedliterals[k] or v==(other.default k) or return }
|
107
|
+
@matchers.each_pair{|k,v| matchedmatchers[k] or v===other.default or return }
|
108
|
+
other.empty? and @literals.empty? and @matchers.empty? and return @others===other.default
|
109
|
+
return true
|
110
|
+
end
|
111
|
+
|
112
|
+
#tla of +{}
|
113
|
+
assign_TLAs :Rah=>:Hash
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
#--------------------------
|
118
|
+
class OrderedHash
|
119
|
+
include Reg
|
120
|
+
def initialize(*args)
|
121
|
+
@keys=[]
|
122
|
+
@vals=[]
|
123
|
+
@others=nil
|
124
|
+
args.each{|a|
|
125
|
+
if Pair===a
|
126
|
+
l,r=a.left,a.right
|
127
|
+
Fixed===l and l=l.unwrap
|
128
|
+
if l==OB
|
129
|
+
@others=r
|
130
|
+
else
|
131
|
+
@keys<<l
|
132
|
+
@vals<<r
|
133
|
+
end
|
134
|
+
else
|
135
|
+
@keys<<a
|
136
|
+
@vals<<OB
|
137
|
+
end
|
138
|
+
}
|
139
|
+
end
|
140
|
+
|
141
|
+
def ===(other)
|
142
|
+
matched=0
|
143
|
+
saw1=nil
|
144
|
+
other.each_pair do |ko,vo|
|
145
|
+
saw1=nil
|
146
|
+
@vals.each_index do|i|
|
147
|
+
kr,vr=@keys[i],@vals[i]
|
148
|
+
if kr===ko
|
149
|
+
vr===vo or return
|
150
|
+
saw1=matched |= 1<<i
|
151
|
+
break
|
152
|
+
end
|
153
|
+
end
|
154
|
+
saw1 or (@others===vo or return)
|
155
|
+
end
|
156
|
+
@vals.each_index {|i|
|
157
|
+
unless (matched&(1<<i)).nonzero?
|
158
|
+
@vals[i]===other.default((@keys[i] unless Reg::interesting_matcher? @keys[i])) or return
|
159
|
+
end
|
160
|
+
}
|
161
|
+
other.empty? and @vals.empty? and return @others===other.default
|
162
|
+
# @subhashes.each do|subhash|
|
163
|
+
# subhash===other or return false
|
164
|
+
# end
|
165
|
+
return other||true #huh need more complex result?
|
166
|
+
end
|
167
|
+
|
168
|
+
def self.[](*args); new(*args); end
|
169
|
+
|
170
|
+
def matches_class; ::Hash end
|
171
|
+
|
172
|
+
def &; huh end
|
173
|
+
def inspect;
|
174
|
+
"+[#{
|
175
|
+
map{|k,v| k.inspect+ ((Reg===k)? "" : ".reg") +
|
176
|
+
"**"+v.inspect unless OB==k && nil==v
|
177
|
+
}.compact.join ", "
|
178
|
+
}]"
|
179
|
+
end
|
180
|
+
def subregs; huh end
|
181
|
+
|
182
|
+
def each
|
183
|
+
@keys.each_index{|i|
|
184
|
+
yield @keys[i],@vals[i]
|
185
|
+
}
|
186
|
+
yield OB,@others
|
187
|
+
end
|
188
|
+
include Enumerable
|
189
|
+
|
190
|
+
|
191
|
+
def to_ruby
|
192
|
+
result= "def self.===(a_hash)\n"
|
193
|
+
result<<" a_hash.each_pair{|k,v|\n"
|
194
|
+
result<<" case k\n"
|
195
|
+
@keys.each_index{|i|
|
196
|
+
result<<" when #{@keys[i]}: #{vals[i]}\n"
|
197
|
+
}
|
198
|
+
result<<" else #{@other}\n" +
|
199
|
+
" end===v or break\n" +
|
200
|
+
" }\n" +
|
201
|
+
"end\n"
|
202
|
+
|
203
|
+
return result
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
#--------------------------
|
208
|
+
class Object < Hash
|
209
|
+
#decending from Hash isn't particularly useful here
|
210
|
+
#it looks like everything (but &) is overridden, anyway
|
211
|
+
|
212
|
+
def initialize(*args)
|
213
|
+
hash= (::Hash===args.last ? args.pop : {})
|
214
|
+
@vars={}; @meths={}; @meth_matchers={}
|
215
|
+
hash.each_pair{|item,val|
|
216
|
+
if ::String===item or ::Symbol===item
|
217
|
+
item=item.to_s
|
218
|
+
(/^@@?/===item ? @vars : @meths)[item.to_sym]=val
|
219
|
+
else
|
220
|
+
@meth_matchers[item]=val
|
221
|
+
end
|
222
|
+
}
|
223
|
+
@meths[:class]=args.shift if (Module===args.first)
|
224
|
+
end
|
225
|
+
def self.[](*args) new(*args); end
|
226
|
+
|
227
|
+
|
228
|
+
def inspect
|
229
|
+
"-{"+@vars.inspect.sub( /^.(.*).$/, '\\1') +
|
230
|
+
@meths.inspect.sub(/^.(.*).$/, '\\1') +
|
231
|
+
@meth_matchers.inspect.sub(/^.(.*).$/, '\\1') + "}"
|
232
|
+
|
233
|
+
end
|
234
|
+
|
235
|
+
def matches_class
|
236
|
+
@meths[:class] or Object
|
237
|
+
end
|
238
|
+
|
239
|
+
def -@ #make object matcher
|
240
|
+
self
|
241
|
+
end
|
242
|
+
|
243
|
+
def ===(other)
|
244
|
+
seenmeths=[];seenvars=[];seenmats=[]
|
245
|
+
@meths.each_pair{|name,val|
|
246
|
+
val===other.send(name) or return
|
247
|
+
seenmeths<<name
|
248
|
+
}
|
249
|
+
@vars.each_pair{|name,val|
|
250
|
+
val===other.instance_eval(name.to_s) or return
|
251
|
+
seenvars<<name
|
252
|
+
}
|
253
|
+
@meth_matchers.empty? or other.public_methods.each {|meth|
|
254
|
+
@meth_matchers.each_pair{|name, val|
|
255
|
+
if name===meth
|
256
|
+
val===other.send(meth) || return
|
257
|
+
seenmats<< name
|
258
|
+
end
|
259
|
+
}
|
260
|
+
}
|
261
|
+
@meths.keys.-(seenmeths).empty? or return
|
262
|
+
@vars.keys.-(seenvars).empty? or return
|
263
|
+
@meth_matchers.keys.-(seenmats).empty? or return
|
264
|
+
|
265
|
+
|
266
|
+
return other || true
|
267
|
+
|
268
|
+
rescue
|
269
|
+
return false
|
270
|
+
end
|
271
|
+
|
272
|
+
#tla of -{}
|
273
|
+
assign_TLAs :Rob=>:Object
|
274
|
+
|
275
|
+
|
276
|
+
end
|
277
|
+
|
278
|
+
|
279
|
+
#OrderedObject not even attempted yet
|
280
|
+
|
281
|
+
module Reg
|
282
|
+
def **(other)
|
283
|
+
Pair[self,other]
|
284
|
+
end
|
285
|
+
alias has **
|
286
|
+
end
|
287
|
+
|
288
|
+
class Pair
|
289
|
+
include Reg
|
290
|
+
class<<self; alias [] new; end
|
291
|
+
|
292
|
+
attr_reader :left,:right
|
293
|
+
|
294
|
+
def initialize(l,r)
|
295
|
+
@left,@right=l,r
|
296
|
+
end
|
297
|
+
|
298
|
+
if false #not sure if i know what i want here...
|
299
|
+
def hash_cmp(hash,k,v)
|
300
|
+
@left
|
301
|
+
end
|
302
|
+
|
303
|
+
def obj_cmp
|
304
|
+
end
|
305
|
+
end
|
306
|
+
#tla of **
|
307
|
+
assign_TLAs :Rap=>:Pair
|
308
|
+
|
309
|
+
|
310
|
+
|
311
|
+
end
|
312
|
+
|
313
|
+
|
314
|
+
|
315
|
+
end
|
316
|
+
|
317
|
+
|
318
|
+
|
data/regitem_that.rb
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
=begin copyright
|
2
|
+
reg - the ruby extended grammar
|
3
|
+
Copyright (C) 2005 Caleb Clausen
|
4
|
+
|
5
|
+
This library is free software; you can redistribute it and/or
|
6
|
+
modify it under the terms of the GNU Lesser General Public
|
7
|
+
License as published by the Free Software Foundation; either
|
8
|
+
version 2.1 of the License, or (at your option) any later version.
|
9
|
+
|
10
|
+
This library is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13
|
+
Lesser General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU Lesser General Public
|
16
|
+
License along with this library; if not, write to the Free Software
|
17
|
+
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
18
|
+
=end
|
19
|
+
require 'regdeferred.rb'
|
20
|
+
|
21
|
+
module Reg
|
22
|
+
class <<self
|
23
|
+
#sugar forwards this from Kernel
|
24
|
+
def item_that(klass=nil,&block)
|
25
|
+
return ItemThat.new(klass) unless block
|
26
|
+
|
27
|
+
class <<block
|
28
|
+
#include arguments to include appear to be processed in a strange order... this is
|
29
|
+
#significant if order is important to you
|
30
|
+
#the #included methods are perhaps not called when i think they should be....
|
31
|
+
#(DON'T simplify the next line; it'll break.)
|
32
|
+
[BlankSlate ,Formula, BlockLike].each{|mod| include mod}
|
33
|
+
restore :inspect,:extend,:call
|
34
|
+
|
35
|
+
alias === eeee #workaround-- shouldn't be needed
|
36
|
+
alias formula_value call
|
37
|
+
# undef eeee
|
38
|
+
end
|
39
|
+
block.klass=klass
|
40
|
+
block
|
41
|
+
end
|
42
|
+
alias item_is item_that
|
43
|
+
end
|
44
|
+
|
45
|
+
#----------------------------------
|
46
|
+
module BlockLike
|
47
|
+
# include Formula
|
48
|
+
|
49
|
+
attr_writer :klass #for internal use only
|
50
|
+
|
51
|
+
def eeee(val)
|
52
|
+
@klass and @klass===val || return
|
53
|
+
begin call(val)
|
54
|
+
rescue: false
|
55
|
+
end
|
56
|
+
end
|
57
|
+
alias === eeee #does nothing in includers.... why?
|
58
|
+
def formula_value *a,&b; call( *a,&b) end
|
59
|
+
|
60
|
+
|
61
|
+
def mixmod; ItemThatLike end
|
62
|
+
def reg; dup.extend Reg end
|
63
|
+
end
|
64
|
+
|
65
|
+
#----------------------------------
|
66
|
+
module DeferredQuery
|
67
|
+
#just an ancestor for ItemThat and RegThat
|
68
|
+
def eee(item)
|
69
|
+
begin formula_value item
|
70
|
+
rescue: false
|
71
|
+
end
|
72
|
+
end
|
73
|
+
alias === eee #this doesn't work!!! WHY????
|
74
|
+
#there's no way to define the method === in this
|
75
|
+
#module and have it be defined in class ItemThat.
|
76
|
+
#mixmod and reg don't have this problem. this must
|
77
|
+
#be a bug. for now, I work around it with clever
|
78
|
+
#alias/undefing in places that include/extend ItemThatLike
|
79
|
+
#(seemingly, this is only a problem when including, not extending... dunno why)
|
80
|
+
#this bug may be gone now; need to try to get rid of weird eee stuff.
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
#----------------------------------
|
85
|
+
module ItemThatLike
|
86
|
+
include DeferredQuery
|
87
|
+
|
88
|
+
def mixmod; ItemThatLike end
|
89
|
+
def reg; dup.extend RegThatLike end
|
90
|
+
end
|
91
|
+
|
92
|
+
#----------------------------------
|
93
|
+
class ItemThat
|
94
|
+
include BlankSlate
|
95
|
+
restore :inspect,:extend
|
96
|
+
include Formula
|
97
|
+
include ItemThatLike
|
98
|
+
alias === eee
|
99
|
+
undef eee
|
100
|
+
def initialize(klass=nil)
|
101
|
+
@klass=klass
|
102
|
+
end
|
103
|
+
|
104
|
+
def formula_value(val,*rest)
|
105
|
+
#the exception raised here should be (eventually) caught by
|
106
|
+
#the handler in ItemThatLike#eee. calling ItemThat#formula_value isn't
|
107
|
+
#really legitimate otherwise.
|
108
|
+
@klass and @klass===val || fail("item_that constraint mismatch")
|
109
|
+
|
110
|
+
val
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
#----------------------------------
|
116
|
+
module RegThatLike
|
117
|
+
include DeferredQuery
|
118
|
+
include Reg
|
119
|
+
|
120
|
+
def mixmod; RegThatLike end
|
121
|
+
end
|
122
|
+
|
123
|
+
#----------------------------------
|
124
|
+
class RegThat
|
125
|
+
include BlankSlate
|
126
|
+
restore :inspect,:extend
|
127
|
+
include Formula
|
128
|
+
include RegThatLike
|
129
|
+
alias === eee
|
130
|
+
undef eee
|
131
|
+
def initialize(klass=nil)
|
132
|
+
@klass=klass
|
133
|
+
end
|
134
|
+
|
135
|
+
def formula_value(val,*rest)
|
136
|
+
#the exception raised here should be (eventually) caught by
|
137
|
+
#the handler in RegThatLike#eee. calling RegThat#formula_value isn't
|
138
|
+
#really legitimate otherwise.
|
139
|
+
@klass and @klass===val || fail("item_that constraint mismatch")
|
140
|
+
|
141
|
+
val
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|