Skip to content

Commit b70baf7

Browse files
committed
updates
1 parent 34277ac commit b70baf7

File tree

8 files changed

+173
-29
lines changed

8 files changed

+173
-29
lines changed

example/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import { Token } from '@sinclair/parsebox'
44

55
const R = Token.String(`'hello'`)
6+
67
console.log(R)
78

89
// todo: comment tests

src/token/bigint.ts

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,70 @@ THE SOFTWARE.
2828

2929
// deno-fmt-ignore-file
3030

31+
import { Guard } from '../guard/index.ts'
3132
import { type TTrim, Trim } from './internal/trim.ts'
32-
import { type TTake, Take } from './internal/take.ts'
33+
import { type TTake, Take, IsTakeTrue } from './internal/take.ts'
3334

3435
import { type TDigit, Digit } from './internal/char.ts'
3536
import { type TZero, Zero } from './internal/char.ts'
37+
import { type THyphen, Hyphen } from './internal/char.ts'
38+
import { type TNonZero, NonZero } from './internal/char.ts'
39+
import { type TUnderScore, UnderScore } from './internal/char.ts'
40+
41+
42+
// ------------------------------------------------------------------
43+
// Sign
44+
// ------------------------------------------------------------------
45+
type TTakeSign<Input extends string> = (
46+
TTake<Input, ['-']> extends [infer Sign extends string, infer Rest extends string]
47+
? [Sign, Rest]
48+
: ['', Input]
49+
)
50+
function TakeSign<Input extends string>(input: Input): TTakeSign<Input> {
51+
const result = Take(input, ['-'])
52+
return (
53+
IsTakeTrue(result)
54+
? result
55+
: ['', input]
56+
) as never
57+
}
58+
// ------------------------------------------------------------------
59+
// NonZero
60+
// ------------------------------------------------------------------
61+
type TTakeNonZero<Input extends string> = (
62+
TTake<Input, TNonZero>
63+
)
64+
function TakeNonZero<Input extends string>(input: Input): TTakeNonZero<Input> {
65+
return Take(input, NonZero)
66+
}
67+
// ------------------------------------------------------------------
68+
// Digits
69+
// ------------------------------------------------------------------
70+
type TTakeDigits<Input extends string, Result extends string = ''> = (
71+
TTake<Input, TDigit> extends [infer Digit extends string, infer Rest extends string]
72+
? TTakeDigits<Rest, `${Result}${Digit}`>
73+
: [Result, Input]
74+
)
75+
function TakeDigits<Input extends string>(input: Input, result: string = ''): TTakeDigits<Input> {
76+
const takeResult = Take(input, Digit) as [string, string]
77+
return (
78+
IsTakeTrue(takeResult)
79+
? TakeDigits(takeResult[1] as never, `${result}${takeResult[0]}`)
80+
: [result, input]
81+
) as never
82+
}
83+
// ------------------------------------------------------------------
84+
// Integer
85+
// ------------------------------------------------------------------
86+
type TTakeInteger<Input extends string> = (
87+
TTakeSign<Input> extends [infer Sign extends string, infer Rest extends string]
88+
? TTakeNonZero<Rest> extends [infer NonZero extends string, infer Rest extends string]
89+
? TTakeDigits<Rest> extends [infer Digits extends string, infer Rest extends string]
90+
? [`${Sign}${NonZero}${Digits}`, Rest]
91+
: [] // fail: did not match Digits
92+
: [] // fail: did not match NonZero
93+
: [] // fail: did not match Sign
94+
)
3695

3796
/** Matches if next is a BigInt literal with trailing `n` */
3897
export type TBigInt<Input extends string> = (

src/token/ident.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import { type TUnderScore, UnderScore } from './internal/char.ts'
3838
import { type TDollarSign, DollarSign } from './internal/char.ts'
3939

4040
// ------------------------------------------------------------------
41-
// First
41+
// TakeFirst
4242
// ------------------------------------------------------------------
4343
type TFirst = [...TAlpha, TUnderScore, TDollarSign]
4444
const First = [...Alpha, UnderScore, DollarSign]
@@ -57,7 +57,7 @@ function TakeFirst<Input extends string>(input: Input): TTakeFirst<Input> {
5757
) as never
5858
}
5959
// ------------------------------------------------------------------
60-
// Remaining
60+
// TakeRemaining
6161
// ------------------------------------------------------------------
6262
type TRemaining = [...TFirst, ...TDigit]
6363
const Remaining = [...First, ...Digit]
@@ -76,7 +76,7 @@ function TakeRemaining<Input extends string>(input: Input, result: string = ''):
7676
) as never
7777
}
7878
// ------------------------------------------------------------------
79-
// Take
79+
// TakeIdent
8080
// ------------------------------------------------------------------
8181
type TTakeIdent<Input extends string> = (
8282
TTakeFirst<Input> extends [infer First extends string, infer Remaining extends string]

src/token/integer.ts

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,87 @@ THE SOFTWARE.
2828

2929
// deno-fmt-ignore-file
3030

31+
import { IsResult } from './internal/result.ts'
3132
import { type TTrim, Trim } from './internal/trim.ts'
3233
import { type TTake, Take } from './internal/take.ts'
33-
3434
import { type TDigit, Digit } from './internal/char.ts'
35-
import { type TZero, Zero } from './internal/char.ts'
35+
import { type THyphen, Hyphen } from './internal/char.ts'
36+
import { type TNonZero, NonZero } from './internal/char.ts'
37+
import { type TUnderScore, UnderScore } from './internal/char.ts'
3638

37-
/** Matches if next is a BigInt literal with trailing `n` */
38-
export type TInteger<Input extends string> = (
39-
TTake<TTrim<Input>, []>
39+
// ------------------------------------------------------------------
40+
// TakeSign
41+
// ------------------------------------------------------------------
42+
type TTakeSign<Input extends string> = (
43+
TTake<Input, [THyphen]> extends [infer Sign extends string, infer Rest extends string]
44+
? [Sign, Rest]
45+
: ['', Input]
46+
)
47+
function TakeSign<Input extends string>(input: Input): TTakeSign<Input> {
48+
const result = Take(input, [Hyphen])
49+
return (
50+
IsResult(result) ? result : ['', input]
51+
) as never
52+
}
53+
// ------------------------------------------------------------------
54+
// TakeNonZero
55+
// ------------------------------------------------------------------
56+
type TTakeNonZero<Input extends string> = (
57+
TTake<Input, TNonZero>
58+
)
59+
function TakeNonZero<Input extends string>(input: Input): TTakeNonZero<Input> {
60+
return Take(input, NonZero)
61+
}
62+
// ------------------------------------------------------------------
63+
// TakeDigits
64+
// ------------------------------------------------------------------
65+
type TTakeDigits<Input extends string, Result extends string = ''> = (
66+
TTake<Input, TDigit> extends [infer Digit extends string, infer Rest extends string]
67+
? TTakeDigits<Rest, `${Result}${Digit}`>
68+
: [Result, Input]
69+
)
70+
function TakeDigits<Input extends string>(input: Input, result: string = ''): TTakeDigits<Input> {
71+
const takeResult = Take(input, Digit) as [string, string]
72+
return (
73+
IsResult(takeResult)
74+
? TakeDigits(takeResult[1] as never, `${result}${takeResult[0]}`)
75+
: [result, input]
76+
) as never
77+
}
78+
// ------------------------------------------------------------------
79+
// TakeInteger
80+
// ------------------------------------------------------------------
81+
type TTakeInteger<Input extends string> = (
82+
TTakeSign<Input> extends [infer Sign extends string, infer Rest extends string]
83+
? TTakeNonZero<Rest> extends [infer NonZero extends string, infer Rest extends string]
84+
? TTakeDigits<Rest> extends [infer Digits extends string, infer Rest extends string]
85+
? [`${Sign}${NonZero}${Digits}`, Rest]
86+
: [] // fail: did not match Digits
87+
: [] // fail: did not match NonZero
88+
: [] // fail: did not match Sign
4089
)
41-
/** Matches if next is a BigInt literal with trailing `n` */
90+
function TakeInteger<Input extends string>(input: Input): TTakeInteger<Input> {
91+
const signResult = TakeSign(input)
92+
return (
93+
IsResult(signResult) ? (() => {
94+
const nonZeroResult = TakeNonZero(signResult[1])
95+
return IsResult(nonZeroResult) ? (() => {
96+
const digitsResult = TakeDigits(nonZeroResult[1])
97+
return IsResult(digitsResult)
98+
? [`${signResult[0]}${nonZeroResult[0]}${digitsResult[0]}`, digitsResult[1]]
99+
: [] // fail: did not match Digits
100+
})() : [] // fail: did not match NonZero
101+
})() : [] // fail: did not match Sign
102+
) as never
103+
}
104+
/** Matches if next is a Integer */
105+
export type TInteger<Input extends string,
106+
Trimmed extends string = TTrim<Input>
107+
> = TTakeInteger<Trimmed>
108+
/** Matches if next is a Integer */
42109
export function Integer<Input extends string>
43110
(input: Input): TInteger<Input> {
44-
return Take(Trim(input), []) as never
111+
const trimmed = Trim(input)
112+
return TakeInteger(trimmed) as never
45113
}
46114

src/token/internal/char.ts

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,32 +26,41 @@ THE SOFTWARE.
2626
2727
---------------------------------------------------------------------------*/
2828

29+
// deno-fmt-ignore-file
30+
31+
// ------------------------------------------------------------------
32+
// Range
33+
// ------------------------------------------------------------------
34+
function Range(start: number, end: number): string[] {
35+
return Array.from({ length: end - start + 1 }, (_, i) => String.fromCharCode(start + i))
36+
}
2937
// ------------------------------------------------------------------
3038
// Alphas
3139
// ------------------------------------------------------------------
32-
export type TAlpha = typeof Alpha
33-
34-
// deno-fmt-ignore
35-
export const Alpha = [
40+
export type TAlpha = [
3641
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
3742
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
3843
'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
3944
'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F',
4045
'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
4146
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
4247
'W', 'X', 'Y', 'Z',
43-
] as const
48+
]
49+
export const Alpha = [
50+
...Range(97, 122), // Lowercase
51+
...Range(65, 90) // Uppercase
52+
] as TAlpha
4453

4554
// ------------------------------------------------------------------
4655
// Digits
4756
// ------------------------------------------------------------------
48-
export type TNonZero = typeof NonZero
4957
export type TZero = typeof Zero
50-
export type TDigit = typeof Digit
58+
export type TNonZero = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
59+
export type TDigit = [TZero, ...TNonZero]
5160

52-
export const NonZero = ['1', '2', '3', '4', '5', '6', '7', '8', '9'] as const
5361
export const Zero = '0'
54-
export const Digit = [Zero, ...NonZero] as const
62+
export const NonZero = Range(49, 57) as TNonZero // 1 - 9
63+
export const Digit = [Zero, ...NonZero] as TDigit
5564

5665
// ------------------------------------------------------------------
5766
// Characters
@@ -64,6 +73,7 @@ export const DollarSign = '$'
6473
export const SingleQuote = "'"
6574
export const DoubleQuote = '"'
6675
export const BackTick = '`'
76+
export const Hyphen = '-'
6777

6878
export type TWhiteSpace = typeof WhiteSpace
6979
export type TNewLine = typeof NewLine
@@ -73,3 +83,4 @@ export type TDollarSign = typeof DollarSign
7383
export type TSingleQuote = typeof SingleQuote
7484
export type TDoubleQuote = typeof DoubleQuote
7585
export type TBackTick = typeof BackTick
86+
export type THyphen = typeof Hyphen

src/token/internal/result.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { Guard } from '../guard/index.ts'
2+
3+
export function IsResult(value: unknown): value is [string, string] {
4+
return Guard.IsArray(value) && Guard.IsEqual(value.length, 2)
5+
}

src/token/span.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ THE SOFTWARE.
2828

2929
// deno-fmt-ignore-file
3030

31+
import { Guard } from '../guard/index.ts'
3132
import { type TTrim, Trim } from './internal/trim.ts'
32-
import { type TUntil, Until } from './until.ts'
3333
import { type TNewLine, NewLine } from './internal/char.ts'
34-
import { Guard } from "../guard/index.ts"
34+
import { type TUntil, Until } from './until.ts'
3535

3636
// ------------------------------------------------------------------
3737
// MultiLine
@@ -50,9 +50,9 @@ function MultiLine<Input extends string, Start extends string, End extends strin
5050
TMultiLine<Input, Start, End> {
5151
return (
5252
input.startsWith(start) ? (() => {
53-
const result = Until(input.slice(start.length), [end]) as [string, string]
54-
return Guard.IsEqual(result.length, 2) ? (() => {
55-
const [left, right] = result
53+
const untilResult = Until(input.slice(start.length), [end]) as [string, string]
54+
return Guard.IsEqual(untilResult.length, 2) ? (() => {
55+
const [left, right] = untilResult
5656
return right.startsWith(end)
5757
? [`${start}${left}${end}`, right.slice(end.length)]
5858
: [] // fail: did not match End
@@ -76,9 +76,9 @@ function SingleLine<Input extends string, Start extends string, End extends stri
7676
(input: Input, start: Start, end: End): TSingleLine<Input, Start, End> {
7777
return (
7878
input.startsWith(start) ? (() => {
79-
const result = Until(input.slice(start.length), [NewLine, end]) as [string, string]
80-
return Guard.IsEqual(result.length, 2) ? (() => {
81-
const [left, right] = result
79+
const untilResult = Until(input.slice(start.length), [NewLine, end]) as [string, string]
80+
return Guard.IsEqual(untilResult.length, 2) ? (() => {
81+
const [left, right] = untilResult
8282
return right.startsWith(end)
8383
? [`${start}${left}${end}`, right.slice(end.length)]
8484
: [] // fail: did not match End

src/token/string.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export function String<Input extends string>(input: Input): TString<Input> {
4343
const result = Span(input, SingleQuote, SingleQuote, false)
4444
return (
4545
Guard.IsEqual(result.length, 2)
46-
? result
46+
? result
4747
: Span(input, DoubleQuote, DoubleQuote, false)
4848
) as never
4949
}

0 commit comments

Comments
 (0)