From 2cbd7076eced17eb0213febb9400f2ba91e4edf1 Mon Sep 17 00:00:00 2001 From: GearsDatapacks Date: Mon, 1 Sep 2025 18:31:50 +0100 Subject: [PATCH] Use new splitter functions to improve performance --- gleam.toml | 2 +- manifest.toml | 4 ++-- src/just.gleam | 47 +++++++++++++++++++++++++---------------------- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/gleam.toml b/gleam.toml index 15ded3b..fac108a 100644 --- a/gleam.toml +++ b/gleam.toml @@ -10,7 +10,7 @@ links = [] gleam_stdlib = ">= 0.44.0 and < 2.0.0" gleam_community_ansi = ">= 1.4.3 and < 2.0.0" houdini = ">= 1.1.0 and < 2.0.0" -splitter = ">= 1.0.0 and < 2.0.0" +splitter = ">= 1.1.0 and < 2.0.0" [dev-dependencies] gleeunit = ">= 1.0.0 and < 2.0.0" diff --git a/manifest.toml b/manifest.toml index c395cbf..d74663a 100644 --- a/manifest.toml +++ b/manifest.toml @@ -19,7 +19,7 @@ packages = [ { name = "justin", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "justin", source = "hex", outer_checksum = "7FA0C6DB78640C6DC5FBFD59BF3456009F3F8B485BF6825E97E1EB44E9A1E2CD" }, { name = "rank", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "rank", source = "hex", outer_checksum = "5660E361F0E49CBB714CC57CC4C89C63415D8986F05B2DA0C719D5642FAD91C9" }, { name = "simplifile", version = "2.2.1", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "C88E0EE2D509F6D86EB55161D631657675AA7684DAB83822F7E59EB93D9A60E3" }, - { name = "splitter", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "splitter", source = "hex", outer_checksum = "128FC521EE33B0012E3E64D5B55168586BC1B9C8D7B0D0CA223B68B0D770A547" }, + { name = "splitter", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "splitter", source = "hex", outer_checksum = "05564A381580395DCDEFF4F88A64B021E8DAFA6540AE99B4623962F52976AA9D" }, { name = "term_size", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "term_size", source = "hex", outer_checksum = "D00BD2BC8FB3EBB7E6AE076F3F1FF2AC9D5ED1805F004D0896C784D06C6645F1" }, { name = "trie_again", version = "1.1.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "trie_again", source = "hex", outer_checksum = "5B19176F52B1BD98831B57FDC97BD1F88C8A403D6D8C63471407E78598E27184" }, ] @@ -31,4 +31,4 @@ gleam_stdlib = { version = ">= 0.44.0 and < 2.0.0" } gleeunit = { version = ">= 1.0.0 and < 2.0.0" } houdini = { version = ">= 1.1.0 and < 2.0.0" } simplifile = { version = ">= 2.2.1 and < 3.0.0" } -splitter = { version = ">= 1.0.0 and < 2.0.0" } +splitter = { version = ">= 1.1.0 and < 2.0.0" } diff --git a/src/just.gleam b/src/just.gleam index 6975997..831ef8a 100644 --- a/src/just.gleam +++ b/src/just.gleam @@ -1068,20 +1068,15 @@ fn ensure_no_letters_after_numbers(lexer: Lexer) -> Lexer { } fn lex_string(lexer: Lexer, quote: String, contents: String) -> #(Lexer, Token) { - let #(before, split, after) = - splitter.split(lexer.splitters.string, lexer.source) - case split { - "" -> #( + let #(before, after) = + splitter.split_before(lexer.splitters.string, lexer.source) + case after { + "\r" <> _rest | "\n" <> _rest -> #( error(advance(lexer, after), UnterminatedStringLiteral), UnterminatedString(quote:, contents: contents <> before), ) - "\r" | "\n" -> #( - error(advance(lexer, split <> after), UnterminatedStringLiteral), - UnterminatedString(quote:, contents: contents <> before), - ) - - "\\" -> + "\\" <> after -> case string.pop_grapheme(after) { Error(_) -> #( error(advance(lexer, after), UnterminatedStringLiteral), @@ -1095,7 +1090,7 @@ fn lex_string(lexer: Lexer, quote: String, contents: String) -> #(Lexer, Token) ) } - _ if split == quote -> #( + "\"" as split <> after | "'" as split <> after if split == quote -> #( advance(lexer, after), String(quote:, contents: contents <> before), ) @@ -1103,7 +1098,13 @@ fn lex_string(lexer: Lexer, quote: String, contents: String) -> #(Lexer, Token) // Here, we've split on a quote which doesn't match the current string. // In this case, we must continue lexing until we find a quote of the // correct kind. - _ -> lex_string(advance(lexer, after), quote, contents <> before <> split) + "\"" as split <> after | "'" as split <> after -> + lex_string(advance(lexer, after), quote, contents <> before <> split) + + _ -> #( + error(advance(lexer, after), UnterminatedStringLiteral), + UnterminatedString(quote:, contents: contents <> before), + ) } } @@ -1211,17 +1212,19 @@ fn lex_regex(lexer: Lexer, lexed: String, in_group: Bool) -> #(Lexer, Token) { gleam.False -> lexer.splitters.regex_regular gleam.True -> lexer.splitters.regex_in_group } - let #(before, split, after) = splitter.split(splitter, lexer.source) - case split { - "/" -> { + let #(before, after) = splitter.split_before(splitter, lexer.source) + case after { + "/" <> after -> { let lexer = advance(lexer, after) let #(lexer, flags) = lex_identifier(lexer, "") #(lexer, RegularExpression(contents: lexed <> before, flags:)) } - "[" -> lex_regex(advance(lexer, after), lexed <> before <> "[", gleam.True) - "]" -> lex_regex(advance(lexer, after), lexed <> before <> "]", gleam.False) + "[" <> after -> + lex_regex(advance(lexer, after), lexed <> before <> "[", gleam.True) + "]" <> after -> + lex_regex(advance(lexer, after), lexed <> before <> "]", gleam.False) - "\\" -> + "\\" <> after -> case string.pop_grapheme(after) { Error(_) -> #( error(advance(lexer, after), UnterminatedRegExpLiteral), @@ -1236,7 +1239,7 @@ fn lex_regex(lexer: Lexer, lexed: String, in_group: Bool) -> #(Lexer, Token) { } _ -> #( - error(advance(lexer, split <> after), UnterminatedRegExpLiteral), + error(advance(lexer, after), UnterminatedRegExpLiteral), UnterminatedRegularExpression(lexed <> before), ) } @@ -1347,9 +1350,9 @@ fn whitespace(lexer: Lexer, lexed: String) -> #(Lexer, Token) { } fn lex_until_end_of_line(lexer: Lexer) -> #(Lexer, String) { - let #(before, split, after) = - splitter.split(lexer.splitters.until_end_of_line, lexer.source) - #(advance(lexer, split <> after), before) + let #(before, after) = + splitter.split_before(lexer.splitters.until_end_of_line, lexer.source) + #(advance(lexer, after), before) } fn advance(lexer: Lexer, source: String) -> Lexer { -- 2.51.2