Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
JosephTLyons committed Oct 20, 2024
1 parent f708f69 commit 555d2c4
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 8 deletions.
32 changes: 24 additions & 8 deletions src/lenient_parse/internal/coerce.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import gleam/string
import lenient_parse/internal/tokenizer.{
type Token, DecimalPoint, Digit, Sign, Underscore, Whitespace,
}
import lenient_parse/internal/whitespace_block_tracker.{
type WhitespaceBlockTracker,
}
import parse_error.{
type ParseError, EmptyString, InvalidCharacter, InvalidDecimalPosition,
InvalidSignPosition, InvalidUnderscorePosition, WhitespaceOnlyString,
Expand All @@ -15,6 +18,7 @@ pub type ParseState {
index: Int,
previous: Option(Token),
text_length: Int,
tracker: WhitespaceBlockTracker,
seen_decimal: Bool,
seen_digit: Bool,
acc: String,
Expand All @@ -29,6 +33,7 @@ pub fn coerce_into_valid_number_string(
index: 0,
previous: None,
text_length: text |> string.length,
tracker: whitespace_block_tracker.new(),
seen_decimal: False,
seen_digit: False,
acc: "",
Expand Down Expand Up @@ -84,15 +89,26 @@ fn do_coerce_into_valid_number_string(
}
}

use state <- result.try(parse_result)
let tracker = state.tracker |> whitespace_block_tracker.mark(first)

case state.previous {
Some(previous) if tracker == 0b101 -> {
let previous = previous |> tokenizer.to_result |> result.unwrap_both
Error(InvalidCharacter(previous, state.index - 1))
}
_ -> {
use state <- result.try(parse_result)

State(
..state,
tokens: rest,
previous: Some(first),
index: state.index + 1,
)
|> do_coerce_into_valid_number_string
State(
..state,
tokens: rest,
previous: Some(first),
index: state.index + 1,
tracker: tracker,
)
|> do_coerce_into_valid_number_string
}
}
}
}
}
7 changes: 7 additions & 0 deletions src/lenient_parse/internal/tokenizer.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ pub fn is_digit(token: Token) -> Bool {
}
}

pub fn is_whitespace(token: Token) -> Bool {
case token {
Whitespace(_) -> True
_ -> False
}
}

pub fn to_result(token: Token) -> Result(String, String) {
case token {
DecimalPoint -> Ok(".")
Expand Down
23 changes: 23 additions & 0 deletions src/lenient_parse/internal/whitespace_block_tracker.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import gleam/int
import lenient_parse/internal/tokenizer.{type Token, Whitespace}

// TODO: Better name

pub type WhitespaceBlockTracker =
Int

pub fn new() -> WhitespaceBlockTracker {
0
}

pub fn mark(
tracker: WhitespaceBlockTracker,
token: Token,
) -> WhitespaceBlockTracker {
case token, tracker % 2 == 0 {
Whitespace(_), True -> tracker
Whitespace(_), False -> tracker |> int.bitwise_shift_left(1)
_, True -> { tracker |> int.bitwise_shift_left(1) } + 1
_, False -> tracker
}
}
32 changes: 32 additions & 0 deletions test/whitespace_block_tracker_test.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import gleam/list
import lenient_parse/internal/tokenizer
import lenient_parse/internal/whitespace_block_tracker
import startest/expect

// TODO: Convert to describe-style data-driven tests

pub fn whitespace_block_tracker_test() {
" "
|> build_tracker_int
|> expect.to_equal(0b0)

"123123"
|> build_tracker_int
|> expect.to_equal(0b1)

"1 1 1 1 "
|> build_tracker_int
|> expect.to_equal(0b10101010)

" 12 3.400 "
|> build_tracker_int
|> expect.to_equal(0b1010)
}

fn build_tracker_int(text: String) -> Int {
text
|> tokenizer.tokenize_number_string
|> list.fold(whitespace_block_tracker.new(), fn(tracker, token) {
tracker |> whitespace_block_tracker.mark(token)
})
}

0 comments on commit 555d2c4

Please sign in to comment.