Skip to content

Commit 94ced10

Browse files
committed
Inline
1 parent a2b03fd commit 94ced10

8 files changed

Lines changed: 176 additions & 42 deletions

File tree

src/build/project.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export function Types(module: Runtime.Module, options: Options = DefaultOptions(
7272
comment: CompileComment(key, parser),
7373
funcMap: BuildRuntimeMapping(key, parser),
7474
typeMap: BuildStaticMapping(key, parser),
75-
type: BuildStaticParse(key, parser),
75+
type: BuildStaticParse(module.parsers, key, parser),
7676
func: BuildRuntimeParse(key, parser),
7777
}
7878
})

src/build/static/parse.ts

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -42,141 +42,141 @@ const state = { reducers: new Set<string>() }
4242
// ------------------------------------------------------------------
4343
// Array
4444
// ------------------------------------------------------------------
45-
function FromArrayReducer(name: string, parser: Runtime.IParser): string {
45+
function FromArrayReducer(context: Runtime.IProperties, name: string, parser: Runtime.IParser): string {
4646
const reducer_name = `${name}_${state.reducers.size}`
47-
const reducer = `export type ${reducer_name}<Input extends string, Result extends unknown[] = []> = ${FromParser(reducer_name, parser)} extends [infer _0, infer Input extends string] ? ${reducer_name}<Input, [...Result, _0]> : [Result, Input]`
47+
const reducer = `export type ${reducer_name}<Input extends string, Result extends unknown[] = []> = ${FromParser(context, reducer_name, parser)} extends [infer _0, infer Input extends string] ? ${reducer_name}<Input, [...Result, _0]> : [Result, Input]`
4848
state.reducers.add(reducer)
4949
return reducer_name
5050
}
51-
function FromArray(name: string, parser: Runtime.IParser): string {
52-
const reducer_name = FromArrayReducer(Name(name), parser)
51+
function FromArray(context: Runtime.IProperties, name: string, parser: Runtime.IParser): string {
52+
const reducer_name = FromArrayReducer(context, Name(name), parser)
5353
return `${reducer_name}<Input>`
5454
}
5555
// ------------------------------------------------------------------
5656
// Const
5757
// ------------------------------------------------------------------
58-
function FromConst(name: string, const_: string): string {
58+
function FromConst(context: Runtime.IProperties, name: string, const_: string): string {
5959
return `Token.TConst<'${Escape(const_)}', Input>`
6060
}
6161
// ------------------------------------------------------------------
6262
// BigInt
6363
// ------------------------------------------------------------------
64-
function FromBigInt(name: string): string {
64+
function FromBigInt(context: Runtime.IProperties, name: string): string {
6565
return `Token.TBigInt<Input>`
6666
}
6767
// ------------------------------------------------------------------
6868
// Ident
6969
// ------------------------------------------------------------------
70-
function FromIdent(name: string): string {
70+
function FromIdent(context: Runtime.IProperties, name: string): string {
7171
return `Token.TIdent<Input>`
7272
}
7373
// ------------------------------------------------------------------
7474
// Integer
7575
// ------------------------------------------------------------------
76-
function FromInteger(name: string): string {
76+
function FromInteger(context: Runtime.IProperties, name: string): string {
7777
return `Token.TInteger<Input>`
7878
}
7979
// ------------------------------------------------------------------
8080
// Number
8181
// ------------------------------------------------------------------
82-
function FromNumber(name: string): string {
82+
function FromNumber(context: Runtime.IProperties, name: string): string {
8383
return `Token.TNumber<Input>`
8484
}
8585
// ------------------------------------------------------------------
8686
// Optional
8787
// ------------------------------------------------------------------
88-
function FromOptional(name: string, parser: Runtime.IOptional): string {
89-
return `(${FromParser(name, parser.parser)} extends [infer _0, infer Input extends string] ? [[_0], Input]: [[], Input])`
88+
function FromOptional(context: Runtime.IProperties, name: string, parser: Runtime.IOptional): string {
89+
return `(${FromParser(context, name, parser.parser)} extends [infer _0, infer Input extends string] ? [[_0], Input]: [[], Input])`
9090
}
9191
// ------------------------------------------------------------------
9292
// Ref
9393
// ------------------------------------------------------------------
94-
function FromRef(name: string, ref: string): string {
94+
function FromRef(context: Runtime.IProperties, name: string, ref: string): string {
9595
return `${Name(ref)}<Input>`
9696
}
9797
// ------------------------------------------------------------------
9898
// Rest
9999
// ------------------------------------------------------------------
100-
function FromRest(name: string): string {
100+
function FromRest(context: Runtime.IProperties, name: string): string {
101101
return `Token.TRest<Input>`
102102
}
103103
// ------------------------------------------------------------------
104104
// String
105105
// ------------------------------------------------------------------
106-
function FromString(name: string, quotes: string[]): string {
106+
function FromString(context: Runtime.IProperties, name: string, quotes: string[]): string {
107107
const _quotes = quotes.map((option) => `'${Escape(option)}'`).join(', ')
108108
return `Token.TString<[${_quotes}], Input>`
109109
}
110110
// ------------------------------------------------------------------
111111
// Tuple
112112
// ------------------------------------------------------------------
113-
function FromTuple(name: string, parsers: Runtime.IParser[]): string {
113+
function FromTuple(context: Runtime.IProperties, name: string, parsers: Runtime.IParser[]): string {
114114
const initial = `[[${parsers.map((_, index) => `_${index}`).join(', ')}], Input]`
115-
return parsers.reduceRight((result, right, index) => `(${FromParser(name, right)} extends [infer _${index}, infer Input extends string] ? ${result} : [])`, initial)
115+
return parsers.reduceRight((result, right, index) => `(${FromParser(context, name, right)} extends [infer _${index}, infer Input extends string] ? ${result} : [])`, initial)
116116
}
117117
// ------------------------------------------------------------------
118118
// Union
119119
// ------------------------------------------------------------------
120-
function FromUnion(name: string, parsers: Runtime.IParser[]): string {
121-
return parsers.length === 0 ? '[]' : `(${parsers.reduceRight((result, right) => `${FromParser(name, right)} extends [infer _0, infer Input extends string] ? [_0, Input] : ${result}`, '[]')})`
120+
function FromUnion(context: Runtime.IProperties, name: string, parsers: Runtime.IParser[]): string {
121+
return parsers.length === 0 ? '[]' : `(${parsers.reduceRight((result, right) => `${FromParser(context, name, right)} extends [infer _0, infer Input extends string] ? [_0, Input] : ${result}`, '[]')})`
122122
}
123123
// ------------------------------------------------------------------
124124
// UnsignedInteger
125125
// ------------------------------------------------------------------
126-
function FromUnsignedInteger(name: string): string {
126+
function FromUnsignedInteger(context: Runtime.IProperties, name: string): string {
127127
return `Token.TUnsignedInteger<Input>`
128128
}
129129
// ------------------------------------------------------------------
130130
// UnsignedNumber
131131
// ------------------------------------------------------------------
132-
function FromUnsignedNumber(name: string): string {
132+
function FromUnsignedNumber(context: Runtime.IProperties, name: string): string {
133133
return `Token.TUnsignedNumber<Input>`
134134
}
135135
// ------------------------------------------------------------------
136136
// Until_1
137137
// ------------------------------------------------------------------
138-
function FromUntil_1(name: string, end: string[]): string {
138+
function FromUntil_1(context: Runtime.IProperties, name: string, end: string[]): string {
139139
const escaped = end.map(value => `'${Escape(value)}'`)
140140
return `Token.TUntil_1<[${escaped.join(', ')}], Input>`
141141
}
142142
// ------------------------------------------------------------------
143143
// Until
144144
// ------------------------------------------------------------------
145-
function FromUntil(name: string, end: string[]): string {
145+
function FromUntil(context: Runtime.IProperties, name: string, end: string[]): string {
146146
const escaped = end.map(value => `'${Escape(value)}'`)
147147
return `Token.TUntil<[${escaped.join(', ')}], Input>`
148148
}
149149
// ------------------------------------------------------------------
150150
// Parser
151151
// ------------------------------------------------------------------
152-
function FromParser(name: string, parser: Runtime.IParser): string {
152+
function FromParser(context: Runtime.IProperties, name: string, parser: Runtime.IParser): string {
153153
return (
154-
Runtime.IsArray(parser) ? FromArray(name, parser.parser) :
155-
Runtime.IsBigInt(parser) ? FromBigInt(name) :
156-
Runtime.IsConst(parser) ? FromConst(name, parser.const) :
157-
Runtime.IsIdent(parser) ? FromIdent(name) :
158-
Runtime.IsInteger(parser) ? FromInteger(name) :
159-
Runtime.IsNumber(parser) ? FromNumber(name) :
160-
Runtime.IsOptional(parser) ? FromOptional(name, parser) :
161-
Runtime.IsRef(parser) ? FromRef(name, parser.ref) :
162-
Runtime.IsRest(parser) ? FromRest(name) :
163-
Runtime.IsString(parser) ? FromString(name, parser.quotes) :
164-
Runtime.IsTuple(parser) ? FromTuple(name, parser.parsers) :
165-
Runtime.IsUnion(parser) ? FromUnion(name, parser.parsers) :
166-
Runtime.IsUnsignedInteger(parser) ? FromUnsignedInteger(name) :
167-
Runtime.IsUnsignedNumber(parser) ? FromUnsignedNumber(name) :
168-
Runtime.IsUntil_1(parser) ? FromUntil_1(name, parser.end) :
169-
Runtime.IsUntil(parser) ? FromUntil(name, parser.end) :
154+
Runtime.IsArray(parser) ? FromArray(context, name, parser.parser) :
155+
Runtime.IsBigInt(parser) ? FromBigInt(context, name) :
156+
Runtime.IsConst(parser) ? FromConst(context, name, parser.const) :
157+
Runtime.IsIdent(parser) ? FromIdent(context, name) :
158+
Runtime.IsInteger(parser) ? FromInteger(context, name) :
159+
Runtime.IsNumber(parser) ? FromNumber(context, name) :
160+
Runtime.IsOptional(parser) ? FromOptional(context, name, parser) :
161+
Runtime.IsRef(parser) ? FromRef(context, name, parser.ref) :
162+
Runtime.IsRest(parser) ? FromRest(context, name) :
163+
Runtime.IsString(parser) ? FromString(context, name, parser.quotes) :
164+
Runtime.IsTuple(parser) ? FromTuple(context, name, parser.parsers) :
165+
Runtime.IsUnion(parser) ? FromUnion(context, name, parser.parsers) :
166+
Runtime.IsUnsignedInteger(parser) ? FromUnsignedInteger(context, name) :
167+
Runtime.IsUnsignedNumber(parser) ? FromUnsignedNumber(context, name) :
168+
Runtime.IsUntil_1(parser) ? FromUntil_1(context, name, parser.end) :
169+
Runtime.IsUntil(parser) ? FromUntil(context, name, parser.end) :
170170
Unreachable(parser)
171171
)
172172
}
173173
// ------------------------------------------------------------------
174174
// Type
175175
// ------------------------------------------------------------------
176-
export function BuildStaticParse(name: string, parser: Runtime.IParser): string {
176+
export function BuildStaticParse(context: Runtime.IProperties, name: string, parser: Runtime.IParser): string {
177177
state.reducers.clear()
178178
const semanticsType = `S.${Name(name)}Mapping`
179-
const type = `export type ${Name(name)}<Input extends string> = ${FromParser(name, parser)} extends [infer _0 extends ${Infer(parser)}, infer Input extends string] ? [${semanticsType}<_0>, Input] : []`
179+
const type = `export type ${Name(name)}<Input extends string> = ${FromParser(context, name, parser)} extends [infer _0 extends ${Infer(parser)}, infer Input extends string] ? [${semanticsType}<_0>, Input] : []`
180180
const reducers = [...state.reducers]
181181
return [...reducers, type].join('\n')
182182
}

src/runtime/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export { type IArray, Array, IsArray } from './array.ts'
3232
export { type IBigInt, BigInt, IsBigInt } from './bigint.ts'
3333
export { type IConst, Const, IsConst } from './const.ts'
3434
export { type IIdent, Ident, IsIdent } from './ident.ts'
35+
export { type IInline, Inline, IsInline } from './inline.ts'
3536
export { type IInteger, Integer, IsInteger } from './integer.ts'
3637
export { Module } from './module.ts'
3738
export { type INumber, IsNumber, Number } from './number.ts'

src/runtime/inline.ts

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*--------------------------------------------------------------------------
2+
3+
ParseBox
4+
5+
The MIT License (MIT)
6+
7+
Copyright (c) 2024-2026 Haydn Paterson
8+
9+
Permission is hereby granted, free of charge, to any person obtaining a copy
10+
of this software and associated documentation files (the "Software"), to deal
11+
in the Software without restriction, including without limitation the rights
12+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
copies of the Software, and to permit persons to whom the Software is
14+
furnished to do so, subject to the following conditions:
15+
16+
The above copyright notice and this permission notice shall be included in
17+
all copies or substantial portions of the Software.
18+
19+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
THE SOFTWARE.
26+
27+
---------------------------------------------------------------------------*/
28+
29+
// deno-fmt-ignore-file
30+
31+
import { Arguments } from '../system/arguments/index.ts'
32+
import { Guard } from '../guard/index.ts'
33+
import { type StaticParser, type StaticEnsure } from './static.ts'
34+
import { type IParser, type IProperties, type IMapping, Identity } from './parser.ts'
35+
36+
import { ParseParser } from './parse.ts'
37+
38+
// ------------------------------------------------------------------
39+
// Static
40+
// ------------------------------------------------------------------
41+
export type StaticInline<Parser extends IParser> = StaticEnsure<
42+
StaticParser<Parser>[]
43+
>
44+
// ------------------------------------------------------------------
45+
// Type
46+
// ------------------------------------------------------------------
47+
export interface IInline<Output extends unknown = unknown> extends IParser<Output> {
48+
type: 'Inline'
49+
parser: IParser
50+
}
51+
// ------------------------------------------------------------------
52+
// Factory
53+
// ------------------------------------------------------------------
54+
/** Directive to inline the parse expression instead of calling to remote function */
55+
export function Inline<Parser extends IParser, Mapping extends IMapping = IMapping<StaticInline<Parser>>>(parser: Parser, mapping: Mapping): IInline<ReturnType<Mapping>>
56+
/** Directive to inline the parse expression instead of calling to remote function */
57+
export function Inline<Parser extends IParser>(parser: Parser): IInline<StaticInline<Parser>>
58+
/** Directive to inline the parse expression instead of calling to remote function */
59+
export function Inline(...args: unknown[]): never {
60+
const [parser, mapping] = Arguments.Match<[IParser, IMapping]>(args, {
61+
2: (parser, mapping) => [parser, mapping],
62+
1: (parser) => [parser, Identity]
63+
})
64+
return { type: 'Inline', parser, mapping } as never
65+
}
66+
// ------------------------------------------------------------------
67+
// Guard
68+
// ------------------------------------------------------------------
69+
/** True if the value is a Inline parser */
70+
export function IsInline(value: unknown): value is IInline {
71+
return Guard.IsObject(value)
72+
&& Guard.HasPropertyKey(value, 'type')
73+
&& Guard.HasPropertyKey(value, 'parser')
74+
&& Guard.IsEqual(value.type, 'Inline')
75+
&& Guard.IsObject(value.parser)
76+
}
77+
// ------------------------------------------------------------------
78+
// Parse
79+
// ------------------------------------------------------------------
80+
export function ParseInline<Context extends IProperties, Parser extends IParser>(context: Context, parser: Parser, input: string): unknown[] {
81+
return ParseParser(context, parser, input)
82+
}

src/runtime/parse.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import { ParseArray, IsArray } from './array.ts'
3838
import { ParseBigInt, IsBigInt } from './bigint.ts'
3939
import { ParseConst, IsConst } from './const.ts'
4040
import { ParseIdent, IsIdent } from './ident.ts'
41+
import { ParseInline, IsInline } from './inline.ts'
4142
import { ParseInteger, IsInteger } from './integer.ts'
4243
import { ParseNumber, IsNumber } from './number.ts'
4344
import { ParseOptional, IsOptional } from './optional.ts'
@@ -61,6 +62,7 @@ export function ParseParser<Parser extends IParser>(context: IProperties, parser
6162
IsConst(parser) ? ParseConst(parser.const, input) :
6263
IsIdent(parser) ? ParseIdent(input) :
6364
IsInteger(parser) ? ParseInteger(input) :
65+
IsInline(parser) ? ParseInline(context, parser.parser, input) :
6466
IsNumber(parser) ? ParseNumber(input) :
6567
IsOptional(parser) ? ParseOptional(context, parser.parser, input) :
6668
IsRef(parser) ? ParseRef(context, parser.ref, input) :

src/static/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export type { Array } from './array.ts'
3030
export type { BigInt } from './bigint.ts'
3131
export type { Const } from './const.ts'
3232
export type { Ident } from './ident.ts'
33+
export type { Inline } from './inline.ts'
3334
export type { Integer } from './integer.ts'
3435
export type { Number } from './number.ts'
3536
export type { Optional } from './optional.ts'

src/static/inline.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*--------------------------------------------------------------------------
2+
3+
ParseBox
4+
5+
The MIT License (MIT)
6+
7+
Copyright (c) 2024-2026 Haydn Paterson
8+
9+
Permission is hereby granted, free of charge, to any person obtaining a copy
10+
of this software and associated documentation files (the "Software"), to deal
11+
in the Software without restriction, including without limitation the rights
12+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
copies of the Software, and to permit persons to whom the Software is
14+
furnished to do so, subject to the following conditions:
15+
16+
The above copyright notice and this permission notice shall be included in
17+
all copies or substantial portions of the Software.
18+
19+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
THE SOFTWARE.
26+
27+
---------------------------------------------------------------------------*/
28+
29+
// deno-fmt-ignore-file
30+
31+
import type { Identity, IMapping, IParser } from './parser.ts'
32+
import type { Parse } from './parse.ts'
33+
34+
// ------------------------------------------------------------------
35+
// Type
36+
// ------------------------------------------------------------------
37+
export interface Inline<Parser extends IParser = IParser, Mapping extends IMapping = Identity> extends IParser<Mapping> {
38+
type: 'Inline'
39+
parser: Parser
40+
}
41+
// ------------------------------------------------------------------
42+
// Parse
43+
// ------------------------------------------------------------------
44+
export type ParseInline<Parser extends IParser, Input extends string> = (
45+
Parse<Parser, Input>
46+
)

src/static/parse.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import type { Array, ParseArray } from './array.ts'
3232
import type { BigInt, ParseBigInt } from './bigint.ts'
3333
import type { Const, ParseConst } from './const.ts'
3434
import type { Ident, ParseIdent } from './ident.ts'
35+
import type { Inline, ParseInline } from './inline.ts'
3536
import type { Integer, ParseInteger } from './integer.ts'
3637
import type { Number, ParseNumber } from './number.ts'
3738
import type { Optional, ParseOptional } from './optional.ts'
@@ -55,6 +56,7 @@ type ParseInput<Input extends string, Parser extends IParser> = (
5556
Parser extends Const<infer Const extends string> ? ParseConst<Const, Input> :
5657
Parser extends Ident ? ParseIdent<Input> :
5758
Parser extends Integer ? ParseInteger<Input> :
59+
Parser extends Inline<infer Parser extends IParser> ? ParseInline<Parser, Input> :
5860
Parser extends Number ? ParseNumber<Input> :
5961
Parser extends Optional<infer Parser extends IParser> ? ParseOptional<Parser, Input> :
6062
Parser extends Rest ? ParseRest<Input> :

0 commit comments

Comments
 (0)