Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion example/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,4 @@ console.log(Json)
})
console.log(project.parser) // parser file content
console.log(project.mapping) // semantic mapping file content
}
}
38 changes: 36 additions & 2 deletions example/typebox/compiled/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,40 @@ const GenericReference = Runtime.Tuple([
// Reference
// ------------------------------------------------------------------
const Reference = Runtime.Ident()

// ------------------------------------------------------------------
// TemplateText
// ------------------------------------------------------------------
const TemplateText = Runtime.Union([
Runtime.Until('${'),
Runtime.Until('`'),
])
// ------------------------------------------------------------------
// TemplateInterpolate
// ------------------------------------------------------------------
const TemplateInterpolate = Runtime.Tuple([
Runtime.Const('${'),
Runtime.Ref('Type'),
Runtime.Const('}')
])
// ------------------------------------------------------------------
// TemplateBody
// ------------------------------------------------------------------
const TemplateBody = Runtime.Union([
Runtime.Tuple([Runtime.Ref('TemplateText'), Runtime.Ref('TemplateInterpolate'), Runtime.Ref('TemplateBody')]),
Runtime.Tuple([Runtime.Ref('TemplateText')]),
])
// ------------------------------------------------------------------
// TemplateLiteral
// ------------------------------------------------------------------
const TemplateLiteral = Runtime.Tuple([
Runtime.Const('`'),
Runtime.Ref('TemplateBody'),
Runtime.Const('`'),
])
// ------------------------------------------------------------------
// Literal
// ------------------------------------------------------------------
const LiteralString = Runtime.String([SingleQuote, DoubleQuote, Tilde])
const LiteralString = Runtime.String([SingleQuote, DoubleQuote])
const LiteralNumber = Runtime.Number()
const LiteralBoolean = Runtime.Union([Runtime.Const('true'), Runtime.Const('false')])
const Literal = Runtime.Union([
Expand Down Expand Up @@ -177,6 +206,7 @@ const Base = Runtime.Union([
Runtime.Ref('Object'),
Runtime.Ref('Tuple'),
Runtime.Ref('Literal'),
Runtime.Ref('TemplateLiteral'),
Runtime.Ref('Constructor'),
Runtime.Ref('Function'),
Runtime.Ref('Mapped'),
Expand Down Expand Up @@ -589,6 +619,10 @@ export const SyntaxModule = new Runtime.Module({
KeywordSymbol,
KeywordVoid,
Keyword,
TemplateInterpolate,
TemplateBody,
TemplateText,
TemplateLiteral,
LiteralString,
LiteralNumber,
LiteralBoolean,
Expand Down
55 changes: 54 additions & 1 deletion example/typebox/interpreted/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,60 @@ function ReferenceMapping(result: string, context: T.TProperties) {
return target
}
const Reference = Runtime.Ident((result, context) => ReferenceMapping(result, context))
// ------------------------------------------------------------------
// TemplateText
// ------------------------------------------------------------------
function TemplateTextMapping(input: string) {
return T.Literal(input)
}
const TemplateText = Runtime.Union([
Runtime.Until('${'),
Runtime.Until('`'),
], TemplateTextMapping)
// ------------------------------------------------------------------
// TemplateInterpolate
// ------------------------------------------------------------------
function TemplateInterpolateMapping(input: [unknown, unknown, unknown]) {
return input[1]
}
const TemplateInterpolate = Runtime.Tuple([
Runtime.Const('${'),
Runtime.Ref('Type'),
Runtime.Const('}')
], TemplateInterpolateMapping)
// ------------------------------------------------------------------
// TemplateBody
// ------------------------------------------------------------------
function TemplateBodyMapping(input: [unknown] | [unknown, unknown, unknown]) {
return (
input.length === 3
? [input[0], input[1], ...input[2] as unknown[]]
: [input[0]]
)
}
const TemplateBody = Runtime.Union([
Runtime.Tuple([Runtime.Ref('TemplateText'), Runtime.Ref('TemplateInterpolate'), Runtime.Ref('TemplateBody')]),
Runtime.Tuple([Runtime.Ref('TemplateText')]),
], TemplateBodyMapping)
// ------------------------------------------------------------------
// TemplateLiteral
// ------------------------------------------------------------------
function TemplateLiteralMapping(input: [unknown, unknown, unknown]) {
return T.TemplateLiteral(input[1] as T.TTemplateLiteralKind[])
}
const TemplateLiteral = Runtime.Tuple([
Runtime.Const('`'),
Runtime.Ref('TemplateBody'),
Runtime.Const('`'),
], TemplateLiteralMapping)

// ------------------------------------------------------------------
// Literal
// ------------------------------------------------------------------
const Literal = Runtime.Union([
Runtime.Union([Runtime.Const('true'), Runtime.Const('false')], value => T.Literal(value === 'true')),
Runtime.Number(value => T.Literal(parseFloat(value))),
Runtime.String([SingleQuote, DoubleQuote, Tilde], value => T.Literal(value))
Runtime.String([SingleQuote, DoubleQuote], value => T.Literal(value))
])
// ------------------------------------------------------------------
// Keyword
Expand Down Expand Up @@ -208,6 +255,7 @@ const Base = Runtime.Union([
Runtime.Ref('Object'),
Runtime.Ref('Tuple'),
Runtime.Ref('Literal'),
Runtime.Ref('TemplateLiteral'),
Runtime.Ref('Constructor'),
Runtime.Ref('Function'),
Runtime.Ref('Mapped'),
Expand Down Expand Up @@ -630,12 +678,17 @@ const Date = Runtime.Const('Date', Runtime.As(T.Date()))
// Uint8Array
// ------------------------------------------------------------------
const Uint8Array = Runtime.Const('Uint8Array', Runtime.As(T.Uint8Array()))

// ------------------------------------------------------------------
// Module
// ------------------------------------------------------------------
export const Module = new Runtime.Module({
GenericArgumentsList,
GenericArguments,
TemplateInterpolate,
TemplateBody,
TemplateText,
TemplateLiteral,
Literal,
Keyword,
KeyOf,
Expand Down
53 changes: 52 additions & 1 deletion example/typebox/interpreted/static.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,56 @@ type Dereference<Context extends T.TProperties, Ref extends string> = (
Ref extends keyof Context ? Context[Ref] : T.TRef<Ref>
)
// ------------------------------------------------------------------
// TemplateText
// ------------------------------------------------------------------
interface TemplateTextMapping extends Static.IMapping {
output: this['input'] extends string ? T.TLiteral<this['input']> : never
}
type TemplateText = Static.Union<[
Static.Until<'${'>,
Static.Until<'`'>,
], TemplateTextMapping>
// ------------------------------------------------------------------
// TemplateInterpolate
// ------------------------------------------------------------------
interface TemplateInterpolateMapping extends Static.IMapping {
output: this['input'] extends ['${', infer Type extends T.TSchema, '}']
? Type
: never
}
type TemplateInterpolate = Static.Tuple<[
Static.Const<'${'>,
Type,
Static.Const<'}'>
], TemplateInterpolateMapping>
// ------------------------------------------------------------------
// TemplateBody
// ------------------------------------------------------------------
interface TemplateBodyMapping extends Static.IMapping {
output: (
this['input'] extends [infer Text extends T.TSchema, infer Type extends T.TSchema, infer Rest extends T.TSchema[]] ? [Text, Type, ...Rest] :
this['input'] extends [infer Text extends T.TSchema] ? [Text] :
[]
)
}
type TemplateBody = Static.Union<[
Static.Tuple<[TemplateText, TemplateInterpolate, TemplateBody]>,
Static.Tuple<[TemplateText]>,
], TemplateBodyMapping>
// ------------------------------------------------------------------
// TemplateLiteral
// ------------------------------------------------------------------
interface TemplateLiteralMapping extends Static.IMapping {
output: this['input'] extends ['`', infer Types extends T.TTemplateLiteralKind[], '`']
? T.TTemplateLiteral<Types>
: never
}
type TemplateLiteral = Static.Tuple<[
Static.Const<'`'>,
TemplateBody,
Static.Const<'`'>,
], TemplateLiteralMapping>
// ------------------------------------------------------------------
// GenericArguments
// ------------------------------------------------------------------
type GenericArgumentsContext<Args extends string[], Context extends T.TProperties, Result extends T.TProperties = {}> = (
Expand Down Expand Up @@ -154,7 +204,7 @@ interface LiteralStringMapping extends Static.IMapping {
type Literal = Static.Union<[
Static.Union<[Static.Const<'true'>, Static.Const<'false'>], LiteralBooleanMapping>,
Static.Number<LiteralNumberMapping>,
Static.String<[DoubleQuote, SingleQuote, Tilde], LiteralStringMapping>,
Static.String<[DoubleQuote, SingleQuote], LiteralStringMapping>,
]>
// ------------------------------------------------------------------
// Keyword
Expand Down Expand Up @@ -230,6 +280,7 @@ type Base = Static.Union<[
Object,
Tuple,
Literal,
TemplateLiteral,
Function,
Constructor,
Mapped,
Expand Down
22 changes: 22 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ License: MIT
- [Tuple](#Tuple)
- [Union](#Union)
- [Array](#Array)
- [Until](#Until)
- [Optional](#Optional)
- [Epsilon](#Epsilon)
- [Terminals](#Terminals)
Expand Down Expand Up @@ -186,6 +187,27 @@ const R2 = Runtime.Parse(T, 'X X X Y Z') // const R2 = [['X', 'X', '
const R3 = Runtime.Parse(T, 'Y Z') // const R3 = [[], 'Y Z']
```

### Until

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.

**BNF**

```bnf
<T> ::= ? any character until 'Z' ?
```

**TypeScript**

```typescript
const T = Runtime.Until('Z') // const T = {
// type: 'Until',
// value: 'X'
// }

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

### Optional

The Optional combinator parses zero or one occurrence of the interior parser, returning a tuple with one element or an empty tuple if there is no match.
Expand Down
4 changes: 4 additions & 0 deletions src/compile/common/comment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ function FromRef(parser: Runtime.IRef): string {
function FromConst(parser: Runtime.IConst): string {
return `'${Escape(parser.value)}'`
}
function FromUntil(parser: Runtime.IUntil): string {
return `string`
}
function FromIdent(parser: Runtime.IIdent): string {
return `<Ident>`
}
Expand All @@ -71,6 +74,7 @@ function FromParser(parser: Runtime.IParser): string {
Runtime.IsOptional(parser) ? FromOptional(parser) :
Runtime.IsString(parser) ? FromString(parser) :
Runtime.IsConst(parser) ? FromConst(parser) :
Runtime.IsUntil(parser) ? FromUntil(parser) :
Runtime.IsRef(parser) ? FromRef(parser) :
Runtime.IsIdent(parser) ? FromIdent(parser) :
Runtime.IsNumber(parser) ? FromNumber(parser) :
Expand Down
4 changes: 4 additions & 0 deletions src/compile/common/infer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ function InferOptional(parser: Runtime.IParser) {
function InferConst(parser: Runtime.IConst) {
return `'${parser.value}'`
}
function InferUntil(parser: Runtime.IUntil) {
return `string`
}
export function Infer(parser: Runtime.IParser): string {
return (
Runtime.IsContext(parser) ? InferContext(parser.right, parser.right) :
Expand All @@ -58,6 +61,7 @@ export function Infer(parser: Runtime.IParser): string {
Runtime.IsOptional(parser) ? InferOptional(parser.parser) :
Runtime.IsRef(parser) ? `unknown` :
Runtime.IsConst(parser) ? InferConst(parser) :
Runtime.IsUntil(parser) ? InferUntil(parser) :
Runtime.IsString(parser) ? `string` :
Runtime.IsIdent(parser) ? `string` :
Runtime.IsNumber(parser) ? `string` :
Expand Down
7 changes: 7 additions & 0 deletions src/compile/func/func.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ function FromConst(options: Options, name: string, value: string): string {
return `Runtime.Token.Const('${Escape(value)}', input)`
}
// ------------------------------------------------------------------
// Const
// ------------------------------------------------------------------
function FromUntil(options: Options, name: string, value: string): string {
return `Runtime.Token.Until('${Escape(value)}', input)`
}
// ------------------------------------------------------------------
// Ident
// ------------------------------------------------------------------
function FromIdent(options: Options, name: string): string {
Expand Down Expand Up @@ -119,6 +125,7 @@ function FromParser(options: Options, name: string, parser: Runtime.IParser): st
Runtime.IsOptional(parser) ? FromOptional(options, name, parser) :
Runtime.IsString(parser) ? FromString(options, name, parser.options) :
Runtime.IsConst(parser) ? FromConst(options, name, parser.value) :
Runtime.IsUntil(parser) ? FromUntil(options, name, parser.value) :
Runtime.IsRef(parser) ? FromRef(options, name, parser.ref) :
Runtime.IsIdent(parser) ? FromIdent(options, name) :
Runtime.IsNumber(parser) ? FromNumber(options, name) :
Expand Down
Loading