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/regbackref.rb
ADDED
@@ -0,0 +1,126 @@
|
|
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 'pp'
|
20
|
+
require 'regdeferred'
|
21
|
+
|
22
|
+
module Reg
|
23
|
+
|
24
|
+
=begin
|
25
|
+
#----------------------------------
|
26
|
+
module Block
|
27
|
+
# include Formula
|
28
|
+
|
29
|
+
attr_writer :klass #for internal use only
|
30
|
+
|
31
|
+
def eeee(val)
|
32
|
+
@klass and @klass===val || return
|
33
|
+
begin call(val)
|
34
|
+
rescue: false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
alias === eeee #does nothing in includers.... why?
|
38
|
+
alias formula_value eeee
|
39
|
+
|
40
|
+
|
41
|
+
def mixmod; ItemThatLike end
|
42
|
+
def reg; extend Reg end
|
43
|
+
end
|
44
|
+
#----------------------------------
|
45
|
+
module ItemThatLike
|
46
|
+
def eee(item)
|
47
|
+
begin formula_value item
|
48
|
+
rescue: false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
alias === eee #this doesn't work!!! WHY????
|
52
|
+
#there's no way to define the method === in this
|
53
|
+
#module and have it be defined in class ItemThat.
|
54
|
+
#mixmod and reg don't have this problem. this must
|
55
|
+
#be a bug. for now, I work around it with clever
|
56
|
+
#alias/undefing in places that include/extend ItemThatLike
|
57
|
+
#(seemingly, this is only a problem when including, not extending... dunno why)
|
58
|
+
#this bug may be gone now; need to try to get rid of weird eee stuff.
|
59
|
+
|
60
|
+
def mixmod; ItemThatLike end
|
61
|
+
def reg; extend Reg end
|
62
|
+
end
|
63
|
+
#----------------------------------
|
64
|
+
class ItemThat
|
65
|
+
include BlankSlate
|
66
|
+
restore :inspect,:extend
|
67
|
+
include Formula
|
68
|
+
include ItemThatLike
|
69
|
+
alias === eee
|
70
|
+
undef eee
|
71
|
+
def initialize(klass=nil)
|
72
|
+
@klass=klass
|
73
|
+
end
|
74
|
+
|
75
|
+
def formula_value(val,*rest)
|
76
|
+
#the exception raised here should be (eventually) caught by
|
77
|
+
#the handler in ItemThatLike#eee. calling ItemThat#formula_value isn't
|
78
|
+
#really legitimate otherwise.
|
79
|
+
@klass and @klass===val || fail("item_that constraint mismatch")
|
80
|
+
|
81
|
+
val
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
=end
|
86
|
+
#----------------------------------
|
87
|
+
module BackrefLike
|
88
|
+
def mmatch(ary,idx)
|
89
|
+
huh #need info thats not_in ary or idx
|
90
|
+
end
|
91
|
+
|
92
|
+
def mixmod; BackrefLike end
|
93
|
+
end
|
94
|
+
#----------------------------------
|
95
|
+
class Backref
|
96
|
+
include BlankSlate
|
97
|
+
restore :inspect,:extend
|
98
|
+
include Formula
|
99
|
+
include BackrefLike
|
100
|
+
def initialize(name,*path)
|
101
|
+
#complex paths not handled yet
|
102
|
+
raise ParameterError.new unless path.empty? and Reg|Symbol===name
|
103
|
+
@name=name
|
104
|
+
end
|
105
|
+
|
106
|
+
def formula_value(*ctx)
|
107
|
+
progress=ctx[1]
|
108
|
+
progress.variables[@name]
|
109
|
+
end
|
110
|
+
|
111
|
+
class<<self
|
112
|
+
alias [] new
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
#----------------------------------
|
118
|
+
module BRLike
|
119
|
+
include BackrefLike
|
120
|
+
include Reg
|
121
|
+
def mixmod; BRLike end
|
122
|
+
end
|
123
|
+
class BR < Backref
|
124
|
+
include BRLike
|
125
|
+
end
|
126
|
+
end
|
data/regbind.rb
ADDED
@@ -0,0 +1,74 @@
|
|
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
|
+
module Reg
|
20
|
+
module Reg
|
21
|
+
def bind(name=self)
|
22
|
+
Bound.new(name,self)
|
23
|
+
end
|
24
|
+
alias << bind
|
25
|
+
|
26
|
+
def side_effect(&block); SideEffect.new(self,&block) end
|
27
|
+
def undo(&block); Undo.new(self,&block) end
|
28
|
+
end
|
29
|
+
|
30
|
+
#-------------------------------------
|
31
|
+
class Bound
|
32
|
+
include Reg
|
33
|
+
def initialize(name,reg)
|
34
|
+
@name,@reg=name,reg
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
def mmatch(progress)
|
39
|
+
result=@reg.mmatch(progress) and
|
40
|
+
progress.register_var(@name,@reg)
|
41
|
+
return result
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
#-------------------------------------
|
46
|
+
class SideEffect
|
47
|
+
include Reg
|
48
|
+
|
49
|
+
def initialize(reg,&block)
|
50
|
+
@reg,@block=reg,block
|
51
|
+
end
|
52
|
+
|
53
|
+
def mmatch(progress)
|
54
|
+
result=@reg.mmatch(progress) and
|
55
|
+
@block.call(progress)
|
56
|
+
return result
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
#------------------------------------
|
61
|
+
class Undo
|
62
|
+
include Reg
|
63
|
+
|
64
|
+
def initialize(reg,&block)
|
65
|
+
@reg,@block=reg,block
|
66
|
+
end
|
67
|
+
|
68
|
+
def mmatch(progress)
|
69
|
+
result=@reg.mmatch(progress) and
|
70
|
+
progress.register_undo(@block)
|
71
|
+
return result
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/regcase.rb
ADDED
@@ -0,0 +1,78 @@
|
|
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
|
+
module Reg
|
20
|
+
class Case
|
21
|
+
def initialize(*args)
|
22
|
+
if args.size==1 and Hash===args.first
|
23
|
+
scalars=[]; sets=[]
|
24
|
+
matchers=[];
|
25
|
+
|
26
|
+
args.first.each{|k,v|
|
27
|
+
if Reg.interesting_matcher? k
|
28
|
+
matchers<<k.reg**v
|
29
|
+
elsif Set===k
|
30
|
+
sets<<k.reg**v
|
31
|
+
else
|
32
|
+
scalars<<k.reg**v
|
33
|
+
end
|
34
|
+
}
|
35
|
+
args=scalars+sets+matchers
|
36
|
+
end
|
37
|
+
|
38
|
+
@others=others_given=nil
|
39
|
+
@pairlist=args.delete_if{|a|
|
40
|
+
if !(Pair===a)
|
41
|
+
warn "ignoring non-Reg::Pair in Reg::Case: #{a}"
|
42
|
+
true
|
43
|
+
elsif OB==a.left
|
44
|
+
others_given and warn 'more than one default specified'
|
45
|
+
others_given=true
|
46
|
+
@others=v
|
47
|
+
end
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
def ===(other)
|
52
|
+
@pairlist.each{|pair|
|
53
|
+
pair.left===other and pair.right===other || return
|
54
|
+
}
|
55
|
+
@others===other
|
56
|
+
end
|
57
|
+
|
58
|
+
#hash-based optimization of scalars and sets is possible here
|
59
|
+
|
60
|
+
def previous_matchers(val,*)
|
61
|
+
val #by default, do nothing
|
62
|
+
end
|
63
|
+
|
64
|
+
def previous_matchers_ordered(val,index,other)
|
65
|
+
val,index=*args
|
66
|
+
(0..index).each{|i|
|
67
|
+
pair=@pairlist[i]
|
68
|
+
|
69
|
+
pair.left===other and pair.right===other || return
|
70
|
+
}
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
Rac=Case #tla of case
|
77
|
+
assign_TLA :Rac=>:Case
|
78
|
+
end
|
data/regcore.rb
ADDED
@@ -0,0 +1,379 @@
|
|
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
|
+
|
20
|
+
require 'trace.rb'
|
21
|
+
|
22
|
+
module Reg #namespace
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
INFINITY= (
|
28
|
+
result= [ Float::MAX**Float::MAX, Float::MAX**2, Float::MAX*2].max
|
29
|
+
result.infinite? ? result :
|
30
|
+
begin result=1.0/0
|
31
|
+
rescue: Float::MAX #maybe 1.0/0 doesn't work on some systems?
|
32
|
+
end
|
33
|
+
)
|
34
|
+
#there's also this way: 999999999999999999999999999999999999999999999999e999999999999999999999999999999
|
35
|
+
#but stuff like that sometimes returns zero, so it doesn't seem as reliable.
|
36
|
+
#(plus it generates a warning)
|
37
|
+
|
38
|
+
INFINITY>1_000_000 or raise 'INFINITY is too small'
|
39
|
+
INFINITY.to_f.infinite? or warn "INFINITY is merely very large, not infinite"
|
40
|
+
|
41
|
+
|
42
|
+
#--------------------------
|
43
|
+
#abstact ancestor of all reg classes
|
44
|
+
module Reg
|
45
|
+
|
46
|
+
#=== must be defined in the includer for the appropriate types
|
47
|
+
#and some others:
|
48
|
+
#itemrange
|
49
|
+
#scalar?, vector?, multiple?, variable?, multilength?, fixed?
|
50
|
+
#starts_with
|
51
|
+
#ends_with
|
52
|
+
#breakdown
|
53
|
+
#what else?
|
54
|
+
|
55
|
+
#--------------------------
|
56
|
+
def =~(other)
|
57
|
+
self===other
|
58
|
+
end
|
59
|
+
|
60
|
+
#--------------------------
|
61
|
+
#low-precedence method call
|
62
|
+
def <=>(other)
|
63
|
+
send other
|
64
|
+
end
|
65
|
+
|
66
|
+
#--------------------------
|
67
|
+
alias pristine_inspect inspect
|
68
|
+
def pp_inspect
|
69
|
+
pp pristine_inspect
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
#--------------------------
|
74
|
+
#makes a Reg object literal (aliased to +@ by default)
|
75
|
+
def lit
|
76
|
+
Literal.new(self)
|
77
|
+
end
|
78
|
+
def +@; lit end
|
79
|
+
|
80
|
+
#--------------------------
|
81
|
+
#makes a version of self suitable for use in Reg matching
|
82
|
+
#expressions. in subclasses of Reg this just returns self.
|
83
|
+
def reg; self end
|
84
|
+
|
85
|
+
#--------------------------
|
86
|
+
#returns a (vector) Reg that will match a list of self
|
87
|
+
#separated by other. watch out if other and self might
|
88
|
+
#match the same thing(s).
|
89
|
+
def sep other; -[self,-[other,self]+0]; end
|
90
|
+
|
91
|
+
#--------------------------
|
92
|
+
#returns a (vector) Reg that will match a list of stuff
|
93
|
+
#separated by self. somewhat analogous to Regexp#split,
|
94
|
+
#but returns the separators as well.
|
95
|
+
def splitter; (~self+0).sep self; end
|
96
|
+
|
97
|
+
#--------------------------
|
98
|
+
#set a breakpoint when matches against a Reg
|
99
|
+
#are made. of dubious value to those unfamiliar
|
100
|
+
#with Reg::Array source code.
|
101
|
+
def bp #:nodoc: all
|
102
|
+
class <<self #:nodoc:
|
103
|
+
alias_method :unbroken___eee, :=== #:nodoc:
|
104
|
+
alias_method :unbroken___mmatch,
|
105
|
+
method_defined?(:mmatch) ? :mmatch : :fail #:nodoc:
|
106
|
+
def ===(other) #:nodoc:
|
107
|
+
defined? DEBUGGER__ and Process.kill("INT",0)
|
108
|
+
unbroken___eee other
|
109
|
+
end
|
110
|
+
|
111
|
+
def mmatch(arr,start) #:nodoc:
|
112
|
+
defined? DEBUGGER__ and Process.kill("INT",0)
|
113
|
+
unbroken___mmatch arr,start
|
114
|
+
end
|
115
|
+
end
|
116
|
+
self
|
117
|
+
end
|
118
|
+
|
119
|
+
#--------------------------
|
120
|
+
#return a list of sub Regs of this Reg (if any)
|
121
|
+
def subregs
|
122
|
+
[]
|
123
|
+
end
|
124
|
+
|
125
|
+
#--------------------------
|
126
|
+
#a simple reg that always starts this reg
|
127
|
+
def starts_with
|
128
|
+
self
|
129
|
+
end
|
130
|
+
|
131
|
+
#--------------------------
|
132
|
+
#a simple reg that always ends this reg
|
133
|
+
def ends_with
|
134
|
+
self
|
135
|
+
end
|
136
|
+
|
137
|
+
#--------------------------
|
138
|
+
def Reg.interesting_matcher?(mat) #a hack
|
139
|
+
case mat
|
140
|
+
when ItemThatLike,BackrefLike,Module,Set,Regexp,Range,::Reg::Reg: true
|
141
|
+
#when Symbol,Pathname: false
|
142
|
+
else
|
143
|
+
/^#<UnboundMethod: .*\(Kernel\)#===>$/===mat.method(:===).unbind.inspect and return false
|
144
|
+
|
145
|
+
eee_call=nil
|
146
|
+
result=!trace(proc do|event,*stuff|
|
147
|
+
if /call$/===event
|
148
|
+
eee_call=stuff
|
149
|
+
|
150
|
+
#attempt to remain debuggable while restoring the old trace func
|
151
|
+
set_trace_func((defined? DEBUGGER__ and (DEBUGGER__.context.method:trace_func).to_proc))
|
152
|
+
end
|
153
|
+
end){mat===mat}; line=__LINE__
|
154
|
+
assert eee_call[0] == __FILE__
|
155
|
+
assert eee_call[1] == line
|
156
|
+
assert eee_call[2] == :===
|
157
|
+
assert eee_call[3].class == Binding
|
158
|
+
assert Module===eee_call[4].class
|
159
|
+
return eee_call[4]!=Kernel && result
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
#--------------------------
|
164
|
+
def interesting_matcher?(mat=self)
|
165
|
+
Reg.interesting_matcher? mat
|
166
|
+
end
|
167
|
+
|
168
|
+
#--------------------------
|
169
|
+
#*,+,- are defined in regarray.rb
|
170
|
+
#~,&,|,^ are defined in reglogic.rb
|
171
|
+
#** is in reghash.rb
|
172
|
+
#<< and side_effect,undo in regbind.rb
|
173
|
+
#>> and later in regreplace.rb
|
174
|
+
#la,lb in reglookab.rb
|
175
|
+
|
176
|
+
|
177
|
+
|
178
|
+
#--------------------------
|
179
|
+
=begin seems risky... disabled til I know why i want it
|
180
|
+
def coerce(other)
|
181
|
+
if Reg===other
|
182
|
+
[other,self]
|
183
|
+
else
|
184
|
+
[other.reg,self]
|
185
|
+
end
|
186
|
+
end
|
187
|
+
=end
|
188
|
+
#--------------------------
|
189
|
+
def mmatch(ary,idx)
|
190
|
+
assert idx<=ary.size
|
191
|
+
idx==ary.size and return nil
|
192
|
+
self===ary[idx] and [[[ary[idx]]],1]
|
193
|
+
end
|
194
|
+
|
195
|
+
protected
|
196
|
+
#--------------------------
|
197
|
+
def maybe_multiples(*regs)
|
198
|
+
regs.each{|reg|
|
199
|
+
reg.respond_to? :maybe_multiple and
|
200
|
+
reg.maybe_multiple(self)
|
201
|
+
}
|
202
|
+
end
|
203
|
+
|
204
|
+
#--------------------------
|
205
|
+
|
206
|
+
#eventually, this will be a list of all tla mappings
|
207
|
+
RegMethods=proc do
|
208
|
+
@@TLAs={}
|
209
|
+
define_method :assign_TLA do |*args|
|
210
|
+
hash=args.pop #extract hash from args
|
211
|
+
noconst,*bogus=*args #peel noconst off front of args
|
212
|
+
hash.each{|k,v|
|
213
|
+
v=@@TLAs[k]= noconst ? [v,true] : v #fold noconst into v (longname) and store in @@TLAs
|
214
|
+
TLA_aliases k,v #always alias the TLA into ::Reg namespace
|
215
|
+
}
|
216
|
+
end
|
217
|
+
|
218
|
+
|
219
|
+
alias_method :assign_TLAs, :assign_TLA
|
220
|
+
|
221
|
+
define_method :TLA_aliases do |short,long_args,*rest| myself=rest.first||::Object
|
222
|
+
long=nil
|
223
|
+
if ::Array===long_args
|
224
|
+
long=long_args.shift
|
225
|
+
noconst=long_args.shift #unfold noconst from long if folded
|
226
|
+
else
|
227
|
+
long=long_args
|
228
|
+
end
|
229
|
+
myself.const_set(short,::Reg::const_get(long)) unless noconst #alias the constant name
|
230
|
+
|
231
|
+
long=(::Reg.const_get long) #convert long from symbol to a module or class
|
232
|
+
myself.send:define_method, short do|*args| long.new( *args) end #forward short name to long
|
233
|
+
end
|
234
|
+
end
|
235
|
+
def self.included(mod)
|
236
|
+
(class<<mod;self;end).instance_eval( &RegMethods )
|
237
|
+
end
|
238
|
+
|
239
|
+
TLA_pirate= proc { @@TLAs.each{|k,v| Reg.TLA_aliases k,v,self} }
|
240
|
+
|
241
|
+
|
242
|
+
end
|
243
|
+
TLA_pirate= Reg::TLA_pirate
|
244
|
+
#the tlas (and where they're found):
|
245
|
+
|
246
|
+
#Rob,Rah,Rap (reghash.rb)
|
247
|
+
#Reg,Res, (regarray.rb)
|
248
|
+
#Rac, (regcase.rb)
|
249
|
+
#Rip (right here, regcore.rb)-----v
|
250
|
+
|
251
|
+
|
252
|
+
#--------------------------
|
253
|
+
class Wrapper
|
254
|
+
|
255
|
+
include Reg
|
256
|
+
def initialize(o)
|
257
|
+
@o=o
|
258
|
+
end
|
259
|
+
|
260
|
+
def matches_class; @o.class end
|
261
|
+
def lit; @o end
|
262
|
+
alias unwrap lit
|
263
|
+
|
264
|
+
def inspect
|
265
|
+
"(#{@o.inspect}).reg"
|
266
|
+
end
|
267
|
+
|
268
|
+
def ===x; raise NoMethodError.new( "Reg::Wrapper") end
|
269
|
+
|
270
|
+
end
|
271
|
+
|
272
|
+
|
273
|
+
#--------------------------
|
274
|
+
class Fixed < Wrapper #matches like a plain object, but responds to Reg#|, etc
|
275
|
+
#but still behaves in a match just like the unadorned obj (uses === to match)
|
276
|
+
def ===(other)
|
277
|
+
@o===other
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
|
282
|
+
#--------------------------
|
283
|
+
class Equals < Wrapper #like Reg::Fixed, but == instead of ===
|
284
|
+
def ===(other)
|
285
|
+
@o==other
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
#--------------------------
|
290
|
+
class Literal < Equals #a literalized Reg
|
291
|
+
def reg; @o end
|
292
|
+
def lit; Literal.new self end
|
293
|
+
def unlit; @o end
|
294
|
+
|
295
|
+
def formula_value(*ctx)
|
296
|
+
@o
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
#--------------------------
|
301
|
+
class ::Object
|
302
|
+
#turns any object into a matcher which matches the same
|
303
|
+
#thing that the object matches, except it's also a Reg::Reg,
|
304
|
+
#and thus respects reg's meanings of: +,*,>>,&,~, etc
|
305
|
+
#the generic case creates a wrapper Reg around any object whose ===
|
306
|
+
#forwards to the wrapped object's ===. the original object is
|
307
|
+
#unchanged.
|
308
|
+
def reg
|
309
|
+
Fixed.new(self)
|
310
|
+
end
|
311
|
+
|
312
|
+
#
|
313
|
+
def lit
|
314
|
+
self
|
315
|
+
end
|
316
|
+
|
317
|
+
#just like ===, but receiver and argument are switched.
|
318
|
+
#for those situations where you just have to put the item
|
319
|
+
#to match to the left, and the pattern on the right.
|
320
|
+
def matches pattern
|
321
|
+
pattern===self
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
#--------------------------
|
326
|
+
String=::Regexp
|
327
|
+
|
328
|
+
#--------------------------
|
329
|
+
class Symbol
|
330
|
+
include Reg
|
331
|
+
|
332
|
+
def initialize(rex)
|
333
|
+
@rex=rex
|
334
|
+
end
|
335
|
+
|
336
|
+
def matches_class; ::Symbol end
|
337
|
+
|
338
|
+
def ===(other)
|
339
|
+
::Symbol===other and m=@rex.match(other.to_s) and m[0]
|
340
|
+
end
|
341
|
+
|
342
|
+
def inspect
|
343
|
+
@rex.inspect+'.sym'
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
#a dynamically created Reg
|
348
|
+
def (::Reg).regproc klass=::Object,&block
|
349
|
+
class <<block
|
350
|
+
include Interpret
|
351
|
+
end
|
352
|
+
block.klass=klass
|
353
|
+
block
|
354
|
+
end
|
355
|
+
|
356
|
+
|
357
|
+
|
358
|
+
#--------------------------
|
359
|
+
module Interpret #a Reg whose makeup isn't determined until runtime.
|
360
|
+
include Reg
|
361
|
+
def klass=(k) @@klass=k end
|
362
|
+
def ===(other)
|
363
|
+
@@klass===other || return
|
364
|
+
r=call
|
365
|
+
#eventually pass params to call
|
366
|
+
Reg::Multiple===r and raise 'this oughtta work, but doesn`t yet'
|
367
|
+
r===other
|
368
|
+
end
|
369
|
+
def matches_class; @@klass end
|
370
|
+
alias starts_with matches_class
|
371
|
+
alias ends_with matches_class
|
372
|
+
|
373
|
+
|
374
|
+
assign_TLA true, :Rip=>:Interpret
|
375
|
+
end
|
376
|
+
|
377
|
+
|
378
|
+
|
379
|
+
end
|