From b9d3a6cc6db335d602a2a49adb4d247e96951d5a Mon Sep 17 00:00:00 2001 From: aquapi Date: Sun, 22 Mar 2026 16:01:24 +0700 Subject: [PATCH 1/3] Token.* micro-optimizations --- src/token/bigint.ts | 19 ++++++------- src/token/const.ts | 14 ++++------ src/token/ident.ts | 27 +++++++++--------- src/token/integer.ts | 40 +++++++++++++------------- src/token/internal/char.ts | 12 ++++---- src/token/internal/guard.ts | 40 -------------------------- src/token/internal/optional.ts | 10 +++---- src/token/internal/result.ts | 6 ++-- src/token/internal/take.ts | 38 +++++++++++-------------- src/token/internal/trim.ts | 12 +++----- src/token/number.ts | 51 ++++++++++++++++++---------------- src/token/span.ts | 48 ++++++++++++++++---------------- src/token/string.ts | 9 ++---- src/token/until.ts | 43 +++++++++++++--------------- src/token/until_1.ts | 15 ++++------ 15 files changed, 161 insertions(+), 223 deletions(-) delete mode 100644 src/token/internal/guard.ts diff --git a/src/token/bigint.ts b/src/token/bigint.ts index c397d3c..fd7a2fb 100644 --- a/src/token/bigint.ts +++ b/src/token/bigint.ts @@ -29,7 +29,7 @@ THE SOFTWARE. // deno-fmt-ignore-file import { IsResult } from './internal/result.ts' -import { type TTake, Take } from './internal/take.ts' +import { type TTake, TakeVariant } from './internal/take.ts' import { type TInteger, Integer } from './integer.ts' // ------------------------------------------------------------------ @@ -44,14 +44,13 @@ type TTakeBigInt = ( ) function TakeBigInt(input: Input): TTakeBigInt { const integer = Integer(input) - return ( - IsResult(integer) ? (() => { - const n = Take(['n'], integer[1]) - return IsResult(n) - ? [`${integer[0]}`, n[1]] - : [] // fail: did not match 'n' - })() : [] // fail: did not match Integer - ) as never + if (IsResult(integer)) { + const n = TakeVariant('n', integer[1]) + if (IsResult(n)) + return [integer[0], n[1]] as never + } + + return [] as never } // ------------------------------------------------------------------ // BigInt @@ -63,4 +62,4 @@ export type TBigInt = ( /** Matches if next is a Integer literal with trailing 'n'. Trailing 'n' is omitted in result. */ export function BigInt(input: Input): TBigInt { return TakeBigInt(input) as never -} \ No newline at end of file +} diff --git a/src/token/const.ts b/src/token/const.ts index d424ccc..44939a9 100644 --- a/src/token/const.ts +++ b/src/token/const.ts @@ -28,10 +28,9 @@ THE SOFTWARE. // deno-fmt-ignore-file -import { IsEqual } from './internal/guard.ts' import { type TTrimWhitespace, TrimWhitespace } from './internal/trim.ts' import { type TTrim, Trim } from './internal/trim.ts' -import { type TTake, Take } from './internal/take.ts' +import { type TTake, TakeVariant } from './internal/take.ts' import { type TNewLine, NewLine } from './internal/char.ts' import { type TWhiteSpace, WhiteSpace } from './internal/char.ts' @@ -42,9 +41,6 @@ import { type TWhiteSpace, WhiteSpace } from './internal/char.ts' type TTakeConst = ( TTake<[Const], Input> ) -function TakeConst(const_: Const, input: Input): TTakeConst { - return Take([const_], input) as never -} // ------------------------------------------------------------------ // Const // ------------------------------------------------------------------ @@ -60,10 +56,10 @@ export type TConst = ( /** Matches if next is the given Const value */ export function Const(const_: Const, input: Input): TConst { return ( - IsEqual(const_, '') ? ['', input] : ( - const_.startsWith(NewLine) ? TakeConst(const_, TrimWhitespace(input)) : - const_.startsWith(WhiteSpace) ? TakeConst(const_, input) : - TakeConst(const_, Trim(input)) + const_ === '' ? ['', input] : ( + const_.startsWith(NewLine) ? TakeVariant(const_, TrimWhitespace(input)) : + const_.startsWith(WhiteSpace) ? TakeVariant(const_, input) : + TakeVariant(const_, Trim(input)) ) ) as never } diff --git a/src/token/ident.ts b/src/token/ident.ts index eedc472..f0b98ae 100644 --- a/src/token/ident.ts +++ b/src/token/ident.ts @@ -46,9 +46,6 @@ const Initial = [...Alpha, UnderScore, DollarSign] type TTakeInitial = ( TTake ) -function TakeInitial(input: Input): TTakeInitial { - return Take(Initial, input) as never -} // ------------------------------------------------------------------ // TakeRemaining // ------------------------------------------------------------------ @@ -61,7 +58,7 @@ type TTakeRemaining = ( : [Result, Input] ) function TakeRemaining(input: Input, result: string = ''): TTakeRemaining { - const remaining = Take(Remaining, input) as string[] + const remaining = Take(Remaining, input) return ( IsResult(remaining) ? TakeRemaining(remaining[1], `${result}${remaining[0]}`) @@ -79,15 +76,17 @@ type TTakeIdent = ( : [] // fail: did not match Initial ) function TakeIdent(input: Input): TTakeIdent { - const initial = TakeInitial(input) as string[] - return ( - IsResult(initial) ? (() => { - const remaining = TakeRemaining(initial[1]) - return IsResult(remaining) - ? [`${initial[0]}${remaining[0]}`, remaining[1]] - : [] // fail: did not match Remaining - })() : [] // fail: did not match Initial - ) as never + const initial = Take(Initial, input) as [string, string] | [] + if (IsResult(initial)) { + const remaining = TakeRemaining(initial[1]) + if (IsResult(remaining)) + return [initial[0] + remaining[0], remaining[1]] as never + + // fail: did not match Remaining + } + + // fail: did not match Initial + return [] as never; } // ------------------------------------------------------------------ // Ident @@ -99,4 +98,4 @@ export type TIdent = ( /** Matches if next is an Ident */ export function Ident(input: Input): TIdent { return TakeIdent(Trim(input)) as never -} \ No newline at end of file +} diff --git a/src/token/integer.ts b/src/token/integer.ts index 008c4dd..7783584 100644 --- a/src/token/integer.ts +++ b/src/token/integer.ts @@ -30,7 +30,7 @@ THE SOFTWARE. import { IsResult } from './internal/result.ts' import { type TTrim, Trim } from './internal/trim.ts' -import { type TTake, Take } from './internal/take.ts' +import { type TTake, Take, TakeVariant } from './internal/take.ts' import { type TMany, Many } from './internal/many.ts' import { type TOptional, Optional } from './internal/optional.ts' @@ -65,7 +65,7 @@ type TAllowedDigits = [...TDigit, TUnderScore] const AllowedDigits = [...Digit, UnderScore] as TAllowedDigits // ... type TTakeDigits = ( - TMany + TMany ) function TakeDigits(input: Input): TTakeDigits { return Many(AllowedDigits, [UnderScore], input) as never @@ -86,22 +86,25 @@ type TTakeInteger = ( ) function TakeInteger(input: Input): TTakeInteger { const sign = TakeSign(input) - return ( - IsResult(sign) ? (() => { - const zero = Take([Zero], sign[1]) - return IsResult(zero) - ? [`${sign[0]}${zero[0]}`, zero[1]] - : (() => { - const nonZero = TakeNonZero(sign[1]) - return IsResult(nonZero) ? (() => { - const digits = TakeDigits(nonZero[1]) - return IsResult(digits) - ? [`${sign[0]}${nonZero[0]}${digits[0]}`, digits[1]] - : [] // fail: did not match Digits - })() : [] // fail: did not match NonZero - })() - })() : [] // fail: did not match Sign - ) as never + if (IsResult(sign)) { + const zero = TakeVariant(Zero, sign[1]) + if (IsResult(zero)) + return [sign[0] + zero[0], zero[1]] as never + + const nonZero = TakeNonZero(sign[1]) + if (IsResult(nonZero)) { + const digits = TakeDigits(nonZero[1]) + if (IsResult(digits)) + return [sign[0] + nonZero[0] + digits[0], digits[1]] as never + + // fail: did not match Digits + } + + // fail: did not match NonZero + } + + // fail: did not match Sign + return [] as never } // ------------------------------------------------------------------ // Integer @@ -114,4 +117,3 @@ export type TInteger = ( export function Integer(input: Input): TInteger { return TakeInteger(Trim(input)) as never } - diff --git a/src/token/internal/char.ts b/src/token/internal/char.ts index 791d96c..74e20e1 100644 --- a/src/token/internal/char.ts +++ b/src/token/internal/char.ts @@ -32,7 +32,9 @@ THE SOFTWARE. // Range // ------------------------------------------------------------------ function Range(start: number, end: number): string[] { - return Array.from({ length: end - start + 1 }, (_, i) => String.fromCharCode(start + i)) + return new Array(end - start + 1) + .fill(start) + .map((start, i) => String.fromCharCode(start + i)) } // ------------------------------------------------------------------ // Alphas @@ -46,10 +48,8 @@ export type TAlpha = [ 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ] -export const Alpha = [ - ...Range(97, 122), // Lowercase - ...Range(65, 90) // Uppercase -] as TAlpha +export const Alpha = Range(97, 122) // Lowercase + .concat(Range(65, 90)) as TAlpha // Uppercase // ------------------------------------------------------------------ // Digits @@ -60,7 +60,7 @@ export type TDigit = [TZero, ...TNonZero] export const Zero = '0' export const NonZero = Range(49, 57) as TNonZero // 1 - 9 -export const Digit = [Zero, ...NonZero] as TDigit +export const Digit = [Zero].concat(NonZero) as TDigit // ------------------------------------------------------------------ // Characters diff --git a/src/token/internal/guard.ts b/src/token/internal/guard.ts deleted file mode 100644 index 497a86d..0000000 --- a/src/token/internal/guard.ts +++ /dev/null @@ -1,40 +0,0 @@ -/*-------------------------------------------------------------------------- - -ParseBox - -The MIT License (MIT) - -Copyright (c) 2024-2025 Haydn Paterson - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - ----------------------------------------------------------------------------*/ - -// ------------------------------------------------------------------ -// Internal Guards to ensure Token is portable. -// ------------------------------------------------------------------ -export function IsArray(value: unknown): value is unknown[] { - return Array.isArray(value) -} -export function IsString(value: unknown): value is string { - return IsEqual(typeof value, 'string') -} -export function IsEqual(left: unknown, right: unknown): boolean { - return left === right -} diff --git a/src/token/internal/optional.ts b/src/token/internal/optional.ts index 2f019c0..29afb87 100644 --- a/src/token/internal/optional.ts +++ b/src/token/internal/optional.ts @@ -29,7 +29,7 @@ THE SOFTWARE. // deno-fmt-ignore-file import { IsResult } from './result.ts' -import { type TTake, Take } from './take.ts' +import { type TTake, TakeVariant } from './take.ts' /** Matches the given Value or empty string if no match. This function never fails */ export type TOptional = ( @@ -40,10 +40,10 @@ export type TOptional = ( /** Matches the given Value or empty string if no match. This function never fails */ export function Optional (value: Value, input: Input): TOptional { - const result = Take([value], input) + const result = TakeVariant(value, input) return ( - IsResult(result) - ? result + IsResult(result) + ? result : ['', input] ) as never -} \ No newline at end of file +} diff --git a/src/token/internal/result.ts b/src/token/internal/result.ts index 4b9a3b8..10341ea 100644 --- a/src/token/internal/result.ts +++ b/src/token/internal/result.ts @@ -26,9 +26,7 @@ THE SOFTWARE. ---------------------------------------------------------------------------*/ -import { IsArray, IsEqual } from './guard.ts' - /** Checks the value is a Tuple-2 [string, string] result */ -export function IsResult(value: unknown): value is [string, string] { - return IsArray(value) && IsEqual(value.length, 2) +export function IsResult(value: [] | [string, string]): value is [string, string] { + return value.length === 2 } diff --git a/src/token/internal/take.ts b/src/token/internal/take.ts index f55d389..8798236 100644 --- a/src/token/internal/take.ts +++ b/src/token/internal/take.ts @@ -26,45 +26,39 @@ THE SOFTWARE. ---------------------------------------------------------------------------*/ -// deno-fmt-ignore-file +import { IsResult } from './result.ts' -import { IsEqual, IsString } from './guard.ts' +// deno-fmt-ignore-file // ------------------------------------------------------------------ // TakeString // ------------------------------------------------------------------ type TTakeVariant = ( - Input extends `${Variant}${infer Rest extends string}` + Input extends `${Variant}${infer Rest extends string}` ? [Variant, Rest] : [] ) -function TakeVariant(variant: Variant, input: Input): TTakeVariant { +export function TakeVariant(variant: Variant, input: Input): TTakeVariant { return ( - IsEqual(input.indexOf(variant), 0) - ? [variant, input.slice(variant.length)] - : [] + input.indexOf(variant) === 0 ? [variant, input.slice(variant.length)] : [] ) as never } // ------------------------------------------------------------------ // Take // ------------------------------------------------------------------ /** Takes one of the given variants or fail */ -export type TTake = ( - Variants extends [infer ValueLeft extends string, ...infer ValueRight extends string[]] - ? TTakeVariant extends [infer Take extends string, infer Rest extends string] - ? [Take, Rest] - : TTake +export type TTake = Variants extends [infer ValueLeft extends string, ...infer ValueRight extends string[]] + ? TTakeVariant extends [infer Take extends string, infer Rest extends string] ? [Take, Rest] + : TTake : [] -) /** Takes one of the given variants or fail */ export function Take(variants: [...Variants], input: Input): TTake { - const [left, ...right] = variants - return ( - IsString(left) - ? (() => { - const result = TakeVariant(left, input) - return IsEqual(result.length, 2) ? result : Take(right, input) - })() - : [] - ) as never + for (let i = 0; i < variants.length; i++) { + const result = TakeVariant(variants[i], input) as [] | [string, string] + if (IsResult(result)) { + return result as never + } + } + + return [] as never } diff --git a/src/token/internal/trim.ts b/src/token/internal/trim.ts index cf278f9..a3b398b 100644 --- a/src/token/internal/trim.ts +++ b/src/token/internal/trim.ts @@ -28,7 +28,6 @@ THE SOFTWARE. // deno-fmt-ignore-file -import { IsEqual } from './guard.ts' import * as Char from './char.ts' // ------------------------------------------------------------------ @@ -51,21 +50,19 @@ type TDiscardMultiLineComment = ( ) function DiscardMultilineComment(input: Input): TDiscardMultiLineComment { const index = input.indexOf(CloseComment) - const result = IsEqual(index, -1) ? '' : input.slice(index + 2) - return result as never + return (index > -1 ? input.slice(index + 2) : '') as never } // ------------------------------------------------------------------ // DiscardLineComment // ------------------------------------------------------------------ type TDiscardLineComment = ( - Input extends `${string}${Char.TNewLine}${infer Rest extends string}` - ? TTrimWhitespace<`${Char.TNewLine}${Rest}`> + Input extends `${string}${Char.TNewLine}${infer Rest extends string}` + ? TTrimWhitespace<`${Char.TNewLine}${Rest}`> : '' ) function DiscardLineComment(input: Input): TDiscardLineComment { const index = input.indexOf(Char.NewLine) - const result = IsEqual(index, -1) ? '' : input.slice(index) - return result as never + return (index > -1 ? input.slice(index) : '') as never } // ------------------------------------------------------------------ // Whitespace Filters @@ -121,4 +118,3 @@ export function Trim(input: Input): TTrim { trimmed ) as never } - diff --git a/src/token/number.ts b/src/token/number.ts index 2de08df..6d62a60 100644 --- a/src/token/number.ts +++ b/src/token/number.ts @@ -28,10 +28,9 @@ THE SOFTWARE. // deno-fmt-ignore-file -import { IsEqual } from './internal/guard.ts' import { IsResult } from './internal/result.ts' import { type TTrim, Trim } from './internal/trim.ts' -import { type TTake, Take } from './internal/take.ts' +import { type TTake, Take, TakeVariant } from './internal/take.ts' import { type TMany, Many } from './internal/many.ts' import { type TOptional, Optional } from './internal/optional.ts' @@ -78,7 +77,7 @@ function TakeFractional(input: Input): TTakeFractional = ( : [] // fail: did not match Dot ) function LeadingDot - (sign: Sign, input: Input): + (sign: Sign, input: Input): TLeadingDot { - const dot = Take([Dot], input) - return ( - IsResult(dot) ? (() => { - const fractional = TakeFractional(dot[1]) - return IsResult(fractional) - ? [`${sign}0${dot[0]}${fractional[0]}`, fractional[1]] - : [] // fail: did not match Fractional - })() : [] // fail: did not match Dot - ) as never + const dot = TakeVariant(Dot, input) + if (IsResult(dot)) { + const fractional = TakeFractional(dot[1]) + if (IsResult(fractional)) + return [sign + '0' + dot[0] + fractional[0], fractional[1]] as never + + // fail: did not match Fractional + } + + // fail: did not match Dot + return [] as never } // ------------------------------------------------------------------ // TakeLeadingInteger @@ -120,19 +121,21 @@ type TLeadingInteger = ( : [] // fail: did not match Integer ) function LeadingInteger - (sign: Sign, input: Input): + (sign: Sign, input: Input): TLeadingInteger { const integer = Integer(input) + if (!IsResult(integer)) + return [] as never // fail: did not match Integer + + const dot = TakeVariant(Dot, integer[1]) + if (!IsResult(dot)) + return [sign + integer[0], integer[1]] as never // fail: did not match Dot, use Integer + + const fractional = TakeFractional(dot[1]) return ( - IsResult(integer) ? (() => { - const dot = Take([Dot], integer[1]) - return IsResult(dot) ? (() => { - const fractional = TakeFractional(dot[1]) - return IsResult(fractional) - ? [`${sign}${integer[0]}${dot[0]}${fractional[0]}`, fractional[1]] - : [`${sign}${integer[0]}`, dot[1]] // fail: did not match Fractional, use Integer - })() : [`${sign}${integer[0]}`, integer[1]] // fail: did not match Dot, use Integer - })() : [] // fail: did not match Integer + IsResult(fractional) + ? [sign + integer[0] + dot[0] + fractional[0], fractional[1]] + : [sign + integer[0], dot[1]] // fail: did not match Fractional, use Integer ) as never } // ------------------------------------------------------------------ @@ -165,4 +168,4 @@ export type TNumber = ( /** Matches if next is a literal Number */ export function Number(input: Input): TNumber { return TakeNumber(Trim(input)) as never -} \ No newline at end of file +} diff --git a/src/token/span.ts b/src/token/span.ts index 6dc7470..cc88508 100644 --- a/src/token/span.ts +++ b/src/token/span.ts @@ -46,18 +46,18 @@ type TMultiLine : [] // fail: did not match Start ) function MultiLine - (start: Start, end: End, input: Input): + (start: Start, end: End, input: Input): TMultiLine { - return ( - input.startsWith(start) ? (() => { - const until = Until([end], input.slice(start.length)) - return IsResult(until) ? (() => { - return until[1].startsWith(end) - ? [`${until[0]}`, until[1].slice(end.length)] - : [] // fail: did not match End - })() : [] // fail: did not match Until - })() : [] // fail: did not match Start - ) as never + if (input.startsWith(start)) { + const until = Until([end], input.slice(start.length)) + if (IsResult(until) && until[1].startsWith(end)) + return [until[0], until[1].slice(end.length)] as never + + // fail: did not match End or Until + } + + // fail: did not match Start + return [] as never } // ------------------------------------------------------------------ // SingleLine @@ -72,18 +72,18 @@ type TSingleLine : [] // fail: not match Start ) function SingleLine - (start: Start, end: End, input: Input): + (start: Start, end: End, input: Input): TSingleLine { - return ( - input.startsWith(start) ? (() => { - const until = Until([NewLine, end], input.slice(start.length)) - return IsResult(until) ? (() => { - return until[1].startsWith(end) - ? [`${until[0]}`, until[1].slice(end.length)] - : [] // fail: did not match End - })() : [] // fail: did not match Until - })() : [] // fail: not match Start - ) as never + if (input.startsWith(start)) { + const until = Until([NewLine, end], input.slice(start.length)) + if (IsResult(until) && until[1].startsWith(end)) + return [until[0], until[1].slice(end.length)] as never + + // fail: did not match End or Until + } + + // fail: not match Start + return [] as never } // ------------------------------------------------------------------ // Span @@ -96,11 +96,11 @@ export type TSpan - (start: Start, end: End, multiLine: MultiLine, input: Input): + (start: Start, end: End, multiLine: MultiLine, input: Input): TSpan { return ( multiLine ? MultiLine(start, end, Trim(input)) : SingleLine(start, end, Trim(input)) ) as never -} \ No newline at end of file +} diff --git a/src/token/string.ts b/src/token/string.ts index 848d513..57d1856 100644 --- a/src/token/string.ts +++ b/src/token/string.ts @@ -39,9 +39,6 @@ import { type TSpan, Span } from './span.ts' type TTakeInitial = ( TTake ) -function TakeInitial(quotes: [...Quotes], input: Input): TTakeInitial { - return Take(quotes, input) -} // ------------------------------------------------------------------ // TakeSpan // ------------------------------------------------------------------ @@ -60,10 +57,10 @@ type TTakeString = ( : [] // fail: did not match Initial ) function TakeString(quotes: [...Quotes], input: Input): TTakeString { - const initial = TakeInitial(quotes, input) as [string, string] + const initial = Take(quotes, input) return ( IsResult(initial) - ? TakeSpan(initial[0], `${initial[0]}${initial[1]}`) + ? TakeSpan(initial[0], initial[0] + initial[1]) : [] // fail: did not match Initial ) as never } @@ -74,4 +71,4 @@ export type TString = ( /** Matches a literal String with the given quotes */ export function String(quotes: [...Quotes], input: Input): TString { return TakeString(quotes, Trim(input)) as never -} \ No newline at end of file +} diff --git a/src/token/until.ts b/src/token/until.ts index f3431c0..bb96b58 100644 --- a/src/token/until.ts +++ b/src/token/until.ts @@ -28,29 +28,25 @@ THE SOFTWARE. // deno-fmt-ignore-file -import { IsEqual, IsString } from './internal/guard.ts' - // ------------------------------------------------------------------ // IsEnd // ------------------------------------------------------------------ type TIsEnd = ( - End extends [infer Left extends string, ...infer Right extends string[]] - ? Input extends `${Left}${string}` + End extends [infer Left extends string, ...infer Right extends string[]] + ? Input extends `${Left}${string}` ? true : TIsEnd : false ) function IsEnd - (end: [...End], input: Input): + (end: [...End], input: Input): TIsEnd { - const [left, ...right] = end - return ( - IsString(left) - ? input.startsWith(left) - ? true - : IsEnd(right, input) - : false - ) as never + for (let i = 0; i < end.length; i++) { + if (input.startsWith(end[i])) + return true as never; + } + + return false as never; } // ------------------------------------------------------------------ // Until @@ -59,21 +55,22 @@ function IsEnd export type TUntil = ( Input extends `` ? [] // fail: Input is empty - : TIsEnd extends true + : TIsEnd extends true ? [Result, Input] - : Input extends `${infer Left extends string}${infer Right extends string}` + : Input extends `${infer Left extends string}${infer Right extends string}` ? TUntil : [] ) /** Match Input until but not including End. No match if End not found. */ export function Until (end: [...End], input: Input, result: string = ''): TUntil { - return ( - IsEqual(input, '') - ? [] // fail: Input is empty - : IsEnd(end, input) ? [result, input] : (() => { - const [left, right] = [input.slice(0, 1), input.slice(1)] - return Until(end, right, `${result}${left}`) - })() - ) as never + if (input === '') + return [] as never // fail: Input is empty + + if (IsEnd(end, input)) + return [result, input] as never + + const left = input.slice(0, 1), + right = input.slice(1) + return Until(end, right, result + left) as never } diff --git a/src/token/until_1.ts b/src/token/until_1.ts index e95514c..7b102f9 100644 --- a/src/token/until_1.ts +++ b/src/token/until_1.ts @@ -28,7 +28,6 @@ THE SOFTWARE. // deno-fmt-ignore-file -import { IsEqual } from './internal/guard.ts' import { IsResult } from './internal/result.ts' import { type TUntil, Until } from './until.ts' @@ -37,22 +36,20 @@ import { type TUntil, Until } from './until.ts' // ------------------------------------------------------------------ /** Match Input until but not including End. No match if End not found or match is zero-length. */ export type TUntil_1 = ( - TUntil extends [infer Until extends string, infer UntilRest extends string] - ? Until extends '' + TUntil extends [infer Until extends string, infer UntilRest extends string] + ? Until extends '' ? [] // fail: match has no characters : [Until, UntilRest] : [] // fail: did not match Until ) /** Match Input until but not including End. No match if End not found or match is zero-length. */ export function Until_1 - (end: [...End], input: Input): + (end: [...End], input: Input): TUntil_1 { const until = Until(end, input) return ( - IsResult(until) - ? IsEqual(until[0], '') - ? [] // fail: match has no characters - : until - : [] // fail: did not match Until + IsResult(until) && until[0] !== '' + ? until + : [] // fail: match has no characters or did not match Until ) as never } From ae24ee88d68106170a8dc236483bc5b4fe46c191 Mon Sep 17 00:00:00 2001 From: aquapi Date: Sun, 22 Mar 2026 20:39:05 +0700 Subject: [PATCH 2/3] revert: - guard.ts - TakeVariant(A, input) to Take([A], input) --- .vscode/settings.json | 4 ++-- .zed/settings.json | 7 +++++++ deno.jsonc | 8 ++++++-- deno.lock | 11 ++++++++++- src/token/bigint.ts | 4 ++-- src/token/const.ts | 11 ++++++----- src/token/integer.ts | 4 ++-- src/token/internal/char.ts | 8 +++++--- src/token/internal/guard.ts | 34 ++++++++++++++++++++++++++++++++++ src/token/internal/optional.ts | 4 ++-- src/token/internal/result.ts | 4 +++- src/token/internal/take.ts | 18 +++++++++++------- src/token/internal/trim.ts | 5 +++-- src/token/number.ts | 16 ++++++++-------- src/token/until.ts | 4 +++- src/token/until_1.ts | 3 ++- 16 files changed, 106 insertions(+), 39 deletions(-) create mode 100644 .zed/settings.json create mode 100644 src/token/internal/guard.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index fd4665b..4c2c2d0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,5 +5,5 @@ "package-lock.json": true }, "deno.enable": true, - "deno.lint": false, -} \ No newline at end of file + "deno.lint": false +} diff --git a/.zed/settings.json b/.zed/settings.json new file mode 100644 index 0000000..dfc9997 --- /dev/null +++ b/.zed/settings.json @@ -0,0 +1,7 @@ +{ + "languages": { + "TypeScript": { + "language_servers": ["deno", "!vtsls"] + } + } +} diff --git a/deno.jsonc b/deno.jsonc index f0db3c0..0af3cfb 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -17,7 +17,11 @@ // -------------------------------------------------------------- // ParseBox // -------------------------------------------------------------- - "@sinclair/parsebox": "./src/index.ts" + "@sinclair/parsebox": "./src/index.ts", + // -------------------------------------------------------------- + // Mitata + // -------------------------------------------------------------- + "mitata": "npm:mitata" }, "fmt": { "lineWidth": 240, @@ -27,4 +31,4 @@ "compilerOptions": { "strict": true } -} \ No newline at end of file +} diff --git a/deno.lock b/deno.lock index a77b2cd..fb4e16e 100644 --- a/deno.lock +++ b/deno.lock @@ -5,7 +5,8 @@ "jsr:@std/internal@^1.0.6": "1.0.6", "jsr:@std/path@1.0.8": "1.0.8", "npm:@sinclair/typebox@*": "0.34.33", - "npm:@types/node@*": "22.15.15" + "npm:@types/node@*": "22.15.15", + "npm:mitata@*": "1.0.34" }, "jsr": { "@std/assert@1.0.12": { @@ -31,6 +32,9 @@ "undici-types" ] }, + "mitata@1.0.34": { + "integrity": "sha512-Mc3zrtNBKIMeHSCQ0XqRLo1vbdIx1wvFV9c8NJAiyho6AjNfMY8bVhbS12bwciUdd1t4rj8099CH3N3NFahaUA==" + }, "undici-types@6.21.0": { "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==" } @@ -170,5 +174,10 @@ "https://raw.githubusercontent.com/sinclairzx81/tasksmith/0.8.5/src/test/test.ts": "894650a3af2f7c0c8e4e4f0930d6f3e7bfc5187c5c66ce869c0429b942a51c2d", "https://raw.githubusercontent.com/sinclairzx81/tasksmith/0.8.5/src/tsc/index.ts": "ef3fd7538b1f3d85e102f4b6317ad92e2f1dc007df6d7d7cceb283913e71117d", "https://raw.githubusercontent.com/sinclairzx81/tasksmith/0.8.5/src/tsc/tsc.ts": "2d84d6b8bf155811eec128a03095dbad9f15feb7602c7fc3c6a9e0c36dc38602" + }, + "workspace": { + "dependencies": [ + "npm:mitata@*" + ] } } diff --git a/src/token/bigint.ts b/src/token/bigint.ts index fd7a2fb..d4b3549 100644 --- a/src/token/bigint.ts +++ b/src/token/bigint.ts @@ -29,7 +29,7 @@ THE SOFTWARE. // deno-fmt-ignore-file import { IsResult } from './internal/result.ts' -import { type TTake, TakeVariant } from './internal/take.ts' +import { type TTake, Take } from './internal/take.ts' import { type TInteger, Integer } from './integer.ts' // ------------------------------------------------------------------ @@ -45,7 +45,7 @@ type TTakeBigInt = ( function TakeBigInt(input: Input): TTakeBigInt { const integer = Integer(input) if (IsResult(integer)) { - const n = TakeVariant('n', integer[1]) + const n = Take(['n'], integer[1]) if (IsResult(n)) return [integer[0], n[1]] as never } diff --git a/src/token/const.ts b/src/token/const.ts index 44939a9..302cc40 100644 --- a/src/token/const.ts +++ b/src/token/const.ts @@ -30,10 +30,11 @@ THE SOFTWARE. import { type TTrimWhitespace, TrimWhitespace } from './internal/trim.ts' import { type TTrim, Trim } from './internal/trim.ts' -import { type TTake, TakeVariant } from './internal/take.ts' +import { type TTake, Take } from './internal/take.ts' import { type TNewLine, NewLine } from './internal/char.ts' import { type TWhiteSpace, WhiteSpace } from './internal/char.ts' +import { IsEqual } from './internal/guard.ts' // ------------------------------------------------------------------ // TakeConst @@ -56,10 +57,10 @@ export type TConst = ( /** Matches if next is the given Const value */ export function Const(const_: Const, input: Input): TConst { return ( - const_ === '' ? ['', input] : ( - const_.startsWith(NewLine) ? TakeVariant(const_, TrimWhitespace(input)) : - const_.startsWith(WhiteSpace) ? TakeVariant(const_, input) : - TakeVariant(const_, Trim(input)) + IsEqual(const_, '') ? ['', input] : ( + const_.startsWith(NewLine) ? Take([const_], TrimWhitespace(input)) : + const_.startsWith(WhiteSpace) ? Take([const_], input) : + Take([const_], Trim(input)) ) ) as never } diff --git a/src/token/integer.ts b/src/token/integer.ts index 7783584..565c2f2 100644 --- a/src/token/integer.ts +++ b/src/token/integer.ts @@ -30,7 +30,7 @@ THE SOFTWARE. import { IsResult } from './internal/result.ts' import { type TTrim, Trim } from './internal/trim.ts' -import { type TTake, Take, TakeVariant } from './internal/take.ts' +import { type TTake, Take } from './internal/take.ts' import { type TMany, Many } from './internal/many.ts' import { type TOptional, Optional } from './internal/optional.ts' @@ -87,7 +87,7 @@ type TTakeInteger = ( function TakeInteger(input: Input): TTakeInteger { const sign = TakeSign(input) if (IsResult(sign)) { - const zero = TakeVariant(Zero, sign[1]) + const zero = Take([Zero], sign[1]) if (IsResult(zero)) return [sign[0] + zero[0], zero[1]] as never diff --git a/src/token/internal/char.ts b/src/token/internal/char.ts index 74e20e1..46d6898 100644 --- a/src/token/internal/char.ts +++ b/src/token/internal/char.ts @@ -48,8 +48,10 @@ export type TAlpha = [ 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ] -export const Alpha = Range(97, 122) // Lowercase - .concat(Range(65, 90)) as TAlpha // Uppercase +export const Alpha = [ + ...Range(97, 122), // Lowercase + ...Range(65, 90) // Uppercase +] as TAlpha // ------------------------------------------------------------------ // Digits @@ -60,7 +62,7 @@ export type TDigit = [TZero, ...TNonZero] export const Zero = '0' export const NonZero = Range(49, 57) as TNonZero // 1 - 9 -export const Digit = [Zero].concat(NonZero) as TDigit +export const Digit = [Zero, ...NonZero] as TDigit // ------------------------------------------------------------------ // Characters diff --git a/src/token/internal/guard.ts b/src/token/internal/guard.ts new file mode 100644 index 0000000..ba85b0c --- /dev/null +++ b/src/token/internal/guard.ts @@ -0,0 +1,34 @@ +/*-------------------------------------------------------------------------- + +ParseBox + +The MIT License (MIT) + +Copyright (c) 2024-2025 Haydn Paterson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ + +// ------------------------------------------------------------------ +// Internal Guards to ensure Token is portable. +// ------------------------------------------------------------------ +export function IsEqual(left: unknown, right: unknown): boolean { + return left === right +} diff --git a/src/token/internal/optional.ts b/src/token/internal/optional.ts index 29afb87..2756f64 100644 --- a/src/token/internal/optional.ts +++ b/src/token/internal/optional.ts @@ -29,7 +29,7 @@ THE SOFTWARE. // deno-fmt-ignore-file import { IsResult } from './result.ts' -import { type TTake, TakeVariant } from './take.ts' +import { type TTake, Take } from './take.ts' /** Matches the given Value or empty string if no match. This function never fails */ export type TOptional = ( @@ -40,7 +40,7 @@ export type TOptional = ( /** Matches the given Value or empty string if no match. This function never fails */ export function Optional (value: Value, input: Input): TOptional { - const result = TakeVariant(value, input) + const result = Take([value], input) return ( IsResult(result) ? result diff --git a/src/token/internal/result.ts b/src/token/internal/result.ts index 10341ea..777e1be 100644 --- a/src/token/internal/result.ts +++ b/src/token/internal/result.ts @@ -26,7 +26,9 @@ THE SOFTWARE. ---------------------------------------------------------------------------*/ +import { IsEqual } from './guard.ts' + /** Checks the value is a Tuple-2 [string, string] result */ export function IsResult(value: [] | [string, string]): value is [string, string] { - return value.length === 2 + return IsEqual(value.length, 2) } diff --git a/src/token/internal/take.ts b/src/token/internal/take.ts index 8798236..bf77e2c 100644 --- a/src/token/internal/take.ts +++ b/src/token/internal/take.ts @@ -26,10 +26,11 @@ THE SOFTWARE. ---------------------------------------------------------------------------*/ -import { IsResult } from './result.ts' - // deno-fmt-ignore-file +import { IsEqual } from './guard.ts' +import { IsResult } from './result.ts' + // ------------------------------------------------------------------ // TakeString // ------------------------------------------------------------------ @@ -38,19 +39,22 @@ type TTakeVariant = ( ? [Variant, Rest] : [] ) -export function TakeVariant(variant: Variant, input: Input): TTakeVariant { +function TakeVariant(variant: Variant, input: Input): TTakeVariant { return ( - input.indexOf(variant) === 0 ? [variant, input.slice(variant.length)] : [] + IsEqual(input.indexOf(variant), 0) ? [variant, input.slice(variant.length)] : [] ) as never } // ------------------------------------------------------------------ // Take // ------------------------------------------------------------------ /** Takes one of the given variants or fail */ -export type TTake = Variants extends [infer ValueLeft extends string, ...infer ValueRight extends string[]] - ? TTakeVariant extends [infer Take extends string, infer Rest extends string] ? [Take, Rest] - : TTake +export type TTake = ( + Variants extends [infer ValueLeft extends string, ...infer ValueRight extends string[]] + ? TTakeVariant extends [infer Take extends string, infer Rest extends string] + ? [Take, Rest] + : TTake : [] +) /** Takes one of the given variants or fail */ export function Take(variants: [...Variants], input: Input): TTake { for (let i = 0; i < variants.length; i++) { diff --git a/src/token/internal/trim.ts b/src/token/internal/trim.ts index a3b398b..561c088 100644 --- a/src/token/internal/trim.ts +++ b/src/token/internal/trim.ts @@ -29,6 +29,7 @@ THE SOFTWARE. // deno-fmt-ignore-file import * as Char from './char.ts' +import { IsEqual } from './guard.ts' // ------------------------------------------------------------------ // Comments @@ -50,7 +51,7 @@ type TDiscardMultiLineComment = ( ) function DiscardMultilineComment(input: Input): TDiscardMultiLineComment { const index = input.indexOf(CloseComment) - return (index > -1 ? input.slice(index + 2) : '') as never + return (IsEqual(index, -1) ? '' : input.slice(index + 2)) as never } // ------------------------------------------------------------------ // DiscardLineComment @@ -62,7 +63,7 @@ type TDiscardLineComment = ( ) function DiscardLineComment(input: Input): TDiscardLineComment { const index = input.indexOf(Char.NewLine) - return (index > -1 ? input.slice(index) : '') as never + return (IsEqual(index, -1) ? '' : input.slice(index)) as never } // ------------------------------------------------------------------ // Whitespace Filters diff --git a/src/token/number.ts b/src/token/number.ts index 6d62a60..0c0bc51 100644 --- a/src/token/number.ts +++ b/src/token/number.ts @@ -28,9 +28,11 @@ THE SOFTWARE. // deno-fmt-ignore-file +import { IsEqual } from './internal/guard.ts' + import { IsResult } from './internal/result.ts' import { type TTrim, Trim } from './internal/trim.ts' -import { type TTake, Take, TakeVariant } from './internal/take.ts' +import { type TTake, Take } from './internal/take.ts' import { type TMany, Many } from './internal/many.ts' import { type TOptional, Optional } from './internal/optional.ts' @@ -76,11 +78,9 @@ type TTakeFractional = ( function TakeFractional(input: Input): TTakeFractional { const digits = Many(AllowedDigits, [UnderScore], input) return ( - IsResult(digits) - ? digits[0] === '' - ? [] // fail: no Digits - : [digits[0], digits[1]] - : [] // fail: did not match Digits + IsResult(digits) && !IsEqual(digits[0], '') + ? [digits[0], digits[1]] + : [] // fail: did not match Digits or no Digits ) as never } // ------------------------------------------------------------------ @@ -96,7 +96,7 @@ type TLeadingDot = ( function LeadingDot (sign: Sign, input: Input): TLeadingDot { - const dot = TakeVariant(Dot, input) + const dot = Take([Dot], input) if (IsResult(dot)) { const fractional = TakeFractional(dot[1]) if (IsResult(fractional)) @@ -127,7 +127,7 @@ function LeadingInteger if (!IsResult(integer)) return [] as never // fail: did not match Integer - const dot = TakeVariant(Dot, integer[1]) + const dot = Take([Dot], integer[1]) if (!IsResult(dot)) return [sign + integer[0], integer[1]] as never // fail: did not match Dot, use Integer diff --git a/src/token/until.ts b/src/token/until.ts index bb96b58..e20926e 100644 --- a/src/token/until.ts +++ b/src/token/until.ts @@ -26,6 +26,8 @@ THE SOFTWARE. ---------------------------------------------------------------------------*/ +import { IsEqual } from './internal/guard.ts' + // deno-fmt-ignore-file // ------------------------------------------------------------------ @@ -64,7 +66,7 @@ export type TUntil (end: [...End], input: Input, result: string = ''): TUntil { - if (input === '') + if (IsEqual(input, '')) return [] as never // fail: Input is empty if (IsEnd(end, input)) diff --git a/src/token/until_1.ts b/src/token/until_1.ts index 7b102f9..d9bf9e3 100644 --- a/src/token/until_1.ts +++ b/src/token/until_1.ts @@ -28,6 +28,7 @@ THE SOFTWARE. // deno-fmt-ignore-file +import { IsEqual } from './internal/guard.ts' import { IsResult } from './internal/result.ts' import { type TUntil, Until } from './until.ts' @@ -48,7 +49,7 @@ export function Until_1 TUntil_1 { const until = Until(end, input) return ( - IsResult(until) && until[0] !== '' + IsResult(until) && !IsEqual(until[0], '') ? until : [] // fail: match has no characters or did not match Until ) as never From f81423af93802a422dd47dc1e9d02c276d439341 Mon Sep 17 00:00:00 2001 From: aquapi Date: Tue, 24 Mar 2026 12:16:01 +0700 Subject: [PATCH 3/3] revert formats and deleted methods --- .vscode/settings.json | 2 +- .zed/settings.json | 7 ------- src/token/const.ts | 11 +++++++---- src/token/internal/guard.ts | 6 ++++++ src/token/internal/take.ts | 4 +++- src/token/internal/trim.ts | 8 +++++--- src/token/number.ts | 1 - src/token/string.ts | 5 ++++- src/token/until.ts | 4 ++-- 9 files changed, 28 insertions(+), 20 deletions(-) delete mode 100644 .zed/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json index 4c2c2d0..2f13220 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,5 +5,5 @@ "package-lock.json": true }, "deno.enable": true, - "deno.lint": false + "deno.lint": false, } diff --git a/.zed/settings.json b/.zed/settings.json deleted file mode 100644 index dfc9997..0000000 --- a/.zed/settings.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "languages": { - "TypeScript": { - "language_servers": ["deno", "!vtsls"] - } - } -} diff --git a/src/token/const.ts b/src/token/const.ts index 302cc40..d424ccc 100644 --- a/src/token/const.ts +++ b/src/token/const.ts @@ -28,13 +28,13 @@ THE SOFTWARE. // deno-fmt-ignore-file +import { IsEqual } from './internal/guard.ts' import { type TTrimWhitespace, TrimWhitespace } from './internal/trim.ts' import { type TTrim, Trim } from './internal/trim.ts' import { type TTake, Take } from './internal/take.ts' import { type TNewLine, NewLine } from './internal/char.ts' import { type TWhiteSpace, WhiteSpace } from './internal/char.ts' -import { IsEqual } from './internal/guard.ts' // ------------------------------------------------------------------ // TakeConst @@ -42,6 +42,9 @@ import { IsEqual } from './internal/guard.ts' type TTakeConst = ( TTake<[Const], Input> ) +function TakeConst(const_: Const, input: Input): TTakeConst { + return Take([const_], input) as never +} // ------------------------------------------------------------------ // Const // ------------------------------------------------------------------ @@ -58,9 +61,9 @@ export type TConst = ( export function Const(const_: Const, input: Input): TConst { return ( IsEqual(const_, '') ? ['', input] : ( - const_.startsWith(NewLine) ? Take([const_], TrimWhitespace(input)) : - const_.startsWith(WhiteSpace) ? Take([const_], input) : - Take([const_], Trim(input)) + const_.startsWith(NewLine) ? TakeConst(const_, TrimWhitespace(input)) : + const_.startsWith(WhiteSpace) ? TakeConst(const_, input) : + TakeConst(const_, Trim(input)) ) ) as never } diff --git a/src/token/internal/guard.ts b/src/token/internal/guard.ts index ba85b0c..497a86d 100644 --- a/src/token/internal/guard.ts +++ b/src/token/internal/guard.ts @@ -29,6 +29,12 @@ THE SOFTWARE. // ------------------------------------------------------------------ // Internal Guards to ensure Token is portable. // ------------------------------------------------------------------ +export function IsArray(value: unknown): value is unknown[] { + return Array.isArray(value) +} +export function IsString(value: unknown): value is string { + return IsEqual(typeof value, 'string') +} export function IsEqual(left: unknown, right: unknown): boolean { return left === right } diff --git a/src/token/internal/take.ts b/src/token/internal/take.ts index bf77e2c..d72c029 100644 --- a/src/token/internal/take.ts +++ b/src/token/internal/take.ts @@ -41,7 +41,9 @@ type TTakeVariant = ( ) function TakeVariant(variant: Variant, input: Input): TTakeVariant { return ( - IsEqual(input.indexOf(variant), 0) ? [variant, input.slice(variant.length)] : [] + IsEqual(input.indexOf(variant), 0) + ? [variant, input.slice(variant.length)] + : [] ) as never } // ------------------------------------------------------------------ diff --git a/src/token/internal/trim.ts b/src/token/internal/trim.ts index 561c088..e4d7d25 100644 --- a/src/token/internal/trim.ts +++ b/src/token/internal/trim.ts @@ -28,8 +28,8 @@ THE SOFTWARE. // deno-fmt-ignore-file -import * as Char from './char.ts' import { IsEqual } from './guard.ts' +import * as Char from './char.ts' // ------------------------------------------------------------------ // Comments @@ -51,7 +51,8 @@ type TDiscardMultiLineComment = ( ) function DiscardMultilineComment(input: Input): TDiscardMultiLineComment { const index = input.indexOf(CloseComment) - return (IsEqual(index, -1) ? '' : input.slice(index + 2)) as never + const result = IsEqual(index, -1) ? '' : input.slice(index + 2) + return result as never } // ------------------------------------------------------------------ // DiscardLineComment @@ -63,7 +64,8 @@ type TDiscardLineComment = ( ) function DiscardLineComment(input: Input): TDiscardLineComment { const index = input.indexOf(Char.NewLine) - return (IsEqual(index, -1) ? '' : input.slice(index)) as never + const result = IsEqual(index, -1) ? '' : input.slice(index) + return result as never } // ------------------------------------------------------------------ // Whitespace Filters diff --git a/src/token/number.ts b/src/token/number.ts index 0c0bc51..6bc22a9 100644 --- a/src/token/number.ts +++ b/src/token/number.ts @@ -29,7 +29,6 @@ THE SOFTWARE. // deno-fmt-ignore-file import { IsEqual } from './internal/guard.ts' - import { IsResult } from './internal/result.ts' import { type TTrim, Trim } from './internal/trim.ts' import { type TTake, Take } from './internal/take.ts' diff --git a/src/token/string.ts b/src/token/string.ts index 57d1856..6a2fcd8 100644 --- a/src/token/string.ts +++ b/src/token/string.ts @@ -39,6 +39,9 @@ import { type TSpan, Span } from './span.ts' type TTakeInitial = ( TTake ) +function TakeInitial(quotes: [...Quotes], input: Input): TTakeInitial { + return Take(quotes, input) +} // ------------------------------------------------------------------ // TakeSpan // ------------------------------------------------------------------ @@ -57,7 +60,7 @@ type TTakeString = ( : [] // fail: did not match Initial ) function TakeString(quotes: [...Quotes], input: Input): TTakeString { - const initial = Take(quotes, input) + const initial = TakeInitial(quotes, input) return ( IsResult(initial) ? TakeSpan(initial[0], initial[0] + initial[1]) diff --git a/src/token/until.ts b/src/token/until.ts index e20926e..fda200c 100644 --- a/src/token/until.ts +++ b/src/token/until.ts @@ -26,10 +26,10 @@ THE SOFTWARE. ---------------------------------------------------------------------------*/ -import { IsEqual } from './internal/guard.ts' - // deno-fmt-ignore-file +import { IsEqual } from './internal/guard.ts' + // ------------------------------------------------------------------ // IsEnd // ------------------------------------------------------------------