2 .namespace [ 'TclConst' ]
10 Define the attributes required for the class.
14 .sub __class_init :anon :load
15 $P0 = get_class 'String'
16 $P1 = subclass $P0, 'TclConst'
27 # RT#40640: These should probably be moved into a class attribute.
28 set_root_global ['_tcl'], 'backslashes', $P0
54 set_root_global ['_tcl'], 'hexadecimal', $P0
58 .sub set_string_native :vtable :method
61 .local int value_length
63 .local pmc backslashes, hexadecimal
64 backslashes = get_root_global ['_tcl'], 'backslashes'
65 hexadecimal = get_root_global ['_tcl'], 'hexadecimal'
70 value_length = length value
71 pos = index value, '\', pos
72 if pos == -1 goto done
76 if $I0 == 120 goto hex # x
77 if $I0 == 117 goto unicode # u
78 if $I0 < 48 goto simple # < 0
79 if $I0 <= 55 goto octal # 0..7
82 $I1 = exists backslashes[$I0]
85 substr value, pos, 1, ''
91 Octal escapes consist of one, two, or three octal digits
95 .local int octal_value
99 # at this point, $I0 contains the value of the first digit,
100 # but pos is still at the backslash.
102 digit = $I0 - 48 # ascii value of 0.
106 if $I0 >= value_length goto octal_only1
110 if $I0 < 48 goto octal_only1 # < 0
111 if $I0 <= 55 goto octal2 # 0..7
114 $S0 = chr octal_value
115 substr value, pos, 2, $S0
121 # at this point, $I0 contains the value of the second digit,
122 # but octal_pos is still at the first digit.
123 inc octal_pos # skip first digit
124 digit = $I0 - 48 # ascii value of 0.
130 if $I0 >= value_length goto octal_only2
133 if $I0 < 48 goto octal_only2 # < 0
134 if $I0 <= 55 goto octal3 # 0..7
137 $S0 = chr octal_value
138 substr value, pos, 3, $S0
144 # at this point, $I0 contains the value of the third digit
145 digit = $I0 - 48 # ascii value of 0.
150 $S0 = chr octal_value
151 substr value, pos, 4, $S0
154 goto loop # can't have four digits, stop now.
158 Hexadecimal escapes consist of an C<x>, followed by any number of hexadecimal
159 digits. However, only the last two are used.
163 .local int hex_pos, hex_digit, hex_value
165 # at this point, pos is set to the backslash
167 hex_pos = pos + 2 # skip the backslash and the x
170 if hex_pos >= value_length goto hex_done
171 $I0 = ord value, hex_pos
172 $I1 = exists hexadecimal[$I0]
173 unless $I1 goto hex_done
174 hex_digit = hexadecimal[$I0]
175 band hex_value, 15 # high byte discarded
176 hex_value *= 16 # low byte promoted
177 hex_value += hex_digit # new low byte added.
185 if $I0 == 2 goto hex_not_really
187 substr value, pos, $I0, $S0
194 # This was a \x escape that had no hex value..
195 substr value, pos, 2, 'x'
201 Unicode escapes consist of an C<u>, followed by one to four hexadecimal digits.
205 .local int uni_pos, uni_digit, uni_value, uni_digit_count
207 # at this point, pos is set to the backslash
210 uni_pos = pos + 2 # skip the backslash and the u
213 if uni_digit_count == 4 goto uni_done #only four digits allowed
214 if uni_pos >= value_length goto uni_done
215 $I0 = ord value, uni_pos
216 $I1 = exists hexadecimal[$I0]
217 unless $I1 goto uni_done
218 uni_digit = hexadecimal[$I0]
219 uni_value *= 16 # low byte promoted
220 uni_value += uni_digit # new low byte added.
229 if $I0 == 2 goto uni_not_really
231 substr value, pos, $I0, $S0
237 # This was a \u escape that had no uni value..
238 substr value, pos, 2, 'u'
243 $S0 = backslashes[$I0]
244 substr value, pos, 2, $S0
249 # Finally, delegate to our parent's set_string
250 $P0 = getattribute self, ['String'], 'proxy'
256 Generate PIR code which can be used to generate our value
264 compiler = get_root_global ['_tcl'], 'compile_dispatch'
266 .return compiler(argnum, self)
271 This method enables Data::Dumper to work on us; shouldn't need it, because
272 we're subclassing String...
276 .sub '__dump' :method
287 # vim: expandtab shiftwidth=4 ft=pir: