Skip to content

Commit 66c7ee3

Browse files
committed
Unsigned | Match
1 parent 39f5c56 commit 66c7ee3

File tree

14 files changed

+376
-299
lines changed

14 files changed

+376
-299
lines changed

src/token/bigint.ts

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

2929
// deno-fmt-ignore-file
3030

31-
import { IsResult } from './internal/result.ts'
31+
import { Match } from './internal/match.ts'
3232
import { type TTake, Take } from './internal/take.ts'
3333
import { type TInteger, Integer } from './integer.ts'
3434

@@ -37,21 +37,17 @@ import { type TInteger, Integer } from './integer.ts'
3737
// ------------------------------------------------------------------
3838
type TTakeBigInt<Input extends string> = (
3939
TInteger<Input> extends [infer Integer extends string, infer IntegerRest extends string]
40-
? TTake<['n'], IntegerRest> extends [infer N extends string, infer NRest extends string]
40+
? TTake<['n'], IntegerRest> extends [infer _N extends string, infer NRest extends string]
4141
? [`${Integer}`, NRest]
4242
: [] // fail: did not match 'n'
4343
: [] // fail: did not match Integer
4444
)
4545
function TakeBigInt<Input extends string>(input: Input): TTakeBigInt<Input> {
46-
const integer = Integer(input)
47-
return (
48-
IsResult(integer) ? (() => {
49-
const n = Take(['n'], integer[1])
50-
return IsResult(n)
51-
? [`${integer[0]}`, n[1]]
52-
: [] // fail: did not match 'n'
53-
})() : [] // fail: did not match Integer
54-
) as never
46+
return Match(Integer(input), (Integer, IntegerRest) =>
47+
Match(Take(['n'], IntegerRest), (_N, NRest) =>
48+
[`${Integer}`, NRest],
49+
() => []), // fail: did not match 'n'
50+
() => []) as never // fail: did not match Integer
5551
}
5652
// ------------------------------------------------------------------
5753
// BigInt

src/token/ident.ts

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

2929
// deno-fmt-ignore-file
3030

31-
import { IsResult } from './internal/result.ts'
31+
import { Match } from './internal/match.ts'
3232
import { type TTrim, Trim } from './internal/trim.ts'
3333
import { type TTake, Take } from './internal/take.ts'
3434

@@ -61,12 +61,9 @@ type TTakeRemaining<Input extends string, Result extends string = ''> = (
6161
: [Result, Input]
6262
)
6363
function TakeRemaining<Input extends string>(input: Input, result: string = ''): TTakeRemaining<Input> {
64-
const remaining = Take(Remaining, input) as string[]
65-
return (
66-
IsResult(remaining)
67-
? TakeRemaining(remaining[1], `${result}${remaining[0]}`)
68-
: [result, input]
69-
) as never
64+
return Match(Take(Remaining, input), (Remaining, RemainingRest) =>
65+
TakeRemaining(RemainingRest, `${result}${Remaining}`),
66+
() => [result, input]) as never
7067
}
7168
// ------------------------------------------------------------------
7269
// TakeIdent
@@ -79,15 +76,11 @@ type TTakeIdent<Input extends string> = (
7976
: [] // fail: did not match Initial
8077
)
8178
function TakeIdent<Input extends string>(input: Input): TTakeIdent<Input> {
82-
const initial = TakeInitial(input) as string[]
83-
return (
84-
IsResult(initial) ? (() => {
85-
const remaining = TakeRemaining(initial[1])
86-
return IsResult(remaining)
87-
? [`${initial[0]}${remaining[0]}`, remaining[1]]
88-
: [] // fail: did not match Remaining
89-
})() : [] // fail: did not match Initial
90-
) as never
79+
return Match(TakeInitial(input), (Initial, InitialRest) =>
80+
Match(TakeRemaining(InitialRest), (Remaining, RemainingRest) =>
81+
[`${Initial}${Remaining}`, RemainingRest],
82+
() => []), // fail: did not match Remaining
83+
() => []) as never // fail: did not match Initial
9184
}
9285
// ------------------------------------------------------------------
9386
// Ident

src/token/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,7 @@ export * from './number.ts'
3434
export * from './rest.ts'
3535
export * from './span.ts'
3636
export * from './string.ts'
37+
export * from './unsigned_integer.ts'
38+
export * from './unsigned_number.ts'
3739
export * from './until_1.ts'
3840
export * from './until.ts'

src/token/integer.ts

Lines changed: 19 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,12 @@ THE SOFTWARE.
2828

2929
// deno-fmt-ignore-file
3030

31-
import { IsResult } from './internal/result.ts'
31+
import { Match } from './internal/match.ts'
3232
import { type TTrim, Trim } from './internal/trim.ts'
33-
import { type TTake, Take } from './internal/take.ts'
34-
import { type TMany, Many } from './internal/many.ts'
3533
import { type TOptional, Optional } from './internal/optional.ts'
36-
37-
import { type TDigit, Digit } from './internal/char.ts'
3834
import { type THyphen, Hyphen } from './internal/char.ts'
39-
import { type TZero, Zero } from './internal/char.ts'
40-
import { type TNonZero, NonZero } from './internal/char.ts'
41-
import { type TUnderScore, UnderScore } from './internal/char.ts'
35+
36+
import { type TUnsignedInteger, UnsignedInteger } from './unsigned_integer.ts'
4237

4338
// ------------------------------------------------------------------
4439
// TakeSign
@@ -50,68 +45,30 @@ function TakeSign<Input extends string>(input: Input): TTakeSign<Input> {
5045
return Optional(Hyphen, input) as never
5146
}
5247
// ------------------------------------------------------------------
53-
// TakeNonZero
54-
// ------------------------------------------------------------------
55-
type TTakeNonZero<Input extends string> = (
56-
TTake<TNonZero, Input>
57-
)
58-
function TakeNonZero<Input extends string>(input: Input): TTakeNonZero<Input> {
59-
return Take(NonZero, input)
60-
}
61-
// ------------------------------------------------------------------
62-
// TakeDigits
48+
// TakeSignedInteger
6349
// ------------------------------------------------------------------
64-
type TAllowedDigits = [...TDigit, TUnderScore]
65-
const AllowedDigits = [...Digit, UnderScore] as TAllowedDigits
66-
// ...
67-
type TTakeDigits<Input extends string> = (
68-
TMany<TAllowedDigits, [TUnderScore], Input>
69-
)
70-
function TakeDigits<Input extends string>(input: Input): TTakeDigits<Input> {
71-
return Many(AllowedDigits, [UnderScore], input) as never
72-
}
73-
// ------------------------------------------------------------------
74-
// TakeInteger
75-
// ------------------------------------------------------------------
76-
type TTakeInteger<Input extends string> = (
50+
type TTakeSignedInteger<Input extends string> = (
7751
TTakeSign<Input> extends [infer Sign extends string, infer SignRest extends string]
78-
? TTake<[TZero], SignRest> extends [infer Zero extends string, infer ZeroRest extends string]
79-
? [`${Sign}${Zero}`, ZeroRest]
80-
: TTakeNonZero<SignRest> extends [infer NonZero extends string, infer NonZeroRest extends string]
81-
? TTakeDigits<NonZeroRest> extends [infer Digits extends string, infer DigitsRest extends string]
82-
? [`${Sign}${NonZero}${Digits}`, DigitsRest]
83-
: [] // fail: did not match Digits
84-
: [] // fail: did not match NonZero
52+
? TUnsignedInteger<SignRest> extends [infer UnsignedInteger extends string, infer UnsignedIntegerRest extends string]
53+
? [`${Sign}${UnsignedInteger}`, UnsignedIntegerRest]
54+
: [] // fail: did not match unsigned integer
8555
: [] // fail: did not match Sign
8656
)
87-
function TakeInteger<Input extends string>(input: Input): TTakeInteger<Input> {
88-
const sign = TakeSign(input)
89-
return (
90-
IsResult(sign) ? (() => {
91-
const zero = Take([Zero], sign[1])
92-
return IsResult(zero)
93-
? [`${sign[0]}${zero[0]}`, zero[1]]
94-
: (() => {
95-
const nonZero = TakeNonZero(sign[1])
96-
return IsResult(nonZero) ? (() => {
97-
const digits = TakeDigits(nonZero[1])
98-
return IsResult(digits)
99-
? [`${sign[0]}${nonZero[0]}${digits[0]}`, digits[1]]
100-
: [] // fail: did not match Digits
101-
})() : [] // fail: did not match NonZero
102-
})()
103-
})() : [] // fail: did not match Sign
104-
) as never
57+
function TakeSignedInteger<Input extends string>(input: Input): TTakeSignedInteger<Input> {
58+
return Match(TakeSign(input), (Sign, SignRest) =>
59+
Match(UnsignedInteger(SignRest), (UnsignedInteger, UnsignedIntegerRest) =>
60+
[`${Sign}${UnsignedInteger}`, UnsignedIntegerRest],
61+
() => []), // fail: did not match unsigned integer
62+
() => []) as never // fail: did not match Sign
10563
}
10664
// ------------------------------------------------------------------
10765
// Integer
10866
// ------------------------------------------------------------------
109-
/** Matches if next is a Integer */
67+
/** Matches if next is a signed or unsigned Integer */
11068
export type TInteger<Input extends string> = (
111-
TTakeInteger<TTrim<Input>>
69+
TTakeSignedInteger<TTrim<Input>>
11270
)
113-
/** Matches if next is a Integer */
71+
/** Matches if next is a signed or unsigned Integer */
11472
export function Integer<Input extends string>(input: Input): TInteger<Input> {
115-
return TakeInteger(Trim(input)) as never
116-
}
117-
73+
return TakeSignedInteger(Trim(input)) as never
74+
}

src/token/internal/many.ts

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

2929
// deno-fmt-ignore-file
3030

31-
import { IsResult } from './result.ts'
31+
import { Match } from './match.ts'
3232
import { type TTake, Take } from './take.ts'
3333

3434
// ------------------------------------------------------------------
@@ -58,15 +58,10 @@ export type TMany<Allowed extends string[], Discard extends string[], Input exte
5858
: [Result, Input]
5959
)
6060
/** Takes characters from the Input until no-match. The Discard set is used to omit characters from the match */
61-
export function Many<Allowed extends string[], Discard extends string[], Input extends string>
62-
(allowed: [...Allowed], discard: [...Discard], input: Input, result: string = ''):
63-
TMany<Allowed, Discard, Input> {
64-
const takeResult = Take(allowed, input) as [string, string]
65-
return (
66-
IsResult(takeResult)
67-
? IsDiscard(discard, takeResult[0])
68-
? Many(allowed, discard, takeResult[1], result)
69-
: Many(allowed, discard, takeResult[1], `${result}${takeResult[0]}`)
70-
: [result, input]
71-
) as never
61+
export function Many<Allowed extends string[], Discard extends string[], Input extends string>(allowed: [...Allowed], discard: [...Discard], input: Input, result: string = ''): TMany<Allowed, Discard, Input> {
62+
return Match(Take(allowed, input), (Char, Rest) =>
63+
IsDiscard(discard, Char)
64+
? Many(allowed, discard, Rest, result)
65+
: Many(allowed, discard, Rest, `${result}${Char}`),
66+
() => [result, input]) as never
7267
}
Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,15 @@ THE SOFTWARE.
2626
2727
---------------------------------------------------------------------------*/
2828

29-
import { IsArray, IsEqual } from './guard.ts'
29+
import { IsEqual } from './guard.ts'
30+
31+
type TResult = [string, string] | []
3032

3133
/** Checks the value is a Tuple-2 [string, string] result */
32-
export function IsResult(value: unknown): value is [string, string] {
33-
return IsArray(value) && IsEqual(value.length, 2)
34+
export function IsMatch(value: TResult): value is [string, string] {
35+
return IsEqual(value.length, 2)
36+
}
37+
/** Matches on a result and dispatches either left or right arm */
38+
export function Match(input: TResult, ok: (value: string, rest: string) => TResult, fail: () => TResult): TResult {
39+
return IsMatch(input) ? ok(input[0], input[1]) : fail()
3440
}

src/token/internal/optional.ts

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

2929
// deno-fmt-ignore-file
3030

31-
import { IsResult } from './result.ts'
31+
import { Match } from './match.ts'
3232
import { type TTake, Take } from './take.ts'
3333

3434
/** Matches the given Value or empty string if no match. This function never fails */
@@ -38,12 +38,8 @@ export type TOptional<Value extends string, Input extends string> = (
3838
: ['', Input]
3939
)
4040
/** Matches the given Value or empty string if no match. This function never fails */
41-
export function Optional<Value extends string, Input extends string>
42-
(value: Value, input: Input): TOptional<Value, Value> {
43-
const result = Take([value], input)
44-
return (
45-
IsResult(result)
46-
? result
47-
: ['', input]
48-
) as never
41+
export function Optional<Value extends string, Input extends string>(value: Value, input: Input): TOptional<Value, Value> {
42+
return Match(Take([value], input), (Optional, Rest) =>
43+
[Optional, Rest],
44+
() => ['', input]) as never
4945
}

0 commit comments

Comments
 (0)