reg 0.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|