Skip to content

Commit da42098

Browse files
authored
introduce LexerStateSimple (#27)
It's not a nice interface but I can't think of anything better.
1 parent 6d49028 commit da42098

File tree

2 files changed

+39
-9
lines changed

2 files changed

+39
-9
lines changed

src/ParseUnparse.jl

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,7 @@ module ParseUnparse
945945
end
946946
end
947947
module LexingUtil
948-
export TokenIteratorState, token_iterator_state_init, lexer_state_new, lexer_state_get_extra, lexer_state_get_consumed_character_count, lexer_state_destroy!, lexer_state_peek!, lexer_state_consume!
948+
export TokenIteratorState, token_iterator_state_init, lexer_state_simple_new, lexer_state_new, lexer_state_get_extra, lexer_state_get_consumed_character_count, lexer_state_destroy!, lexer_state_peek!, lexer_state_consume!
949949
using ..Optionals
950950
const TokenIteratorStateOpaque = Tuple{
951951
Int64, IOBuffer, Optional{Character}, OptionalCharacterIteratorState,
@@ -964,6 +964,30 @@ module ParseUnparse
964964
opaque,
965965
)
966966
end
967+
mutable struct LexerStateSimple{Character, CharacterIterator, CharacterIteratorState}
968+
optional_most_recently_read_character::Optional{Character}
969+
const character_iterator::CharacterIterator
970+
"""
971+
* If empty, the input is exhausted.
972+
973+
* Assuming the character iterator state type stays the same after each iteration!
974+
"""
975+
optional_character_iterator_state::Optional{CharacterIteratorState}
976+
function LexerStateSimple(oc::AbstractVector, it, os::AbstractVector)
977+
new{eltype(oc), typeof(it), eltype(os)}(oc, it, os)
978+
end
979+
end
980+
function lexer_state_simple_new(character_iterator)
981+
iter = iterate(character_iterator)
982+
if iter === nothing
983+
()
984+
else
985+
ls = let (e, s) = iter
986+
LexerStateSimple(Optional(e), character_iterator, Optional(s))
987+
end
988+
(ls,)
989+
end
990+
end
967991
mutable struct LexerState{Character, CharacterIterator, CharacterIteratorState, Extra}
968992
optional_most_recently_read_character::Optional{Character}
969993
const character_iterator::CharacterIterator
@@ -1005,13 +1029,13 @@ module ParseUnparse
10051029
function lexer_state_get_extra(lexer_state::LexerState)
10061030
lexer_state.extra
10071031
end
1008-
function lexer_state_is_empty(lexer_state::LexerState)
1032+
function lexer_state_is_empty(lexer_state::Union{LexerStateSimple, LexerState})
10091033
isempty(lexer_state.optional_most_recently_read_character)
10101034
end
1011-
function lexer_state_destroy_most_recently_read_character!(lexer_state::LexerState)
1035+
function lexer_state_destroy_most_recently_read_character!(lexer_state::Union{LexerStateSimple, LexerState})
10121036
lexer_state.optional_most_recently_read_character = typeof(lexer_state.optional_most_recently_read_character)()
10131037
end
1014-
function lexer_state_advance!(lexer_state::LexerState)
1038+
function lexer_state_advance!(lexer_state::Union{LexerStateSimple, LexerState})
10151039
optional_state = lexer_state.optional_character_iterator_state
10161040
C = typeof(lexer_state.optional_most_recently_read_character)
10171041
S = typeof(optional_state)
@@ -1024,7 +1048,9 @@ module ParseUnparse
10241048
lexer_state_destroy_most_recently_read_character!(lexer_state)
10251049
lexer_state.optional_character_iterator_state = S()
10261050
else
1027-
lexer_state.read_character_count += true
1051+
if lexer_state isa LexerState
1052+
lexer_state.read_character_count += true
1053+
end
10281054
let (c, s) = iter
10291055
lexer_state.optional_most_recently_read_character = C(c)
10301056
lexer_state.optional_character_iterator_state = S(s)
@@ -1049,21 +1075,21 @@ module ParseUnparse
10491075
token_source = take!(buffer)
10501076
(; opaque, token_source)
10511077
end
1052-
function lexer_state_advance_if_possible!(lexer_state::LexerState)
1078+
function lexer_state_advance_if_possible!(lexer_state::Union{LexerStateSimple, LexerState})
10531079
if lexer_state_is_empty(lexer_state)
10541080
lexer_state_advance!(lexer_state)
10551081
lexer_state_is_empty(lexer_state)
10561082
else
10571083
false
10581084
end
10591085
end
1060-
function lexer_state_peek!(lexer_state::LexerState)
1086+
function lexer_state_peek!(lexer_state::Union{LexerStateSimple, LexerState})
10611087
lexer_state_advance_if_possible!(lexer_state)
10621088
lexer_state.optional_most_recently_read_character
10631089
end
1064-
function lexer_state_consume!(lexer_state::LexerState)
1090+
function lexer_state_consume!(lexer_state::Union{LexerStateSimple, LexerState})
10651091
oc = lexer_state_peek!(lexer_state)
1066-
if !isempty(oc)
1092+
if (lexer_state isa LexerState) && !isempty(oc)
10671093
print(lexer_state.buffer, only(oc))
10681094
end
10691095
lexer_state_destroy_most_recently_read_character!(lexer_state)

test/runtests_lexing_util.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,8 @@ using Test
4747
lexer_state_consume!(ls)
4848
Int64(1) === @inferred lexer_state_get_consumed_character_count(ls)
4949
end
50+
@test () === lexer_state_simple_new("")
51+
@test let (ls,) = lexer_state_simple_new("a")
52+
'a' === only(@inferred lexer_state_peek!(ls))
53+
end
5054
end

0 commit comments

Comments
 (0)