Skip to content

Commit 4fcd8bb

Browse files
KristofferCtecosaur
authored andcommitted
Use const fields in parser State instead of refs
This avoids using the (technically) internal RefValue, and so the need to use [] for access. It may also perform slightly better, not that this is a performance-critical area of the codebase, but why not.
1 parent 35a3cdf commit 4fcd8bb

File tree

1 file changed

+54
-54
lines changed

1 file changed

+54
-54
lines changed

src/styledmarkup.jl

Lines changed: 54 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -77,31 +77,31 @@ Its fields are as follows:
7777
- `pending_styles::Vector{Tuple{UnitRange{Int}, Union{Symbol, Expr, Pair{Symbol, Any}}}}`,
7878
A list of styles that have been terminated, and so are known to occur over a certain range,
7979
but have yet to be applied.
80-
- `offset::RefValue{Int}`, a record of the between the `content` index and the index in the resulting
80+
- `offset::Int`, a record of the between the `content` index and the index in the resulting
8181
styled string, as markup structures are absorbed.
82-
- `point::RefValue{Int}`, the current index in `content`.
83-
- `escape::RefValue{Bool}`, whether the last character seen was an escape character.
84-
- `interpolated::RefValue{Bool}`, whether any interpolated values have been seen. Knowing whether or not
82+
- `point::Int`, the current index in `content`.
83+
- `escape::Bool`, whether the last character seen was an escape character.
84+
- `interpolated::Bool`, whether any interpolated values have been seen. Knowing whether or not
8585
anything needs to be evaluated allows the resulting string to be computed at macroexpansion time,
8686
when possible.
8787
- `errors::Vector`, any errors raised during parsing. We collect them instead of immediately throwing
8888
so that we can list as many issues as possible at once, instead of forcing the author of the invalid
8989
styled markup to resolve each issue one at a time. This is expected to be populated by invocations of
9090
`styerr!`.
9191
"""
92-
struct State
93-
content::String
94-
bytes::Vector{UInt8}
95-
s::Iterators.Stateful
96-
mod::Union{Module, Nothing}
97-
parts::Vector{Any}
98-
active_styles::Vector{Vector{Tuple{Int, Int, Union{Symbol, Expr, Pair{Symbol, Any}}}}}
99-
pending_styles::Vector{Tuple{UnitRange{Int}, Union{Symbol, Expr, Pair{Symbol, Any}}}}
100-
offset::Base.RefValue{Int}
101-
point::Base.RefValue{Int}
102-
escape::Base.RefValue{Bool}
103-
interpolated::Base.RefValue{Bool}
104-
errors::Vector
92+
mutable struct State
93+
const content::String
94+
const bytes::Vector{UInt8}
95+
const s::Iterators.Stateful
96+
const mod::Union{Module, Nothing}
97+
const parts::Vector{Any}
98+
const active_styles::Vector{Vector{Tuple{Int, Int, Union{Symbol, Expr, Pair{Symbol, Any}}}}}
99+
const pending_styles::Vector{Tuple{UnitRange{Int}, Union{Symbol, Expr, Pair{Symbol, Any}}}}
100+
offset::Int
101+
point::Int
102+
escape::Bool
103+
interpolated::Bool
104+
const errors::Vector
105105
end
106106

107107
function State(content::AbstractString, mod::Union{Module, Nothing}=nothing)
@@ -110,8 +110,8 @@ function State(content::AbstractString, mod::Union{Module, Nothing}=nothing)
110110
Any[], # parts
111111
Vector{Tuple{Int, Int, Union{Symbol, Expr, Pair{Symbol, Any}}}}[], # active_styles
112112
Tuple{UnitRange{Int}, Union{Symbol, Expr, Pair{Symbol, Any}}}[], # pending_styles
113-
Ref(0), Ref(1), # offset, point
114-
Ref(false), Ref(false), # escape, interpolated
113+
0, 1, # offset, point
114+
false, false, # escape, interpolated
115115
NamedTuple{(:message, :position, :hint), # errors
116116
Tuple{AnnotatedString{String}, <:Union{Int, Nothing}, String}}[])
117117
end
@@ -192,11 +192,11 @@ This consumes all the content between `state.point` and `stop`, and shifts
192192
`state.point` to be the index after `stop`.
193193
"""
194194
function addpart!(state::State, stop::Int)
195-
if state.point[] > stop+state.offset[]+ncodeunits(state.content[stop])-1
196-
return state.point[] = nextind(state.content, stop) + state.offset[]
195+
if state.point > stop+state.offset+ncodeunits(state.content[stop])-1
196+
return state.point = nextind(state.content, stop) + state.offset
197197
end
198198
str = String(state.bytes[
199-
state.point[]:stop+state.offset[]+ncodeunits(state.content[stop])-1])
199+
state.point:stop+state.offset+ncodeunits(state.content[stop])-1])
200200
sty_type, tupl = if ismacro(state)
201201
Expr, (a, b) -> Expr(:tuple, a, b)
202202
else
@@ -210,15 +210,15 @@ function addpart!(state::State, stop::Int)
210210
sort!(state.pending_styles, by = (r -> (first(r), -last(r))) first) # Prioritise the most specific styles
211211
for (range, annot) in state.pending_styles
212212
if !isempty(range)
213-
push!(styles, tupl(range .- state.point[], annot))
213+
push!(styles, tupl(range .- state.point, annot))
214214
end
215215
end
216216
empty!(state.pending_styles)
217217
relevant_styles = Iterators.filter(
218-
(_, start, _)::Tuple -> start <= stop + state.offset[] + 1,
218+
(_, start, _)::Tuple -> start <= stop + state.offset + 1,
219219
Iterators.flatten(map(reverse, state.active_styles)))
220220
for (_, start, annot) in relevant_styles
221-
range = (start - state.point[]):(stop - state.point[] + state.offset[] + 1)
221+
range = (start - state.point):(stop - state.point + state.offset + 1)
222222
push!(styles, tupl(range, annot))
223223
end
224224
if isempty(styles)
@@ -229,7 +229,7 @@ function addpart!(state::State, stop::Int)
229229
:(AnnotatedString($str, $(Expr(:vect, styles...))))
230230
end
231231
end)
232-
state.point[] = nextind(state.content, stop) + state.offset[]
232+
state.point = nextind(state.content, stop) + state.offset
233233
end
234234

235235
"""
@@ -239,7 +239,7 @@ Create a new part based on (the eventual evaluation of) `expr`, running from
239239
`start` to `stop`, taking the currently active styles into account.
240240
"""
241241
function addpart!(state::State, start::Int, expr, stop::Int)
242-
if state.point[] < start
242+
if state.point < start
243243
addpart!(state, start)
244244
end
245245
if isempty(state.active_styles)
@@ -270,7 +270,7 @@ function addpart!(state::State, start::Int, expr, stop::Int)
270270
end
271271
end))
272272
end
273-
map!.((i, _, annot)::Tuple -> (i, stop + state.offset[] + 1, annot),
273+
map!.((i, _, annot)::Tuple -> (i, stop + state.offset + 1, annot),
274274
state.active_styles, state.active_styles)
275275
end
276276
end
@@ -282,8 +282,8 @@ Parse the escaped character `char`, at index `i`, into `state`
282282
"""
283283
function escaped!(state::State, i::Int, char::Char)
284284
if char in ('{', '}', '\\') || (char == '$' && ismacro(state))
285-
deleteat!(state.bytes, i + state.offset[] - 1)
286-
state.offset[] -= ncodeunits('\\')
285+
deleteat!(state.bytes, i + state.offset - 1)
286+
state.offset -= ncodeunits('\\')
287287
elseif char ('\n', '\r') && !isempty(state.s)
288288
skipped = 0
289289
if char == '\r' && isnextchar(state, '\n')
@@ -294,10 +294,10 @@ function escaped!(state::State, i::Int, char::Char)
294294
popfirst!(state.s)
295295
skipped += 1
296296
end
297-
deleteat!(state.bytes, i+state.offset[]-1:i+skipped+state.offset[])
298-
state.offset[] -= skipped + ncodeunits("\\\n")
297+
deleteat!(state.bytes, i+state.offset-1:i+skipped+state.offset)
298+
state.offset -= skipped + ncodeunits("\\\n")
299299
end
300-
state.escape[] = false
300+
state.escape = false
301301
end
302302

303303
"""
@@ -307,11 +307,11 @@ Interpolate the expression starting at `i`, and add it as a part to `state`.
307307
"""
308308
function interpolated!(state::State, i::Int, _)
309309
expr, nexti = readexpr!(state, i + ncodeunits('$'))
310-
deleteat!(state.bytes, i + state.offset[])
311-
state.offset[] -= ncodeunits('$')
310+
deleteat!(state.bytes, i + state.offset)
311+
state.offset -= ncodeunits('$')
312312
addpart!(state, i, esc(expr), nexti)
313-
state.point[] = nexti + state.offset[]
314-
state.interpolated[] = true
313+
state.point = nexti + state.offset
314+
state.interpolated = true
315315
end
316316

317317
"""
@@ -408,8 +408,8 @@ function begin_style!(state::State, i::Int, char::Char)
408408
# style declaration(s).
409409
if !isempty(state.s)
410410
nexti = first(peek(state.s))
411-
deleteat!(state.bytes, i+state.offset[]:nexti+state.offset[]-1)
412-
state.offset[] -= nexti - i
411+
deleteat!(state.bytes, i+state.offset:nexti+state.offset-1)
412+
state.offset -= nexti - i
413413
end
414414
end
415415

@@ -420,10 +420,10 @@ Close of the most recent active style in `state`, making it a pending style.
420420
"""
421421
function end_style!(state::State, i::Int, char::Char)
422422
for (_, start, annot) in pop!(state.active_styles)
423-
pushfirst!(state.pending_styles, (start:i+state.offset[], annot))
423+
pushfirst!(state.pending_styles, (start:i+state.offset, annot))
424424
end
425-
deleteat!(state.bytes, i + state.offset[])
426-
state.offset[] -= ncodeunits('}')
425+
deleteat!(state.bytes, i + state.offset)
426+
state.offset -= ncodeunits('}')
427427
end
428428

429429
"""
@@ -511,7 +511,7 @@ function read_inlineface!(state::State, i::Int, char::Char, newstyles)
511511
elseif isnextchar(state, '$') && ismacro(state)
512512
expr, _ = readexpr!(state)
513513
lastchar = last(popfirst!(state.s))
514-
state.interpolated[] = true
514+
state.interpolated = true
515515
needseval = true
516516
esc(expr)
517517
else
@@ -525,7 +525,7 @@ function read_inlineface!(state::State, i::Int, char::Char, newstyles)
525525
if isnextchar(state, '$') && ismacro(state)
526526
expr, _ = readexpr!(state)
527527
lastchar = last(popfirst!(state.s))
528-
state.interpolated[] = true
528+
state.interpolated = true
529529
needseval = true
530530
ustyle = esc(expr)
531531
else
@@ -639,7 +639,7 @@ function read_inlineface!(state::State, i::Int, char::Char, newstyles)
639639
val = if ismacro(state) && isnextchar(state, '$')
640640
expr, _ = readexpr!(state)
641641
lastchar = last(popfirst!(state.s))
642-
state.interpolated[] = true
642+
state.interpolated = true
643643
needseval = true
644644
esc(expr)
645645
elseif key == :font
@@ -724,7 +724,7 @@ function read_inlineface!(state::State, i::Int, char::Char, newstyles)
724724
end
725725
face = Expr(:call, Face, kwargs...)
726726
push!(newstyles,
727-
(i, i + state.offset[] + 1,
727+
(i, i + state.offset + 1,
728728
if !ismacro(state)
729729
Pair{Symbol, Any}(:face, Face(; NamedTuple(kwargs)...))
730730
elseif needseval
@@ -766,7 +766,7 @@ function read_face_or_keyval!(state::State, i::Int, char::Char, newstyles)
766766
# this isn't the 'last' char yet, but it will be
767767
key = if ismacro(state) && last(peek(state.s)) == '$'
768768
expr, _ = readexpr!(state)
769-
state.interpolated[] = true
769+
state.interpolated = true
770770
needseval = true
771771
esc(expr)
772772
else
@@ -788,7 +788,7 @@ function read_face_or_keyval!(state::State, i::Int, char::Char, newstyles)
788788
read_curlywrapped!(state)
789789
elseif ismacro(state) && nextchar == '$'
790790
expr, _ = readexpr!(state)
791-
state.interpolated[] = true
791+
state.interpolated = true
792792
needseval = true
793793
esc(expr)
794794
else
@@ -800,7 +800,7 @@ function read_face_or_keyval!(state::State, i::Int, char::Char, newstyles)
800800
String(chars)
801801
end
802802
push!(newstyles,
803-
(i, i + state.offset[] + ncodeunits('{'),
803+
(i, i + state.offset + ncodeunits('{'),
804804
if key isa String && !(value isa Symbol || value isa Expr)
805805
Pair{Symbol, Any}(Symbol(key), value)
806806
elseif key isa Expr || key isa Symbol
@@ -811,7 +811,7 @@ function read_face_or_keyval!(state::State, i::Int, char::Char, newstyles)
811811
end))
812812
elseif key !== ""
813813
push!(newstyles,
814-
(i, i + state.offset[] + ncodeunits('{'),
814+
(i, i + state.offset + ncodeunits('{'),
815815
if key isa Symbol || key isa Expr
816816
:(Pair{Symbol, Any}(:face, $key))
817817
else # Face symbol
@@ -836,8 +836,8 @@ function run_state_machine!(state::State)
836836
# Run the state machine
837837
for (i, char) in state.s
838838
if char == '\\'
839-
state.escape[] = true
840-
elseif state.escape[]
839+
state.escape = true
840+
elseif state.escape
841841
escaped!(state, i, char)
842842
elseif ismacro(state) && char == '$'
843843
interpolated!(state, i, char)
@@ -852,7 +852,7 @@ function run_state_machine!(state::State)
852852
end
853853
end
854854
# Ensure that any trailing unstyled content is added
855-
if state.point[] <= lastindex(state.content) + state.offset[]
855+
if state.point <= lastindex(state.content) + state.offset
856856
addpart!(state, lastindex(state.content))
857857
end
858858
for incomplete in Iterators.flatten(state.active_styles)
@@ -988,7 +988,7 @@ macro styled_str(raw_content::String)
988988
run_state_machine!(state)
989989
if !isempty(state.errors)
990990
throw(MalformedStylingMacro(state.content, state.errors))
991-
elseif state.interpolated[]
991+
elseif state.interpolated
992992
:(annotatedstring($(state.parts...)) |> annotatedstring_optimize!)
993993
else
994994
annotatedstring(map(Base.Fix1(hygienic_eval, state), state.parts)...) |> annotatedstring_optimize!

0 commit comments

Comments
 (0)