Skip to content

Commit 5073309

Browse files
committed
Revision 0.9.4
1 parent 83f8ea8 commit 5073309

File tree

14 files changed

+248
-196
lines changed

14 files changed

+248
-196
lines changed

example/typebox/interpreted/runtime.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,7 @@ const Reference = Runtime.Ident((result, context) => ReferenceMapping(result, co
139139
function TemplateTextMapping(input: string) {
140140
return T.Literal(input)
141141
}
142-
const TemplateText = Runtime.Union([
143-
Runtime.Until('${'),
144-
Runtime.Until('`'),
145-
], TemplateTextMapping)
142+
const TemplateText = Runtime.Until(['`', '${'], TemplateTextMapping)
146143
// ------------------------------------------------------------------
147144
// TemplateInterpolate
148145
// ------------------------------------------------------------------

readme.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,20 +189,20 @@ const R3 = Runtime.Parse(T, 'Y Z') // const R3 = [[], 'Y Z']
189189

190190
### Until
191191

192-
The Until combinator parses all characters up to (but not including) the specified string. The specified string remains unconsumed in the input. If the string is not found, parsing fails.
192+
The Until combinator will parse characters up to (but not including) one of the specified sentinel string values. If a sentinel value is not found, parsing fails.
193193

194194
**BNF**
195195

196196
```bnf
197-
<T> ::= ? any character until 'Z' ?
197+
<T> ::= ? any character until ['Z'] ?
198198
```
199199

200200
**TypeScript**
201201

202202
```typescript
203-
const T = Runtime.Until('Z') // const T = {
203+
const T = Runtime.Until(['Z']) // const T = {
204204
// type: 'Until',
205-
// value: 'Z'
205+
// values: ['Z']
206206
// }
207207

208208
const R = Runtime.Parse(T, 'X Y Z') // const R = ['X Y ', 'Z']

src/compile/func/func.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,9 @@ function FromConst(options: Options, name: string, value: string): string {
8585
// ------------------------------------------------------------------
8686
// Const
8787
// ------------------------------------------------------------------
88-
function FromUntil(options: Options, name: string, value: string): string {
89-
return `Runtime.Token.Until('${Escape(value)}', input)`
88+
function FromUntil(options: Options, name: string, values: string[]): string {
89+
const escaped = values.map(value => `'${Escape(value)}'`)
90+
return `Runtime.Token.Until(${escaped.join(', ')}, input)`
9091
}
9192
// ------------------------------------------------------------------
9293
// Ident
@@ -125,7 +126,7 @@ function FromParser(options: Options, name: string, parser: Runtime.IParser): st
125126
Runtime.IsOptional(parser) ? FromOptional(options, name, parser) :
126127
Runtime.IsString(parser) ? FromString(options, name, parser.options) :
127128
Runtime.IsConst(parser) ? FromConst(options, name, parser.value) :
128-
Runtime.IsUntil(parser) ? FromUntil(options, name, parser.value) :
129+
Runtime.IsUntil(parser) ? FromUntil(options, name, parser.values) :
129130
Runtime.IsRef(parser) ? FromRef(options, name, parser.ref) :
130131
Runtime.IsIdent(parser) ? FromIdent(options, name) :
131132
Runtime.IsNumber(parser) ? FromNumber(options, name) :

src/compile/type/type.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,9 @@ function FromConst(options: Options, name: string, value: string): string {
8787
// ------------------------------------------------------------------
8888
// Until
8989
// ------------------------------------------------------------------
90-
function FromUntil(options: Options, name: string, value: string): string {
91-
return `Static.Token.Until<'${Escape(value)}', Input>`
90+
function FromUntil(options: Options, name: string, values: string[]): string {
91+
const escaped = values.map(value => `'${Escape(value)}'`)
92+
return `Static.Token.Until<${escaped.join(', ')}, Input>`
9293
}
9394
// ------------------------------------------------------------------
9495
// Ident
@@ -127,7 +128,7 @@ function FromParser(options: Options, name: string, parser: Runtime.IParser): st
127128
Runtime.IsOptional(parser) ? FromOptional(options, name, parser) :
128129
Runtime.IsString(parser) ? FromString(options, name, parser.options) :
129130
Runtime.IsConst(parser) ? FromConst(options, name, parser.value) :
130-
Runtime.IsUntil(parser) ? FromUntil(options, name, parser.value) :
131+
Runtime.IsUntil(parser) ? FromUntil(options, name, parser.values) :
131132
Runtime.IsRef(parser) ? FromRef(options, name, parser.ref) :
132133
Runtime.IsIdent(parser) ? FromIdent(options, name) :
133134
Runtime.IsNumber(parser) ? FromNumber(options, name) :

src/runtime/parse.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,6 @@ function ParseConst<Value extends string>(value: Value, code: string, context: u
6666
return Token.Const(value, code) as never
6767
}
6868
// ------------------------------------------------------------------
69-
// Until
70-
// ------------------------------------------------------------------
71-
function ParseUntil<Value extends string>(value: Value, code: string, context: unknown): [] | [Value, string] {
72-
return Token.Until(value, code) as never
73-
}
74-
// ------------------------------------------------------------------
7569
// Ident
7670
// ------------------------------------------------------------------
7771
function ParseIdent(code: string, _context: unknown): [] | [string, string] {
@@ -129,6 +123,12 @@ function ParseUnion<ModuleProperties extends Types.IModuleProperties, Parsers ex
129123
return []
130124
}
131125
// ------------------------------------------------------------------
126+
// Until
127+
// ------------------------------------------------------------------
128+
function ParseUntil<Values extends string[]>(values: [...Values], code: string, context: unknown): [] | [string, string] {
129+
return Token.Until(values, code) as never
130+
}
131+
// ------------------------------------------------------------------
132132
// Parser
133133
// ------------------------------------------------------------------
134134
function ParseParser<Parser extends Types.IParser>(moduleProperties: Types.IModuleProperties, parser: Parser, code: string, context: unknown): [] | [Types.StaticParser<Parser>, string] {
@@ -143,7 +143,7 @@ function ParseParser<Parser extends Types.IParser>(moduleProperties: Types.IModu
143143
Types.IsString(parser) ? ParseString(parser.options, code, context) :
144144
Types.IsTuple(parser) ? ParseTuple(moduleProperties, parser.parsers, code, context) :
145145
Types.IsUnion(parser) ? ParseUnion(moduleProperties, parser.parsers, code, context) :
146-
Types.IsUntil(parser) ? ParseUntil(parser.value, code, context) :
146+
Types.IsUntil(parser) ? ParseUntil(parser.values, code, context) :
147147
[]
148148
)
149149
return (result.length === 2 ? [parser.mapping(result[0], context), result[1]] : result) as never

src/runtime/token.ts

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -233,18 +233,22 @@ export function String(options: string[], input: string) {
233233
// ------------------------------------------------------------------
234234
// Until
235235
// ------------------------------------------------------------------
236-
function UntilStartsWith(value: string, input: string) {
237-
return input.startsWith(value)
238-
}
239-
export function Until(value: string, input: string, result: string = ''): [] | [string, string] {
236+
function UntilStartsWith(value: string[], input: string): boolean {
237+
const [left, ...right] = value
238+
return (typeof left === 'string')
239+
? input.startsWith(left)
240+
? true
241+
: UntilStartsWith(right, input)
242+
: false
243+
}
244+
export function Until(value: string[], input: string, result: string = ''): [] | [string, string] {
240245
return (
241-
input === '' ? [] : (() => {
242-
return UntilStartsWith(value, input)
243-
? [result, input]
244-
: (() => {
245-
const [left, right] = [input.slice(0, 1), input.slice(1)]
246-
return Until(value, right, `${result}${left}`)
247-
})()
246+
input === '' ? [] :
247+
UntilStartsWith(value, input)
248+
? [result, input]
249+
: (() => {
250+
const [left, right] = [input.slice(0, 1), input.slice(1)]
251+
return Until(value, right, `${result}${left}`)
248252
})()
249253
)
250254
}

src/runtime/types.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -324,22 +324,22 @@ export function IsUnion(value: unknown): value is IUnion {
324324
// ------------------------------------------------------------------
325325
export interface IUntil<Output extends unknown = unknown> extends IParser<Output> {
326326
type: 'Until'
327-
value: string
327+
values: string[]
328328
}
329329
/** `[TERM]` Creates a Until Parser */
330-
export function Until<Mapping extends IMapping<string>>(value: string, mapping: Mapping): IUntil<string>
330+
export function Until<Mapping extends IMapping<string>>(values: string[], mapping: Mapping): IUntil<string>
331331
/** `[TERM]` Creates a Until Parser */
332-
export function Until(value: string): IUntil<string>
332+
export function Until(values: string[]): IUntil<string>
333333
/** `[TERM]` Creates a Until Parser */
334334
export function Until(...args: unknown[]): never {
335-
const [value, mapping] = args.length === 2 ? [args[0], args[1]] : [args[0], Identity]
336-
return { type: 'Until', value, mapping } as never
335+
const [values, mapping] = args.length === 2 ? [args[0], args[1]] : [args[0], Identity]
336+
return { type: 'Until', values, mapping } as never
337337
}
338338
/** Returns true if the value is a Until Parser */
339339
export function IsUntil(value: unknown): value is IUntil {
340340
return Guard.IsObject(value)
341341
&& Guard.HasPropertyKey(value, 'type')
342-
&& Guard.HasPropertyKey(value, 'value')
342+
&& Guard.HasPropertyKey(value, 'values')
343343
&& Guard.IsEqual(value.type, 'Until')
344-
&& Guard.IsString(value.value)
344+
&& Guard.IsArray(value.values)
345345
}

src/static/parse.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,6 @@ type ConstParser<Value extends string, Input extends string, _Context extends un
5656
: []
5757
)
5858
// ------------------------------------------------------------------
59-
// Until
60-
// ------------------------------------------------------------------
61-
type UntilParser<Value extends string, Input extends string, _Context extends unknown> = (
62-
Tokens.Until<Value, Input> extends [infer Match extends string, infer Rest extends string]
63-
? [Match, Rest]
64-
: []
65-
)
66-
// ------------------------------------------------------------------
6759
// Ident
6860
// ------------------------------------------------------------------
6961
type IdentParser<Input extends string, _Context extends unknown> = (
@@ -116,6 +108,14 @@ type UnionParser<Parsers extends Types.IParser[], Input extends string, Context
116108
: []
117109
)
118110
// ------------------------------------------------------------------
111+
// Until
112+
// ------------------------------------------------------------------
113+
type UntilParser<Values extends string[], Input extends string, _Context extends unknown> = (
114+
Tokens.Until<Values, Input> extends [infer Match extends string, infer Rest extends string]
115+
? [Match, Rest]
116+
: []
117+
)
118+
// ------------------------------------------------------------------
119119
// Parse
120120
// ------------------------------------------------------------------
121121
type ParseCode<Parser extends Types.IParser, Input extends string, Context extends unknown = unknown> = (
@@ -128,7 +128,7 @@ type ParseCode<Parser extends Types.IParser, Input extends string, Context exten
128128
Parser extends Types.String<infer Options extends string[]> ? StringParser<Options, Input, Context> :
129129
Parser extends Types.Tuple<infer Parsers extends Types.IParser[]> ? TupleParser<Parsers, Input, Context> :
130130
Parser extends Types.Union<infer Parsers extends Types.IParser[]> ? UnionParser<Parsers, Input, Context> :
131-
Parser extends Types.Until<infer Value extends string> ? UntilParser<Value, Input, Context> :
131+
Parser extends Types.Until<infer Values extends string[]> ? UntilParser<Values, Input, Context> :
132132
[]
133133
)
134134
type ParseMapping<Parser extends Types.IParser, Result extends unknown, Context extends unknown = unknown> = (

src/static/token.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -204,14 +204,18 @@ export type Ident<Code extends string> = NextIdent<Trim.TrimAll<Code>>
204204
// ------------------------------------------------------------------
205205
// Until
206206
// ------------------------------------------------------------------
207-
type UntilStartsWith<Value extends string, Input extends string> = (
208-
Input extends `${Value}${string}` ? true : false
207+
type UntilStartsWith<Values extends string[], Input extends string> = (
208+
Values extends [infer Left extends string, ...infer Right extends string[]]
209+
? Input extends `${Left}${string}`
210+
? true
211+
: UntilStartsWith<Right, Input>
212+
: false
209213
)
210-
export type Until<Value extends string, Input extends string, Result extends string = ''> = (
214+
export type Until<Values extends string[], Input extends string, Result extends string = ''> = (
211215
Input extends `` ? [] :
212-
UntilStartsWith<Value, Input> extends true
216+
UntilStartsWith<Values, Input> extends true
213217
? [Result, Input]
214218
: Input extends `${infer Left extends string}${infer Right extends string}`
215-
? Until<Value, Right, `${Result}${Left}`>
219+
? Until<Values, Right, `${Result}${Left}`>
216220
: never
217221
)

src/static/types.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,25 +88,24 @@ export interface Const<Value extends string = string, Mapping extends IMapping =
8888
// Until
8989
// ------------------------------------------------------------------
9090
/** Creates a Until Parser */
91-
export interface Until<Value extends string = string, Mapping extends IMapping = Identity> extends IParser<Mapping> {
91+
export interface Until<Values extends string[] = string[], Mapping extends IMapping = Identity> extends IParser<Mapping> {
9292
type: 'Until'
93-
value: Value
93+
values: Values
9494
}
9595
// ------------------------------------------------------------------
9696
// Ident
9797
// ------------------------------------------------------------------
98-
/** Creates an Ident Parser. */
98+
/** Creates an Ident Parser */
9999
export interface Ident<Mapping extends IMapping = Identity> extends IParser<Mapping> {
100100
type: 'Ident'
101101
}
102102
// ------------------------------------------------------------------
103103
// Number
104104
// ------------------------------------------------------------------
105-
/** Creates a Number Parser. */
105+
/** Creates a Number Parser */
106106
export interface Number<Mapping extends IMapping = Identity> extends IParser<Mapping> {
107107
type: 'Number'
108108
}
109-
110109
// ------------------------------------------------------------------
111110
// Optional
112111
// ------------------------------------------------------------------

0 commit comments

Comments
 (0)