From 25c8c91a88aeec090022194c21737053d0cce43d Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 26 Jun 2022 19:03:48 +0300 Subject: [PATCH 001/286] wip --- foo.js | 22 ++++++++ package.json | 6 ++- src/dataTypes.ts | 19 ++++--- src/index.ts | 67 ++----------------------- src/parse.ts | 28 +++++++++++ src/tokenize.ts | 108 ++++++++++++++++++++++++++++++++++++++++ src/utils/arrayUtils.ts | 8 +-- yarn.lock | 9 ++++ 8 files changed, 189 insertions(+), 78 deletions(-) create mode 100644 foo.js create mode 100644 src/parse.ts create mode 100644 src/tokenize.ts diff --git a/foo.js b/foo.js new file mode 100644 index 0000000..dbefd45 --- /dev/null +++ b/foo.js @@ -0,0 +1,22 @@ +// const result = require('@babel/core').parse('function foo (hello: string) {}', { +// sourceType: 'module', +// plugins: [require.resolve('@babel/plugin-syntax-typescript')], +// // sourceFilename: 'foo.ts', +// // tokens: true, +// }); + +// console.log(result); + +const result = require('@babel/parser').parse('function foo (hello: Foo) {}', { + sourceType: 'module', + plugins: [ + ['typescript', { disallowAmbiguousJSXLike: undefined }], + 'classProperties', + 'objectRestSpread', + ], + ranges: false, + // sourceFilename: 'foo.ts', + // tokens: true, +}); + +console.log(JSON.stringify(result.program.body, null, 2)); diff --git a/package.json b/package.json index 13fa795..8bd5bfa 100644 --- a/package.json +++ b/package.json @@ -29,5 +29,9 @@ "semi": true, "singleQuote": true, "trailingComma": "all" + }, + "dependencies": { + "@babel/parser": "^7.18.5", + "@babel/plugin-transform-typescript": "^7.18.4" } -} \ No newline at end of file +} diff --git a/src/dataTypes.ts b/src/dataTypes.ts index eee1119..121fe71 100644 --- a/src/dataTypes.ts +++ b/src/dataTypes.ts @@ -1,14 +1,13 @@ -// Tokenizer types -export type ParenToken = { type: 'paren'; value: V }; +export type Paren = { type: 'paren'; value: V }; -export type NumberToken = { type: 'number'; value: V }; +export type Number = { type: 'number'; value: V }; -export type StringToken = { type: 'string'; value: V }; +export type String = { type: 'string'; value: V }; -export type SymbolToken = { type: 'symbol'; value: V }; +export type Symbol = { type: 'symbol'; value: V }; -export type Token = - | ParenToken - | NumberToken - | StringToken - | SymbolToken; +// export type Token = +// | ParenToken +// | NumberToken +// | StringToken +// | SymbolToken; diff --git a/src/index.ts b/src/index.ts index 60d1c59..df0b08f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,64 +1,5 @@ -import type { Reverse, Unshift } from './utils/arrayUtils'; -import type { - EatFirstChar, - FirstChar, - ConcatStrings, -} from './utils/stringUtils'; -import type { Numbers, Symbols } from './utils/generalUtils'; -import type { Token } from './dataTypes'; +import type { Tokenize } from './tokenize'; +import type { Parse } from './parse'; -type TokenizeInput = FirstChar extends ' ' | '\n' - ? ['', EatFirstChar] - : FirstChar extends '(' - ? [ - { - type: 'paren'; - value: '('; - }, - EatFirstChar, - ] - : FirstChar extends ')' - ? [ - { - type: 'paren'; - value: ')'; - }, - EatFirstChar, - ] - : FirstChar extends Numbers - ? TokenizeNumber> - : FirstChar extends '"' - ? TokenizeString> - : FirstChar extends Symbols - ? TokenizeSymbol> - : never; - -type TokenizeNumber< - I extends string, - A extends string = '', - C extends string = FirstChar, -> = C extends Numbers - ? TokenizeNumber, ConcatStrings> - : [{ type: 'number'; value: A }, I]; - -type TokenizeString = I extends `${infer H}"${infer G}` - ? [{ type: 'string'; value: H }, G] - : never; - -type TokenizeSymbol< - I extends string, - A extends string = '', - C extends string = FirstChar, -> = C extends Symbols - ? TokenizeSymbol, ConcatStrings> - : [{ type: 'symbol'; value: A }, I]; - -export type TokenizeSequence< - I extends string, - R extends Array> = [], - P extends [any, string] = TokenizeInput, -> = I extends '' - ? R - : TokenizeSequence>; - -export type Tokenize = Reverse>; +type T = Tokenize<`function foo (foo: string): bar {}`>; +type R = Parse; diff --git a/src/parse.ts b/src/parse.ts new file mode 100644 index 0000000..cd5f7aa --- /dev/null +++ b/src/parse.ts @@ -0,0 +1,28 @@ +import type { Reverse, Tail, Unshift } from './utils/arrayUtils'; + +export type ParseInput< + T extends Array, + F = T[0], +> = F extends ParenToken<'('> + ? ParseList> + : F extends SymbolToken<'True'> + ? [{ type: 'Boolean'; value: true }, Tail] + : F extends SymbolToken<'False'> + ? [{ type: 'Boolean'; value: false }, Tail] + : F extends SymbolToken<'Null'> + ? [{ type: 'Null'; value: null }, Tail] + : F extends NumberToken + ? [{ type: 'Number'; value: V }, Tail] + : F extends StringToken + ? [{ type: 'String'; value: V }, Tail] + : F extends SymbolToken + ? [{ type: 'Variable'; value: V }, Tail] + : [never, []]; + +export type ParseSequence< + T extends Array, + R extends Array = [], + P extends [any, Array] = ParseInput, +> = T extends [] ? R : ParseSequence>; + +export type Parse> = Reverse>; diff --git a/src/tokenize.ts b/src/tokenize.ts new file mode 100644 index 0000000..fe39d07 --- /dev/null +++ b/src/tokenize.ts @@ -0,0 +1,108 @@ +import type { Reverse, Unshift } from './utils/arrayUtils'; +import type { + EatFirstChar, + FirstChar, + ConcatStrings, +} from './utils/stringUtils'; +import type { Numbers, Symbols } from './utils/generalUtils'; +import type {} from './dataTypes'; + +type TokenizeInput = FirstChar extends infer F + ? EatFirstChar extends infer E + ? F extends ' ' | '\n' + ? ['', E] + : F extends '(' + ? [ + { + type: 'paren'; + value: '('; + }, + E, + ] + : F extends ')' + ? [ + { + type: 'paren'; + value: ')'; + }, + E, + ] + : F extends '{' + ? [ + { + type: 'curly'; + value: '{'; + }, + E, + ] + : F extends '}' + ? [ + { + type: 'curly'; + value: '}'; + }, + E, + ] + : F extends '.' + ? [ + { + type: 'dot'; + value: '.'; + }, + E, + ] + : F extends ';' + ? [ + { + type: ';'; + value: ';'; + }, + E, + ] + : F extends ':' + ? [ + { + type: ':'; + value: ':'; + }, + E, + ] + : F extends Numbers + ? TokenizeNumber + : F extends '"' + ? TokenizeString + : F extends Symbols + ? TokenizeSymbol + : never + : never + : never; + +type TokenizeNumber< + I extends string, + A extends string = '', + C extends string = FirstChar, +> = C extends Numbers + ? TokenizeNumber, ConcatStrings> + : [{ type: 'number'; value: A }, I]; + +type TokenizeString = I extends `${infer H}"${infer G}` + ? [{ type: 'string'; value: H }, G] + : never; + +type TokenizeSymbol< + I extends string, + A extends string = '', + C extends string = FirstChar, +> = C extends Symbols + ? TokenizeSymbol, ConcatStrings> + : [{ type: 'symbol'; value: A }, I]; + +export type TokenizeSequence< + I extends string, + R extends Array> = [], + P extends [any, string] = TokenizeInput, +> = I extends '' + ? R + : TokenizeSequence>; + +export type Tokenize = Reverse>; diff --git a/src/utils/arrayUtils.ts b/src/utils/arrayUtils.ts index be3bc30..f9da970 100644 --- a/src/utils/arrayUtils.ts +++ b/src/utils/arrayUtils.ts @@ -12,7 +12,7 @@ export type Unshift, E> = (( ? R : never; -export type Reverse, R extends Array = []> = { - finish: R; - next: Reverse, Unshift>; -}[T extends [] ? 'finish' : 'next']; +export type Reverse< + T extends Array, + R extends Array = [], +> = T extends [] ? R : Reverse, Unshift>; diff --git a/yarn.lock b/yarn.lock index fd6f210..3d25abd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -860,6 +860,15 @@ "@babel/helper-plugin-utils" "^7.17.12" "@babel/plugin-syntax-typescript" "^7.17.12" +"@babel/plugin-transform-typescript@^7.18.4": + version "7.18.4" + resolved "https://repo.dev.wixpress.com/artifactory/api/npm/npm-repos/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.18.4.tgz#587eaf6a39edb8c06215e550dc939faeadd750bf" + integrity sha1-WH6vajntuMBiFeVQ3JOfrq3XUL8= + dependencies: + "@babel/helper-create-class-features-plugin" "^7.18.0" + "@babel/helper-plugin-utils" "^7.17.12" + "@babel/plugin-syntax-typescript" "^7.17.12" + "@babel/plugin-transform-unicode-escapes@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz#da8717de7b3287a2c6d659750c964f302b31ece3" From ad1b62adcf25ccf18c4be9b6e9e8671a407ee8ce Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 26 Jun 2022 19:20:20 +0300 Subject: [PATCH 002/286] wip --- src/dataTypes.ts | 30 +++++++++++------ src/index.ts | 4 +-- src/parse.ts | 50 ++++++++++++++--------------- src/tokenize.ts | 83 ++++++++++++++++-------------------------------- 4 files changed, 75 insertions(+), 92 deletions(-) diff --git a/src/dataTypes.ts b/src/dataTypes.ts index 121fe71..4cbd357 100644 --- a/src/dataTypes.ts +++ b/src/dataTypes.ts @@ -1,13 +1,25 @@ -export type Paren = { type: 'paren'; value: V }; +export type ParenToken = { type: 'paren'; value: V }; -export type Number = { type: 'number'; value: V }; +export type CurlyToken = { type: 'curly'; value: V }; -export type String = { type: 'string'; value: V }; +export type DotToken = { type: 'dot' }; -export type Symbol = { type: 'symbol'; value: V }; +export type SemicolonToken = { type: 'semicolon' }; -// export type Token = -// | ParenToken -// | NumberToken -// | StringToken -// | SymbolToken; +export type ColonToken = { type: 'colon' }; + +export type NumberToken = { type: 'number'; value: V }; + +export type StringToken = { type: 'string'; value: V }; + +export type SymbolToken = { type: 'symbol'; value: V }; + +export type Token = + | NumberToken + | StringToken + | SymbolToken + | ParenToken + | CurlyToken + | DotToken + | SemicolonToken + | ColonToken; diff --git a/src/index.ts b/src/index.ts index df0b08f..1fb3e09 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import type { Tokenize } from './tokenize'; -import type { Parse } from './parse'; +// import type { Parse } from './parse'; type T = Tokenize<`function foo (foo: string): bar {}`>; -type R = Parse; +// type R = Parse; diff --git a/src/parse.ts b/src/parse.ts index cd5f7aa..1819807 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -1,28 +1,28 @@ -import type { Reverse, Tail, Unshift } from './utils/arrayUtils'; +// import type { Reverse, Tail, Unshift } from './utils/arrayUtils'; -export type ParseInput< - T extends Array, - F = T[0], -> = F extends ParenToken<'('> - ? ParseList> - : F extends SymbolToken<'True'> - ? [{ type: 'Boolean'; value: true }, Tail] - : F extends SymbolToken<'False'> - ? [{ type: 'Boolean'; value: false }, Tail] - : F extends SymbolToken<'Null'> - ? [{ type: 'Null'; value: null }, Tail] - : F extends NumberToken - ? [{ type: 'Number'; value: V }, Tail] - : F extends StringToken - ? [{ type: 'String'; value: V }, Tail] - : F extends SymbolToken - ? [{ type: 'Variable'; value: V }, Tail] - : [never, []]; +// export type ParseInput< +// T extends Array, +// F = T[0], +// > = F extends ParenToken<'('> +// ? ParseList> +// : F extends SymbolToken<'True'> +// ? [{ type: 'Boolean'; value: true }, Tail] +// : F extends SymbolToken<'False'> +// ? [{ type: 'Boolean'; value: false }, Tail] +// : F extends SymbolToken<'Null'> +// ? [{ type: 'Null'; value: null }, Tail] +// : F extends NumberToken +// ? [{ type: 'Number'; value: V }, Tail] +// : F extends StringToken +// ? [{ type: 'String'; value: V }, Tail] +// : F extends SymbolToken +// ? [{ type: 'Variable'; value: V }, Tail] +// : [never, []]; -export type ParseSequence< - T extends Array, - R extends Array = [], - P extends [any, Array] = ParseInput, -> = T extends [] ? R : ParseSequence>; +// export type ParseSequence< +// T extends Array, +// R extends Array = [], +// P extends [any, Array] = ParseInput, +// > = T extends [] ? R : ParseSequence>; -export type Parse> = Reverse>; +// export type Parse> = Reverse>; diff --git a/src/tokenize.ts b/src/tokenize.ts index fe39d07..deec01e 100644 --- a/src/tokenize.ts +++ b/src/tokenize.ts @@ -5,72 +5,42 @@ import type { ConcatStrings, } from './utils/stringUtils'; import type { Numbers, Symbols } from './utils/generalUtils'; -import type {} from './dataTypes'; +import type { + CurlyToken, + ParenToken, + DotToken, + SemicolonToken, + ColonToken, + Token, + NumberToken, + SymbolToken, + StringToken, +} from './dataTypes'; type TokenizeInput = FirstChar extends infer F ? EatFirstChar extends infer E ? F extends ' ' | '\n' ? ['', E] : F extends '(' - ? [ - { - type: 'paren'; - value: '('; - }, - E, - ] + ? [ParenToken<'('>, E] : F extends ')' - ? [ - { - type: 'paren'; - value: ')'; - }, - E, - ] + ? [ParenToken<')'>, E] : F extends '{' - ? [ - { - type: 'curly'; - value: '{'; - }, - E, - ] + ? [CurlyToken<'{'>, E] : F extends '}' - ? [ - { - type: 'curly'; - value: '}'; - }, - E, - ] + ? [CurlyToken<'}'>, E] : F extends '.' - ? [ - { - type: 'dot'; - value: '.'; - }, - E, - ] + ? [DotToken, E] : F extends ';' - ? [ - { - type: ';'; - value: ';'; - }, - E, - ] + ? [SemicolonToken, E] : F extends ':' - ? [ - { - type: ':'; - value: ':'; - }, - E, - ] + ? [ColonToken, E] : F extends Numbers ? TokenizeNumber : F extends '"' - ? TokenizeString + ? TokenizeString + : F extends "'" + ? TokenizeString : F extends Symbols ? TokenizeSymbol : never @@ -83,11 +53,12 @@ type TokenizeNumber< C extends string = FirstChar, > = C extends Numbers ? TokenizeNumber, ConcatStrings> - : [{ type: 'number'; value: A }, I]; + : [NumberToken, I]; -type TokenizeString = I extends `${infer H}"${infer G}` - ? [{ type: 'string'; value: H }, G] - : never; +type TokenizeString< + I, + W extends '"' | "'", +> = I extends `${infer H}${W}${infer G}` ? [StringToken, G] : never; type TokenizeSymbol< I extends string, @@ -95,7 +66,7 @@ type TokenizeSymbol< C extends string = FirstChar, > = C extends Symbols ? TokenizeSymbol, ConcatStrings> - : [{ type: 'symbol'; value: A }, I]; + : [SymbolToken, I]; export type TokenizeSequence< I extends string, From 24297d62ca48bd677cc935af1324538ca3e157ba Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 26 Jun 2022 21:51:45 +0300 Subject: [PATCH 003/286] wip --- foo.js | 5 ++-- src/ast.ts | 19 +++++++++++++ src/index.ts | 6 ++--- src/parse.ts | 48 ++++++++++++++++----------------- src/tokenize.ts | 2 +- src/{dataTypes.ts => tokens.ts} | 0 6 files changed, 49 insertions(+), 31 deletions(-) create mode 100644 src/ast.ts rename src/{dataTypes.ts => tokens.ts} (100%) diff --git a/foo.js b/foo.js index dbefd45..ab910f8 100644 --- a/foo.js +++ b/foo.js @@ -7,7 +7,7 @@ // console.log(result); -const result = require('@babel/parser').parse('function foo (hello: Foo) {}', { +const result = require('@babel/parser').parse('[]', { sourceType: 'module', plugins: [ ['typescript', { disallowAmbiguousJSXLike: undefined }], @@ -16,7 +16,8 @@ const result = require('@babel/parser').parse('function foo (hello: Foo) {}', { ], ranges: false, // sourceFilename: 'foo.ts', - // tokens: true, + tokens: true, }); +// console.log(result.tokens); console.log(JSON.stringify(result.program.body, null, 2)); diff --git a/src/ast.ts b/src/ast.ts new file mode 100644 index 0000000..91c504d --- /dev/null +++ b/src/ast.ts @@ -0,0 +1,19 @@ +export type VariableDeclaration = { + type: 'VariableDeclaration'; + declarations: T; +}; + +export type NumericLiteral = { + type: 'NumericLiteral'; + value: T; +}; + +export type BooleanLiteral = { + type: 'BooleanLiteral'; + value: T; +}; + +export type StringLiteral = { + type: 'StringLiteral'; + value: T; +}; diff --git a/src/index.ts b/src/index.ts index 1fb3e09..bac5e70 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import type { Tokenize } from './tokenize'; -// import type { Parse } from './parse'; +import type { Parse } from './parse'; -type T = Tokenize<`function foo (foo: string): bar {}`>; -// type R = Parse; +type T = Tokenize<`[]`>; +type R = Parse; diff --git a/src/parse.ts b/src/parse.ts index 1819807..a6ab2e1 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -1,28 +1,26 @@ -// import type { Reverse, Tail, Unshift } from './utils/arrayUtils'; +import type { BooleanLiteral, NumericLiteral, StringLiteral } from './ast'; +import type { NumberToken, StringToken, SymbolToken, Token } from './tokens'; +import type { Reverse, Tail, Unshift } from './utils/arrayUtils'; -// export type ParseInput< -// T extends Array, -// F = T[0], -// > = F extends ParenToken<'('> -// ? ParseList> -// : F extends SymbolToken<'True'> -// ? [{ type: 'Boolean'; value: true }, Tail] -// : F extends SymbolToken<'False'> -// ? [{ type: 'Boolean'; value: false }, Tail] -// : F extends SymbolToken<'Null'> -// ? [{ type: 'Null'; value: null }, Tail] -// : F extends NumberToken -// ? [{ type: 'Number'; value: V }, Tail] -// : F extends StringToken -// ? [{ type: 'String'; value: V }, Tail] -// : F extends SymbolToken -// ? [{ type: 'Variable'; value: V }, Tail] -// : [never, []]; +export type ParseInput< + T extends Array>, + F = T[0], +> = F extends SymbolToken<'true'> + ? [BooleanLiteral, Tail] + : F extends SymbolToken<'false'> + ? [BooleanLiteral, Tail] + : F extends SymbolToken<'null'> + ? [{ type: 'null'; value: null }, Tail] + : F extends NumberToken + ? [NumericLiteral, Tail] + : F extends StringToken + ? [StringLiteral, Tail] + : [never, []]; -// export type ParseSequence< -// T extends Array, -// R extends Array = [], -// P extends [any, Array] = ParseInput, -// > = T extends [] ? R : ParseSequence>; +export type ParseSequence< + T extends Array>, + R extends Array = [], + P extends [any, Array>] = ParseInput, +> = T extends [] ? R : ParseSequence>; -// export type Parse> = Reverse>; +export type Parse>> = Reverse>; diff --git a/src/tokenize.ts b/src/tokenize.ts index deec01e..84915d6 100644 --- a/src/tokenize.ts +++ b/src/tokenize.ts @@ -15,7 +15,7 @@ import type { NumberToken, SymbolToken, StringToken, -} from './dataTypes'; +} from './tokens'; type TokenizeInput = FirstChar extends infer F ? EatFirstChar extends infer E diff --git a/src/dataTypes.ts b/src/tokens.ts similarity index 100% rename from src/dataTypes.ts rename to src/tokens.ts From 4dcc77ea09363c5f0262f46ac8049a103f854f39 Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 26 Jun 2022 22:29:36 +0300 Subject: [PATCH 004/286] wip --- foo.js | 2 +- src/ast.ts | 16 ++++++++++++ src/index.ts | 2 +- src/parse.ts | 69 +++++++++++++++++++++++++++++++++++++++++++++++-- src/tokenize.ts | 8 ++++++ src/tokens.ts | 8 +++++- 6 files changed, 100 insertions(+), 5 deletions(-) diff --git a/foo.js b/foo.js index ab910f8..510a69f 100644 --- a/foo.js +++ b/foo.js @@ -7,7 +7,7 @@ // console.log(result); -const result = require('@babel/parser').parse('[]', { +const result = require('@babel/parser').parse('const a = { hello: "world" }', { sourceType: 'module', plugins: [ ['typescript', { disallowAmbiguousJSXLike: undefined }], diff --git a/src/ast.ts b/src/ast.ts index 91c504d..04d6508 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -17,3 +17,19 @@ export type StringLiteral = { type: 'StringLiteral'; value: T; }; + +export type ArrayExpression = { + type: 'ArrayExpression'; + elements: T; +}; + +export type ObjectExpression = { + type: 'ObjectExpression'; + properties: T; +}; + +export type ObjectProperty = { + type: 'ObjectProperty'; + key: K; + value: T; +}; diff --git a/src/index.ts b/src/index.ts index bac5e70..2a541fd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; -type T = Tokenize<`[]`>; +type T = Tokenize<`{ hello: "world", foo: 123 }`>; type R = Parse; diff --git a/src/parse.ts b/src/parse.ts index a6ab2e1..a17b235 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -1,6 +1,23 @@ -import type { BooleanLiteral, NumericLiteral, StringLiteral } from './ast'; -import type { NumberToken, StringToken, SymbolToken, Token } from './tokens'; +import type { + ArrayExpression, + BooleanLiteral, + NumericLiteral, + ObjectExpression, + StringLiteral, + ObjectProperty, +} from './ast'; +import type { + BracketToken, + ColonToken, + CommaToken, + CurlyToken, + NumberToken, + StringToken, + SymbolToken, + Token, +} from './tokens'; import type { Reverse, Tail, Unshift } from './utils/arrayUtils'; +import type { Cast } from './utils/generalUtils'; export type ParseInput< T extends Array>, @@ -15,8 +32,56 @@ export type ParseInput< ? [NumericLiteral, Tail] : F extends StringToken ? [StringLiteral, Tail] + : F extends BracketToken<'['> + ? ParseArray> + : F extends CurlyToken<'{'> + ? ParseObject> : [never, []]; +type ParseObject>> = + ParseObjectBody extends infer G + ? [ObjectExpression>[0]>, Cast>[1]] + : never; + +type ParseObjectBody< + T extends Array>, + R extends Array = [], + F extends Token = T[0], +> = F extends CurlyToken<'}'> + ? [Reverse, Tail] + : T extends [] + ? never + : T[0] extends CommaToken + ? ParseObjectBody, R> + : T[0] extends SymbolToken + ? T[1] extends ColonToken + ? ParseInput>> extends infer G + ? ParseObjectBody< + Cast>[1], + Unshift>[0]>> + > + : never + : never + : never; + +type ParseArray>> = ParseArrayBody extends infer G + ? [ArrayExpression>[0]>, Cast>[1]] + : never; + +type ParseArrayBody< + T extends Array>, + R extends Array = [], + F extends Token = T[0], +> = F extends BracketToken<']'> + ? [Reverse, Tail] + : T extends [] + ? never + : T[0] extends CommaToken + ? ParseArrayBody, R> + : ParseInput extends infer G + ? ParseArrayBody>[1], Unshift>[0]>> + : never; + export type ParseSequence< T extends Array>, R extends Array = [], diff --git a/src/tokenize.ts b/src/tokenize.ts index 84915d6..1d7645f 100644 --- a/src/tokenize.ts +++ b/src/tokenize.ts @@ -15,16 +15,24 @@ import type { NumberToken, SymbolToken, StringToken, + BracketToken, + CommaToken, } from './tokens'; type TokenizeInput = FirstChar extends infer F ? EatFirstChar extends infer E ? F extends ' ' | '\n' ? ['', E] + : F extends ',' + ? [CommaToken, E] : F extends '(' ? [ParenToken<'('>, E] : F extends ')' ? [ParenToken<')'>, E] + : F extends '[' + ? [BracketToken<'['>, E] + : F extends ']' + ? [BracketToken<']'>, E] : F extends '{' ? [CurlyToken<'{'>, E] : F extends '}' diff --git a/src/tokens.ts b/src/tokens.ts index 4cbd357..5a9c892 100644 --- a/src/tokens.ts +++ b/src/tokens.ts @@ -1,5 +1,7 @@ export type ParenToken = { type: 'paren'; value: V }; +export type BracketToken = { type: 'bracket'; value: V }; + export type CurlyToken = { type: 'curly'; value: V }; export type DotToken = { type: 'dot' }; @@ -14,12 +16,16 @@ export type StringToken = { type: 'string'; value: V }; export type SymbolToken = { type: 'symbol'; value: V }; +export type CommaToken = { type: 'comma' }; + export type Token = | NumberToken + | BracketToken | StringToken | SymbolToken | ParenToken | CurlyToken | DotToken | SemicolonToken - | ColonToken; + | ColonToken + | CommaToken; From 461d709e52a9a519b1d08f00a4e6546c670ab04b Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 26 Jun 2022 22:33:58 +0300 Subject: [PATCH 005/286] wip --- README.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..ff78ea0 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +## 🥑 Type-Fusion + +> A (very) simplified implementation of TypeScript's type-system in TypeScript type-system + +### Introduction From d98dd2520bf07782f900d42149cacb017e1fca07 Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 26 Jun 2022 23:46:04 +0300 Subject: [PATCH 006/286] wip --- foo.js | 2 +- src/ast.ts | 17 ++++++++++++----- src/index.ts | 2 +- src/parse.ts | 29 +++++++++++++++++++++++++---- 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/foo.js b/foo.js index 510a69f..fa24bc7 100644 --- a/foo.js +++ b/foo.js @@ -7,7 +7,7 @@ // console.log(result); -const result = require('@babel/parser').parse('const a = { hello: "world" }', { +const result = require('@babel/parser').parse('const a = 5', { sourceType: 'module', plugins: [ ['typescript', { disallowAmbiguousJSXLike: undefined }], diff --git a/src/ast.ts b/src/ast.ts index 04d6508..ccf368c 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -1,8 +1,3 @@ -export type VariableDeclaration = { - type: 'VariableDeclaration'; - declarations: T; -}; - export type NumericLiteral = { type: 'NumericLiteral'; value: T; @@ -33,3 +28,15 @@ export type ObjectProperty = { key: K; value: T; }; + +export type VariableDeclaration = { + type: 'VariableDeclaration'; + declarations: D; + kind: K; +}; + +export type VariableDeclarator = { + type: 'VariableDeclarator'; + name: N; + init: I; +}; diff --git a/src/index.ts b/src/index.ts index 2a541fd..63f8dc9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; -type T = Tokenize<`{ hello: "world", foo: 123 }`>; +type T = Tokenize<`const hello = "world"`>; type R = Parse; diff --git a/src/parse.ts b/src/parse.ts index a17b235..8e56466 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -5,6 +5,8 @@ import type { ObjectExpression, StringLiteral, ObjectProperty, + VariableDeclaration, + VariableDeclarator, } from './ast'; import type { BracketToken, @@ -19,7 +21,7 @@ import type { import type { Reverse, Tail, Unshift } from './utils/arrayUtils'; import type { Cast } from './utils/generalUtils'; -export type ParseInput< +export type ParseLiteral< T extends Array>, F = T[0], > = F extends SymbolToken<'true'> @@ -38,6 +40,25 @@ export type ParseInput< ? ParseObject> : [never, []]; +export type ParseExpression< + T extends Array>, + F = T[0], +> = F extends SymbolToken<'const'> + ? T[1] extends SymbolToken + ? T[2] extends SymbolToken<'='> + ? ParseLiteral>>> extends infer G + ? [ + VariableDeclaration< + [VariableDeclarator>[0]>], + 'const' + >, + Cast>[1], + ] + : never + : never + : never + : never; + type ParseObject>> = ParseObjectBody extends infer G ? [ObjectExpression>[0]>, Cast>[1]] @@ -55,7 +76,7 @@ type ParseObjectBody< ? ParseObjectBody, R> : T[0] extends SymbolToken ? T[1] extends ColonToken - ? ParseInput>> extends infer G + ? ParseLiteral>> extends infer G ? ParseObjectBody< Cast>[1], Unshift>[0]>> @@ -78,14 +99,14 @@ type ParseArrayBody< ? never : T[0] extends CommaToken ? ParseArrayBody, R> - : ParseInput extends infer G + : ParseLiteral extends infer G ? ParseArrayBody>[1], Unshift>[0]>> : never; export type ParseSequence< T extends Array>, R extends Array = [], - P extends [any, Array>] = ParseInput, + P extends [any, Array>] = ParseExpression, > = T extends [] ? R : ParseSequence>; export type Parse>> = Reverse>; From a46dd81e606a27a591434133012139377a27e414 Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 27 Jun 2022 00:14:50 +0300 Subject: [PATCH 007/286] wip --- foo.js | 2 +- src/ast.ts | 7 +++++++ src/index.ts | 2 +- src/parse.ts | 30 +++++++++++++++++++++++++----- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/foo.js b/foo.js index fa24bc7..2bd34fd 100644 --- a/foo.js +++ b/foo.js @@ -7,7 +7,7 @@ // console.log(result); -const result = require('@babel/parser').parse('const a = 5', { +const result = require('@babel/parser').parse('function foo (a, b) {}', { sourceType: 'module', plugins: [ ['typescript', { disallowAmbiguousJSXLike: undefined }], diff --git a/src/ast.ts b/src/ast.ts index ccf368c..79324c9 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -40,3 +40,10 @@ export type VariableDeclarator = { name: N; init: I; }; + +export type FunctionDeclaration = { + type: 'FunctionDeclaration'; + id: I; + params: P; + body: B; +}; diff --git a/src/index.ts b/src/index.ts index 63f8dc9..a811ae0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; -type T = Tokenize<`const hello = "world"`>; +type T = Tokenize<`function foo () {}`>; type R = Parse; diff --git a/src/parse.ts b/src/parse.ts index 8e56466..af0ccd2 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -7,6 +7,7 @@ import type { ObjectProperty, VariableDeclaration, VariableDeclarator, + FunctionDeclaration, } from './ast'; import type { BracketToken, @@ -14,6 +15,7 @@ import type { CommaToken, CurlyToken, NumberToken, + ParenToken, StringToken, SymbolToken, Token, @@ -44,9 +46,28 @@ export type ParseExpression< T extends Array>, F = T[0], > = F extends SymbolToken<'const'> - ? T[1] extends SymbolToken - ? T[2] extends SymbolToken<'='> - ? ParseLiteral>>> extends infer G + ? ParseVariableDeclaration> + : F extends SymbolToken<'function'> + ? ParseFunctionDeclaration> + : never; + +type ParseFunctionDeclaration>> = + T[0] extends SymbolToken + ? T[1] extends ParenToken<'('> + ? T[2] extends ParenToken<')'> + ? T[3] extends CurlyToken<'{'> + ? T[4] extends CurlyToken<'}'> + ? [FunctionDeclaration, Tail>>>>] + : never + : never + : never + : never + : never; + +type ParseVariableDeclaration>> = + T[0] extends SymbolToken + ? T[1] extends SymbolToken<'='> + ? ParseLiteral>> extends infer G ? [ VariableDeclaration< [VariableDeclarator>[0]>], @@ -56,8 +77,7 @@ export type ParseExpression< ] : never : never - : never - : never; + : never; type ParseObject>> = ParseObjectBody extends infer G From 856287360c881f62271c75cb3d9b523c77864052 Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 27 Jun 2022 00:57:48 +0300 Subject: [PATCH 008/286] wip --- src/index.ts | 2 +- src/parse.ts | 52 ++++++++++++++++++++++++++++++---------------------- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/src/index.ts b/src/index.ts index a811ae0..6f02b3c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; -type T = Tokenize<`function foo () {}`>; +type T = Tokenize<`const a = { hello: 1, world: 2 }`>; type R = Parse; diff --git a/src/parse.ts b/src/parse.ts index af0ccd2..620f8f3 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -79,48 +79,56 @@ type ParseVariableDeclaration>> = : never : never; -type ParseObject>> = - ParseObjectBody extends infer G - ? [ObjectExpression>[0]>, Cast>[1]] - : never; - -type ParseObjectBody< +type ParseObject< T extends Array>, R extends Array = [], + N extends boolean = false, F extends Token = T[0], > = F extends CurlyToken<'}'> - ? [Reverse, Tail] + ? [ObjectExpression>, Tail] : T extends [] ? never - : T[0] extends CommaToken - ? ParseObjectBody, R> - : T[0] extends SymbolToken + : N extends true + ? F extends CommaToken + ? ParseObjectItem, R> + : never + : ParseObjectItem; + +type ParseObjectItem< + T extends Array>, + R extends Array = [], +> = T[0] extends SymbolToken ? T[1] extends ColonToken ? ParseLiteral>> extends infer G - ? ParseObjectBody< + ? ParseObject< Cast>[1], - Unshift>[0]>> + Unshift>[0]>>, + true > : never : never : never; -type ParseArray>> = ParseArrayBody extends infer G - ? [ArrayExpression>[0]>, Cast>[1]] - : never; - -type ParseArrayBody< +type ParseArray< T extends Array>, R extends Array = [], + N extends boolean = false, F extends Token = T[0], > = F extends BracketToken<']'> - ? [Reverse, Tail] + ? [ArrayExpression>, Tail] : T extends [] ? never - : T[0] extends CommaToken - ? ParseArrayBody, R> - : ParseLiteral extends infer G - ? ParseArrayBody>[1], Unshift>[0]>> + : N extends true + ? F extends CommaToken + ? ParseArrayItem, R> + : never + : ParseArrayItem; + +type ParseArrayItem< + T extends Array>, + R extends Array = [], +> = ParseLiteral extends infer G + ? ParseArray>[1], Unshift>[0]>, true> : never; export type ParseSequence< From dd13ad00ed2d578b3c5d8959b387bde0de2ca9c4 Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 27 Jun 2022 10:11:17 +0300 Subject: [PATCH 009/286] wip --- foo.js | 2 +- src/index.ts | 2 +- src/parse.ts | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/foo.js b/foo.js index 2bd34fd..8edbeed 100644 --- a/foo.js +++ b/foo.js @@ -7,7 +7,7 @@ // console.log(result); -const result = require('@babel/parser').parse('function foo (a, b) {}', { +const result = require('@babel/parser').parse('const a = 5;', { sourceType: 'module', plugins: [ ['typescript', { disallowAmbiguousJSXLike: undefined }], diff --git a/src/index.ts b/src/index.ts index 6f02b3c..2453698 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; -type T = Tokenize<`const a = { hello: 1, world: 2 }`>; +type T = Tokenize<`const a = 5`>; type R = Parse; diff --git a/src/parse.ts b/src/parse.ts index 620f8f3..3834b9f 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -16,6 +16,7 @@ import type { CurlyToken, NumberToken, ParenToken, + SemicolonToken, StringToken, SymbolToken, Token, @@ -51,6 +52,9 @@ export type ParseExpression< ? ParseFunctionDeclaration> : never; +type OptionalSemicolon>> = + T[0] extends SemicolonToken ? Tail : T; + type ParseFunctionDeclaration>> = T[0] extends SymbolToken ? T[1] extends ParenToken<'('> @@ -73,7 +77,7 @@ type ParseVariableDeclaration>> = [VariableDeclarator>[0]>], 'const' >, - Cast>[1], + OptionalSemicolon>[1]>, ] : never : never From fe2439389e1fe9c7933ad00382018b917b588f8b Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 28 Jun 2022 00:54:01 +0300 Subject: [PATCH 010/286] wip --- foo.js | 2 +- src/ast.ts | 11 ++++++++++- src/index.ts | 2 +- src/parse.ts | 51 ++++++++++++++++++++++++++++++++++++++------------- 4 files changed, 50 insertions(+), 16 deletions(-) diff --git a/foo.js b/foo.js index 8edbeed..5a455a2 100644 --- a/foo.js +++ b/foo.js @@ -7,7 +7,7 @@ // console.log(result); -const result = require('@babel/parser').parse('const a = 5;', { +const result = require('@babel/parser').parse('const a = {hello: "world"}', { sourceType: 'module', plugins: [ ['typescript', { disallowAmbiguousJSXLike: undefined }], diff --git a/src/ast.ts b/src/ast.ts index 79324c9..773e004 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -37,7 +37,7 @@ export type VariableDeclaration = { export type VariableDeclarator = { type: 'VariableDeclarator'; - name: N; + id: N; init: I; }; @@ -47,3 +47,12 @@ export type FunctionDeclaration = { params: P; body: B; }; + +export type Identifier = { + type: 'Identifier'; + name: N; +}; + +export type NullLiteral = { + type: 'NullLiteral'; +}; diff --git a/src/index.ts b/src/index.ts index 2453698..ef357de 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; -type T = Tokenize<`const a = 5`>; +type T = Tokenize<`const a = { hello: "world" }`>; type R = Parse; diff --git a/src/parse.ts b/src/parse.ts index 3834b9f..6b4ddc2 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -8,6 +8,8 @@ import type { VariableDeclaration, VariableDeclarator, FunctionDeclaration, + Identifier, + NullLiteral, } from './ast'; import type { BracketToken, @@ -32,7 +34,7 @@ export type ParseLiteral< : F extends SymbolToken<'false'> ? [BooleanLiteral, Tail] : F extends SymbolToken<'null'> - ? [{ type: 'null'; value: null }, Tail] + ? [NullLiteral, Tail] : F extends NumberToken ? [NumericLiteral, Tail] : F extends StringToken @@ -41,6 +43,8 @@ export type ParseLiteral< ? ParseArray> : F extends CurlyToken<'{'> ? ParseObject> + : F extends SymbolToken + ? [Identifier, Tail] : [never, []]; export type ParseExpression< @@ -55,18 +59,39 @@ export type ParseExpression< type OptionalSemicolon>> = T[0] extends SemicolonToken ? Tail : T; -type ParseFunctionDeclaration>> = - T[0] extends SymbolToken - ? T[1] extends ParenToken<'('> - ? T[2] extends ParenToken<')'> - ? T[3] extends CurlyToken<'{'> - ? T[4] extends CurlyToken<'}'> - ? [FunctionDeclaration, Tail>>>>] - : never - : never +type ParseFunctionDeclaration< + T extends Array>, + G extends [any, Array>] = ParseFunctionParams>>, +> = T[0] extends SymbolToken + ? T[1] extends ParenToken<'('> + ? G[1][0] extends CurlyToken<'{'> + ? G[1][1] extends CurlyToken<'}'> + ? [FunctionDeclaration, G[0], []>, Tail>] : never : never - : never; + : never + : never; + +type ParseFunctionParams< + T extends Array>, + R extends Array = [], + N extends boolean = false, +> = T[0] extends ParenToken<')'> + ? [Reverse, Tail] + : T extends [] + ? never + : N extends true + ? T[0] extends CommaToken + ? ParseFunctionParamsItem, R> + : never + : ParseFunctionParamsItem; + +type ParseFunctionParamsItem< + T extends Array>, + R extends Array = [], +> = T[0] extends SymbolToken + ? ParseFunctionParams, Unshift>, true> + : never; type ParseVariableDeclaration>> = T[0] extends SymbolToken @@ -74,7 +99,7 @@ type ParseVariableDeclaration>> = ? ParseLiteral>> extends infer G ? [ VariableDeclaration< - [VariableDeclarator>[0]>], + [VariableDeclarator, Cast>[0]>], 'const' >, OptionalSemicolon>[1]>, @@ -106,7 +131,7 @@ type ParseObjectItem< ? ParseLiteral>> extends infer G ? ParseObject< Cast>[1], - Unshift>[0]>>, + Unshift, Cast>[0]>>, true > : never From ff58a7cfe216dbaf77990541bd62cf756ca6d2de Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 28 Jun 2022 01:07:00 +0300 Subject: [PATCH 011/286] wip --- foo.js | 2 +- src/ast.ts | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/foo.js b/foo.js index 5a455a2..072d27a 100644 --- a/foo.js +++ b/foo.js @@ -7,7 +7,7 @@ // console.log(result); -const result = require('@babel/parser').parse('const a = {hello: "world"}', { +const result = require('@babel/parser').parse('function foo () {}', { sourceType: 'module', plugins: [ ['typescript', { disallowAmbiguousJSXLike: undefined }], diff --git a/src/ast.ts b/src/ast.ts index 773e004..28a597d 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -56,3 +56,24 @@ export type Identifier = { export type NullLiteral = { type: 'NullLiteral'; }; + +export type ExpressionStatement = { + type: 'ExpressionStatement'; + expression: E; +}; + +export type CallExpression = { + type: 'CallExpression'; + callee: C; + arguments: A; +}; + +export type MemberExpression = { + type: 'MemberExpression'; + object: O; + property: P; +}; + +// ReturnStatement +// IfStatement +// BlockStatement From 05578410dc39b40dd868fc8036803138dfeb4581 Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 28 Jun 2022 20:48:17 +0300 Subject: [PATCH 012/286] wip --- foo.js | 2 +- src/index.ts | 2 +- src/parse.ts | 45 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/foo.js b/foo.js index 072d27a..6458751 100644 --- a/foo.js +++ b/foo.js @@ -7,7 +7,7 @@ // console.log(result); -const result = require('@babel/parser').parse('function foo () {}', { +const result = require('@babel/parser').parse('foo.bar()', { sourceType: 'module', plugins: [ ['typescript', { disallowAmbiguousJSXLike: undefined }], diff --git a/src/index.ts b/src/index.ts index ef357de..96604a0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; -type T = Tokenize<`const a = { hello: "world" }`>; +type T = Tokenize<`console.log(1)`>; type R = Parse; diff --git a/src/parse.ts b/src/parse.ts index 6b4ddc2..664c2c1 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -10,12 +10,15 @@ import type { FunctionDeclaration, Identifier, NullLiteral, + ExpressionStatement, + CallExpression, } from './ast'; import type { BracketToken, ColonToken, CommaToken, CurlyToken, + DotToken, NumberToken, ParenToken, SemicolonToken, @@ -54,6 +57,48 @@ export type ParseExpression< ? ParseVariableDeclaration> : F extends SymbolToken<'function'> ? ParseFunctionDeclaration> + : F extends SymbolToken + ? ParseExpressionStatement, V> + : never; + +type ParseExpressionStatement>, V> = T extends [] + ? [ExpressionStatement>, []] + : T[0] extends ParenToken<'('> + ? ParseFunctionArguments> extends infer G + ? [ + ExpressionStatement< + CallExpression, Cast>[0]> + >, + Cast>[1], + ] + : never + : T[0] extends DotToken + ? [] + : never; + +type ParseFunctionArguments< + T extends Array>, + R extends Array = [], + N extends boolean = false, +> = T[0] extends ParenToken<')'> + ? [Reverse, Tail] + : T extends [] + ? never + : N extends true + ? T[0] extends CommaToken + ? ParseFunctionArgumentsItem, R> + : never + : ParseFunctionArgumentsItem; + +type ParseFunctionArgumentsItem< + T extends Array>, + R extends Array = [], +> = ParseLiteral extends infer G + ? ParseFunctionArguments< + Cast>[1], + Unshift>[0]>, + true + > : never; type OptionalSemicolon>> = From 77bc4effb01a4fa05aeb7c466cfce9d88d3dc005 Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 28 Jun 2022 21:38:34 +0300 Subject: [PATCH 013/286] wip --- foo.js | 2 +- src/index.ts | 2 +- src/parse.ts | 59 +++++++++++++--------------------------------------- 3 files changed, 17 insertions(+), 46 deletions(-) diff --git a/foo.js b/foo.js index 6458751..9e8bbdc 100644 --- a/foo.js +++ b/foo.js @@ -7,7 +7,7 @@ // console.log(result); -const result = require('@babel/parser').parse('foo.bar()', { +const result = require('@babel/parser').parse('a.b.c', { sourceType: 'module', plugins: [ ['typescript', { disallowAmbiguousJSXLike: undefined }], diff --git a/src/index.ts b/src/index.ts index 96604a0..68ae9ee 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; -type T = Tokenize<`console.log(1)`>; +type T = Tokenize<`a.b.c`>; type R = Parse; diff --git a/src/parse.ts b/src/parse.ts index 664c2c1..c2db950 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -12,6 +12,7 @@ import type { NullLiteral, ExpressionStatement, CallExpression, + MemberExpression, } from './ast'; import type { BracketToken, @@ -52,58 +53,24 @@ export type ParseLiteral< export type ParseExpression< T extends Array>, + R extends Array, F = T[0], > = F extends SymbolToken<'const'> ? ParseVariableDeclaration> : F extends SymbolToken<'function'> ? ParseFunctionDeclaration> : F extends SymbolToken - ? ParseExpressionStatement, V> - : never; - -type ParseExpressionStatement>, V> = T extends [] - ? [ExpressionStatement>, []] - : T[0] extends ParenToken<'('> - ? ParseFunctionArguments> extends infer G + ? [Identifier, Tail] + : F extends DotToken + ? T[1] extends SymbolToken ? [ - ExpressionStatement< - CallExpression, Cast>[0]> - >, - Cast>[1], + [], + Tail>, + Unshift, MemberExpression>>, ] : never - : T[0] extends DotToken - ? [] - : never; - -type ParseFunctionArguments< - T extends Array>, - R extends Array = [], - N extends boolean = false, -> = T[0] extends ParenToken<')'> - ? [Reverse, Tail] - : T extends [] - ? never - : N extends true - ? T[0] extends CommaToken - ? ParseFunctionArgumentsItem, R> - : never - : ParseFunctionArgumentsItem; - -type ParseFunctionArgumentsItem< - T extends Array>, - R extends Array = [], -> = ParseLiteral extends infer G - ? ParseFunctionArguments< - Cast>[1], - Unshift>[0]>, - true - > : never; -type OptionalSemicolon>> = - T[0] extends SemicolonToken ? Tail : T; - type ParseFunctionDeclaration< T extends Array>, G extends [any, Array>] = ParseFunctionParams>>, @@ -147,7 +114,7 @@ type ParseVariableDeclaration>> = [VariableDeclarator, Cast>[0]>], 'const' >, - OptionalSemicolon>[1]>, + Cast>[1], ] : never : never @@ -208,7 +175,11 @@ type ParseArrayItem< export type ParseSequence< T extends Array>, R extends Array = [], - P extends [any, Array>] = ParseExpression, -> = T extends [] ? R : ParseSequence>; + P extends [any, Array>, Array?] = ParseExpression, +> = T extends [] + ? R + : P[2] extends Array + ? ParseSequence + : ParseSequence>; export type Parse>> = Reverse>; From 8ac289cd4b2725bedafaa38be941a1e650652d05 Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 28 Jun 2022 22:44:33 +0300 Subject: [PATCH 014/286] wip --- src/index.ts | 2 +- src/parse.ts | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 68ae9ee..07e36fb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; -type T = Tokenize<`a.b.c`>; +type T = Tokenize<`const a = console.log(1, 2, 3)`>; type R = Parse; diff --git a/src/parse.ts b/src/parse.ts index c2db950..4c3d5e5 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -69,6 +69,39 @@ export type ParseExpression< Unshift, MemberExpression>>, ] : never + : T[0] extends ParenToken<'('> + ? ParseFunctionArguments> extends infer G + ? [ + [], + Cast>[1], + Unshift, CallExpression>[0]>>, + ] + : never + : never; + +type ParseFunctionArguments< + T extends Array>, + R extends Array = [], + N extends boolean = false, +> = T[0] extends ParenToken<')'> + ? [Reverse, Tail] + : T extends [] + ? never + : N extends true + ? T[0] extends CommaToken + ? ParseFunctionArgumentsItem, R> + : never + : ParseFunctionArgumentsItem; + +type ParseFunctionArgumentsItem< + T extends Array>, + R extends Array = [], +> = ParseLiteral extends infer G + ? ParseFunctionArguments< + Cast>[1], + Unshift>[0]>, + true + > : never; type ParseFunctionDeclaration< From e7f905aa1b4f9dc2333fa2875cf76fd8e1c8227a Mon Sep 17 00:00:00 2001 From: ronami Date: Wed, 29 Jun 2022 19:37:05 +0300 Subject: [PATCH 015/286] wip --- src/ast.ts | 6 ++++++ src/index.ts | 2 +- src/parse.ts | 55 +++++++++++++++++++++++++++------------------------- 3 files changed, 36 insertions(+), 27 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index 28a597d..153ce06 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -77,3 +77,9 @@ export type MemberExpression = { // ReturnStatement // IfStatement // BlockStatement + +// Add unit-tests +// Fn-calls, member-access on expressions +// Parse statements, parse expressions, no parse literal +// Show parse errors +// Type check and inference diff --git a/src/index.ts b/src/index.ts index 07e36fb..7134f45 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; -type T = Tokenize<`const a = console.log(1, 2, 3)`>; +type T = Tokenize<`a.b()`>; type R = Parse; diff --git a/src/parse.ts b/src/parse.ts index 4c3d5e5..3ef7d36 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -30,7 +30,7 @@ import type { import type { Reverse, Tail, Unshift } from './utils/arrayUtils'; import type { Cast } from './utils/generalUtils'; -export type ParseLiteral< +type ParseLiteral< T extends Array>, F = T[0], > = F extends SymbolToken<'true'> @@ -51,32 +51,39 @@ export type ParseLiteral< ? [Identifier, Tail] : [never, []]; -export type ParseExpression< +type ParseExpression< T extends Array>, - R extends Array, F = T[0], > = F extends SymbolToken<'const'> ? ParseVariableDeclaration> : F extends SymbolToken<'function'> ? ParseFunctionDeclaration> : F extends SymbolToken - ? [Identifier, Tail] - : F extends DotToken - ? T[1] extends SymbolToken - ? [ - [], - Tail>, - Unshift, MemberExpression>>, - ] - : never + ? ParseIdentifier, V> + : never; + +type ParseIdentifier>, V> = T[0] extends DotToken + ? ParseMemberExpression, Tail> : T[0] extends ParenToken<'('> - ? ParseFunctionArguments> extends infer G - ? [ - [], - Cast>[1], - Unshift, CallExpression>[0]>>, - ] - : never + ? ParseCallExpression, Tail> + : [Identifier, T]; + +type ParseMemberExpression< + I, + T extends Array>, +> = T[0] extends SymbolToken + ? T[1] extends DotToken + ? ParseMemberExpression>, Tail>> + : T[1] extends ParenToken<'('> + ? ParseCallExpression>, Tail>> + : [MemberExpression>, Tail] + : never; + +type ParseCallExpression< + I, + T extends Array>, +> = ParseFunctionArguments extends infer G + ? [CallExpression>[0]>, Cast>[1]] : never; type ParseFunctionArguments< @@ -205,14 +212,10 @@ type ParseArrayItem< ? ParseArray>[1], Unshift>[0]>, true> : never; -export type ParseSequence< +type ParseSequence< T extends Array>, R extends Array = [], - P extends [any, Array>, Array?] = ParseExpression, -> = T extends [] - ? R - : P[2] extends Array - ? ParseSequence - : ParseSequence>; + P extends [any, Array>] = ParseExpression, +> = T extends [] ? R : ParseSequence>; export type Parse>> = Reverse>; From e51e2c986b1f69bf703019f238241e897412ff9f Mon Sep 17 00:00:00 2001 From: ronami Date: Wed, 29 Jun 2022 20:17:05 +0300 Subject: [PATCH 016/286] wip --- src/test/parser.test.ts | 164 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 src/test/parser.test.ts diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts new file mode 100644 index 0000000..8fa730e --- /dev/null +++ b/src/test/parser.test.ts @@ -0,0 +1,164 @@ +import type { Tokenize } from '../tokenize'; +import type { Parse } from '../parse'; +import type { Cast } from '../utils/generalUtils'; + +const expectType = (value: T) => {}; + +type ParseAst = Tokenize extends infer G + ? Parse>> + : never; + +expectType>([{ type: 'Identifier', name: 'hello' }]); + +expectType>([ + { + type: 'MemberExpression', + object: { type: 'Identifier', name: 'hello' }, + property: { type: 'Identifier', name: 'world' }, + }, +]); + +expectType>([ + { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'hello', + }, + arguments: [], + }, +]); + +expectType>([ + { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'hello', + }, + arguments: [ + { type: 'NumericLiteral', value: '1' }, + { type: 'BooleanLiteral', value: true }, + ], + }, +]); + +expectType>([ + { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: { + type: 'Identifier', + name: 'hello', + }, + property: { + type: 'Identifier', + name: 'world', + }, + }, + arguments: [ + { type: 'NumericLiteral', value: '1' }, + { type: 'BooleanLiteral', value: true }, + ], + }, +]); + +expectType>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + }, + params: [], + body: [], + }, +]); + +expectType>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + }, + params: [ + { type: 'Identifier', name: 'first' }, + { type: 'Identifier', name: 'last' }, + ], + body: [], + }, +]); + +expectType>([ + { + type: 'VariableDeclaration', + kind: 'const', + declarations: [ + { + type: 'VariableDeclarator', + init: { type: 'StringLiteral', value: 'world' }, + id: { type: 'Identifier', name: 'hello' }, + }, + ], + }, +]); + +expectType>([ + { + type: 'VariableDeclaration', + kind: 'const', + declarations: [ + { + type: 'VariableDeclarator', + init: { type: 'NumericLiteral', value: '123' }, + id: { type: 'Identifier', name: 'hello' }, + }, + ], + }, +]); + +expectType>([ + { + type: 'VariableDeclaration', + kind: 'const', + declarations: [ + { + type: 'VariableDeclarator', + init: { + type: 'ArrayExpression', + elements: [ + { type: 'NumericLiteral', value: '1' }, + { type: 'NumericLiteral', value: '2' }, + { type: 'NumericLiteral', value: '3' }, + ], + }, + id: { type: 'Identifier', name: 'hello' }, + }, + ], + }, +]); + +expectType>([ + { + type: 'VariableDeclaration', + kind: 'const', + declarations: [ + { + type: 'VariableDeclarator', + init: { + type: 'ObjectExpression', + properties: [ + { + type: 'ObjectProperty', + key: { type: 'Identifier', name: 'hey' }, + value: { type: 'StringLiteral', value: 'ho' }, + }, + ], + }, + id: { type: 'Identifier', name: 'hello' }, + }, + ], + }, +]); From 4c5657b4c60dde424d20aa06ded4330ee59abcdb Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 01:07:07 +0300 Subject: [PATCH 017/286] wip --- src/index.ts | 2 +- src/parse.ts | 103 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 63 insertions(+), 42 deletions(-) diff --git a/src/index.ts b/src/index.ts index 7134f45..b8bd4b1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; -type T = Tokenize<`a.b()`>; +type T = Tokenize<`"foo".bar`>; type R = Parse; diff --git a/src/parse.ts b/src/parse.ts index 3ef7d36..bdd339e 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -30,15 +30,38 @@ import type { import type { Reverse, Tail, Unshift } from './utils/arrayUtils'; import type { Cast } from './utils/generalUtils'; -type ParseLiteral< +// type ParseExpression< +// T extends Array>, +// F = T[0], +// > = ParseExpressionHelper extends infer G +// ? G[1][0] extends DotToken +// ? ParseMemberExpression> +// : G[1][0] extends ParenToken<'('> +// ? ParseCallExpression> +// : G +// : never; + +type Wrap>]> = T[1][0] extends DotToken + ? T[1][1] extends SymbolToken + ? Wrap<[MemberExpression>, Tail>]> + : T + : T[1][0] extends ParenToken<'('> + ? ParseFunctionArguments> extends infer G + ? Wrap< + [CallExpression>[0]>, Cast>[1]] + > + : never + : T; + +type ParseExpression< T extends Array>, F = T[0], > = F extends SymbolToken<'true'> - ? [BooleanLiteral, Tail] + ? Wrap<[BooleanLiteral, Tail]> : F extends SymbolToken<'false'> - ? [BooleanLiteral, Tail] + ? Wrap<[BooleanLiteral, Tail]> : F extends SymbolToken<'null'> - ? [NullLiteral, Tail] + ? Wrap<[NullLiteral, Tail]> : F extends NumberToken ? [NumericLiteral, Tail] : F extends StringToken @@ -48,43 +71,37 @@ type ParseLiteral< : F extends CurlyToken<'{'> ? ParseObject> : F extends SymbolToken - ? [Identifier, Tail] - : [never, []]; + ? Wrap<[Identifier, Tail]> + : [T, []]; -type ParseExpression< +type ParseStatement< T extends Array>, F = T[0], > = F extends SymbolToken<'const'> ? ParseVariableDeclaration> : F extends SymbolToken<'function'> ? ParseFunctionDeclaration> - : F extends SymbolToken - ? ParseIdentifier, V> - : never; - -type ParseIdentifier>, V> = T[0] extends DotToken - ? ParseMemberExpression, Tail> - : T[0] extends ParenToken<'('> - ? ParseCallExpression, Tail> - : [Identifier, T]; - -type ParseMemberExpression< - I, - T extends Array>, -> = T[0] extends SymbolToken - ? T[1] extends DotToken - ? ParseMemberExpression>, Tail>> - : T[1] extends ParenToken<'('> - ? ParseCallExpression>, Tail>> - : [MemberExpression>, Tail] - : never; - -type ParseCallExpression< - I, - T extends Array>, -> = ParseFunctionArguments extends infer G - ? [CallExpression>[0]>, Cast>[1]] - : never; + : ParseExpression; + +// type Wrap>, V> = + +// type ParseMemberExpression< +// I, +// T extends Array>, +// > = T[0] extends SymbolToken +// ? T[1] extends DotToken +// ? ParseMemberExpression>, Tail>> +// : T[1] extends ParenToken<'('> +// ? ParseCallExpression>, Tail>> +// : [MemberExpression>, Tail] +// : never; + +// type ParseCallExpression< +// I, +// T extends Array>, +// > = ParseFunctionArguments extends infer G +// ? [CallExpression>[0]>, Cast>[1]] +// : never; type ParseFunctionArguments< T extends Array>, @@ -103,7 +120,7 @@ type ParseFunctionArguments< type ParseFunctionArgumentsItem< T extends Array>, R extends Array = [], -> = ParseLiteral extends infer G +> = ParseExpression extends infer G ? ParseFunctionArguments< Cast>[1], Unshift>[0]>, @@ -148,7 +165,7 @@ type ParseFunctionParamsItem< type ParseVariableDeclaration>> = T[0] extends SymbolToken ? T[1] extends SymbolToken<'='> - ? ParseLiteral>> extends infer G + ? ParseExpression>> extends infer G ? [ VariableDeclaration< [VariableDeclarator, Cast>[0]>], @@ -180,7 +197,7 @@ type ParseObjectItem< R extends Array = [], > = T[0] extends SymbolToken ? T[1] extends ColonToken - ? ParseLiteral>> extends infer G + ? ParseExpression>> extends infer G ? ParseObject< Cast>[1], Unshift, Cast>[0]>>, @@ -208,14 +225,18 @@ type ParseArray< type ParseArrayItem< T extends Array>, R extends Array = [], -> = ParseLiteral extends infer G +> = ParseExpression extends infer G ? ParseArray>[1], Unshift>[0]>, true> : never; type ParseSequence< T extends Array>, R extends Array = [], - P extends [any, Array>] = ParseExpression, -> = T extends [] ? R : ParseSequence>; +> = T extends [] + ? R + : ParseStatement extends infer P + ? ParseSequence>[1], Unshift>[0]>> + : never; -export type Parse>> = Reverse>; +export type Parse>> = + ParseSequence extends infer P ? Reverse>> : never; From c54a5b7b5c7068ff3dcdd0ae7030d7f941da41a4 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 02:12:35 +0300 Subject: [PATCH 018/286] wip --- src/index.ts | 2 +- src/parse.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/index.ts b/src/index.ts index b8bd4b1..c5b81c2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; -type T = Tokenize<`"foo".bar`>; +type T = Tokenize<`"foo"()()`>; type R = Parse; diff --git a/src/parse.ts b/src/parse.ts index bdd339e..42641eb 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -63,9 +63,9 @@ type ParseExpression< : F extends SymbolToken<'null'> ? Wrap<[NullLiteral, Tail]> : F extends NumberToken - ? [NumericLiteral, Tail] + ? Wrap<[NumericLiteral, Tail]> : F extends StringToken - ? [StringLiteral, Tail] + ? Wrap<[StringLiteral, Tail]> : F extends BracketToken<'['> ? ParseArray> : F extends CurlyToken<'{'> From 5b2d35b5af6e370870b181a24f6e93f05d3d0da8 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 02:13:14 +0300 Subject: [PATCH 019/286] wip --- src/parse.ts | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/src/parse.ts b/src/parse.ts index 42641eb..5f47288 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -22,7 +22,6 @@ import type { DotToken, NumberToken, ParenToken, - SemicolonToken, StringToken, SymbolToken, Token, @@ -30,17 +29,6 @@ import type { import type { Reverse, Tail, Unshift } from './utils/arrayUtils'; import type { Cast } from './utils/generalUtils'; -// type ParseExpression< -// T extends Array>, -// F = T[0], -// > = ParseExpressionHelper extends infer G -// ? G[1][0] extends DotToken -// ? ParseMemberExpression> -// : G[1][0] extends ParenToken<'('> -// ? ParseCallExpression> -// : G -// : never; - type Wrap>]> = T[1][0] extends DotToken ? T[1][1] extends SymbolToken ? Wrap<[MemberExpression>, Tail>]> @@ -83,26 +71,6 @@ type ParseStatement< ? ParseFunctionDeclaration> : ParseExpression; -// type Wrap>, V> = - -// type ParseMemberExpression< -// I, -// T extends Array>, -// > = T[0] extends SymbolToken -// ? T[1] extends DotToken -// ? ParseMemberExpression>, Tail>> -// : T[1] extends ParenToken<'('> -// ? ParseCallExpression>, Tail>> -// : [MemberExpression>, Tail] -// : never; - -// type ParseCallExpression< -// I, -// T extends Array>, -// > = ParseFunctionArguments extends infer G -// ? [CallExpression>[0]>, Cast>[1]] -// : never; - type ParseFunctionArguments< T extends Array>, R extends Array = [], From 92b9b3afde3f3dc0f943a5994f987123823e3b77 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 09:02:00 +0300 Subject: [PATCH 020/286] wip --- src/index.ts | 2 +- src/parse.ts | 21 ++++--- src/test/parser.test.ts | 123 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 137 insertions(+), 9 deletions(-) diff --git a/src/index.ts b/src/index.ts index c5b81c2..aa1b077 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; -type T = Tokenize<`"foo"()()`>; +type T = Tokenize<`[].foo`>; type R = Parse; diff --git a/src/parse.ts b/src/parse.ts index 5f47288..af966e1 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -41,26 +41,31 @@ type Wrap>]> = T[1][0] extends DotToken : never : T; -type ParseExpression< +type DoParseExpression< T extends Array>, F = T[0], > = F extends SymbolToken<'true'> - ? Wrap<[BooleanLiteral, Tail]> + ? [BooleanLiteral, Tail] : F extends SymbolToken<'false'> - ? Wrap<[BooleanLiteral, Tail]> + ? [BooleanLiteral, Tail] : F extends SymbolToken<'null'> - ? Wrap<[NullLiteral, Tail]> + ? [NullLiteral, Tail] : F extends NumberToken - ? Wrap<[NumericLiteral, Tail]> + ? [NumericLiteral, Tail] : F extends StringToken - ? Wrap<[StringLiteral, Tail]> + ? [StringLiteral, Tail] : F extends BracketToken<'['> ? ParseArray> : F extends CurlyToken<'{'> ? ParseObject> : F extends SymbolToken - ? Wrap<[Identifier, Tail]> - : [T, []]; + ? [Identifier, Tail] + : [never, []]; + +type ParseExpression>> = + DoParseExpression extends infer G + ? Wrap]>> + : never; type ParseStatement< T extends Array>, diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index 8fa730e..786c0a3 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -18,6 +18,30 @@ expectType>([ }, ]); +expectType>([ + { + type: 'MemberExpression', + object: { type: 'StringLiteral', value: 'hello' }, + property: { type: 'Identifier', name: 'world' }, + }, +]); + +expectType>([ + { + type: 'MemberExpression', + object: { type: 'NullLiteral' }, + property: { type: 'Identifier', name: 'world' }, + }, +]); + +expectType>([ + { + type: 'CallExpression', + callee: { type: 'StringLiteral', value: 'hello' }, + arguments: [], + }, +]); + expectType>([ { type: 'CallExpression', @@ -29,6 +53,84 @@ expectType>([ }, ]); +expectType>([ + { + type: 'CallExpression', + callee: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'hello', + }, + arguments: [], + }, + arguments: [], + }, +]); + +expectType>([ + { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: { + type: 'CallExpression', + callee: { type: 'Identifier', name: 'hello' }, + arguments: [], + }, + property: { + type: 'Identifier', + name: 'world', + }, + }, + arguments: [], + }, +]); + +expectType>([ + { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'hello', + }, + arguments: [ + { + type: 'CallExpression', + callee: { type: 'Identifier', name: 'world' }, + arguments: [ + { + type: 'NumericLiteral', + value: '1', + }, + ], + }, + ], + }, +]); + +expectType>([ + { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'hello', + }, + arguments: [ + { + type: 'CallExpression', + callee: { type: 'StringLiteral', value: 'world' }, + arguments: [ + { + type: 'NumericLiteral', + value: '1', + }, + ], + }, + ], + }, +]); + expectType>([ { type: 'CallExpression', @@ -162,3 +264,24 @@ expectType>([ ], }, ]); + +expectType>([ + { + type: 'VariableDeclaration', + kind: 'const', + declarations: [ + { + type: 'VariableDeclarator', + init: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'foo', + }, + arguments: [], + }, + id: { type: 'Identifier', name: 'hello' }, + }, + ], + }, +]); From 21148cfb686c82babdc91e72b1f8e8cfa6f34846 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 09:59:50 +0300 Subject: [PATCH 021/286] wip --- package.json | 2 +- src/index.ts | 10 +++++++++- src/parse.ts | 27 ++++++++++++++++++--------- tsconfig.json | 13 ++++++++----- yarn.lock | 19 +++++-------------- 5 files changed, 41 insertions(+), 30 deletions(-) diff --git a/package.json b/package.json index 8bd5bfa..321b062 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "eslint-plugin-react": "^7.30.1", "eslint-plugin-react-hooks": "^4.6.0", "prettier": "^2.7.1", - "typescript": "^4.7.4" + "typescript": "next" }, "prettier": { "printWidth": 80, diff --git a/src/index.ts b/src/index.ts index aa1b077..a1053f1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,13 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; -type T = Tokenize<`[].foo`>; +type T = Tokenize<` +function foo() { + bar() +} + +function foo() { + bar() +} +`>; type R = Parse; diff --git a/src/parse.ts b/src/parse.ts index af966e1..8d57c41 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -101,17 +101,26 @@ type ParseFunctionArgumentsItem< > : never; -type ParseFunctionDeclaration< - T extends Array>, - G extends [any, Array>] = ParseFunctionParams>>, -> = T[0] extends SymbolToken - ? T[1] extends ParenToken<'('> - ? G[1][0] extends CurlyToken<'{'> - ? G[1][1] extends CurlyToken<'}'> - ? [FunctionDeclaration, G[0], []>, Tail>] +type ParseFunctionDeclaration>> = + T[0] extends SymbolToken + ? T[1] extends ParenToken<'('> + ? ParseFunctionParams>> extends infer G + ? G[1][0] extends CurlyToken<'{'> + ? ParseFunctionBody> extends infer H + ? [FunctionDeclaration, G[0], H[0]>, H[1]] + : never + : never : never : never - : never + : never; + +type ParseFunctionBody< + T extends Array>, + R extends Array = [], +> = T[0] extends CurlyToken<'}'> + ? [Reverse, Tail] + : ParseStatement extends infer F + ? ParseFunctionBody> : never; type ParseFunctionParams< diff --git a/tsconfig.json b/tsconfig.json index eef761d..0cfd4b8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,20 +2,23 @@ "compilerOptions": { "target": "es2019", "module": "es2022", - "lib": ["esnext", "dom"], - "declaration": true, - "composite": true, + "lib": ["esnext"], + "declaration": false, + "composite": false, "isolatedModules": true, "importsNotUsedAsValues": "error", - "jsx": "react", + "diagnostics": false, "strict": true, + "noEmit": true, + "skipLibCheck": true, + "skipDefaultLibCheck": true, "moduleResolution": "node", "esModuleInterop": true, "allowSyntheticDefaultImports": true, "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true, + "resolveJsonModule": false, "rootDir": "src", "outDir": "build" diff --git a/yarn.lock b/yarn.lock index 3d25abd..635b045 100644 --- a/yarn.lock +++ b/yarn.lock @@ -851,16 +851,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.17.12" -"@babel/plugin-transform-typescript@^7.17.12": - version "7.18.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.18.4.tgz#587eaf6a39edb8c06215e550dc939faeadd750bf" - integrity sha512-l4vHuSLUajptpHNEOUDEGsnpl9pfRLsN1XUoDQDD/YBuXTM+v37SHGS+c6n4jdcZy96QtuUuSvZYMLSSsjH8Mw== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.0" - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/plugin-syntax-typescript" "^7.17.12" - -"@babel/plugin-transform-typescript@^7.18.4": +"@babel/plugin-transform-typescript@^7.17.12", "@babel/plugin-transform-typescript@^7.18.4": version "7.18.4" resolved "https://repo.dev.wixpress.com/artifactory/api/npm/npm-repos/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.18.4.tgz#587eaf6a39edb8c06215e550dc939faeadd750bf" integrity sha1-WH6vajntuMBiFeVQ3JOfrq3XUL8= @@ -2943,10 +2934,10 @@ type-fest@^0.20.2: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== -typescript@^4.7.4: - version "4.7.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235" - integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== +typescript@next: + version "4.8.0-dev.20220629" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.0-dev.20220629.tgz#9d719936f77a811d6859051f327c7868700ab250" + integrity sha512-QEp1M6iqlYpQXFF2f9ucXMkXbYcAoXcG0ws0IG8bWd7mjPGf8R5iVCbQVSm1dzV/GoOy0PsvfNe5/uL6D9TSPA== unbox-primitive@^1.0.2: version "1.0.2" From e952133b9902ee7128f2837d8922b551ac0d5301 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 10:08:31 +0300 Subject: [PATCH 022/286] wip --- src/index.ts | 8 ++++---- src/parse.ts | 16 +++++++++++++--- src/test/parser.test.ts | 30 ++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/index.ts b/src/index.ts index a1053f1..5bb483c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,10 +3,10 @@ import type { Parse } from './parse'; type T = Tokenize<` function foo() { - bar() -} - -function foo() { + function foo() { + bar() + } + bar() } `>; diff --git a/src/parse.ts b/src/parse.ts index 8d57c41..b1c6e45 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -105,9 +105,16 @@ type ParseFunctionDeclaration>> = T[0] extends SymbolToken ? T[1] extends ParenToken<'('> ? ParseFunctionParams>> extends infer G - ? G[1][0] extends CurlyToken<'{'> + ? Cast>[1][0] extends CurlyToken<'{'> ? ParseFunctionBody> extends infer H - ? [FunctionDeclaration, G[0], H[0]>, H[1]] + ? [ + FunctionDeclaration< + Identifier, + Cast>[0], + Cast>[0] + >, + Cast>[1], + ] : never : never : never @@ -120,7 +127,10 @@ type ParseFunctionBody< > = T[0] extends CurlyToken<'}'> ? [Reverse, Tail] : ParseStatement extends infer F - ? ParseFunctionBody> + ? ParseFunctionBody< + Cast>[1], + Unshift>[0]> + > : never; type ParseFunctionParams< diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index 786c0a3..f163cc0 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -193,6 +193,36 @@ expectType>([ }, ]); +expectType>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + }, + params: [ + { type: 'Identifier', name: 'first' }, + { type: 'Identifier', name: 'last' }, + ], + body: [ + { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: { type: 'Identifier', name: 'console' }, + property: { type: 'Identifier', name: 'log' }, + }, + arguments: [ + { + type: 'NumericLiteral', + value: '1', + }, + ], + }, + ], + }, +]); + expectType>([ { type: 'VariableDeclaration', From 8910cad49779f6049405408962fdde4df1e4b736 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 10:17:43 +0300 Subject: [PATCH 023/286] wip --- src/index.ts | 4 ---- src/parse.ts | 24 ++++++++++++------------ 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/index.ts b/src/index.ts index 5bb483c..b8b2c29 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,10 +3,6 @@ import type { Parse } from './parse'; type T = Tokenize<` function foo() { - function foo() { - bar() - } - bar() } `>; diff --git a/src/parse.ts b/src/parse.ts index b1c6e45..088c39f 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -105,17 +105,15 @@ type ParseFunctionDeclaration>> = T[0] extends SymbolToken ? T[1] extends ParenToken<'('> ? ParseFunctionParams>> extends infer G - ? Cast>[1][0] extends CurlyToken<'{'> - ? ParseFunctionBody> extends infer H - ? [ - FunctionDeclaration< - Identifier, - Cast>[0], - Cast>[0] - >, - Cast>[1], - ] - : never + ? ParseFunctionBody>[1]> extends infer H + ? [ + FunctionDeclaration< + Identifier, + Cast>[0], + Cast>[0] + >, + Cast>[1], + ] : never : never : never @@ -138,7 +136,9 @@ type ParseFunctionParams< R extends Array = [], N extends boolean = false, > = T[0] extends ParenToken<')'> - ? [Reverse, Tail] + ? T[1] extends CurlyToken<'{'> + ? [Reverse, Tail>] + : never : T extends [] ? never : N extends true From b19b3fe96ec7d0df3dcb4fb01ae510ce5da1081b Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 11:46:29 +0300 Subject: [PATCH 024/286] wip --- src/test/parser.test.ts | 53 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index f163cc0..da2a841 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -223,6 +223,59 @@ expectType>([ }, ]); +expectType< + ParseAst<` +function foo(foo) { + console.log(foo) + + function bar() { + console.log(foo) + } +} +`> +>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + }, + params: [{ type: 'Identifier', name: 'foo' }], + body: [ + { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: { type: 'Identifier', name: 'console' }, + property: { type: 'Identifier', name: 'log' }, + }, + arguments: [ + { + type: 'Identifier', + name: 'foo', + }, + ], + }, + { + type: 'FunctionDeclaration', + id: { type: 'Identifier', name: 'bar' }, + params: [], + body: [ + { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: { type: 'Identifier', name: 'console' }, + property: { type: 'Identifier', name: 'log' }, + }, + arguments: [{ type: 'Identifier', name: 'foo' }], + }, + ], + }, + ], + }, +]); + expectType>([ { type: 'VariableDeclaration', From 2fcc1a442612dee4d3c0a1daff682e4e3abddb46 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 11:53:21 +0300 Subject: [PATCH 025/286] wip --- src/index.ts | 4 +- src/parse.ts | 4 +- src/test/parser.test.ts | 281 +++++++++++++++++++++++----------------- 3 files changed, 168 insertions(+), 121 deletions(-) diff --git a/src/index.ts b/src/index.ts index b8b2c29..9abcb06 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,8 +2,6 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; type T = Tokenize<` -function foo() { - bar() -} +"hello" `>; type R = Parse; diff --git a/src/parse.ts b/src/parse.ts index 088c39f..ff74e76 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -74,7 +74,9 @@ type ParseStatement< ? ParseVariableDeclaration> : F extends SymbolToken<'function'> ? ParseFunctionDeclaration> - : ParseExpression; + : ParseExpression extends infer G + ? [ExpressionStatement>[0]>, Cast>[1]] + : never; type ParseFunctionArguments< T extends Array>, diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index da2a841..60ac32b 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -8,161 +8,199 @@ type ParseAst = Tokenize extends infer G ? Parse>> : never; -expectType>([{ type: 'Identifier', name: 'hello' }]); +expectType>([ + { + type: 'ExpressionStatement', + expression: { type: 'Identifier', name: 'hello' }, + }, +]); expectType>([ { - type: 'MemberExpression', - object: { type: 'Identifier', name: 'hello' }, - property: { type: 'Identifier', name: 'world' }, + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + object: { type: 'Identifier', name: 'hello' }, + property: { type: 'Identifier', name: 'world' }, + }, }, ]); expectType>([ { - type: 'MemberExpression', - object: { type: 'StringLiteral', value: 'hello' }, - property: { type: 'Identifier', name: 'world' }, + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + object: { type: 'StringLiteral', value: 'hello' }, + property: { type: 'Identifier', name: 'world' }, + }, }, ]); expectType>([ { - type: 'MemberExpression', - object: { type: 'NullLiteral' }, - property: { type: 'Identifier', name: 'world' }, + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + object: { type: 'NullLiteral' }, + property: { type: 'Identifier', name: 'world' }, + }, }, ]); expectType>([ { - type: 'CallExpression', - callee: { type: 'StringLiteral', value: 'hello' }, - arguments: [], + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { type: 'StringLiteral', value: 'hello' }, + arguments: [], + }, }, ]); expectType>([ { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'hello', + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'hello', + }, + arguments: [], }, - arguments: [], }, ]); expectType>([ { - type: 'CallExpression', - callee: { + type: 'ExpressionStatement', + expression: { type: 'CallExpression', callee: { - type: 'Identifier', - name: 'hello', + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'hello', + }, + arguments: [], }, arguments: [], }, - arguments: [], }, ]); expectType>([ { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: { - type: 'CallExpression', - callee: { type: 'Identifier', name: 'hello' }, - arguments: [], - }, - property: { - type: 'Identifier', - name: 'world', + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: { + type: 'CallExpression', + callee: { type: 'Identifier', name: 'hello' }, + arguments: [], + }, + property: { + type: 'Identifier', + name: 'world', + }, }, + arguments: [], }, - arguments: [], }, ]); expectType>([ { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'hello', - }, - arguments: [ - { - type: 'CallExpression', - callee: { type: 'Identifier', name: 'world' }, - arguments: [ - { - type: 'NumericLiteral', - value: '1', - }, - ], + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'hello', }, - ], + arguments: [ + { + type: 'CallExpression', + callee: { type: 'Identifier', name: 'world' }, + arguments: [ + { + type: 'NumericLiteral', + value: '1', + }, + ], + }, + ], + }, }, ]); expectType>([ { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'hello', - }, - arguments: [ - { - type: 'CallExpression', - callee: { type: 'StringLiteral', value: 'world' }, - arguments: [ - { - type: 'NumericLiteral', - value: '1', - }, - ], + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'hello', }, - ], + arguments: [ + { + type: 'CallExpression', + callee: { type: 'StringLiteral', value: 'world' }, + arguments: [ + { + type: 'NumericLiteral', + value: '1', + }, + ], + }, + ], + }, }, ]); expectType>([ { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'hello', + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'hello', + }, + arguments: [ + { type: 'NumericLiteral', value: '1' }, + { type: 'BooleanLiteral', value: true }, + ], }, - arguments: [ - { type: 'NumericLiteral', value: '1' }, - { type: 'BooleanLiteral', value: true }, - ], }, ]); expectType>([ { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: { - type: 'Identifier', - name: 'hello', - }, - property: { - type: 'Identifier', - name: 'world', + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: { + type: 'Identifier', + name: 'hello', + }, + property: { + type: 'Identifier', + name: 'world', + }, }, + arguments: [ + { type: 'NumericLiteral', value: '1' }, + { type: 'BooleanLiteral', value: true }, + ], }, - arguments: [ - { type: 'NumericLiteral', value: '1' }, - { type: 'BooleanLiteral', value: true }, - ], }, ]); @@ -206,18 +244,21 @@ expectType>([ ], body: [ { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: { type: 'Identifier', name: 'console' }, - property: { type: 'Identifier', name: 'log' }, - }, - arguments: [ - { - type: 'NumericLiteral', - value: '1', + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: { type: 'Identifier', name: 'console' }, + property: { type: 'Identifier', name: 'log' }, }, - ], + arguments: [ + { + type: 'NumericLiteral', + value: '1', + }, + ], + }, }, ], }, @@ -243,18 +284,21 @@ function foo(foo) { params: [{ type: 'Identifier', name: 'foo' }], body: [ { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: { type: 'Identifier', name: 'console' }, - property: { type: 'Identifier', name: 'log' }, - }, - arguments: [ - { - type: 'Identifier', - name: 'foo', + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: { type: 'Identifier', name: 'console' }, + property: { type: 'Identifier', name: 'log' }, }, - ], + arguments: [ + { + type: 'Identifier', + name: 'foo', + }, + ], + }, }, { type: 'FunctionDeclaration', @@ -262,13 +306,16 @@ function foo(foo) { params: [], body: [ { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: { type: 'Identifier', name: 'console' }, - property: { type: 'Identifier', name: 'log' }, + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: { type: 'Identifier', name: 'console' }, + property: { type: 'Identifier', name: 'log' }, + }, + arguments: [{ type: 'Identifier', name: 'foo' }], }, - arguments: [{ type: 'Identifier', name: 'foo' }], }, ], }, From c054b98b30b71a62fabdd84ba21e26b3a6db3766 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 12:16:12 +0300 Subject: [PATCH 026/286] wip --- src/ast.ts | 7 +++++ src/index.ts | 4 ++- src/parse.ts | 16 ++++++++++ src/test/parser.test.ts | 67 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 1 deletion(-) diff --git a/src/ast.ts b/src/ast.ts index 153ce06..72b4960 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -74,6 +74,13 @@ export type MemberExpression = { property: P; }; +export type IfStatement = { + type: 'IfStatement'; + test: T; + consequent: C; + // alternate: A; +}; + // ReturnStatement // IfStatement // BlockStatement diff --git a/src/index.ts b/src/index.ts index 9abcb06..c1f4f8a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,8 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; type T = Tokenize<` -"hello" +if (foo) { + log() +} `>; type R = Parse; diff --git a/src/parse.ts b/src/parse.ts index ff74e76..912d205 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -13,6 +13,7 @@ import type { ExpressionStatement, CallExpression, MemberExpression, + IfStatement, } from './ast'; import type { BracketToken, @@ -74,10 +75,25 @@ type ParseStatement< ? ParseVariableDeclaration> : F extends SymbolToken<'function'> ? ParseFunctionDeclaration> + : F extends SymbolToken<'if'> + ? ParseIfStatement> : ParseExpression extends infer G ? [ExpressionStatement>[0]>, Cast>[1]] : never; +type ParseIfStatement>> = + T[0] extends ParenToken<'('> + ? ParseExpression> extends infer G + ? G[1][0] extends ParenToken<')'> + ? G[1][1] extends CurlyToken<'{'> + ? ParseFunctionBody>> extends infer B + ? [IfStatement, B[1]] + : never + : never + : never + : never + : never; + type ParseFunctionArguments< T extends Array>, R extends Array = [], diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index 60ac32b..01ae23b 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -415,3 +415,70 @@ expectType>([ ], }, ]); + +expectType>([ + { + type: 'IfStatement', + test: { + type: 'Identifier', + name: 'a', + }, + consequent: [], + }, +]); + +expectType>([ + { + type: 'IfStatement', + test: { + type: 'StringLiteral', + value: 'a', + }, + consequent: [], + }, +]); + +expectType>([ + { + type: 'IfStatement', + test: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'a', + }, + arguments: [], + }, + consequent: [], + }, +]); + +expectType>([ + { + type: 'IfStatement', + test: { + type: 'Identifier', + name: 'a', + }, + consequent: [ + { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: { + type: 'Identifier', + name: 'console', + }, + property: { + type: 'Identifier', + name: 'log', + }, + }, + arguments: [], + }, + }, + ], + }, +]); From 3c89ef1c025c35911c75c40d67b70ce9a86fa3b4 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 12:55:13 +0300 Subject: [PATCH 027/286] wip --- src/index.ts | 9 ++++++++- src/parse.ts | 18 +++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/index.ts b/src/index.ts index c1f4f8a..fc84394 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,16 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; +import type { Tail } from './utils/arrayUtils'; +import type { Cast } from './utils/generalUtils'; + type T = Tokenize<` if (foo) { log() } `>; -type R = Parse; +type R = Parse[0]; + +// type Z = Cast>; +// type A = Tail>; +// type B = R[0][1]; diff --git a/src/parse.ts b/src/parse.ts index 912d205..b476316 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -81,13 +81,25 @@ type ParseStatement< ? [ExpressionStatement>[0]>, Cast>[1]] : never; +// type ParseExpressionHelperIf = Cast< +// G, +// Array +// >[1][0] extends ParenToken<')'> +// ? Cast>[1][1] extends CurlyToken<'{'> +// ? Tail>[1]>> +// : never +// : never; + type ParseIfStatement>> = T[0] extends ParenToken<'('> ? ParseExpression> extends infer G - ? G[1][0] extends ParenToken<')'> - ? G[1][1] extends CurlyToken<'{'> + ? Cast>[1][0] extends ParenToken<')'> + ? Cast>[1][1] extends CurlyToken<'{'> ? ParseFunctionBody>> extends infer B - ? [IfStatement, B[1]] + ? [ + IfStatement>[0], Cast>[0]>, + Cast>[1], + ] : never : never : never From 2ddbfa3d5574f9a656a6b7b9734ae3fc33ab6280 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 13:22:05 +0300 Subject: [PATCH 028/286] wip --- src/index.ts | 9 +-------- src/parse.ts | 25 +++++++++---------------- 2 files changed, 10 insertions(+), 24 deletions(-) diff --git a/src/index.ts b/src/index.ts index fc84394..c1f4f8a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,16 +1,9 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; -import type { Tail } from './utils/arrayUtils'; -import type { Cast } from './utils/generalUtils'; - type T = Tokenize<` if (foo) { log() } `>; -type R = Parse[0]; - -// type Z = Cast>; -// type A = Tail>; -// type B = R[0][1]; +type R = Parse; diff --git a/src/parse.ts b/src/parse.ts index b476316..3a71176 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -81,25 +81,18 @@ type ParseStatement< ? [ExpressionStatement>[0]>, Cast>[1]] : never; -// type ParseExpressionHelperIf = Cast< -// G, -// Array -// >[1][0] extends ParenToken<')'> -// ? Cast>[1][1] extends CurlyToken<'{'> -// ? Tail>[1]>> -// : never -// : never; - type ParseIfStatement>> = T[0] extends ParenToken<'('> ? ParseExpression> extends infer G - ? Cast>[1][0] extends ParenToken<')'> - ? Cast>[1][1] extends CurlyToken<'{'> - ? ParseFunctionBody>> extends infer B - ? [ - IfStatement>[0], Cast>[0]>, - Cast>[1], - ] + ? Cast>[1] extends infer J + ? Cast>[0] extends ParenToken<')'> + ? Cast>[1] extends CurlyToken<'{'> + ? ParseFunctionBody>>>> extends infer B + ? [ + IfStatement>[0], Cast>[0]>, + Cast>[1], + ] + : never : never : never : never From 3a8a0a3bd79c6f8b77412a72d236bc6edffbfb67 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 13:29:39 +0300 Subject: [PATCH 029/286] wip --- src/ast.ts | 5 +++++ src/index.ts | 4 ++-- src/parse.ts | 10 +++++++++- src/test/parser.test.ts | 44 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 3 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index 72b4960..fd48535 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -81,6 +81,11 @@ export type IfStatement = { // alternate: A; }; +export type ReturnStatement = { + type: 'ReturnStatement'; + argument: T; +}; + // ReturnStatement // IfStatement // BlockStatement diff --git a/src/index.ts b/src/index.ts index c1f4f8a..1621d59 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,8 +2,8 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; type T = Tokenize<` -if (foo) { - log() +function foo() { + return 1 } `>; type R = Parse; diff --git a/src/parse.ts b/src/parse.ts index 3a71176..1dde3fe 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -14,6 +14,7 @@ import type { CallExpression, MemberExpression, IfStatement, + ReturnStatement, } from './ast'; import type { BracketToken, @@ -81,6 +82,13 @@ type ParseStatement< ? [ExpressionStatement>[0]>, Cast>[1]] : never; +type ParseFunctionStatement>> = + T[0] extends SymbolToken<'return'> + ? ParseExpression> extends infer G + ? [ReturnStatement>[0]>, Cast>[1]] + : never + : ParseStatement; + type ParseIfStatement>> = T[0] extends ParenToken<'('> ? ParseExpression> extends infer G @@ -147,7 +155,7 @@ type ParseFunctionBody< R extends Array = [], > = T[0] extends CurlyToken<'}'> ? [Reverse, Tail] - : ParseStatement extends infer F + : ParseFunctionStatement extends infer F ? ParseFunctionBody< Cast>[1], Unshift>[0]> diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index 01ae23b..90e361a 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -231,6 +231,50 @@ expectType>([ }, ]); +expectType>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + }, + params: [], + body: [ + { + type: 'ReturnStatement', + argument: { + type: 'NumericLiteral', + value: '5', + }, + }, + ], + }, +]); + +expectType>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + }, + params: [], + body: [ + { + type: 'ReturnStatement', + argument: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'bar', + }, + arguments: [], + }, + }, + ], + }, +]); + expectType>([ { type: 'FunctionDeclaration', From 69627eeb9ad25c1da9c024ebe54593682c1b5f23 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 13:39:42 +0300 Subject: [PATCH 030/286] wip --- src/ast.ts | 5 + src/parse.ts | 13 ++- src/test/parser.test.ts | 217 +++++++++++++++++++++++----------------- 3 files changed, 138 insertions(+), 97 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index fd48535..29da5d5 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -86,6 +86,11 @@ export type ReturnStatement = { argument: T; }; +export type BlockStatement = { + type: 'BlockStatement'; + body: B; +}; + // ReturnStatement // IfStatement // BlockStatement diff --git a/src/parse.ts b/src/parse.ts index 1dde3fe..c940331 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -15,6 +15,7 @@ import type { MemberExpression, IfStatement, ReturnStatement, + BlockStatement, } from './ast'; import type { BracketToken, @@ -95,7 +96,9 @@ type ParseIfStatement>> = ? Cast>[1] extends infer J ? Cast>[0] extends ParenToken<')'> ? Cast>[1] extends CurlyToken<'{'> - ? ParseFunctionBody>>>> extends infer B + ? ParseBlockStatement< + Tail>>> + > extends infer B ? [ IfStatement>[0], Cast>[0]>, Cast>[1], @@ -136,7 +139,7 @@ type ParseFunctionDeclaration>> = T[0] extends SymbolToken ? T[1] extends ParenToken<'('> ? ParseFunctionParams>> extends infer G - ? ParseFunctionBody>[1]> extends infer H + ? ParseBlockStatement>[1]> extends infer H ? [ FunctionDeclaration< Identifier, @@ -150,13 +153,13 @@ type ParseFunctionDeclaration>> = : never : never; -type ParseFunctionBody< +type ParseBlockStatement< T extends Array>, R extends Array = [], > = T[0] extends CurlyToken<'}'> - ? [Reverse, Tail] + ? [BlockStatement>, Tail] : ParseFunctionStatement extends infer F - ? ParseFunctionBody< + ? ParseBlockStatement< Cast>[1], Unshift>[0]> > diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index 90e361a..f2e3bd8 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -212,7 +212,10 @@ expectType>([ name: 'foo', }, params: [], - body: [], + body: { + type: 'BlockStatement', + body: [], + }, }, ]); @@ -227,7 +230,10 @@ expectType>([ { type: 'Identifier', name: 'first' }, { type: 'Identifier', name: 'last' }, ], - body: [], + body: { + type: 'BlockStatement', + body: [], + }, }, ]); @@ -239,15 +245,18 @@ expectType>([ name: 'foo', }, params: [], - body: [ - { - type: 'ReturnStatement', - argument: { - type: 'NumericLiteral', - value: '5', + body: { + type: 'BlockStatement', + body: [ + { + type: 'ReturnStatement', + argument: { + type: 'NumericLiteral', + value: '5', + }, }, - }, - ], + ], + }, }, ]); @@ -259,19 +268,22 @@ expectType>([ name: 'foo', }, params: [], - body: [ - { - type: 'ReturnStatement', - argument: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'bar', + body: { + type: 'BlockStatement', + body: [ + { + type: 'ReturnStatement', + argument: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'bar', + }, + arguments: [], }, - arguments: [], }, - }, - ], + ], + }, }, ]); @@ -286,25 +298,28 @@ expectType>([ { type: 'Identifier', name: 'first' }, { type: 'Identifier', name: 'last' }, ], - body: [ - { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: { type: 'Identifier', name: 'console' }, - property: { type: 'Identifier', name: 'log' }, - }, - arguments: [ - { - type: 'NumericLiteral', - value: '1', + body: { + type: 'BlockStatement', + body: [ + { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: { type: 'Identifier', name: 'console' }, + property: { type: 'Identifier', name: 'log' }, }, - ], + arguments: [ + { + type: 'NumericLiteral', + value: '1', + }, + ], + }, }, - }, - ], + ], + }, }, ]); @@ -326,44 +341,50 @@ function foo(foo) { name: 'foo', }, params: [{ type: 'Identifier', name: 'foo' }], - body: [ - { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: { type: 'Identifier', name: 'console' }, - property: { type: 'Identifier', name: 'log' }, - }, - arguments: [ - { - type: 'Identifier', - name: 'foo', + body: { + type: 'BlockStatement', + body: [ + { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: { type: 'Identifier', name: 'console' }, + property: { type: 'Identifier', name: 'log' }, }, - ], + arguments: [ + { + type: 'Identifier', + name: 'foo', + }, + ], + }, }, - }, - { - type: 'FunctionDeclaration', - id: { type: 'Identifier', name: 'bar' }, - params: [], - body: [ - { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: { type: 'Identifier', name: 'console' }, - property: { type: 'Identifier', name: 'log' }, + { + type: 'FunctionDeclaration', + id: { type: 'Identifier', name: 'bar' }, + params: [], + body: { + type: 'BlockStatement', + body: [ + { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: { type: 'Identifier', name: 'console' }, + property: { type: 'Identifier', name: 'log' }, + }, + arguments: [{ type: 'Identifier', name: 'foo' }], + }, }, - arguments: [{ type: 'Identifier', name: 'foo' }], - }, + ], }, - ], - }, - ], + }, + ], + }, }, ]); @@ -467,7 +488,10 @@ expectType>([ type: 'Identifier', name: 'a', }, - consequent: [], + consequent: { + type: 'BlockStatement', + body: [], + }, }, ]); @@ -478,7 +502,10 @@ expectType>([ type: 'StringLiteral', value: 'a', }, - consequent: [], + consequent: { + type: 'BlockStatement', + body: [], + }, }, ]); @@ -493,7 +520,10 @@ expectType>([ }, arguments: [], }, - consequent: [], + consequent: { + type: 'BlockStatement', + body: [], + }, }, ]); @@ -504,25 +534,28 @@ expectType>([ type: 'Identifier', name: 'a', }, - consequent: [ - { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: { - type: 'Identifier', - name: 'console', - }, - property: { - type: 'Identifier', - name: 'log', + consequent: { + type: 'BlockStatement', + body: [ + { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: { + type: 'Identifier', + name: 'console', + }, + property: { + type: 'Identifier', + name: 'log', + }, }, + arguments: [], }, - arguments: [], }, - }, - ], + ], + }, }, ]); From 95f2d6bdd01f678f2892ecbcb09fcb8eee734427 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 13:42:08 +0300 Subject: [PATCH 031/286] wip --- src/ast.ts | 8 +------- src/index.ts | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index 29da5d5..09538f5 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -91,12 +91,6 @@ export type BlockStatement = { body: B; }; -// ReturnStatement -// IfStatement -// BlockStatement - -// Add unit-tests -// Fn-calls, member-access on expressions -// Parse statements, parse expressions, no parse literal +// Parse type annotations // Show parse errors // Type check and inference diff --git a/src/index.ts b/src/index.ts index 1621d59..2c4f83a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,7 +3,7 @@ import type { Parse } from './parse'; type T = Tokenize<` function foo() { - return 1 + const a = {} } `>; type R = Parse; From c7efb9b7b422a274ee88b9227776719b8b972f85 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 14:47:05 +0300 Subject: [PATCH 032/286] wip --- src/ast.ts | 40 ++++++++++++++++++++++++++++++++++++---- src/index.ts | 4 +--- src/parse.ts | 17 ++++++++++++++++- 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index 09538f5..2723e52 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -48,10 +48,16 @@ export type FunctionDeclaration = { body: B; }; -export type Identifier = { - type: 'Identifier'; - name: N; -}; +export type Identifier = T extends null + ? { + type: 'Identifier'; + name: N; + } + : { + type: 'Identifier'; + name: N; + typeAnnotation: T; + }; export type NullLiteral = { type: 'NullLiteral'; @@ -91,6 +97,32 @@ export type BlockStatement = { body: B; }; +export type TypeAnnotation = { + type: 'TypeAnnotation'; + typeAnnotation: T; +}; + +export type StringTypeAnnotation = { + type: 'StringTypeAnnotation'; +}; + +export type NumberTypeAnnotation = { + type: 'NumberTypeAnnotation'; +}; + +export type NullLiteralTypeAnnotation = { + type: 'NullLiteralTypeAnnotation'; +}; + +export type BooleanTypeAnnotation = { + type: 'BooleanTypeAnnotation'; +}; + +export type GenericTypeAnnotation = { + type: 'GenericTypeAnnotation'; + id: I; +}; + // Parse type annotations // Show parse errors // Type check and inference diff --git a/src/index.ts b/src/index.ts index 2c4f83a..4cc5ca4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,8 +2,6 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; type T = Tokenize<` -function foo() { - const a = {} -} +function foo(a: string) {} `>; type R = Parse; diff --git a/src/parse.ts b/src/parse.ts index c940331..cd9c65e 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -16,6 +16,8 @@ import type { IfStatement, ReturnStatement, BlockStatement, + TypeAnnotation, + GenericTypeAnnotation, } from './ast'; import type { BracketToken, @@ -181,11 +183,24 @@ type ParseFunctionParams< : never : ParseFunctionParamsItem; +type ParseTypeAnnotation>> = + T[0] extends SymbolToken + ? [TypeAnnotation>, Tail] + : never; + type ParseFunctionParamsItem< T extends Array>, R extends Array = [], > = T[0] extends SymbolToken - ? ParseFunctionParams, Unshift>, true> + ? T[1] extends ColonToken + ? T[2] extends SymbolToken + ? ParseFunctionParams< + Tail>>, + Unshift>>>, + true + > + : never + : ParseFunctionParams, Unshift>, true> : never; type ParseVariableDeclaration>> = From ce8f327435b7b29a4857ece916eb48d6877fd290 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 14:47:09 +0300 Subject: [PATCH 033/286] wip --- src/index.ts | 2 +- src/parse.ts | 20 ++++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/index.ts b/src/index.ts index 4cc5ca4..5b6d6c7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; type T = Tokenize<` -function foo(a: string) {} +const a: number = 5 `>; type R = Parse; diff --git a/src/parse.ts b/src/parse.ts index cd9c65e..ec498e5 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -18,6 +18,10 @@ import type { BlockStatement, TypeAnnotation, GenericTypeAnnotation, + StringTypeAnnotation, + BooleanTypeAnnotation, + NullLiteralTypeAnnotation, + NumberTypeAnnotation, } from './ast'; import type { BracketToken, @@ -184,7 +188,15 @@ type ParseFunctionParams< : ParseFunctionParamsItem; type ParseTypeAnnotation>> = - T[0] extends SymbolToken + T[0] extends SymbolToken<'string'> + ? [TypeAnnotation, Tail] + : T[0] extends SymbolToken<'boolean'> + ? [TypeAnnotation, Tail] + : T[0] extends SymbolToken<'null'> + ? [TypeAnnotation, Tail] + : T[0] extends SymbolToken<'number'> + ? [TypeAnnotation, Tail] + : T[0] extends SymbolToken ? [TypeAnnotation>, Tail] : never; @@ -193,10 +205,10 @@ type ParseFunctionParamsItem< R extends Array = [], > = T[0] extends SymbolToken ? T[1] extends ColonToken - ? T[2] extends SymbolToken + ? ParseTypeAnnotation>> extends infer G ? ParseFunctionParams< - Tail>>, - Unshift>>>, + Cast>[1], + Unshift>[0]>>, true > : never From 72d63ca76decacab41cc26b819df3382cefbc6d0 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 15:15:57 +0300 Subject: [PATCH 034/286] wip --- src/index.ts | 2 +- src/parse.ts | 36 ++++++-- src/test/parser.test.ts | 198 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 226 insertions(+), 10 deletions(-) diff --git a/src/index.ts b/src/index.ts index 5b6d6c7..5a1d4a4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; type T = Tokenize<` -const a: number = 5 +const a: string = foo() `>; type R = Parse; diff --git a/src/parse.ts b/src/parse.ts index ec498e5..17da47f 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -215,18 +215,36 @@ type ParseFunctionParamsItem< : ParseFunctionParams, Unshift>, true> : never; +type ParseVariableDeclarationHelper< + T extends Array>, + K, + Q = null, +> = ParseExpression extends infer G + ? [ + VariableDeclaration< + [VariableDeclarator, Cast>[0]>], + 'const' + >, + Cast>[1], + ] + : never; + type ParseVariableDeclaration>> = T[0] extends SymbolToken - ? T[1] extends SymbolToken<'='> - ? ParseExpression>> extends infer G - ? [ - VariableDeclaration< - [VariableDeclarator, Cast>[0]>], - 'const' - >, - Cast>[1], - ] + ? T[1] extends ColonToken + ? ParseTypeAnnotation>> extends infer G + ? Cast>[1][0] extends SymbolToken<'='> + ? Cast>[1] extends infer J + ? ParseVariableDeclarationHelper< + Tail>>, + K, + Cast>[0] + > + : never + : never : never + : T[1] extends SymbolToken<'='> + ? ParseVariableDeclarationHelper>, K> : never : never; diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index f2e3bd8..294c40c 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -559,3 +559,201 @@ expectType>([ }, }, ]); + +expectType>([ + { + type: 'VariableDeclaration', + kind: 'const', + declarations: [ + { + type: 'VariableDeclarator', + init: { type: 'StringLiteral', value: 'world' }, + id: { + type: 'Identifier', + name: 'hello', + typeAnnotation: { + type: 'TypeAnnotation', + typeAnnotation: { type: 'StringTypeAnnotation' }, + }, + }, + }, + ], + }, +]); + +expectType>([ + { + type: 'VariableDeclaration', + kind: 'const', + declarations: [ + { + type: 'VariableDeclarator', + init: { type: 'StringLiteral', value: 'world' }, + id: { + type: 'Identifier', + name: 'hello', + typeAnnotation: { + type: 'TypeAnnotation', + typeAnnotation: { type: 'NumberTypeAnnotation' }, + }, + }, + }, + ], + }, +]); + +expectType>([ + { + type: 'VariableDeclaration', + kind: 'const', + declarations: [ + { + type: 'VariableDeclarator', + init: { type: 'BooleanLiteral', value: true }, + id: { + type: 'Identifier', + name: 'hello', + typeAnnotation: { + type: 'TypeAnnotation', + typeAnnotation: { type: 'BooleanTypeAnnotation' }, + }, + }, + }, + ], + }, +]); + +expectType>([ + { + type: 'VariableDeclaration', + kind: 'const', + declarations: [ + { + type: 'VariableDeclarator', + init: { type: 'StringLiteral', value: 'world' }, + id: { + type: 'Identifier', + name: 'hello', + typeAnnotation: { + type: 'TypeAnnotation', + typeAnnotation: { type: 'NullLiteralTypeAnnotation' }, + }, + }, + }, + ], + }, +]); + +expectType>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + }, + params: [ + { + type: 'Identifier', + name: 'bar', + typeAnnotation: { + type: 'TypeAnnotation', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + }, + ], + body: { + type: 'BlockStatement', + body: [], + }, + }, +]); + +expectType>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + }, + params: [ + { + type: 'Identifier', + name: 'bar', + typeAnnotation: { + type: 'TypeAnnotation', + typeAnnotation: { + type: 'BooleanTypeAnnotation', + }, + }, + }, + ], + body: { + type: 'BlockStatement', + body: [], + }, + }, +]); + +expectType>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + }, + params: [ + { + type: 'Identifier', + name: 'bar', + typeAnnotation: { + type: 'TypeAnnotation', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + }, + ], + body: { + type: 'BlockStatement', + body: [], + }, + }, +]); + +expectType>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + }, + params: [ + { + type: 'Identifier', + name: 'bar', + typeAnnotation: { + type: 'TypeAnnotation', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + }, + { + type: 'Identifier', + name: 'baz', + typeAnnotation: { + type: 'TypeAnnotation', + typeAnnotation: { + type: 'NullLiteralTypeAnnotation', + }, + }, + }, + ], + body: { + type: 'BlockStatement', + body: [], + }, + }, +]); From c6b53cf342ce65c6d227c050fbfe7b842c8719bf Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 15:34:04 +0300 Subject: [PATCH 035/286] wip --- src/ast.ts | 4 ---- src/checker.ts | 1 + src/index.ts | 2 ++ 3 files changed, 3 insertions(+), 4 deletions(-) create mode 100644 src/checker.ts diff --git a/src/ast.ts b/src/ast.ts index 2723e52..f63b505 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -122,7 +122,3 @@ export type GenericTypeAnnotation = { type: 'GenericTypeAnnotation'; id: I; }; - -// Parse type annotations -// Show parse errors -// Type check and inference diff --git a/src/checker.ts b/src/checker.ts new file mode 100644 index 0000000..b103aea --- /dev/null +++ b/src/checker.ts @@ -0,0 +1 @@ +export type Check = T; diff --git a/src/index.ts b/src/index.ts index 5a1d4a4..d22dca8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,9 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; +import type { Check } from './checker'; type T = Tokenize<` const a: string = foo() `>; type R = Parse; +type C = Check; From 0c5fd0eb3483cb149f8975526f1bd52c019dba07 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 16:59:20 +0300 Subject: [PATCH 036/286] wip --- .eslintrc | 1 - src/checker.ts | 38 +++++++++++++++++++++++++++++++++++++- src/index.ts | 8 +++----- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/.eslintrc b/.eslintrc index 24cca27..f9ee1d0 100644 --- a/.eslintrc +++ b/.eslintrc @@ -15,7 +15,6 @@ "@typescript-eslint/no-unused-vars": "off", "import/no-anonymous-default-export": "off", "@typescript-eslint/prefer-ts-expect-error": "error", - "@typescript-eslint/ban-types": "error", "@typescript-eslint/explicit-module-boundary-types": [ "error", { "allowArgumentsExplicitlyTypedAsAny": true } diff --git a/src/checker.ts b/src/checker.ts index b103aea..f38075d 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -1 +1,37 @@ -export type Check = T; +import type { + BlockStatement, + BooleanLiteral, + ExpressionStatement, + NullLiteral, + NumericLiteral, + ReturnStatement, + StringLiteral, +} from './ast'; +import type { Cast } from './utils/generalUtils'; + +export type Check> = CheckBlock; + +type InferExpression = T extends StringLiteral + ? 'string' + : T extends NumericLiteral + ? 'number' + : T extends NullLiteral + ? 'null' + : T extends BooleanLiteral + ? 'boolean' + : 'unknown'; + +type InferBlock, S = {}> = T[0] extends ReturnStatement< + infer E +> + ? InferExpression + : []; + +type CheckBlock< + T extends Array, + S = {}, +> = T[0] extends ExpressionStatement + ? InferExpression + : T[0] extends BlockStatement + ? InferBlock>> + : []; diff --git a/src/index.ts b/src/index.ts index d22dca8..be12d26 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,8 +2,6 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; import type { Check } from './checker'; -type T = Tokenize<` -const a: string = foo() -`>; -type R = Parse; -type C = Check; +type T = Tokenize<`function foo () { return 123 }`>; +type R = Parse[0]['body']; +type C = Check<[R]>; From 01fdeb3b7608cae86011286443a050eeb54843a2 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 18:13:25 +0300 Subject: [PATCH 037/286] wip --- src/checker.ts | 28 +++++++++++++++++++++------- src/index.ts | 9 ++++++++- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index f38075d..999e26b 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -2,16 +2,20 @@ import type { BlockStatement, BooleanLiteral, ExpressionStatement, + Identifier, NullLiteral, NumericLiteral, ReturnStatement, StringLiteral, + VariableDeclaration, + VariableDeclarator, } from './ast'; -import type { Cast } from './utils/generalUtils'; +import type { Tail } from './utils/arrayUtils'; +import type { Cast, MergeWithOverride } from './utils/generalUtils'; export type Check> = CheckBlock; -type InferExpression = T extends StringLiteral +type InferExpression = T extends StringLiteral ? 'string' : T extends NumericLiteral ? 'number' @@ -19,13 +23,23 @@ type InferExpression = T extends StringLiteral ? 'null' : T extends BooleanLiteral ? 'boolean' + : T extends Identifier + ? S[Cast] : 'unknown'; -type InferBlock, S = {}> = T[0] extends ReturnStatement< - infer E -> - ? InferExpression - : []; +type InferBlock, S = {}> = T extends [] + ? 'void' + : T[0] extends ReturnStatement + ? InferExpression + : T[0] extends VariableDeclaration< + [VariableDeclarator, infer I>], + any + > + ? InferBlock< + Tail, + MergeWithOverride]: InferExpression }> + > + : InferBlock, S>; type CheckBlock< T extends Array, diff --git a/src/index.ts b/src/index.ts index be12d26..8966b29 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,13 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; import type { Check } from './checker'; -type T = Tokenize<`function foo () { return 123 }`>; +type T = Tokenize<` +function foo () { + const a = "1" + const b = a + + return b +} +`>; type R = Parse[0]['body']; type C = Check<[R]>; From ae6e73f6d15b06e744c56c9745464eefba9ed5b6 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 18:15:06 +0300 Subject: [PATCH 038/286] wip --- src/index.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 8966b29..096fb1a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,10 +4,11 @@ import type { Check } from './checker'; type T = Tokenize<` function foo () { - const a = "1" + const a = true const b = a + const c = b - return b + return c } `>; type R = Parse[0]['body']; From 5a81dea2620fb2ffcc94902a158ffa10ddb922e9 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 18:16:35 +0300 Subject: [PATCH 039/286] wip --- src/ast.ts | 4 ++++ src/parse.ts | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/ast.ts b/src/ast.ts index f63b505..114d3c6 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -122,3 +122,7 @@ export type GenericTypeAnnotation = { type: 'GenericTypeAnnotation'; id: I; }; + +export type AnyTypeAnnotation = { + type: 'AnyTypeAnnotation'; +}; diff --git a/src/parse.ts b/src/parse.ts index 17da47f..974b889 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -22,6 +22,7 @@ import type { BooleanTypeAnnotation, NullLiteralTypeAnnotation, NumberTypeAnnotation, + AnyTypeAnnotation, } from './ast'; import type { BracketToken, @@ -196,6 +197,8 @@ type ParseTypeAnnotation>> = ? [TypeAnnotation, Tail] : T[0] extends SymbolToken<'number'> ? [TypeAnnotation, Tail] + : T[0] extends SymbolToken<'any'> + ? [TypeAnnotation, Tail] : T[0] extends SymbolToken ? [TypeAnnotation>, Tail] : never; From 8765c32da5e2c3a335b2dc147a9c963890cd8062 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 18:24:12 +0300 Subject: [PATCH 040/286] wip --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ff78ea0..b29d414 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ ## 🥑 Type-Fusion -> A (very) simplified implementation of TypeScript's type-system in TypeScript type-system +> A (very) simplified implementation of TypeScript's type-system written in TypeScript's own type-system ### Introduction + +This project includes a simplified implementation of TypeScript's type-system that's implemented in TypeScript's own type-system. The implementation includes an EcmaScript tokenizer and parser, along with a limited type-system. From ad3bafa4d6831b19d8dbe234d9462176b7800461 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 19:01:46 +0300 Subject: [PATCH 041/286] wip --- src/checker.ts | 24 ++++++++++++++++++------ src/index.ts | 15 +++++++++++---- src/utils/arrayUtils.ts | 10 ++++++++++ 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 999e26b..2bdaa4c 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -3,6 +3,7 @@ import type { BooleanLiteral, ExpressionStatement, Identifier, + IfStatement, NullLiteral, NumericLiteral, ReturnStatement, @@ -10,7 +11,7 @@ import type { VariableDeclaration, VariableDeclarator, } from './ast'; -import type { Tail } from './utils/arrayUtils'; +import type { Concat, Tail, Unshift } from './utils/arrayUtils'; import type { Cast, MergeWithOverride } from './utils/generalUtils'; export type Check> = CheckBlock; @@ -27,19 +28,30 @@ type InferExpression = T extends StringLiteral ? S[Cast] : 'unknown'; -type InferBlock, S = {}> = T extends [] - ? 'void' +type InferBlock< + T extends Array, + S = {}, + R extends Array = [], +> = T extends [] + ? Unshift : T[0] extends ReturnStatement - ? InferExpression + ? Unshift> : T[0] extends VariableDeclaration< [VariableDeclarator, infer I>], any > ? InferBlock< Tail, - MergeWithOverride]: InferExpression }> + MergeWithOverride]: InferExpression }>, + R > - : InferBlock, S>; + : T[0] extends IfStatement> + ? InferBlock>, S> extends infer J + ? Concat>> extends infer G + ? InferBlock, S, Cast>> + : never + : never + : InferBlock, S, R>; type CheckBlock< T extends Array, diff --git a/src/index.ts b/src/index.ts index 096fb1a..b82f3de 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,13 +2,20 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; import type { Check } from './checker'; +// type T = Tokenize<` +// function ran (foo: string, bar: boolean) {} +// `>; +// type R = Parse; + type T = Tokenize<` function foo () { const a = true - const b = a - const c = b - - return c + + if (a) { + return a + } + + return "bar" } `>; type R = Parse[0]['body']; diff --git a/src/utils/arrayUtils.ts b/src/utils/arrayUtils.ts index f9da970..680c3a9 100644 --- a/src/utils/arrayUtils.ts +++ b/src/utils/arrayUtils.ts @@ -1,3 +1,5 @@ +import type { Cast } from './generalUtils'; + export type Tail> = ((...t: T) => void) extends ( h: any, ...rest: infer R @@ -16,3 +18,11 @@ export type Reverse< T extends Array, R extends Array = [], > = T extends [] ? R : Reverse, Unshift>; + +export type Head> = T extends [any, ...Array] + ? T['0'] + : never; + +export type Concat, T2 extends Array> = T2 extends [] + ? T1 + : Concat>, Tail>; From 26d30947dbbe3326383a790ba862b556df995209 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 21:36:11 +0300 Subject: [PATCH 042/286] wip --- foo.js | 23 ----------------------- src/checker.ts | 4 ++-- 2 files changed, 2 insertions(+), 25 deletions(-) delete mode 100644 foo.js diff --git a/foo.js b/foo.js deleted file mode 100644 index 9e8bbdc..0000000 --- a/foo.js +++ /dev/null @@ -1,23 +0,0 @@ -// const result = require('@babel/core').parse('function foo (hello: string) {}', { -// sourceType: 'module', -// plugins: [require.resolve('@babel/plugin-syntax-typescript')], -// // sourceFilename: 'foo.ts', -// // tokens: true, -// }); - -// console.log(result); - -const result = require('@babel/parser').parse('a.b.c', { - sourceType: 'module', - plugins: [ - ['typescript', { disallowAmbiguousJSXLike: undefined }], - 'classProperties', - 'objectRestSpread', - ], - ranges: false, - // sourceFilename: 'foo.ts', - tokens: true, -}); - -// console.log(result.tokens); -console.log(JSON.stringify(result.program.body, null, 2)); diff --git a/src/checker.ts b/src/checker.ts index 2bdaa4c..71d315e 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -57,7 +57,7 @@ type CheckBlock< T extends Array, S = {}, > = T[0] extends ExpressionStatement - ? InferExpression + ? InferExpression : T[0] extends BlockStatement - ? InferBlock>> + ? InferBlock>, S> : []; From 892011030de11cf61d7c1ac98cad5b79100f8267 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 21:41:53 +0300 Subject: [PATCH 043/286] wip --- README.md | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b29d414..fc65ecf 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,30 @@ ### Introduction -This project includes a simplified implementation of TypeScript's type-system that's implemented in TypeScript's own type-system. The implementation includes an EcmaScript tokenizer and parser, along with a limited type-system. +This project includes a simplified implementation of TypeScript's type-system that's implemented in TypeScript's own type-system. + +The implementation includes an EcmaScript tokenizer and parser, along with a limited type-system. Here's an example of using it: + +```typescript +import type Check from '.' + +type R = Check<` + function foo (name: string) { + console.log(name) + } + + foo(5) +`> +``` + +Hovering with the mouse on `R` (when cloned or in TypeScript's playground) will show the next type error: + +``` +Argument of type 'number' is not assignable to parameter of type 'string'. +``` + +Passing in a string instead (like `'hello'`) will resolve the error. + +*☝ Please note that this project is meant to be used for fun and learning purposes and not for practical use.* + +### Supported features and syntax From 0f432d0ea09f4e602223e86f774547e14b36a4d3 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 21:53:45 +0300 Subject: [PATCH 044/286] wip --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fc65ecf..0bb389d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## 🥑 Type-Fusion +## 🐟 Type-Fusion > A (very) simplified implementation of TypeScript's type-system written in TypeScript's own type-system From dcdb1d5dad47b4eb817fca59abbaa72669f04756 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 21:54:06 +0300 Subject: [PATCH 045/286] wip --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0bb389d..3980408 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ### Introduction -This project includes a simplified implementation of TypeScript's type-system that's implemented in TypeScript's own type-system. +This project includes a simplified implementation of TypeScript's type-system that's written in TypeScript's own type-system. The implementation includes an EcmaScript tokenizer and parser, along with a limited type-system. Here's an example of using it: From 9cf73268300cca5c3fc29bdaa1868a3fbf86cafd Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 21:56:44 +0300 Subject: [PATCH 046/286] wip --- README.md | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 3980408..60a8756 100644 --- a/README.md +++ b/README.md @@ -6,28 +6,10 @@ This project includes a simplified implementation of TypeScript's type-system that's written in TypeScript's own type-system. -The implementation includes an EcmaScript tokenizer and parser, along with a limited type-system. Here's an example of using it: - -```typescript -import type Check from '.' - -type R = Check<` - function foo (name: string) { - console.log(name) - } - - foo(5) -`> -``` - -Hovering with the mouse on `R` (when cloned or in TypeScript's playground) will show the next type error: - -``` -Argument of type 'number' is not assignable to parameter of type 'string'. -``` - -Passing in a string instead (like `'hello'`) will resolve the error. +The implementation includes an EcmaScript tokenizer and parser, along with a limited type-system. *☝ Please note that this project is meant to be used for fun and learning purposes and not for practical use.* ### Supported features and syntax + +Some syntax or type checking features aren't supported (yet), here's what currently works: From f42719b53a56d78b994aac4481fd54e6d7144c8a Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 21:57:29 +0300 Subject: [PATCH 047/286] wip --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 60a8756..0901c62 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This project includes a simplified implementation of TypeScript's type-system that's written in TypeScript's own type-system. -The implementation includes an EcmaScript tokenizer and parser, along with a limited type-system. +The implementation includes an EcmaScript tokenizer and parser, along with a limited type-system. I used comments to describe how this is working. *☝ Please note that this project is meant to be used for fun and learning purposes and not for practical use.* From be1623da2c8e8e74b5b0bfeb2c8efceadd48b250 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 22:00:12 +0300 Subject: [PATCH 048/286] wip --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0901c62..e07f9b5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## 🐟 Type-Fusion +## 🪁 Type-Fusion > A (very) simplified implementation of TypeScript's type-system written in TypeScript's own type-system From 1ffbac816c590820f5bd90367a52635805aaad02 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 22:02:02 +0300 Subject: [PATCH 049/286] wip --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index e07f9b5..df3a215 100644 --- a/README.md +++ b/README.md @@ -13,3 +13,11 @@ The implementation includes an EcmaScript tokenizer and parser, along with a lim ### Supported features and syntax Some syntax or type checking features aren't supported (yet), here's what currently works: + +### Additional links + +- [The Super Tiny Compiler](https://github.com/jamiebuilds/the-super-tiny-compiler) +- [TypeScripts Type System is Turing Complete](https://github.com/microsoft/TypeScript/issues/14833) +- [Typing the Technical Interview in TypeScript](https://gal.hagever.com/posts/typing-the-technical-interview-in-typescript/) +- [Functions and algorithms implemented purely with TypeScript's type system](https://github.com/ronami/meta-typing) +- [A SQL database implemented purely in TypeScript type annotations](https://github.com/codemix/ts-sql) From 25b4a4dea25c9c9ed8849f37356da99503cea71a Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 30 Jun 2022 22:06:09 +0300 Subject: [PATCH 050/286] wip --- TODO.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 TODO.md diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..b58a117 --- /dev/null +++ b/TODO.md @@ -0,0 +1,6 @@ +### TODOs + +- Adjut parser/tokenizer to using line-breaks and `;` when parsing expressions +- Fully implement type checks include object/array types that require parser/tokenizer work +- Re-organize tests from a long list into reasonable groups +- Add comments to explain the implementation From 90c21d3f70d13de3710e7bce04824fd626cde935 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 1 Jul 2022 09:22:22 +0300 Subject: [PATCH 051/286] wip --- TODO.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/TODO.md b/TODO.md index b58a117..0d6ef61 100644 --- a/TODO.md +++ b/TODO.md @@ -4,3 +4,16 @@ - Fully implement type checks include object/array types that require parser/tokenizer work - Re-organize tests from a long list into reasonable groups - Add comments to explain the implementation + +Errors: + +- `Expected 1 arguments, but got 0.` +- `Expected 1 arguments, but got 2.` +- `This expression is not callable. Type 'String' has no call signatures.` +- `Argument of type 'number' is not assignable to parameter of type 'string'.` +- `Parameter 'a' implicitly has an 'any' type.` +- `Type 'string' is not assignable to type 'number'.` +- `A function whose declared type is neither 'void' nor 'any' must return a value.` +- `Property 'bar' does not exist on type '"hello"'.` +- `Unreachable code detected.` +- `Cannot find name 'bar'.` From 5db270d7dcab1d1a4cd8ba9d2da6faec19cacf68 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 1 Jul 2022 11:52:02 +0300 Subject: [PATCH 052/286] wip --- src/checker.ts | 19 +++++++++++++++++++ src/index.ts | 13 +++---------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 71d315e..902ead8 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -2,6 +2,7 @@ import type { BlockStatement, BooleanLiteral, ExpressionStatement, + FunctionDeclaration, Identifier, IfStatement, NullLiteral, @@ -45,6 +46,24 @@ type InferBlock< MergeWithOverride]: InferExpression }>, R > + : T[0] extends FunctionDeclaration< + Identifier, + infer P, + BlockStatement + > + ? InferBlock< + Tail, + MergeWithOverride< + S, + { + [a in Cast]: InferBlock< + Cast>, + MergeWithOverride + >; + } + >, + R + > : T[0] extends IfStatement> ? InferBlock>, S> extends infer J ? Concat>> extends infer G diff --git a/src/index.ts b/src/index.ts index b82f3de..14c98c1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,20 +2,13 @@ import type { Tokenize } from './tokenize'; import type { Parse } from './parse'; import type { Check } from './checker'; -// type T = Tokenize<` -// function ran (foo: string, bar: boolean) {} -// `>; -// type R = Parse; - type T = Tokenize<` function foo () { - const a = true - - if (a) { - return a + function bar(a) { + return 1 } - return "bar" + return bar } `>; type R = Parse[0]['body']; From ef30c50d927cdf3731a80e1c92a2c492828e12b1 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 1 Jul 2022 12:21:33 +0300 Subject: [PATCH 053/286] wip --- src/checker.ts | 22 ++++++++++++++++------ src/index.ts | 4 ++-- src/types.ts | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 8 deletions(-) create mode 100644 src/types.ts diff --git a/src/checker.ts b/src/checker.ts index 902ead8..c0cefe2 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -12,29 +12,39 @@ import type { VariableDeclaration, VariableDeclarator, } from './ast'; +import type { + BooleanType, + NullType, + NumberType, + StringType, + UnknownType, + VoidType, +} from './types'; import type { Concat, Tail, Unshift } from './utils/arrayUtils'; import type { Cast, MergeWithOverride } from './utils/generalUtils'; export type Check> = CheckBlock; type InferExpression = T extends StringLiteral - ? 'string' + ? StringType : T extends NumericLiteral - ? 'number' + ? NumberType : T extends NullLiteral - ? 'null' + ? NullType : T extends BooleanLiteral - ? 'boolean' + ? BooleanType : T extends Identifier ? S[Cast] - : 'unknown'; + : UnknownType; + +// type InferFunctionParams = T; type InferBlock< T extends Array, S = {}, R extends Array = [], > = T extends [] - ? Unshift + ? Unshift : T[0] extends ReturnStatement ? Unshift> : T[0] extends VariableDeclaration< diff --git a/src/index.ts b/src/index.ts index 14c98c1..ab79c19 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,8 +4,8 @@ import type { Check } from './checker'; type T = Tokenize<` function foo () { - function bar(a) { - return 1 + function bar(num: string) { + return 5 } return bar diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..3d40b6e --- /dev/null +++ b/src/types.ts @@ -0,0 +1,49 @@ +export type StringType = { + type: 'StringType'; +}; + +export type NumberType = { + type: 'NumberType'; +}; + +export type NullType = { + type: 'NullType'; +}; + +export type BooleanType = { + type: 'BooleanType'; +}; + +export type UnknownType = { + type: 'UnknownType'; +}; + +export type VoidType = { + type: 'VoidType'; +}; + +export type AnyType = { + type: 'AnyType'; +}; + +export type FunctionType = { + type: 'FunctionType'; + params: P; + return: R; +}; + +export type ObjectType = { + type: 'ObjectType'; + key: K; + value: V; +}; + +export type ArrayType = { + type: 'ArrayType'; + value: V; +}; + +export type UnionType = { + type: 'UnionType'; + values: V; +}; From cf75223c5dec668dd7c6a6716a9a22505ed4402a Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 1 Jul 2022 13:58:51 +0300 Subject: [PATCH 054/286] wip --- src/checker.ts | 69 +++++++++++++++++++++++++++++++++++++++----------- src/index.ts | 10 ++++++-- 2 files changed, 62 insertions(+), 17 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index c0cefe2..9764dfb 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -1,26 +1,34 @@ import type { + AnyTypeAnnotation, BlockStatement, BooleanLiteral, + BooleanTypeAnnotation, ExpressionStatement, FunctionDeclaration, Identifier, IfStatement, NullLiteral, + NullLiteralTypeAnnotation, + NumberTypeAnnotation, NumericLiteral, ReturnStatement, StringLiteral, + StringTypeAnnotation, + TypeAnnotation, VariableDeclaration, VariableDeclarator, } from './ast'; import type { + AnyType, BooleanType, + FunctionType, NullType, NumberType, StringType, UnknownType, VoidType, } from './types'; -import type { Concat, Tail, Unshift } from './utils/arrayUtils'; +import type { Concat, Reverse, Tail, Unshift } from './utils/arrayUtils'; import type { Cast, MergeWithOverride } from './utils/generalUtils'; export type Check> = CheckBlock; @@ -37,7 +45,34 @@ type InferExpression = T extends StringLiteral ? S[Cast] : UnknownType; -// type InferFunctionParams = T; +type MapTypeAnnotationToType = A extends StringTypeAnnotation + ? StringType + : A extends NumberTypeAnnotation + ? NumberType + : A extends BooleanTypeAnnotation + ? BooleanType + : A extends NullLiteralTypeAnnotation + ? NullType + : A extends AnyTypeAnnotation + ? AnyType + : never; + +type InferFunctionParams< + T extends Array, + R extends Array = [], + G = {}, +> = T extends [] + ? [Reverse, G] + : T[0] extends Identifier> + ? InferFunctionParams< + Tail, + Unshift>, + MergeWithOverride< + G, + { [a in Cast]: MapTypeAnnotationToType } + > + > + : never; type InferBlock< T extends Array, @@ -61,19 +96,23 @@ type InferBlock< infer P, BlockStatement > - ? InferBlock< - Tail, - MergeWithOverride< - S, - { - [a in Cast]: InferBlock< - Cast>, - MergeWithOverride - >; - } - >, - R - > + ? InferFunctionParams>> extends infer O + ? FunctionType< + Cast>[0], + InferBlock< + Tail, + MergeWithOverride< + S, + { + [a in Cast]: InferBlock< + Cast>, + MergeWithOverride>[1]> + >; + } + > + > + > + : never : T[0] extends IfStatement> ? InferBlock>, S> extends infer J ? Concat>> extends infer G diff --git a/src/index.ts b/src/index.ts index ab79c19..d8b833c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,8 +4,14 @@ import type { Check } from './checker'; type T = Tokenize<` function foo () { - function bar(num: string) { - return 5 + const hey = null + + function bar(num: string, hey: boolean) { + if (a) { + return num + } + + return hey } return bar From 2d16b9302d3a0d315c554ac14d262f9a33922355 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 1 Jul 2022 14:01:52 +0300 Subject: [PATCH 055/286] wip --- src/checker.ts | 25 +++++++++++++------------ src/index.ts | 6 +----- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 9764dfb..d5e62ae 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -97,20 +97,21 @@ type InferBlock< BlockStatement > ? InferFunctionParams>> extends infer O - ? FunctionType< - Cast>[0], - InferBlock< - Tail, - MergeWithOverride< - S, - { - [a in Cast]: InferBlock< + ? InferBlock< + Tail, + MergeWithOverride< + S, + { + [a in Cast]: FunctionType< + Cast>[0], + InferBlock< Cast>, MergeWithOverride>[1]> - >; - } - > - > + > + >; + } + >, + R > : never : T[0] extends IfStatement> diff --git a/src/index.ts b/src/index.ts index d8b833c..c4f4f4c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,11 +6,7 @@ type T = Tokenize<` function foo () { const hey = null - function bar(num: string, hey: boolean) { - if (a) { - return num - } - + function bar(num: string) { return hey } From 40979d1cd968b778ee0cde81c4b4b53cf7640d56 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 1 Jul 2022 14:34:03 +0300 Subject: [PATCH 056/286] wip --- src/checker.ts | 11 +++++++++++ src/index.ts | 8 +------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index d5e62ae..356bed5 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -1,5 +1,6 @@ import type { AnyTypeAnnotation, + ArrayExpression, BlockStatement, BooleanLiteral, BooleanTypeAnnotation, @@ -20,6 +21,7 @@ import type { } from './ast'; import type { AnyType, + ArrayType, BooleanType, FunctionType, NullType, @@ -33,6 +35,13 @@ import type { Cast, MergeWithOverride } from './utils/generalUtils'; export type Check> = CheckBlock; +type InferArrayElements< + T extends Array, + R extends Array = [], +> = T extends [] + ? R + : InferArrayElements, Unshift>>; + type InferExpression = T extends StringLiteral ? StringType : T extends NumericLiteral @@ -43,6 +52,8 @@ type InferExpression = T extends StringLiteral ? BooleanType : T extends Identifier ? S[Cast] + : T extends ArrayExpression + ? ArrayType>>> : UnknownType; type MapTypeAnnotationToType = A extends StringTypeAnnotation diff --git a/src/index.ts b/src/index.ts index c4f4f4c..2f84f60 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,13 +4,7 @@ import type { Check } from './checker'; type T = Tokenize<` function foo () { - const hey = null - - function bar(num: string) { - return hey - } - - return bar + return [1, 2, 3] } `>; type R = Parse[0]['body']; From 534a5b2bcd1bd87090060eaf8711f9643a1e64df Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 1 Jul 2022 14:35:29 +0300 Subject: [PATCH 057/286] wip --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index df3a215..9e48686 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## 🪁 Type-Fusion +## 🪁 Extremely-Typed > A (very) simplified implementation of TypeScript's type-system written in TypeScript's own type-system From 684f6b10d0e6866bec9254df6a52028c6fa4454c Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 1 Jul 2022 14:36:36 +0300 Subject: [PATCH 058/286] wip --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9e48686..0e3859f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## 🪁 Extremely-Typed +## 🐬 Extremely-Typed > A (very) simplified implementation of TypeScript's type-system written in TypeScript's own type-system From 19c972886acd202aa536689a9bb10898234c2e3b Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 1 Jul 2022 14:37:15 +0300 Subject: [PATCH 059/286] wip --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0e3859f..2d8b3ad 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## 🐬 Extremely-Typed -> A (very) simplified implementation of TypeScript's type-system written in TypeScript's own type-system +> A simplified implementation of TypeScript's type-system written in TypeScript's own type-system ### Introduction From 1383fd5c6a5aa25ff387fc5bf67442007af2f324 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 1 Jul 2022 14:37:24 +0300 Subject: [PATCH 060/286] wip --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2d8b3ad..def0e70 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ### Introduction -This project includes a simplified implementation of TypeScript's type-system that's written in TypeScript's own type-system. +This project includes a (very) simplified implementation of TypeScript's type-system that's written in TypeScript's own type-system. The implementation includes an EcmaScript tokenizer and parser, along with a limited type-system. I used comments to describe how this is working. From 0abf9cb76bae692c548435776954752638033cce Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 1 Jul 2022 14:43:57 +0300 Subject: [PATCH 061/286] wip --- README.md | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index def0e70..0e1a9d5 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,34 @@ This project includes a (very) simplified implementation of TypeScript's type-system that's written in TypeScript's own type-system. -The implementation includes an EcmaScript tokenizer and parser, along with a limited type-system. I used comments to describe how this is working. +The implementation includes a tokenizer and parser, along with a simple type-system. That code itself is full with comments explaining what's going on. *☝ Please note that this project is meant to be used for fun and learning purposes and not for practical use.* +### Try running the code + +See it live on your browser on the [TypeScript Playground](). + +Alternatively, clone the repository with the following: + +``` +git clone +``` + +Install dependencies with `Yarn` or `npm`: + +``` +yarn install +``` + +Open any file and hover over the types to see the results of "running" that them with some input (try hovering the resulting type). + +You can also run tests (written with [tsd]()) with: + +``` +yarn test +``` + ### Supported features and syntax Some syntax or type checking features aren't supported (yet), here's what currently works: From fcf668bccf455b1826181526e8bef31defb16558 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 1 Jul 2022 15:25:36 +0300 Subject: [PATCH 062/286] wip --- src/checker.ts | 7 +++++++ src/index.ts | 6 +++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/checker.ts b/src/checker.ts index 356bed5..6325b43 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -4,6 +4,7 @@ import type { BlockStatement, BooleanLiteral, BooleanTypeAnnotation, + CallExpression, ExpressionStatement, FunctionDeclaration, Identifier, @@ -54,6 +55,12 @@ type InferExpression = T extends StringLiteral ? S[Cast] : T extends ArrayExpression ? ArrayType>>> + : T extends CallExpression, infer A> + ? S[Cast] extends FunctionType + ? InferArrayElements>> extends P + ? R + : never + : never : UnknownType; type MapTypeAnnotationToType = A extends StringTypeAnnotation diff --git a/src/index.ts b/src/index.ts index 2f84f60..1278802 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,7 +4,11 @@ import type { Check } from './checker'; type T = Tokenize<` function foo () { - return [1, 2, 3] + function bar (a: number, b: string) { + return true + } + + return bar(1, "hello") } `>; type R = Parse[0]['body']; From 27e67f8aa1bcf9d73495fabf2b5edb38ddb6289c Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 1 Jul 2022 15:25:38 +0300 Subject: [PATCH 063/286] wip --- src/checker.ts | 9 ++++++++- src/index.ts | 4 +++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 6325b43..cffb0ea 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -43,6 +43,13 @@ type InferArrayElements< ? R : InferArrayElements, Unshift>>; +type InferCallArguments< + T extends Array, + R extends Array = [], +> = T extends [] + ? Reverse + : InferCallArguments, Unshift>>; + type InferExpression = T extends StringLiteral ? StringType : T extends NumericLiteral @@ -57,7 +64,7 @@ type InferExpression = T extends StringLiteral ? ArrayType>>> : T extends CallExpression, infer A> ? S[Cast] extends FunctionType - ? InferArrayElements>> extends P + ? InferCallArguments>> extends P ? R : never : never diff --git a/src/index.ts b/src/index.ts index 1278802..873006e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,7 +8,9 @@ function foo () { return true } - return bar(1, "hello") + const a = bar(1, "hello") + + return a } `>; type R = Parse[0]['body']; From ecb3dc26863240b90df1b4f91dd0659b83bf6219 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 1 Jul 2022 16:00:45 +0300 Subject: [PATCH 064/286] wip --- TODO.md | 1 - src/checker.ts | 16 +++++++++------- src/index.ts | 10 +++++----- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/TODO.md b/TODO.md index 0d6ef61..e885889 100644 --- a/TODO.md +++ b/TODO.md @@ -8,7 +8,6 @@ Errors: - `Expected 1 arguments, but got 0.` -- `Expected 1 arguments, but got 2.` - `This expression is not callable. Type 'String' has no call signatures.` - `Argument of type 'number' is not assignable to parameter of type 'string'.` - `Parameter 'a' implicitly has an 'any' type.` diff --git a/src/checker.ts b/src/checker.ts index cffb0ea..6070dd6 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -38,19 +38,21 @@ export type Check> = CheckBlock; type InferArrayElements< T extends Array, + S extends {}, R extends Array = [], > = T extends [] ? R - : InferArrayElements, Unshift>>; + : InferArrayElements, S, Unshift>>; type InferCallArguments< T extends Array, + S extends {}, R extends Array = [], > = T extends [] ? Reverse - : InferCallArguments, Unshift>>; + : InferCallArguments, S, Unshift>>; -type InferExpression = T extends StringLiteral +type InferExpression = T extends StringLiteral ? StringType : T extends NumericLiteral ? NumberType @@ -61,10 +63,10 @@ type InferExpression = T extends StringLiteral : T extends Identifier ? S[Cast] : T extends ArrayExpression - ? ArrayType>>> + ? ArrayType>, S>> : T extends CallExpression, infer A> ? S[Cast] extends FunctionType - ? InferCallArguments>> extends P + ? InferCallArguments>, S> extends P ? R : never : never @@ -101,7 +103,7 @@ type InferFunctionParams< type InferBlock< T extends Array, - S = {}, + S extends {}, R extends Array = [], > = T extends [] ? Unshift @@ -149,7 +151,7 @@ type InferBlock< type CheckBlock< T extends Array, - S = {}, + S extends {} = {}, > = T[0] extends ExpressionStatement ? InferExpression : T[0] extends BlockStatement diff --git a/src/index.ts b/src/index.ts index 873006e..afbce9c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,14 +4,14 @@ import type { Check } from './checker'; type T = Tokenize<` function foo () { - function bar (a: number, b: string) { + const c = 5 + + function bar (a: number) { return true } - const a = bar(1, "hello") - - return a + return bar(c) } `>; type R = Parse[0]['body']; -type C = Check<[R]>; +type C = Check<[R]>[0]; From ef3087809cdd70bc3bdc3ba2f47cf692c261f140 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 1 Jul 2022 16:25:52 +0300 Subject: [PATCH 065/286] wip --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index afbce9c..e1776ef 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,4 +14,4 @@ function foo () { } `>; type R = Parse[0]['body']; -type C = Check<[R]>[0]; +type C = Check<[R]>; From 91b119527c19249a88bb89132358520814de82a0 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 1 Jul 2022 16:32:46 +0300 Subject: [PATCH 066/286] wip --- src/checker.ts | 6 +++++- src/index.ts | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 6070dd6..a6fc145 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -108,7 +108,11 @@ type InferBlock< > = T extends [] ? Unshift : T[0] extends ReturnStatement - ? Unshift> + ? InferExpression extends infer G + ? G extends Array + ? Concat>> + : Unshift + : never : T[0] extends VariableDeclaration< [VariableDeclarator, infer I>], any diff --git a/src/index.ts b/src/index.ts index e1776ef..ea78f65 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,11 +6,11 @@ type T = Tokenize<` function foo () { const c = 5 - function bar (a: number) { - return true + function foo () { + return c } - return bar(c) + return foo() } `>; type R = Parse[0]['body']; From e614869f6def50d10252c264bb5aa905d929db35 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 1 Jul 2022 16:53:50 +0300 Subject: [PATCH 067/286] wip --- src/index.ts | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/index.ts b/src/index.ts index ea78f65..439ee1a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,13 +4,25 @@ import type { Check } from './checker'; type T = Tokenize<` function foo () { - const c = 5 + function hey() { + if (a) { + return 1 + } - function foo () { - return c + if (a) { + return true + } } - return foo() + function ho() { + if (a) { + return null + } + + return hey() + } + + return ho() } `>; type R = Parse[0]['body']; From b825f9772401600135c7e0a5b9055d916b755bdb Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 1 Jul 2022 17:21:48 +0300 Subject: [PATCH 068/286] wip --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0e1a9d5..1489ba6 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This project includes a (very) simplified implementation of TypeScript's type-system that's written in TypeScript's own type-system. -The implementation includes a tokenizer and parser, along with a simple type-system. That code itself is full with comments explaining what's going on. +The implementation includes a tokenizer and parser, along with the type-system. That code contains comments explaining in detail what's how everything works. *☝ Please note that this project is meant to be used for fun and learning purposes and not for practical use.* From d0b9c7945de3554eb7910502d501ad181bee112f Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 1 Jul 2022 17:22:10 +0300 Subject: [PATCH 069/286] wip --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1489ba6..aac9e36 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This project includes a (very) simplified implementation of TypeScript's type-system that's written in TypeScript's own type-system. -The implementation includes a tokenizer and parser, along with the type-system. That code contains comments explaining in detail what's how everything works. +The implementation include a tokenizer and parser, along with the type-system. That code contains comments explaining in detail what's how everything works. *☝ Please note that this project is meant to be used for fun and learning purposes and not for practical use.* From 5f2b9f35822b03a88e2daaa08fbdc4331802f538 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 1 Jul 2022 17:22:35 +0300 Subject: [PATCH 070/286] wip --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aac9e36..c297499 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This project includes a (very) simplified implementation of TypeScript's type-system that's written in TypeScript's own type-system. -The implementation include a tokenizer and parser, along with the type-system. That code contains comments explaining in detail what's how everything works. +The implementation include a tokenizer and parser, along with the type-system. That code contains comments explaining in detail how everything works. *☝ Please note that this project is meant to be used for fun and learning purposes and not for practical use.* From 40c5b171b3396f72a29afc1325401a6e88c9083c Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 1 Jul 2022 17:25:30 +0300 Subject: [PATCH 071/286] wip --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c297499..ae3ad07 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This project includes a (very) simplified implementation of TypeScript's type-system that's written in TypeScript's own type-system. -The implementation include a tokenizer and parser, along with the type-system. That code contains comments explaining in detail how everything works. +The implementation include a tokenizer and parser, along with the type-system. The code contains comments explaining in detail what's how everything works. *☝ Please note that this project is meant to be used for fun and learning purposes and not for practical use.* From 17f2ba19538eef0b2fb5d2f407a41c3104ada75d Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 1 Jul 2022 17:38:27 +0300 Subject: [PATCH 072/286] wip --- src/checker.ts | 15 +++++++++++++++ src/index.ts | 20 +------------------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index a6fc145..58d38ba 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -13,6 +13,8 @@ import type { NullLiteralTypeAnnotation, NumberTypeAnnotation, NumericLiteral, + ObjectExpression, + ObjectProperty, ReturnStatement, StringLiteral, StringTypeAnnotation, @@ -27,6 +29,7 @@ import type { FunctionType, NullType, NumberType, + ObjectType, StringType, UnknownType, VoidType, @@ -44,6 +47,16 @@ type InferArrayElements< ? R : InferArrayElements, S, Unshift>>; +type InferObjectValues< + T extends Array, + S extends {}, + R extends Array = [], +> = T extends [] + ? R + : T[0] extends ObjectProperty + ? InferObjectValues, S, Unshift>> + : never; + type InferCallArguments< T extends Array, S extends {}, @@ -64,6 +77,8 @@ type InferExpression = T extends StringLiteral ? S[Cast] : T extends ArrayExpression ? ArrayType>, S>> + : T extends ObjectExpression + ? ObjectType>, S>> : T extends CallExpression, infer A> ? S[Cast] extends FunctionType ? InferCallArguments>, S> extends P diff --git a/src/index.ts b/src/index.ts index 439ee1a..e46cb49 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,25 +4,7 @@ import type { Check } from './checker'; type T = Tokenize<` function foo () { - function hey() { - if (a) { - return 1 - } - - if (a) { - return true - } - } - - function ho() { - if (a) { - return null - } - - return hey() - } - - return ho() + return { hello: "world", foo: 5 } } `>; type R = Parse[0]['body']; From 59f56afe10e0c6ccc5d656ffc005ad066104b110 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 1 Jul 2022 17:39:06 +0300 Subject: [PATCH 073/286] wip --- src/checker.ts | 12 ++++++++---- src/index.ts | 2 +- src/types.ts | 5 ++--- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 58d38ba..3c8d4fd 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -50,11 +50,15 @@ type InferArrayElements< type InferObjectValues< T extends Array, S extends {}, - R extends Array = [], + R extends {} = {}, > = T extends [] ? R - : T[0] extends ObjectProperty - ? InferObjectValues, S, Unshift>> + : T[0] extends ObjectProperty, infer K> + ? InferObjectValues< + Tail, + S, + MergeWithOverride]: InferExpression }> + > : never; type InferCallArguments< @@ -78,7 +82,7 @@ type InferExpression = T extends StringLiteral : T extends ArrayExpression ? ArrayType>, S>> : T extends ObjectExpression - ? ObjectType>, S>> + ? ObjectType>, S>> : T extends CallExpression, infer A> ? S[Cast] extends FunctionType ? InferCallArguments>, S> extends P diff --git a/src/index.ts b/src/index.ts index e46cb49..cb3c4f7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,7 +4,7 @@ import type { Check } from './checker'; type T = Tokenize<` function foo () { - return { hello: "world", foo: 5 } + return { hello: { hi: "world" }, foo: 5 } } `>; type R = Parse[0]['body']; diff --git a/src/types.ts b/src/types.ts index 3d40b6e..f8530bc 100644 --- a/src/types.ts +++ b/src/types.ts @@ -32,10 +32,9 @@ export type FunctionType = { return: R; }; -export type ObjectType = { +export type ObjectType = { type: 'ObjectType'; - key: K; - value: V; + keys: O; }; export type ArrayType = { From b69fcf8b02dd56958d3afc5e6f516bd7f7b0da9b Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 1 Jul 2022 17:49:35 +0300 Subject: [PATCH 074/286] wip --- src/checker.ts | 9 +++++++++ src/index.ts | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/checker.ts b/src/checker.ts index 3c8d4fd..db77b78 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -9,6 +9,7 @@ import type { FunctionDeclaration, Identifier, IfStatement, + MemberExpression, NullLiteral, NullLiteralTypeAnnotation, NumberTypeAnnotation, @@ -89,6 +90,14 @@ type InferExpression = T extends StringLiteral ? R : never : never + : T extends MemberExpression> + ? InferExpression extends infer D + ? D extends ObjectType + ? P extends keyof Y + ? Y[P] + : never + : never + : never : UnknownType; type MapTypeAnnotationToType = A extends StringTypeAnnotation diff --git a/src/index.ts b/src/index.ts index cb3c4f7..0dfb4d7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,7 +4,10 @@ import type { Check } from './checker'; type T = Tokenize<` function foo () { - return { hello: { hi: "world" }, foo: 5 } + const b = { hey: 2 } + const a = { hello: { hi: b}, foo: 5 } + + return a.hello.hi.hey } `>; type R = Parse[0]['body']; From ae679e2da9e567f95e28b09c6bca16bb0a36a9d8 Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 2 Jul 2022 10:01:14 +0300 Subject: [PATCH 075/286] wip --- src/checker.ts | 18 ++++++++++++++---- src/index.ts | 5 +---- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index db77b78..478ecbe 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -84,10 +84,12 @@ type InferExpression = T extends StringLiteral ? ArrayType>, S>> : T extends ObjectExpression ? ObjectType>, S>> - : T extends CallExpression, infer A> - ? S[Cast] extends FunctionType - ? InferCallArguments>, S> extends P - ? R + : T extends CallExpression + ? InferExpression extends infer I + ? I extends FunctionType + ? InferCallArguments>, S> extends P + ? R + : never : never : never : T extends MemberExpression> @@ -96,6 +98,14 @@ type InferExpression = T extends StringLiteral ? P extends keyof Y ? Y[P] : never + : D extends StringType + ? P extends 'length' + ? NumberType + : never + : D extends NumberType + ? P extends 'toString' + ? FunctionType<[], StringType> + : never : never : never : UnknownType; diff --git a/src/index.ts b/src/index.ts index 0dfb4d7..b0098dd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,10 +4,7 @@ import type { Check } from './checker'; type T = Tokenize<` function foo () { - const b = { hey: 2 } - const a = { hello: { hi: b}, foo: 5 } - - return a.hello.hi.hey + return 3.toString().length.toString().length.toString().length } `>; type R = Parse[0]['body']; From 2eb7d9e88334420243c84e612e9406a8936a827f Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 2 Jul 2022 10:02:41 +0300 Subject: [PATCH 076/286] wip --- src/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index b0098dd..d4be909 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,7 +4,8 @@ import type { Check } from './checker'; type T = Tokenize<` function foo () { - return 3.toString().length.toString().length.toString().length + const a = "".length + return a.toString() } `>; type R = Parse[0]['body']; From 43922f30452da4c5772fb306f15d7d8222171e42 Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 2 Jul 2022 10:26:18 +0300 Subject: [PATCH 077/286] wip --- src/checker.ts | 32 ++++++++++++++++++++++++++++++-- src/index.ts | 15 +++++++++++++-- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 478ecbe..72ad163 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -70,6 +70,29 @@ type InferCallArguments< ? Reverse : InferCallArguments, S, Unshift>>; +type AssignableUnionType> = B extends [] + ? true + : AssignableTypes extends false + ? false + : AssignableUnionType>; + +type AssignableTypes = A extends AnyType + ? true + : B extends A + ? true + : B extends Array + ? AssignableUnionType + : false; + +type AssignableArgumentTypes< + I extends Array, + P extends Array, +> = I extends [] + ? true + : AssignableTypes extends false + ? false + : AssignableArgumentTypes, Tail

>; + type InferExpression = T extends StringLiteral ? StringType : T extends NumericLiteral @@ -87,8 +110,13 @@ type InferExpression = T extends StringLiteral : T extends CallExpression ? InferExpression extends infer I ? I extends FunctionType - ? InferCallArguments>, S> extends P - ? R + ? InferCallArguments>, S> extends infer O + ? AssignableArgumentTypes< + Cast>, + Cast> + > extends true + ? R + : never : never : never : never diff --git a/src/index.ts b/src/index.ts index d4be909..847287d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,8 +4,19 @@ import type { Check } from './checker'; type T = Tokenize<` function foo () { - const a = "".length - return a.toString() + function bar(a: string) { + return 1 + } + + function bazz() { + if (b) { + return true + } + + return 1 + } + + return bar(bazz()) } `>; type R = Parse[0]['body']; From 7c32903423cc880012b7a69649b1fdd9fc182b69 Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 2 Jul 2022 10:27:12 +0300 Subject: [PATCH 078/286] wip --- src/checker.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 72ad163..aee0876 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -70,18 +70,10 @@ type InferCallArguments< ? Reverse : InferCallArguments, S, Unshift>>; -type AssignableUnionType> = B extends [] - ? true - : AssignableTypes extends false - ? false - : AssignableUnionType>; - type AssignableTypes = A extends AnyType ? true : B extends A ? true - : B extends Array - ? AssignableUnionType : false; type AssignableArgumentTypes< From d42ae692e2ca49c4a7747efff395bb7cc1022607 Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 2 Jul 2022 11:04:05 +0300 Subject: [PATCH 079/286] wip --- src/checker.ts | 14 ++++++++++---- src/index.ts | 12 ++---------- src/types.ts | 5 +++++ 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index aee0876..5cbc2cb 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -7,6 +7,7 @@ import type { CallExpression, ExpressionStatement, FunctionDeclaration, + GenericTypeAnnotation, Identifier, IfStatement, MemberExpression, @@ -28,6 +29,7 @@ import type { ArrayType, BooleanType, FunctionType, + GenericType, NullType, NumberType, ObjectType, @@ -94,15 +96,17 @@ type InferExpression = T extends StringLiteral : T extends BooleanLiteral ? BooleanType : T extends Identifier - ? S[Cast] + ? N extends keyof S + ? S[N] + : never : T extends ArrayExpression ? ArrayType>, S>> : T extends ObjectExpression ? ObjectType>, S>> : T extends CallExpression - ? InferExpression extends infer I - ? I extends FunctionType - ? InferCallArguments>, S> extends infer O + ? InferCallArguments>, S> extends infer O + ? InferExpression extends infer I + ? I extends FunctionType ? AssignableArgumentTypes< Cast>, Cast> @@ -140,6 +144,8 @@ type MapTypeAnnotationToType = A extends StringTypeAnnotation ? NullType : A extends AnyTypeAnnotation ? AnyType + : A extends GenericTypeAnnotation + ? GenericType : never; type InferFunctionParams< diff --git a/src/index.ts b/src/index.ts index 847287d..9968d90 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,19 +4,11 @@ import type { Check } from './checker'; type T = Tokenize<` function foo () { - function bar(a: string) { + function bar(a: number) { return 1 } - function bazz() { - if (b) { - return true - } - - return 1 - } - - return bar(bazz()) + return bar(2) } `>; type R = Parse[0]['body']; diff --git a/src/types.ts b/src/types.ts index f8530bc..9c478d8 100644 --- a/src/types.ts +++ b/src/types.ts @@ -46,3 +46,8 @@ export type UnionType = { type: 'UnionType'; values: V; }; + +export type GenericType = { + type: 'GenericType'; + id: T; +}; From 055e8a48f7b61df75722802b06bdcdbb14be4e4c Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 2 Jul 2022 17:42:01 +0300 Subject: [PATCH 080/286] wip --- src/checker.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/checker.ts b/src/checker.ts index 5cbc2cb..37a8691 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -82,7 +82,9 @@ type AssignableArgumentTypes< I extends Array, P extends Array, > = I extends [] - ? true + ? P extends [] + ? true + : false : AssignableTypes extends false ? false : AssignableArgumentTypes, Tail

>; From 0867259e73298c8f3a54ddb735840dd1834b2807 Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 2 Jul 2022 17:48:17 +0300 Subject: [PATCH 081/286] wip --- src/index.ts | 8 ++++---- src/{parse.ts => parser.ts} | 0 src/test/parser.test.ts | 4 ++-- src/{tokenize.ts => tokenizer.ts} | 0 4 files changed, 6 insertions(+), 6 deletions(-) rename src/{parse.ts => parser.ts} (100%) rename src/{tokenize.ts => tokenizer.ts} (100%) diff --git a/src/index.ts b/src/index.ts index 9968d90..e2f038f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,14 +1,14 @@ -import type { Tokenize } from './tokenize'; -import type { Parse } from './parse'; +import type { Tokenize } from './tokenizer'; +import type { Parse } from './parser'; import type { Check } from './checker'; type T = Tokenize<` function foo () { - function bar(a: number) { + function bar(s: string, b: boolean) { return 1 } - return bar(2) + return bar("", true) } `>; type R = Parse[0]['body']; diff --git a/src/parse.ts b/src/parser.ts similarity index 100% rename from src/parse.ts rename to src/parser.ts diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index 294c40c..cf4fcc6 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -1,5 +1,5 @@ -import type { Tokenize } from '../tokenize'; -import type { Parse } from '../parse'; +import type { Tokenize } from '../tokenizer'; +import type { Parse } from '../parser'; import type { Cast } from '../utils/generalUtils'; const expectType = (value: T) => {}; diff --git a/src/tokenize.ts b/src/tokenizer.ts similarity index 100% rename from src/tokenize.ts rename to src/tokenizer.ts From e9b92d059e0d3c1fc67a0b31c49ac1708e59d670 Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 2 Jul 2022 18:04:10 +0300 Subject: [PATCH 082/286] wip --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ae3ad07..5cf6811 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This project includes a (very) simplified implementation of TypeScript's type-system that's written in TypeScript's own type-system. -The implementation include a tokenizer and parser, along with the type-system. The code contains comments explaining in detail what's how everything works. +The implementation include a tokenizer and parser, along with the type-system. The code contains comments explaining in detail how everything works. *☝ Please note that this project is meant to be used for fun and learning purposes and not for practical use.* From 9fa6cdef7f24cf1207c62131533ea87720e6f5b8 Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 2 Jul 2022 20:09:47 +0300 Subject: [PATCH 083/286] wip --- TODO.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/TODO.md b/TODO.md index e885889..b23269c 100644 --- a/TODO.md +++ b/TODO.md @@ -16,3 +16,7 @@ Errors: - `Property 'bar' does not exist on type '"hello"'.` - `Unreachable code detected.` - `Cannot find name 'bar'.` + +Bugs: + +- Don't return `void` type for empty `if` statements From 60a366d60aed989b5696728b8300a110069844b4 Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 4 Jul 2022 00:51:19 +0300 Subject: [PATCH 084/286] wip --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5cf6811..da9a4de 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Alternatively, clone the repository with the following: git clone ``` -Install dependencies with `Yarn` or `npm`: +Install dependencies with `yarn` or `npm`: ``` yarn install From c9bfd0fbe7c05b101e50ed57c2c7063f4c25ff92 Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 4 Jul 2022 20:40:24 +0300 Subject: [PATCH 085/286] wip --- LICENSE | 21 +++++++++++++++++++ README.md | 57 +++++++++++++++++++++++++++++++++++++--------------- package.json | 7 +------ 3 files changed, 63 insertions(+), 22 deletions(-) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f5c18e3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Ronen Amiel + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index da9a4de..d558612 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,33 @@ -## 🐬 Extremely-Typed +## 🐬 HypeScript > A simplified implementation of TypeScript's type-system written in TypeScript's own type-system ### Introduction -This project includes a (very) simplified implementation of TypeScript's type-system that's written in TypeScript's own type-system. +This project includes a (very) simplified implementation of [TypeScript](https://github.com/microsoft/TypeScript)'s type-system that's written in [TypeScript](https://github.com/microsoft/TypeScript)'s own type-system. -The implementation include a tokenizer and parser, along with the type-system. The code contains comments explaining in detail how everything works. +The implementation uses types only — with no runtime code whatsoever, and to see it in action you'll need to hover your mouse over the resulting type. + +You enter TypeScript code as string and get possible type errors back: + +```typescript +import type { TypeCheck } from 'hypescript'; + +type Errors = TypeCheck<` + +function foo(name: string) { + return name +} + +const result = foo() + +`>; + +// Errors is now equal to the following type: +type Expected = ["Expected 1 arguments, but got 0."]; +``` + +The project contains a tokenizer, parser and type-checker and includes comments explaining how everything works. *☝ Please note that this project is meant to be used for fun and learning purposes and not for practical use.* @@ -14,29 +35,33 @@ The implementation include a tokenizer and parser, along with the type-system. T See it live on your browser on the [TypeScript Playground](). -Alternatively, clone the repository with the following: +Alternatively, install `hypescript` in your own project with `yarn` or `npm` ([TypeScript](https://github.com/microsoft/TypeScript) 4.1 or later is required): ``` -git clone +yarn add hypescript ``` -Install dependencies with `yarn` or `npm`: +### Supported features and syntax -``` -yarn install -``` +Some syntax or type checking features aren't supported (yet), here are some example for what currently works (see demo link for each). -Open any file and hover over the types to see the results of "running" that them with some input (try hovering the resulting type). +#### Calling a function with missing arguments -You can also run tests (written with [tsd]()) with: +The following would result in the `Errors` type showing the following error: `Expected 1 arguments, but got 0.` -``` -yarn test -``` +```typescript +import type { TypeCheck } from 'hypescript'; -### Supported features and syntax +type Errors = TypeCheck<` + +function foo(name: string) { + return name +} -Some syntax or type checking features aren't supported (yet), here's what currently works: +const result = foo() + +`>; +``` ### Additional links diff --git a/package.json b/package.json index 321b062..c1a2274 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,5 @@ { - "name": "type-sys", - "private": true, + "name": "hypescript", "version": "0.0.0", "license": "MIT", "author": "Ronen Amiel", @@ -29,9 +28,5 @@ "semi": true, "singleQuote": true, "trailingComma": "all" - }, - "dependencies": { - "@babel/parser": "^7.18.5", - "@babel/plugin-transform-typescript": "^7.18.4" } } From 683741f816f5a7e7e4882da0879f744e74f7923e Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 3 Jul 2022 19:14:33 +0300 Subject: [PATCH 086/286] wip --- src/errors.ts | 6 + src/index.ts | 18 +- src/test/parser.test.ts | 1520 ++++++++++++++++++++------------------- src/tokenizer.ts | 31 +- 4 files changed, 796 insertions(+), 779 deletions(-) create mode 100644 src/errors.ts diff --git a/src/errors.ts b/src/errors.ts new file mode 100644 index 0000000..67adda2 --- /dev/null +++ b/src/errors.ts @@ -0,0 +1,6 @@ +export type Error = { + type: T; + message: M; +}; + +export type SyntaxError = Error<'SyntaxError', T>; diff --git a/src/index.ts b/src/index.ts index e2f038f..3e378a3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,15 +1,7 @@ import type { Tokenize } from './tokenizer'; -import type { Parse } from './parser'; -import type { Check } from './checker'; +// import type { Parse } from './parser'; +// import type { Check } from './checker'; -type T = Tokenize<` -function foo () { - function bar(s: string, b: boolean) { - return 1 - } - - return bar("", true) -} -`>; -type R = Parse[0]['body']; -type C = Check<[R]>; +type T = Tokenize<`hello`>; +// type R = Parse[0]['body']; +// type C = Check<[R]>; diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index cf4fcc6..a1945cc 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -1,759 +1,761 @@ -import type { Tokenize } from '../tokenizer'; -import type { Parse } from '../parser'; -import type { Cast } from '../utils/generalUtils'; - -const expectType = (value: T) => {}; - -type ParseAst = Tokenize extends infer G - ? Parse>> - : never; - -expectType>([ - { - type: 'ExpressionStatement', - expression: { type: 'Identifier', name: 'hello' }, - }, -]); - -expectType>([ - { - type: 'ExpressionStatement', - expression: { - type: 'MemberExpression', - object: { type: 'Identifier', name: 'hello' }, - property: { type: 'Identifier', name: 'world' }, - }, - }, -]); - -expectType>([ - { - type: 'ExpressionStatement', - expression: { - type: 'MemberExpression', - object: { type: 'StringLiteral', value: 'hello' }, - property: { type: 'Identifier', name: 'world' }, - }, - }, -]); - -expectType>([ - { - type: 'ExpressionStatement', - expression: { - type: 'MemberExpression', - object: { type: 'NullLiteral' }, - property: { type: 'Identifier', name: 'world' }, - }, - }, -]); - -expectType>([ - { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { type: 'StringLiteral', value: 'hello' }, - arguments: [], - }, - }, -]); - -expectType>([ - { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'hello', - }, - arguments: [], - }, - }, -]); - -expectType>([ - { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'hello', - }, - arguments: [], - }, - arguments: [], - }, - }, -]); - -expectType>([ - { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: { - type: 'CallExpression', - callee: { type: 'Identifier', name: 'hello' }, - arguments: [], - }, - property: { - type: 'Identifier', - name: 'world', - }, - }, - arguments: [], - }, - }, -]); - -expectType>([ - { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'hello', - }, - arguments: [ - { - type: 'CallExpression', - callee: { type: 'Identifier', name: 'world' }, - arguments: [ - { - type: 'NumericLiteral', - value: '1', - }, - ], - }, - ], - }, - }, -]); - -expectType>([ - { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'hello', - }, - arguments: [ - { - type: 'CallExpression', - callee: { type: 'StringLiteral', value: 'world' }, - arguments: [ - { - type: 'NumericLiteral', - value: '1', - }, - ], - }, - ], - }, - }, -]); - -expectType>([ - { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'hello', - }, - arguments: [ - { type: 'NumericLiteral', value: '1' }, - { type: 'BooleanLiteral', value: true }, - ], - }, - }, -]); - -expectType>([ - { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: { - type: 'Identifier', - name: 'hello', - }, - property: { - type: 'Identifier', - name: 'world', - }, - }, - arguments: [ - { type: 'NumericLiteral', value: '1' }, - { type: 'BooleanLiteral', value: true }, - ], - }, - }, -]); - -expectType>([ - { - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'foo', - }, - params: [], - body: { - type: 'BlockStatement', - body: [], - }, - }, -]); - -expectType>([ - { - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'foo', - }, - params: [ - { type: 'Identifier', name: 'first' }, - { type: 'Identifier', name: 'last' }, - ], - body: { - type: 'BlockStatement', - body: [], - }, - }, -]); - -expectType>([ - { - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'foo', - }, - params: [], - body: { - type: 'BlockStatement', - body: [ - { - type: 'ReturnStatement', - argument: { - type: 'NumericLiteral', - value: '5', - }, - }, - ], - }, - }, -]); - -expectType>([ - { - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'foo', - }, - params: [], - body: { - type: 'BlockStatement', - body: [ - { - type: 'ReturnStatement', - argument: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'bar', - }, - arguments: [], - }, - }, - ], - }, - }, -]); - -expectType>([ - { - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'foo', - }, - params: [ - { type: 'Identifier', name: 'first' }, - { type: 'Identifier', name: 'last' }, - ], - body: { - type: 'BlockStatement', - body: [ - { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: { type: 'Identifier', name: 'console' }, - property: { type: 'Identifier', name: 'log' }, - }, - arguments: [ - { - type: 'NumericLiteral', - value: '1', - }, - ], - }, - }, - ], - }, - }, -]); - -expectType< - ParseAst<` -function foo(foo) { - console.log(foo) - - function bar() { - console.log(foo) - } -} -`> ->([ - { - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'foo', - }, - params: [{ type: 'Identifier', name: 'foo' }], - body: { - type: 'BlockStatement', - body: [ - { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: { type: 'Identifier', name: 'console' }, - property: { type: 'Identifier', name: 'log' }, - }, - arguments: [ - { - type: 'Identifier', - name: 'foo', - }, - ], - }, - }, - { - type: 'FunctionDeclaration', - id: { type: 'Identifier', name: 'bar' }, - params: [], - body: { - type: 'BlockStatement', - body: [ - { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: { type: 'Identifier', name: 'console' }, - property: { type: 'Identifier', name: 'log' }, - }, - arguments: [{ type: 'Identifier', name: 'foo' }], - }, - }, - ], - }, - }, - ], - }, - }, -]); - -expectType>([ - { - type: 'VariableDeclaration', - kind: 'const', - declarations: [ - { - type: 'VariableDeclarator', - init: { type: 'StringLiteral', value: 'world' }, - id: { type: 'Identifier', name: 'hello' }, - }, - ], - }, -]); - -expectType>([ - { - type: 'VariableDeclaration', - kind: 'const', - declarations: [ - { - type: 'VariableDeclarator', - init: { type: 'NumericLiteral', value: '123' }, - id: { type: 'Identifier', name: 'hello' }, - }, - ], - }, -]); - -expectType>([ - { - type: 'VariableDeclaration', - kind: 'const', - declarations: [ - { - type: 'VariableDeclarator', - init: { - type: 'ArrayExpression', - elements: [ - { type: 'NumericLiteral', value: '1' }, - { type: 'NumericLiteral', value: '2' }, - { type: 'NumericLiteral', value: '3' }, - ], - }, - id: { type: 'Identifier', name: 'hello' }, - }, - ], - }, -]); - -expectType>([ - { - type: 'VariableDeclaration', - kind: 'const', - declarations: [ - { - type: 'VariableDeclarator', - init: { - type: 'ObjectExpression', - properties: [ - { - type: 'ObjectProperty', - key: { type: 'Identifier', name: 'hey' }, - value: { type: 'StringLiteral', value: 'ho' }, - }, - ], - }, - id: { type: 'Identifier', name: 'hello' }, - }, - ], - }, -]); - -expectType>([ - { - type: 'VariableDeclaration', - kind: 'const', - declarations: [ - { - type: 'VariableDeclarator', - init: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'foo', - }, - arguments: [], - }, - id: { type: 'Identifier', name: 'hello' }, - }, - ], - }, -]); - -expectType>([ - { - type: 'IfStatement', - test: { - type: 'Identifier', - name: 'a', - }, - consequent: { - type: 'BlockStatement', - body: [], - }, - }, -]); - -expectType>([ - { - type: 'IfStatement', - test: { - type: 'StringLiteral', - value: 'a', - }, - consequent: { - type: 'BlockStatement', - body: [], - }, - }, -]); - -expectType>([ - { - type: 'IfStatement', - test: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'a', - }, - arguments: [], - }, - consequent: { - type: 'BlockStatement', - body: [], - }, - }, -]); - -expectType>([ - { - type: 'IfStatement', - test: { - type: 'Identifier', - name: 'a', - }, - consequent: { - type: 'BlockStatement', - body: [ - { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: { - type: 'Identifier', - name: 'console', - }, - property: { - type: 'Identifier', - name: 'log', - }, - }, - arguments: [], - }, - }, - ], - }, - }, -]); - -expectType>([ - { - type: 'VariableDeclaration', - kind: 'const', - declarations: [ - { - type: 'VariableDeclarator', - init: { type: 'StringLiteral', value: 'world' }, - id: { - type: 'Identifier', - name: 'hello', - typeAnnotation: { - type: 'TypeAnnotation', - typeAnnotation: { type: 'StringTypeAnnotation' }, - }, - }, - }, - ], - }, -]); - -expectType>([ - { - type: 'VariableDeclaration', - kind: 'const', - declarations: [ - { - type: 'VariableDeclarator', - init: { type: 'StringLiteral', value: 'world' }, - id: { - type: 'Identifier', - name: 'hello', - typeAnnotation: { - type: 'TypeAnnotation', - typeAnnotation: { type: 'NumberTypeAnnotation' }, - }, - }, - }, - ], - }, -]); - -expectType>([ - { - type: 'VariableDeclaration', - kind: 'const', - declarations: [ - { - type: 'VariableDeclarator', - init: { type: 'BooleanLiteral', value: true }, - id: { - type: 'Identifier', - name: 'hello', - typeAnnotation: { - type: 'TypeAnnotation', - typeAnnotation: { type: 'BooleanTypeAnnotation' }, - }, - }, - }, - ], - }, -]); - -expectType>([ - { - type: 'VariableDeclaration', - kind: 'const', - declarations: [ - { - type: 'VariableDeclarator', - init: { type: 'StringLiteral', value: 'world' }, - id: { - type: 'Identifier', - name: 'hello', - typeAnnotation: { - type: 'TypeAnnotation', - typeAnnotation: { type: 'NullLiteralTypeAnnotation' }, - }, - }, - }, - ], - }, -]); - -expectType>([ - { - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'foo', - }, - params: [ - { - type: 'Identifier', - name: 'bar', - typeAnnotation: { - type: 'TypeAnnotation', - typeAnnotation: { - type: 'StringTypeAnnotation', - }, - }, - }, - ], - body: { - type: 'BlockStatement', - body: [], - }, - }, -]); - -expectType>([ - { - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'foo', - }, - params: [ - { - type: 'Identifier', - name: 'bar', - typeAnnotation: { - type: 'TypeAnnotation', - typeAnnotation: { - type: 'BooleanTypeAnnotation', - }, - }, - }, - ], - body: { - type: 'BlockStatement', - body: [], - }, - }, -]); - -expectType>([ - { - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'foo', - }, - params: [ - { - type: 'Identifier', - name: 'bar', - typeAnnotation: { - type: 'TypeAnnotation', - typeAnnotation: { - type: 'NumberTypeAnnotation', - }, - }, - }, - ], - body: { - type: 'BlockStatement', - body: [], - }, - }, -]); - -expectType>([ - { - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'foo', - }, - params: [ - { - type: 'Identifier', - name: 'bar', - typeAnnotation: { - type: 'TypeAnnotation', - typeAnnotation: { - type: 'StringTypeAnnotation', - }, - }, - }, - { - type: 'Identifier', - name: 'baz', - typeAnnotation: { - type: 'TypeAnnotation', - typeAnnotation: { - type: 'NullLiteralTypeAnnotation', - }, - }, - }, - ], - body: { - type: 'BlockStatement', - body: [], - }, - }, -]); +export {}; + +// import type { Tokenize } from '../tokenizer'; +// import type { Parse } from '../parser'; +// import type { Cast } from '../utils/generalUtils'; + +// const expectType = (value: T) => {}; + +// type ParseAst = Tokenize extends infer G +// ? Parse>> +// : never; + +// expectType>([ +// { +// type: 'ExpressionStatement', +// expression: { type: 'Identifier', name: 'hello' }, +// }, +// ]); + +// expectType>([ +// { +// type: 'ExpressionStatement', +// expression: { +// type: 'MemberExpression', +// object: { type: 'Identifier', name: 'hello' }, +// property: { type: 'Identifier', name: 'world' }, +// }, +// }, +// ]); + +// expectType>([ +// { +// type: 'ExpressionStatement', +// expression: { +// type: 'MemberExpression', +// object: { type: 'StringLiteral', value: 'hello' }, +// property: { type: 'Identifier', name: 'world' }, +// }, +// }, +// ]); + +// expectType>([ +// { +// type: 'ExpressionStatement', +// expression: { +// type: 'MemberExpression', +// object: { type: 'NullLiteral' }, +// property: { type: 'Identifier', name: 'world' }, +// }, +// }, +// ]); + +// expectType>([ +// { +// type: 'ExpressionStatement', +// expression: { +// type: 'CallExpression', +// callee: { type: 'StringLiteral', value: 'hello' }, +// arguments: [], +// }, +// }, +// ]); + +// expectType>([ +// { +// type: 'ExpressionStatement', +// expression: { +// type: 'CallExpression', +// callee: { +// type: 'Identifier', +// name: 'hello', +// }, +// arguments: [], +// }, +// }, +// ]); + +// expectType>([ +// { +// type: 'ExpressionStatement', +// expression: { +// type: 'CallExpression', +// callee: { +// type: 'CallExpression', +// callee: { +// type: 'Identifier', +// name: 'hello', +// }, +// arguments: [], +// }, +// arguments: [], +// }, +// }, +// ]); + +// expectType>([ +// { +// type: 'ExpressionStatement', +// expression: { +// type: 'CallExpression', +// callee: { +// type: 'MemberExpression', +// object: { +// type: 'CallExpression', +// callee: { type: 'Identifier', name: 'hello' }, +// arguments: [], +// }, +// property: { +// type: 'Identifier', +// name: 'world', +// }, +// }, +// arguments: [], +// }, +// }, +// ]); + +// expectType>([ +// { +// type: 'ExpressionStatement', +// expression: { +// type: 'CallExpression', +// callee: { +// type: 'Identifier', +// name: 'hello', +// }, +// arguments: [ +// { +// type: 'CallExpression', +// callee: { type: 'Identifier', name: 'world' }, +// arguments: [ +// { +// type: 'NumericLiteral', +// value: '1', +// }, +// ], +// }, +// ], +// }, +// }, +// ]); + +// expectType>([ +// { +// type: 'ExpressionStatement', +// expression: { +// type: 'CallExpression', +// callee: { +// type: 'Identifier', +// name: 'hello', +// }, +// arguments: [ +// { +// type: 'CallExpression', +// callee: { type: 'StringLiteral', value: 'world' }, +// arguments: [ +// { +// type: 'NumericLiteral', +// value: '1', +// }, +// ], +// }, +// ], +// }, +// }, +// ]); + +// expectType>([ +// { +// type: 'ExpressionStatement', +// expression: { +// type: 'CallExpression', +// callee: { +// type: 'Identifier', +// name: 'hello', +// }, +// arguments: [ +// { type: 'NumericLiteral', value: '1' }, +// { type: 'BooleanLiteral', value: true }, +// ], +// }, +// }, +// ]); + +// expectType>([ +// { +// type: 'ExpressionStatement', +// expression: { +// type: 'CallExpression', +// callee: { +// type: 'MemberExpression', +// object: { +// type: 'Identifier', +// name: 'hello', +// }, +// property: { +// type: 'Identifier', +// name: 'world', +// }, +// }, +// arguments: [ +// { type: 'NumericLiteral', value: '1' }, +// { type: 'BooleanLiteral', value: true }, +// ], +// }, +// }, +// ]); + +// expectType>([ +// { +// type: 'FunctionDeclaration', +// id: { +// type: 'Identifier', +// name: 'foo', +// }, +// params: [], +// body: { +// type: 'BlockStatement', +// body: [], +// }, +// }, +// ]); + +// expectType>([ +// { +// type: 'FunctionDeclaration', +// id: { +// type: 'Identifier', +// name: 'foo', +// }, +// params: [ +// { type: 'Identifier', name: 'first' }, +// { type: 'Identifier', name: 'last' }, +// ], +// body: { +// type: 'BlockStatement', +// body: [], +// }, +// }, +// ]); + +// expectType>([ +// { +// type: 'FunctionDeclaration', +// id: { +// type: 'Identifier', +// name: 'foo', +// }, +// params: [], +// body: { +// type: 'BlockStatement', +// body: [ +// { +// type: 'ReturnStatement', +// argument: { +// type: 'NumericLiteral', +// value: '5', +// }, +// }, +// ], +// }, +// }, +// ]); + +// expectType>([ +// { +// type: 'FunctionDeclaration', +// id: { +// type: 'Identifier', +// name: 'foo', +// }, +// params: [], +// body: { +// type: 'BlockStatement', +// body: [ +// { +// type: 'ReturnStatement', +// argument: { +// type: 'CallExpression', +// callee: { +// type: 'Identifier', +// name: 'bar', +// }, +// arguments: [], +// }, +// }, +// ], +// }, +// }, +// ]); + +// expectType>([ +// { +// type: 'FunctionDeclaration', +// id: { +// type: 'Identifier', +// name: 'foo', +// }, +// params: [ +// { type: 'Identifier', name: 'first' }, +// { type: 'Identifier', name: 'last' }, +// ], +// body: { +// type: 'BlockStatement', +// body: [ +// { +// type: 'ExpressionStatement', +// expression: { +// type: 'CallExpression', +// callee: { +// type: 'MemberExpression', +// object: { type: 'Identifier', name: 'console' }, +// property: { type: 'Identifier', name: 'log' }, +// }, +// arguments: [ +// { +// type: 'NumericLiteral', +// value: '1', +// }, +// ], +// }, +// }, +// ], +// }, +// }, +// ]); + +// expectType< +// ParseAst<` +// function foo(foo) { +// console.log(foo) + +// function bar() { +// console.log(foo) +// } +// } +// `> +// >([ +// { +// type: 'FunctionDeclaration', +// id: { +// type: 'Identifier', +// name: 'foo', +// }, +// params: [{ type: 'Identifier', name: 'foo' }], +// body: { +// type: 'BlockStatement', +// body: [ +// { +// type: 'ExpressionStatement', +// expression: { +// type: 'CallExpression', +// callee: { +// type: 'MemberExpression', +// object: { type: 'Identifier', name: 'console' }, +// property: { type: 'Identifier', name: 'log' }, +// }, +// arguments: [ +// { +// type: 'Identifier', +// name: 'foo', +// }, +// ], +// }, +// }, +// { +// type: 'FunctionDeclaration', +// id: { type: 'Identifier', name: 'bar' }, +// params: [], +// body: { +// type: 'BlockStatement', +// body: [ +// { +// type: 'ExpressionStatement', +// expression: { +// type: 'CallExpression', +// callee: { +// type: 'MemberExpression', +// object: { type: 'Identifier', name: 'console' }, +// property: { type: 'Identifier', name: 'log' }, +// }, +// arguments: [{ type: 'Identifier', name: 'foo' }], +// }, +// }, +// ], +// }, +// }, +// ], +// }, +// }, +// ]); + +// expectType>([ +// { +// type: 'VariableDeclaration', +// kind: 'const', +// declarations: [ +// { +// type: 'VariableDeclarator', +// init: { type: 'StringLiteral', value: 'world' }, +// id: { type: 'Identifier', name: 'hello' }, +// }, +// ], +// }, +// ]); + +// expectType>([ +// { +// type: 'VariableDeclaration', +// kind: 'const', +// declarations: [ +// { +// type: 'VariableDeclarator', +// init: { type: 'NumericLiteral', value: '123' }, +// id: { type: 'Identifier', name: 'hello' }, +// }, +// ], +// }, +// ]); + +// expectType>([ +// { +// type: 'VariableDeclaration', +// kind: 'const', +// declarations: [ +// { +// type: 'VariableDeclarator', +// init: { +// type: 'ArrayExpression', +// elements: [ +// { type: 'NumericLiteral', value: '1' }, +// { type: 'NumericLiteral', value: '2' }, +// { type: 'NumericLiteral', value: '3' }, +// ], +// }, +// id: { type: 'Identifier', name: 'hello' }, +// }, +// ], +// }, +// ]); + +// expectType>([ +// { +// type: 'VariableDeclaration', +// kind: 'const', +// declarations: [ +// { +// type: 'VariableDeclarator', +// init: { +// type: 'ObjectExpression', +// properties: [ +// { +// type: 'ObjectProperty', +// key: { type: 'Identifier', name: 'hey' }, +// value: { type: 'StringLiteral', value: 'ho' }, +// }, +// ], +// }, +// id: { type: 'Identifier', name: 'hello' }, +// }, +// ], +// }, +// ]); + +// expectType>([ +// { +// type: 'VariableDeclaration', +// kind: 'const', +// declarations: [ +// { +// type: 'VariableDeclarator', +// init: { +// type: 'CallExpression', +// callee: { +// type: 'Identifier', +// name: 'foo', +// }, +// arguments: [], +// }, +// id: { type: 'Identifier', name: 'hello' }, +// }, +// ], +// }, +// ]); + +// expectType>([ +// { +// type: 'IfStatement', +// test: { +// type: 'Identifier', +// name: 'a', +// }, +// consequent: { +// type: 'BlockStatement', +// body: [], +// }, +// }, +// ]); + +// expectType>([ +// { +// type: 'IfStatement', +// test: { +// type: 'StringLiteral', +// value: 'a', +// }, +// consequent: { +// type: 'BlockStatement', +// body: [], +// }, +// }, +// ]); + +// expectType>([ +// { +// type: 'IfStatement', +// test: { +// type: 'CallExpression', +// callee: { +// type: 'Identifier', +// name: 'a', +// }, +// arguments: [], +// }, +// consequent: { +// type: 'BlockStatement', +// body: [], +// }, +// }, +// ]); + +// expectType>([ +// { +// type: 'IfStatement', +// test: { +// type: 'Identifier', +// name: 'a', +// }, +// consequent: { +// type: 'BlockStatement', +// body: [ +// { +// type: 'ExpressionStatement', +// expression: { +// type: 'CallExpression', +// callee: { +// type: 'MemberExpression', +// object: { +// type: 'Identifier', +// name: 'console', +// }, +// property: { +// type: 'Identifier', +// name: 'log', +// }, +// }, +// arguments: [], +// }, +// }, +// ], +// }, +// }, +// ]); + +// expectType>([ +// { +// type: 'VariableDeclaration', +// kind: 'const', +// declarations: [ +// { +// type: 'VariableDeclarator', +// init: { type: 'StringLiteral', value: 'world' }, +// id: { +// type: 'Identifier', +// name: 'hello', +// typeAnnotation: { +// type: 'TypeAnnotation', +// typeAnnotation: { type: 'StringTypeAnnotation' }, +// }, +// }, +// }, +// ], +// }, +// ]); + +// expectType>([ +// { +// type: 'VariableDeclaration', +// kind: 'const', +// declarations: [ +// { +// type: 'VariableDeclarator', +// init: { type: 'StringLiteral', value: 'world' }, +// id: { +// type: 'Identifier', +// name: 'hello', +// typeAnnotation: { +// type: 'TypeAnnotation', +// typeAnnotation: { type: 'NumberTypeAnnotation' }, +// }, +// }, +// }, +// ], +// }, +// ]); + +// expectType>([ +// { +// type: 'VariableDeclaration', +// kind: 'const', +// declarations: [ +// { +// type: 'VariableDeclarator', +// init: { type: 'BooleanLiteral', value: true }, +// id: { +// type: 'Identifier', +// name: 'hello', +// typeAnnotation: { +// type: 'TypeAnnotation', +// typeAnnotation: { type: 'BooleanTypeAnnotation' }, +// }, +// }, +// }, +// ], +// }, +// ]); + +// expectType>([ +// { +// type: 'VariableDeclaration', +// kind: 'const', +// declarations: [ +// { +// type: 'VariableDeclarator', +// init: { type: 'StringLiteral', value: 'world' }, +// id: { +// type: 'Identifier', +// name: 'hello', +// typeAnnotation: { +// type: 'TypeAnnotation', +// typeAnnotation: { type: 'NullLiteralTypeAnnotation' }, +// }, +// }, +// }, +// ], +// }, +// ]); + +// expectType>([ +// { +// type: 'FunctionDeclaration', +// id: { +// type: 'Identifier', +// name: 'foo', +// }, +// params: [ +// { +// type: 'Identifier', +// name: 'bar', +// typeAnnotation: { +// type: 'TypeAnnotation', +// typeAnnotation: { +// type: 'StringTypeAnnotation', +// }, +// }, +// }, +// ], +// body: { +// type: 'BlockStatement', +// body: [], +// }, +// }, +// ]); + +// expectType>([ +// { +// type: 'FunctionDeclaration', +// id: { +// type: 'Identifier', +// name: 'foo', +// }, +// params: [ +// { +// type: 'Identifier', +// name: 'bar', +// typeAnnotation: { +// type: 'TypeAnnotation', +// typeAnnotation: { +// type: 'BooleanTypeAnnotation', +// }, +// }, +// }, +// ], +// body: { +// type: 'BlockStatement', +// body: [], +// }, +// }, +// ]); + +// expectType>([ +// { +// type: 'FunctionDeclaration', +// id: { +// type: 'Identifier', +// name: 'foo', +// }, +// params: [ +// { +// type: 'Identifier', +// name: 'bar', +// typeAnnotation: { +// type: 'TypeAnnotation', +// typeAnnotation: { +// type: 'NumberTypeAnnotation', +// }, +// }, +// }, +// ], +// body: { +// type: 'BlockStatement', +// body: [], +// }, +// }, +// ]); + +// expectType>([ +// { +// type: 'FunctionDeclaration', +// id: { +// type: 'Identifier', +// name: 'foo', +// }, +// params: [ +// { +// type: 'Identifier', +// name: 'bar', +// typeAnnotation: { +// type: 'TypeAnnotation', +// typeAnnotation: { +// type: 'StringTypeAnnotation', +// }, +// }, +// }, +// { +// type: 'Identifier', +// name: 'baz', +// typeAnnotation: { +// type: 'TypeAnnotation', +// typeAnnotation: { +// type: 'NullLiteralTypeAnnotation', +// }, +// }, +// }, +// ], +// body: { +// type: 'BlockStatement', +// body: [], +// }, +// }, +// ]); diff --git a/src/tokenizer.ts b/src/tokenizer.ts index 1d7645f..0a27cfe 100644 --- a/src/tokenizer.ts +++ b/src/tokenizer.ts @@ -4,7 +4,7 @@ import type { FirstChar, ConcatStrings, } from './utils/stringUtils'; -import type { Numbers, Symbols } from './utils/generalUtils'; +import type { Cast, Numbers, Symbols } from './utils/generalUtils'; import type { CurlyToken, ParenToken, @@ -18,10 +18,11 @@ import type { BracketToken, CommaToken, } from './tokens'; +import type { Error, SyntaxError } from './errors'; type TokenizeInput = FirstChar extends infer F ? EatFirstChar extends infer E - ? F extends ' ' | '\n' + ? F extends ' ' ? ['', E] : F extends ',' ? [CommaToken, E] @@ -51,7 +52,7 @@ type TokenizeInput = FirstChar extends infer F ? TokenizeString : F extends Symbols ? TokenizeSymbol - : never + : SyntaxError<`Invalid character.`> : never : never; @@ -66,7 +67,9 @@ type TokenizeNumber< type TokenizeString< I, W extends '"' | "'", -> = I extends `${infer H}${W}${infer G}` ? [StringToken, G] : never; +> = I extends `${infer H}${W}${infer G}` + ? [StringToken, G] + : SyntaxError<'Unterminated string literal.'>; type TokenizeSymbol< I extends string, @@ -79,9 +82,23 @@ type TokenizeSymbol< export type TokenizeSequence< I extends string, R extends Array> = [], - P extends [any, string] = TokenizeInput, > = I extends '' ? R - : TokenizeSequence>; + : TokenizeInput extends infer P + ? P extends SyntaxError + ? P + : TokenizeSequence< + Cast>[1], + Cast>[0] extends '' + ? R + : Unshift>[0]> + > + : never; -export type Tokenize = Reverse>; +export type Tokenize = TokenizeSequence extends infer G + ? G extends Array + ? Reverse + : G extends Error + ? G + : never + : never; From 7296339fe3e7e28ba13b7d21e49da688b9b7715d Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 4 Jul 2022 20:55:45 +0300 Subject: [PATCH 087/286] wip --- src/utils/arrayUtils.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/utils/arrayUtils.ts b/src/utils/arrayUtils.ts index 680c3a9..71c318d 100644 --- a/src/utils/arrayUtils.ts +++ b/src/utils/arrayUtils.ts @@ -7,6 +7,8 @@ export type Tail> = ((...t: T) => void) extends ( ? R : never; +export type Push, E> = [...T, E]; + export type Unshift, E> = (( h: E, ...t: T @@ -23,6 +25,7 @@ export type Head> = T extends [any, ...Array] ? T['0'] : never; -export type Concat, T2 extends Array> = T2 extends [] - ? T1 - : Concat>, Tail>; +export type Concat, T2 extends Array> = [ + ...T1, + ...T2, +]; From 5822834e34284f1626ddca93291272c11f379a8c Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 4 Jul 2022 21:23:20 +0300 Subject: [PATCH 088/286] wip --- src/test/tokenizer.test.ts | 103 +++++++++++++++++++++++++++++++++++++ src/tokenizer.ts | 8 ++- src/utils/math.ts | 34 ++++++++++++ 3 files changed, 140 insertions(+), 5 deletions(-) create mode 100644 src/test/tokenizer.test.ts create mode 100644 src/utils/math.ts diff --git a/src/test/tokenizer.test.ts b/src/test/tokenizer.test.ts new file mode 100644 index 0000000..ff1c95f --- /dev/null +++ b/src/test/tokenizer.test.ts @@ -0,0 +1,103 @@ +import type { Tokenize } from '../tokenizer'; + +const expectType = (value: T) => {}; + +expectType>([ + { + type: 'symbol', + value: 'hello', + }, +]); + +expectType>([ + { + type: 'string', + value: 'hello', + }, +]); + +expectType>([ + { + type: 'number', + value: '123', + }, +]); + +expectType>([ + { + type: 'bracket', + value: '[', + }, + { + type: 'number', + value: '1', + }, + { + type: 'comma', + }, + { + type: 'number', + value: '2', + }, + { + type: 'comma', + }, + { + type: 'number', + value: '3', + }, + { + type: 'bracket', + value: ']', + }, +]); + +expectType>([ + { + type: 'symbol', + value: 'foo', + }, + { + type: 'paren', + value: '(', + }, + { + type: 'paren', + value: ')', + }, +]); + +expectType>([ + { + type: 'string', + value: 'foo', + }, + { + type: 'paren', + value: '(', + }, + { + type: 'paren', + value: ')', + }, +]); + +expectType>({ + type: 'SyntaxError', + message: 'Unterminated string literal.', +}); + +expectType>({ + type: 'SyntaxError', + message: 'Unterminated string literal.', +}); + +expectType>({ + type: 'SyntaxError', + message: 'Invalid character.', +}); + +expectType>({ + type: 'SyntaxError', + message: 'Invalid character.', +}); diff --git a/src/tokenizer.ts b/src/tokenizer.ts index 0a27cfe..2b435b6 100644 --- a/src/tokenizer.ts +++ b/src/tokenizer.ts @@ -1,4 +1,4 @@ -import type { Reverse, Unshift } from './utils/arrayUtils'; +import type { Push } from './utils/arrayUtils'; import type { EatFirstChar, FirstChar, @@ -89,15 +89,13 @@ export type TokenizeSequence< ? P : TokenizeSequence< Cast>[1], - Cast>[0] extends '' - ? R - : Unshift>[0]> + Cast>[0] extends '' ? R : Push>[0]> > : never; export type Tokenize = TokenizeSequence extends infer G ? G extends Array - ? Reverse + ? G : G extends Error ? G : never diff --git a/src/utils/math.ts b/src/utils/math.ts new file mode 100644 index 0000000..5e9cda6 --- /dev/null +++ b/src/utils/math.ts @@ -0,0 +1,34 @@ +type SuccTable = { + '0': 1; + '1': 2; + '2': 3; + '3': 4; + '4': 5; + '5': 6; + '6': 7; + '7': 8; + '8': 9; + '9': 10; + '10': 11; + '11': 12; + '12': 13; + '13': 14; + '14': 15; + '15': 16; + '16': 17; + '17': 18; + '18': 19; + '19': 20; + '20': 21; + '21': 22; + '22': 23; + '23': 24; + '24': 25; + '25': 26; + '26': 27; + '27': 28; + '28': 29; + '29': 30; +}; + +export type Succ = T extends keyof SuccTable ? SuccTable[T] : never; From 7339a13b8cdd596de615a9f684e62d70e823af12 Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 4 Jul 2022 22:38:49 +0300 Subject: [PATCH 089/286] wip --- src/index.ts | 2 +- src/parser.ts | 592 +++++++++++++++++++------------------ src/test/tokenizer.test.ts | 124 +++++++- src/tokenizer.ts | 119 ++++---- src/tokens.ts | 28 +- src/utils/stringUtils.ts | 10 + 6 files changed, 513 insertions(+), 362 deletions(-) diff --git a/src/index.ts b/src/index.ts index 3e378a3..5e00eb2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; // import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`hello`>; +type T = Tokenize<`"hello\n"`>; // type R = Parse[0]['body']; // type C = Check<[R]>; diff --git a/src/parser.ts b/src/parser.ts index 974b889..cbd348b 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -1,316 +1,318 @@ -import type { - ArrayExpression, - BooleanLiteral, - NumericLiteral, - ObjectExpression, - StringLiteral, - ObjectProperty, - VariableDeclaration, - VariableDeclarator, - FunctionDeclaration, - Identifier, - NullLiteral, - ExpressionStatement, - CallExpression, - MemberExpression, - IfStatement, - ReturnStatement, - BlockStatement, - TypeAnnotation, - GenericTypeAnnotation, - StringTypeAnnotation, - BooleanTypeAnnotation, - NullLiteralTypeAnnotation, - NumberTypeAnnotation, - AnyTypeAnnotation, -} from './ast'; -import type { - BracketToken, - ColonToken, - CommaToken, - CurlyToken, - DotToken, - NumberToken, - ParenToken, - StringToken, - SymbolToken, - Token, -} from './tokens'; -import type { Reverse, Tail, Unshift } from './utils/arrayUtils'; -import type { Cast } from './utils/generalUtils'; +export {}; -type Wrap>]> = T[1][0] extends DotToken - ? T[1][1] extends SymbolToken - ? Wrap<[MemberExpression>, Tail>]> - : T - : T[1][0] extends ParenToken<'('> - ? ParseFunctionArguments> extends infer G - ? Wrap< - [CallExpression>[0]>, Cast>[1]] - > - : never - : T; +// import type { +// ArrayExpression, +// BooleanLiteral, +// NumericLiteral, +// ObjectExpression, +// StringLiteral, +// ObjectProperty, +// VariableDeclaration, +// VariableDeclarator, +// FunctionDeclaration, +// Identifier, +// NullLiteral, +// ExpressionStatement, +// CallExpression, +// MemberExpression, +// IfStatement, +// ReturnStatement, +// BlockStatement, +// TypeAnnotation, +// GenericTypeAnnotation, +// StringTypeAnnotation, +// BooleanTypeAnnotation, +// NullLiteralTypeAnnotation, +// NumberTypeAnnotation, +// AnyTypeAnnotation, +// } from './ast'; +// import type { +// BracketToken, +// ColonToken, +// CommaToken, +// CurlyToken, +// DotToken, +// NumberToken, +// ParenToken, +// StringToken, +// SymbolToken, +// Token, +// } from './tokens'; +// import type { Reverse, Tail, Unshift } from './utils/arrayUtils'; +// import type { Cast } from './utils/generalUtils'; -type DoParseExpression< - T extends Array>, - F = T[0], -> = F extends SymbolToken<'true'> - ? [BooleanLiteral, Tail] - : F extends SymbolToken<'false'> - ? [BooleanLiteral, Tail] - : F extends SymbolToken<'null'> - ? [NullLiteral, Tail] - : F extends NumberToken - ? [NumericLiteral, Tail] - : F extends StringToken - ? [StringLiteral, Tail] - : F extends BracketToken<'['> - ? ParseArray> - : F extends CurlyToken<'{'> - ? ParseObject> - : F extends SymbolToken - ? [Identifier, Tail] - : [never, []]; +// type Wrap>]> = T[1][0] extends DotToken +// ? T[1][1] extends SymbolToken +// ? Wrap<[MemberExpression>, Tail>]> +// : T +// : T[1][0] extends ParenToken<'('> +// ? ParseFunctionArguments> extends infer G +// ? Wrap< +// [CallExpression>[0]>, Cast>[1]] +// > +// : never +// : T; -type ParseExpression>> = - DoParseExpression extends infer G - ? Wrap]>> - : never; +// type DoParseExpression< +// T extends Array>, +// F = T[0], +// > = F extends SymbolToken<'true'> +// ? [BooleanLiteral, Tail] +// : F extends SymbolToken<'false'> +// ? [BooleanLiteral, Tail] +// : F extends SymbolToken<'null'> +// ? [NullLiteral, Tail] +// : F extends NumberToken +// ? [NumericLiteral, Tail] +// : F extends StringToken +// ? [StringLiteral, Tail] +// : F extends BracketToken<'['> +// ? ParseArray> +// : F extends CurlyToken<'{'> +// ? ParseObject> +// : F extends SymbolToken +// ? [Identifier, Tail] +// : [never, []]; -type ParseStatement< - T extends Array>, - F = T[0], -> = F extends SymbolToken<'const'> - ? ParseVariableDeclaration> - : F extends SymbolToken<'function'> - ? ParseFunctionDeclaration> - : F extends SymbolToken<'if'> - ? ParseIfStatement> - : ParseExpression extends infer G - ? [ExpressionStatement>[0]>, Cast>[1]] - : never; +// type ParseExpression>> = +// DoParseExpression extends infer G +// ? Wrap]>> +// : never; -type ParseFunctionStatement>> = - T[0] extends SymbolToken<'return'> - ? ParseExpression> extends infer G - ? [ReturnStatement>[0]>, Cast>[1]] - : never - : ParseStatement; +// type ParseStatement< +// T extends Array>, +// F = T[0], +// > = F extends SymbolToken<'const'> +// ? ParseVariableDeclaration> +// : F extends SymbolToken<'function'> +// ? ParseFunctionDeclaration> +// : F extends SymbolToken<'if'> +// ? ParseIfStatement> +// : ParseExpression extends infer G +// ? [ExpressionStatement>[0]>, Cast>[1]] +// : never; -type ParseIfStatement>> = - T[0] extends ParenToken<'('> - ? ParseExpression> extends infer G - ? Cast>[1] extends infer J - ? Cast>[0] extends ParenToken<')'> - ? Cast>[1] extends CurlyToken<'{'> - ? ParseBlockStatement< - Tail>>> - > extends infer B - ? [ - IfStatement>[0], Cast>[0]>, - Cast>[1], - ] - : never - : never - : never - : never - : never - : never; +// type ParseFunctionStatement>> = +// T[0] extends SymbolToken<'return'> +// ? ParseExpression> extends infer G +// ? [ReturnStatement>[0]>, Cast>[1]] +// : never +// : ParseStatement; -type ParseFunctionArguments< - T extends Array>, - R extends Array = [], - N extends boolean = false, -> = T[0] extends ParenToken<')'> - ? [Reverse, Tail] - : T extends [] - ? never - : N extends true - ? T[0] extends CommaToken - ? ParseFunctionArgumentsItem, R> - : never - : ParseFunctionArgumentsItem; +// type ParseIfStatement>> = +// T[0] extends ParenToken<'('> +// ? ParseExpression> extends infer G +// ? Cast>[1] extends infer J +// ? Cast>[0] extends ParenToken<')'> +// ? Cast>[1] extends CurlyToken<'{'> +// ? ParseBlockStatement< +// Tail>>> +// > extends infer B +// ? [ +// IfStatement>[0], Cast>[0]>, +// Cast>[1], +// ] +// : never +// : never +// : never +// : never +// : never +// : never; -type ParseFunctionArgumentsItem< - T extends Array>, - R extends Array = [], -> = ParseExpression extends infer G - ? ParseFunctionArguments< - Cast>[1], - Unshift>[0]>, - true - > - : never; +// type ParseFunctionArguments< +// T extends Array>, +// R extends Array = [], +// N extends boolean = false, +// > = T[0] extends ParenToken<')'> +// ? [Reverse, Tail] +// : T extends [] +// ? never +// : N extends true +// ? T[0] extends CommaToken +// ? ParseFunctionArgumentsItem, R> +// : never +// : ParseFunctionArgumentsItem; -type ParseFunctionDeclaration>> = - T[0] extends SymbolToken - ? T[1] extends ParenToken<'('> - ? ParseFunctionParams>> extends infer G - ? ParseBlockStatement>[1]> extends infer H - ? [ - FunctionDeclaration< - Identifier, - Cast>[0], - Cast>[0] - >, - Cast>[1], - ] - : never - : never - : never - : never; +// type ParseFunctionArgumentsItem< +// T extends Array>, +// R extends Array = [], +// > = ParseExpression extends infer G +// ? ParseFunctionArguments< +// Cast>[1], +// Unshift>[0]>, +// true +// > +// : never; -type ParseBlockStatement< - T extends Array>, - R extends Array = [], -> = T[0] extends CurlyToken<'}'> - ? [BlockStatement>, Tail] - : ParseFunctionStatement extends infer F - ? ParseBlockStatement< - Cast>[1], - Unshift>[0]> - > - : never; +// type ParseFunctionDeclaration>> = +// T[0] extends SymbolToken +// ? T[1] extends ParenToken<'('> +// ? ParseFunctionParams>> extends infer G +// ? ParseBlockStatement>[1]> extends infer H +// ? [ +// FunctionDeclaration< +// Identifier, +// Cast>[0], +// Cast>[0] +// >, +// Cast>[1], +// ] +// : never +// : never +// : never +// : never; -type ParseFunctionParams< - T extends Array>, - R extends Array = [], - N extends boolean = false, -> = T[0] extends ParenToken<')'> - ? T[1] extends CurlyToken<'{'> - ? [Reverse, Tail>] - : never - : T extends [] - ? never - : N extends true - ? T[0] extends CommaToken - ? ParseFunctionParamsItem, R> - : never - : ParseFunctionParamsItem; +// type ParseBlockStatement< +// T extends Array>, +// R extends Array = [], +// > = T[0] extends CurlyToken<'}'> +// ? [BlockStatement>, Tail] +// : ParseFunctionStatement extends infer F +// ? ParseBlockStatement< +// Cast>[1], +// Unshift>[0]> +// > +// : never; -type ParseTypeAnnotation>> = - T[0] extends SymbolToken<'string'> - ? [TypeAnnotation, Tail] - : T[0] extends SymbolToken<'boolean'> - ? [TypeAnnotation, Tail] - : T[0] extends SymbolToken<'null'> - ? [TypeAnnotation, Tail] - : T[0] extends SymbolToken<'number'> - ? [TypeAnnotation, Tail] - : T[0] extends SymbolToken<'any'> - ? [TypeAnnotation, Tail] - : T[0] extends SymbolToken - ? [TypeAnnotation>, Tail] - : never; +// type ParseFunctionParams< +// T extends Array>, +// R extends Array = [], +// N extends boolean = false, +// > = T[0] extends ParenToken<')'> +// ? T[1] extends CurlyToken<'{'> +// ? [Reverse, Tail>] +// : never +// : T extends [] +// ? never +// : N extends true +// ? T[0] extends CommaToken +// ? ParseFunctionParamsItem, R> +// : never +// : ParseFunctionParamsItem; -type ParseFunctionParamsItem< - T extends Array>, - R extends Array = [], -> = T[0] extends SymbolToken - ? T[1] extends ColonToken - ? ParseTypeAnnotation>> extends infer G - ? ParseFunctionParams< - Cast>[1], - Unshift>[0]>>, - true - > - : never - : ParseFunctionParams, Unshift>, true> - : never; +// type ParseTypeAnnotation>> = +// T[0] extends SymbolToken<'string'> +// ? [TypeAnnotation, Tail] +// : T[0] extends SymbolToken<'boolean'> +// ? [TypeAnnotation, Tail] +// : T[0] extends SymbolToken<'null'> +// ? [TypeAnnotation, Tail] +// : T[0] extends SymbolToken<'number'> +// ? [TypeAnnotation, Tail] +// : T[0] extends SymbolToken<'any'> +// ? [TypeAnnotation, Tail] +// : T[0] extends SymbolToken +// ? [TypeAnnotation>, Tail] +// : never; -type ParseVariableDeclarationHelper< - T extends Array>, - K, - Q = null, -> = ParseExpression extends infer G - ? [ - VariableDeclaration< - [VariableDeclarator, Cast>[0]>], - 'const' - >, - Cast>[1], - ] - : never; +// type ParseFunctionParamsItem< +// T extends Array>, +// R extends Array = [], +// > = T[0] extends SymbolToken +// ? T[1] extends ColonToken +// ? ParseTypeAnnotation>> extends infer G +// ? ParseFunctionParams< +// Cast>[1], +// Unshift>[0]>>, +// true +// > +// : never +// : ParseFunctionParams, Unshift>, true> +// : never; -type ParseVariableDeclaration>> = - T[0] extends SymbolToken - ? T[1] extends ColonToken - ? ParseTypeAnnotation>> extends infer G - ? Cast>[1][0] extends SymbolToken<'='> - ? Cast>[1] extends infer J - ? ParseVariableDeclarationHelper< - Tail>>, - K, - Cast>[0] - > - : never - : never - : never - : T[1] extends SymbolToken<'='> - ? ParseVariableDeclarationHelper>, K> - : never - : never; +// type ParseVariableDeclarationHelper< +// T extends Array>, +// K, +// Q = null, +// > = ParseExpression extends infer G +// ? [ +// VariableDeclaration< +// [VariableDeclarator, Cast>[0]>], +// 'const' +// >, +// Cast>[1], +// ] +// : never; -type ParseObject< - T extends Array>, - R extends Array = [], - N extends boolean = false, - F extends Token = T[0], -> = F extends CurlyToken<'}'> - ? [ObjectExpression>, Tail] - : T extends [] - ? never - : N extends true - ? F extends CommaToken - ? ParseObjectItem, R> - : never - : ParseObjectItem; +// type ParseVariableDeclaration>> = +// T[0] extends SymbolToken +// ? T[1] extends ColonToken +// ? ParseTypeAnnotation>> extends infer G +// ? Cast>[1][0] extends SymbolToken<'='> +// ? Cast>[1] extends infer J +// ? ParseVariableDeclarationHelper< +// Tail>>, +// K, +// Cast>[0] +// > +// : never +// : never +// : never +// : T[1] extends SymbolToken<'='> +// ? ParseVariableDeclarationHelper>, K> +// : never +// : never; -type ParseObjectItem< - T extends Array>, - R extends Array = [], -> = T[0] extends SymbolToken - ? T[1] extends ColonToken - ? ParseExpression>> extends infer G - ? ParseObject< - Cast>[1], - Unshift, Cast>[0]>>, - true - > - : never - : never - : never; +// type ParseObject< +// T extends Array>, +// R extends Array = [], +// N extends boolean = false, +// F extends Token = T[0], +// > = F extends CurlyToken<'}'> +// ? [ObjectExpression>, Tail] +// : T extends [] +// ? never +// : N extends true +// ? F extends CommaToken +// ? ParseObjectItem, R> +// : never +// : ParseObjectItem; -type ParseArray< - T extends Array>, - R extends Array = [], - N extends boolean = false, - F extends Token = T[0], -> = F extends BracketToken<']'> - ? [ArrayExpression>, Tail] - : T extends [] - ? never - : N extends true - ? F extends CommaToken - ? ParseArrayItem, R> - : never - : ParseArrayItem; +// type ParseObjectItem< +// T extends Array>, +// R extends Array = [], +// > = T[0] extends SymbolToken +// ? T[1] extends ColonToken +// ? ParseExpression>> extends infer G +// ? ParseObject< +// Cast>[1], +// Unshift, Cast>[0]>>, +// true +// > +// : never +// : never +// : never; -type ParseArrayItem< - T extends Array>, - R extends Array = [], -> = ParseExpression extends infer G - ? ParseArray>[1], Unshift>[0]>, true> - : never; +// type ParseArray< +// T extends Array>, +// R extends Array = [], +// N extends boolean = false, +// F extends Token = T[0], +// > = F extends BracketToken<']'> +// ? [ArrayExpression>, Tail] +// : T extends [] +// ? never +// : N extends true +// ? F extends CommaToken +// ? ParseArrayItem, R> +// : never +// : ParseArrayItem; -type ParseSequence< - T extends Array>, - R extends Array = [], -> = T extends [] - ? R - : ParseStatement extends infer P - ? ParseSequence>[1], Unshift>[0]>> - : never; +// type ParseArrayItem< +// T extends Array>, +// R extends Array = [], +// > = ParseExpression extends infer G +// ? ParseArray>[1], Unshift>[0]>, true> +// : never; -export type Parse>> = - ParseSequence extends infer P ? Reverse>> : never; +// type ParseSequence< +// T extends Array>, +// R extends Array = [], +// > = T extends [] +// ? R +// : ParseStatement extends infer P +// ? ParseSequence>[1], Unshift>[0]>> +// : never; + +// export type Parse>> = +// ParseSequence extends infer P ? Reverse>> : never; diff --git a/src/test/tokenizer.test.ts b/src/test/tokenizer.test.ts index ff1c95f..667680b 100644 --- a/src/test/tokenizer.test.ts +++ b/src/test/tokenizer.test.ts @@ -6,6 +6,116 @@ expectType>([ { type: 'symbol', value: 'hello', + precedingLinebreak: false, + }, +]); + +expectType>([ + { + type: 'symbol', + value: 'hello', + precedingLinebreak: false, + }, + { + type: 'symbol', + value: 'world', + precedingLinebreak: false, + }, +]); + +expectType>([ + { + type: 'symbol', + value: 'hello', + precedingLinebreak: false, + }, + { + type: 'symbol', + value: 'world', + precedingLinebreak: true, + }, +]); + +expectType>([ + { + type: 'symbol', + value: 'hello', + precedingLinebreak: false, + }, + { + type: 'symbol', + value: 'world', + precedingLinebreak: true, + }, +]); + +expectType>([ + { + type: 'symbol', + value: 'hello', + precedingLinebreak: false, + }, + { + type: 'symbol', + value: 'world', + precedingLinebreak: true, + }, +]); + +expectType>([ + { + type: 'string', + value: 'hello', + precedingLinebreak: false, + }, + { + type: 'string', + value: 'world', + precedingLinebreak: false, + }, +]); + +expectType>([ + { + type: 'string', + value: 'hello', + precedingLinebreak: false, + }, + { + type: 'string', + value: 'world', + precedingLinebreak: true, + }, +]); + +expectType>([ + { + type: 'number', + value: '123', + precedingLinebreak: true, + }, + { + type: 'number', + value: '456', + precedingLinebreak: false, + }, + { + type: 'number', + value: '789', + precedingLinebreak: true, + }, +]); + +expectType>([ + { + type: 'string', + value: 'hello', + precedingLinebreak: false, + }, + { + type: 'string', + value: 'world', + precedingLinebreak: true, }, ]); @@ -13,6 +123,7 @@ expectType>([ { type: 'string', value: 'hello', + precedingLinebreak: false, }, ]); @@ -20,10 +131,11 @@ expectType>([ { type: 'number', value: '123', + precedingLinebreak: false, }, ]); -expectType>([ +expectType>([ { type: 'bracket', value: '[', @@ -31,6 +143,7 @@ expectType>([ { type: 'number', value: '1', + precedingLinebreak: false, }, { type: 'comma', @@ -38,6 +151,7 @@ expectType>([ { type: 'number', value: '2', + precedingLinebreak: false, }, { type: 'comma', @@ -45,6 +159,7 @@ expectType>([ { type: 'number', value: '3', + precedingLinebreak: false, }, { type: 'bracket', @@ -56,6 +171,7 @@ expectType>([ { type: 'symbol', value: 'foo', + precedingLinebreak: false, }, { type: 'paren', @@ -71,6 +187,7 @@ expectType>([ { type: 'string', value: 'foo', + precedingLinebreak: false, }, { type: 'paren', @@ -101,3 +218,8 @@ expectType>({ type: 'SyntaxError', message: 'Invalid character.', }); + +expectType>({ + type: 'SyntaxError', + message: 'Unterminated string literal.', +}); diff --git a/src/tokenizer.ts b/src/tokenizer.ts index 2b435b6..c2db8e2 100644 --- a/src/tokenizer.ts +++ b/src/tokenizer.ts @@ -3,6 +3,7 @@ import type { EatFirstChar, FirstChar, ConcatStrings, + StringContains, } from './utils/stringUtils'; import type { Cast, Numbers, Symbols } from './utils/generalUtils'; import type { @@ -18,85 +19,89 @@ import type { BracketToken, CommaToken, } from './tokens'; -import type { Error, SyntaxError } from './errors'; +import type { SyntaxError } from './errors'; -type TokenizeInput = FirstChar extends infer F - ? EatFirstChar extends infer E - ? F extends ' ' - ? ['', E] - : F extends ',' - ? [CommaToken, E] - : F extends '(' - ? [ParenToken<'('>, E] - : F extends ')' - ? [ParenToken<')'>, E] - : F extends '[' - ? [BracketToken<'['>, E] - : F extends ']' - ? [BracketToken<']'>, E] - : F extends '{' - ? [CurlyToken<'{'>, E] - : F extends '}' - ? [CurlyToken<'}'>, E] - : F extends '.' - ? [DotToken, E] - : F extends ';' - ? [SemicolonToken, E] - : F extends ':' - ? [ColonToken, E] - : F extends Numbers - ? TokenizeNumber - : F extends '"' - ? TokenizeString - : F extends "'" - ? TokenizeString - : F extends Symbols - ? TokenizeSymbol - : SyntaxError<`Invalid character.`> - : never - : never; +type TokenizeInput< + I extends string, + F extends string, + E extends string, + G extends boolean, +> = F extends ',' + ? [CommaToken, E] + : F extends '(' + ? [ParenToken<'('>, E] + : F extends ')' + ? [ParenToken<')'>, E] + : F extends '[' + ? [BracketToken<'['>, E] + : F extends ']' + ? [BracketToken<']'>, E] + : F extends '{' + ? [CurlyToken<'{'>, E] + : F extends '}' + ? [CurlyToken<'}'>, E] + : F extends '.' + ? [DotToken, E] + : F extends ';' + ? [SemicolonToken, E] + : F extends ':' + ? [ColonToken, E] + : F extends Numbers + ? TokenizeNumber + : F extends '"' + ? TokenizeString + : F extends "'" + ? TokenizeString + : F extends Symbols + ? TokenizeSymbol + : SyntaxError<`Invalid character.`>; type TokenizeNumber< I extends string, - A extends string = '', + A extends string, + G extends boolean, C extends string = FirstChar, > = C extends Numbers - ? TokenizeNumber, ConcatStrings> - : [NumberToken, I]; + ? TokenizeNumber, ConcatStrings, G> + : [NumberToken, I]; type TokenizeString< I, W extends '"' | "'", + J extends boolean, > = I extends `${infer H}${W}${infer G}` - ? [StringToken, G] + ? StringContains extends true + ? SyntaxError<'Unterminated string literal.'> + : [StringToken, G] : SyntaxError<'Unterminated string literal.'>; type TokenizeSymbol< I extends string, - A extends string = '', + A extends string, + G extends boolean, C extends string = FirstChar, > = C extends Symbols - ? TokenizeSymbol, ConcatStrings> - : [SymbolToken, I]; + ? TokenizeSymbol, ConcatStrings, G> + : [SymbolToken, I]; export type TokenizeSequence< I extends string, R extends Array> = [], + G extends boolean = false, + F extends string = FirstChar, + E extends string = EatFirstChar, > = I extends '' ? R - : TokenizeInput extends infer P - ? P extends SyntaxError - ? P - : TokenizeSequence< - Cast>[1], - Cast>[0] extends '' ? R : Push>[0]> - > + : F extends ' ' + ? TokenizeSequence + : F extends '\n' + ? TokenizeSequence + : TokenizeInput extends infer P + ? TokenizeHelper : never; -export type Tokenize = TokenizeSequence extends infer G - ? G extends Array - ? G - : G extends Error - ? G - : never - : never; +export type TokenizeHelper> = P extends Array + ? TokenizeSequence> + : P; + +export type Tokenize = TokenizeSequence; diff --git a/src/tokens.ts b/src/tokens.ts index 5a9c892..610e452 100644 --- a/src/tokens.ts +++ b/src/tokens.ts @@ -10,19 +10,31 @@ export type SemicolonToken = { type: 'semicolon' }; export type ColonToken = { type: 'colon' }; -export type NumberToken = { type: 'number'; value: V }; - -export type StringToken = { type: 'string'; value: V }; - -export type SymbolToken = { type: 'symbol'; value: V }; +export type NumberToken = { + type: 'number'; + value: V; + precedingLinebreak: P; +}; + +export type StringToken = { + type: 'string'; + value: V; + precedingLinebreak: P; +}; + +export type SymbolToken = { + type: 'symbol'; + value: V; + precedingLinebreak: P; +}; export type CommaToken = { type: 'comma' }; export type Token = - | NumberToken + | NumberToken | BracketToken - | StringToken - | SymbolToken + | StringToken + | SymbolToken | ParenToken | CurlyToken | DotToken diff --git a/src/utils/stringUtils.ts b/src/utils/stringUtils.ts index d33c361..cfd89c4 100644 --- a/src/utils/stringUtils.ts +++ b/src/utils/stringUtils.ts @@ -3,3 +3,13 @@ export type EatFirstChar = T extends `${infer A}${infer B}` ? B : ''; export type FirstChar = T extends `${infer A}${infer B}` ? A : ''; export type ConcatStrings = `${A}${B}`; + +export type StringContains = I extends T + ? true + : I extends `${T}${infer _}` + ? true + : I extends `${infer _0}${T}${infer _1}` + ? true + : I extends `${infer _}${T}` + ? true + : false; From 92c6503cf39456dd417b733eb873ac8fd82a9592 Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 4 Jul 2022 22:40:07 +0300 Subject: [PATCH 090/286] wip --- src/tokenizer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tokenizer.ts b/src/tokenizer.ts index c2db8e2..808b0ea 100644 --- a/src/tokenizer.ts +++ b/src/tokenizer.ts @@ -5,7 +5,7 @@ import type { ConcatStrings, StringContains, } from './utils/stringUtils'; -import type { Cast, Numbers, Symbols } from './utils/generalUtils'; +import type { Numbers, Symbols } from './utils/generalUtils'; import type { CurlyToken, ParenToken, From 57c14f78cdea5d1561a1492b243d42a0dbeb6fd1 Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 4 Jul 2022 22:40:41 +0300 Subject: [PATCH 091/286] wip --- src/tokenizer.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tokenizer.ts b/src/tokenizer.ts index 808b0ea..c80abb0 100644 --- a/src/tokenizer.ts +++ b/src/tokenizer.ts @@ -68,11 +68,11 @@ type TokenizeNumber< type TokenizeString< I, W extends '"' | "'", - J extends boolean, -> = I extends `${infer H}${W}${infer G}` + G extends boolean, +> = I extends `${infer H}${W}${infer J}` ? StringContains extends true ? SyntaxError<'Unterminated string literal.'> - : [StringToken, G] + : [StringToken, J] : SyntaxError<'Unterminated string literal.'>; type TokenizeSymbol< From eac1b2a36bc087a9992e7bf19e17f5b34be9cfbb Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 4 Jul 2022 23:01:22 +0300 Subject: [PATCH 092/286] wip --- src/index.ts | 2 +- src/test/tokenizer.test.ts | 186 +++++++++++++++++++++++++++++++------ src/tokenizer.ts | 61 ++++++------ src/tokens.ts | 69 ++++++++++---- src/utils/math.ts | 60 ++++++------ 5 files changed, 274 insertions(+), 104 deletions(-) diff --git a/src/index.ts b/src/index.ts index 5e00eb2..177dc83 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; // import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`"hello\n"`>; +type T = Tokenize<`"hello"`>; // type R = Parse[0]['body']; // type C = Check<[R]>; diff --git a/src/test/tokenizer.test.ts b/src/test/tokenizer.test.ts index 667680b..7c8e407 100644 --- a/src/test/tokenizer.test.ts +++ b/src/test/tokenizer.test.ts @@ -6,7 +6,10 @@ expectType>([ { type: 'symbol', value: 'hello', - precedingLinebreak: false, + data: { + precedingLinebreak: false, + lineNumber: 1, + }, }, ]); @@ -14,12 +17,18 @@ expectType>([ { type: 'symbol', value: 'hello', - precedingLinebreak: false, + data: { + precedingLinebreak: false, + lineNumber: 1, + }, }, { type: 'symbol', value: 'world', - precedingLinebreak: false, + data: { + precedingLinebreak: false, + lineNumber: 1, + }, }, ]); @@ -27,12 +36,18 @@ expectType>([ { type: 'symbol', value: 'hello', - precedingLinebreak: false, + data: { + precedingLinebreak: false, + lineNumber: 1, + }, }, { type: 'symbol', value: 'world', - precedingLinebreak: true, + data: { + precedingLinebreak: true, + lineNumber: 2, + }, }, ]); @@ -40,12 +55,18 @@ expectType>([ { type: 'symbol', value: 'hello', - precedingLinebreak: false, + data: { + precedingLinebreak: false, + lineNumber: 1, + }, }, { type: 'symbol', value: 'world', - precedingLinebreak: true, + data: { + precedingLinebreak: true, + lineNumber: 2, + }, }, ]); @@ -53,12 +74,18 @@ expectType>([ { type: 'symbol', value: 'hello', - precedingLinebreak: false, + data: { + precedingLinebreak: false, + lineNumber: 1, + }, }, { type: 'symbol', value: 'world', - precedingLinebreak: true, + data: { + precedingLinebreak: true, + lineNumber: 3, + }, }, ]); @@ -66,12 +93,18 @@ expectType>([ { type: 'string', value: 'hello', - precedingLinebreak: false, + data: { + precedingLinebreak: false, + lineNumber: 1, + }, }, { type: 'string', value: 'world', - precedingLinebreak: false, + data: { + precedingLinebreak: false, + lineNumber: 1, + }, }, ]); @@ -79,30 +112,45 @@ expectType>([ { type: 'string', value: 'hello', - precedingLinebreak: false, + data: { + precedingLinebreak: false, + lineNumber: 1, + }, }, { type: 'string', value: 'world', - precedingLinebreak: true, + data: { + precedingLinebreak: true, + lineNumber: 2, + }, }, ]); -expectType>([ +expectType>([ { type: 'number', value: '123', - precedingLinebreak: true, + data: { + precedingLinebreak: true, + lineNumber: 2, + }, }, { type: 'number', value: '456', - precedingLinebreak: false, + data: { + precedingLinebreak: false, + lineNumber: 2, + }, }, { type: 'number', value: '789', - precedingLinebreak: true, + data: { + precedingLinebreak: true, + lineNumber: 4, + }, }, ]); @@ -110,12 +158,18 @@ expectType>([ { type: 'string', value: 'hello', - precedingLinebreak: false, + data: { + precedingLinebreak: false, + lineNumber: 1, + }, }, { type: 'string', value: 'world', - precedingLinebreak: true, + data: { + precedingLinebreak: true, + lineNumber: 3, + }, }, ]); @@ -123,7 +177,10 @@ expectType>([ { type: 'string', value: 'hello', - precedingLinebreak: false, + data: { + precedingLinebreak: false, + lineNumber: 1, + }, }, ]); @@ -131,7 +188,10 @@ expectType>([ { type: 'number', value: '123', - precedingLinebreak: false, + data: { + precedingLinebreak: false, + lineNumber: 1, + }, }, ]); @@ -139,31 +199,56 @@ expectType>([ { type: 'bracket', value: '[', + data: { + precedingLinebreak: false, + lineNumber: 1, + }, }, { type: 'number', value: '1', - precedingLinebreak: false, + data: { + precedingLinebreak: false, + lineNumber: 1, + }, }, { type: 'comma', + data: { + precedingLinebreak: false, + lineNumber: 1, + }, }, { type: 'number', value: '2', - precedingLinebreak: false, + data: { + precedingLinebreak: false, + lineNumber: 1, + }, }, { type: 'comma', + data: { + precedingLinebreak: false, + lineNumber: 1, + }, }, { type: 'number', value: '3', - precedingLinebreak: false, + data: { + precedingLinebreak: false, + lineNumber: 1, + }, }, { type: 'bracket', value: ']', + data: { + precedingLinebreak: false, + lineNumber: 1, + }, }, ]); @@ -171,15 +256,26 @@ expectType>([ { type: 'symbol', value: 'foo', - precedingLinebreak: false, + data: { + precedingLinebreak: false, + lineNumber: 1, + }, }, { type: 'paren', value: '(', + data: { + precedingLinebreak: false, + lineNumber: 1, + }, }, { type: 'paren', value: ')', + data: { + precedingLinebreak: false, + lineNumber: 1, + }, }, ]); @@ -187,15 +283,53 @@ expectType>([ { type: 'string', value: 'foo', - precedingLinebreak: false, + data: { + precedingLinebreak: false, + lineNumber: 1, + }, }, { type: 'paren', value: '(', + data: { + precedingLinebreak: false, + lineNumber: 1, + }, }, { type: 'paren', value: ')', + data: { + precedingLinebreak: false, + lineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'string', + value: 'foo', + data: { + precedingLinebreak: false, + lineNumber: 1, + }, + }, + { + type: 'paren', + value: '(', + data: { + precedingLinebreak: true, + lineNumber: 2, + }, + }, + { + type: 'paren', + value: ')', + data: { + precedingLinebreak: false, + lineNumber: 2, + }, }, ]); diff --git a/src/tokenizer.ts b/src/tokenizer.ts index c80abb0..0299ac3 100644 --- a/src/tokenizer.ts +++ b/src/tokenizer.ts @@ -18,48 +18,52 @@ import type { StringToken, BracketToken, CommaToken, + TokenData, } from './tokens'; import type { SyntaxError } from './errors'; +import type { Succ } from './utils/math'; type TokenizeInput< I extends string, F extends string, E extends string, G extends boolean, + L extends number, + D extends TokenData = { precedingLinebreak: G; lineNumber: L }, > = F extends ',' - ? [CommaToken, E] + ? [CommaToken, E] : F extends '(' - ? [ParenToken<'('>, E] + ? [ParenToken<'(', D>, E] : F extends ')' - ? [ParenToken<')'>, E] + ? [ParenToken<')', D>, E] : F extends '[' - ? [BracketToken<'['>, E] + ? [BracketToken<'[', D>, E] : F extends ']' - ? [BracketToken<']'>, E] + ? [BracketToken<']', D>, E] : F extends '{' - ? [CurlyToken<'{'>, E] + ? [CurlyToken<'{', D>, E] : F extends '}' - ? [CurlyToken<'}'>, E] + ? [CurlyToken<'}', D>, E] : F extends '.' - ? [DotToken, E] + ? [DotToken, E] : F extends ';' - ? [SemicolonToken, E] + ? [SemicolonToken, E] : F extends ':' - ? [ColonToken, E] + ? [ColonToken, E] : F extends Numbers - ? TokenizeNumber + ? TokenizeNumber : F extends '"' - ? TokenizeString + ? TokenizeString : F extends "'" - ? TokenizeString + ? TokenizeString : F extends Symbols - ? TokenizeSymbol + ? TokenizeSymbol : SyntaxError<`Invalid character.`>; type TokenizeNumber< I extends string, A extends string, - G extends boolean, + G extends TokenData, C extends string = FirstChar, > = C extends Numbers ? TokenizeNumber, ConcatStrings, G> @@ -68,7 +72,7 @@ type TokenizeNumber< type TokenizeString< I, W extends '"' | "'", - G extends boolean, + G extends TokenData, > = I extends `${infer H}${W}${infer J}` ? StringContains extends true ? SyntaxError<'Unterminated string literal.'> @@ -78,7 +82,7 @@ type TokenizeString< type TokenizeSymbol< I extends string, A extends string, - G extends boolean, + G extends TokenData, C extends string = FirstChar, > = C extends Symbols ? TokenizeSymbol, ConcatStrings, G> @@ -86,22 +90,25 @@ type TokenizeSymbol< export type TokenizeSequence< I extends string, - R extends Array> = [], - G extends boolean = false, + R extends Array>, + L extends number, + G extends boolean, F extends string = FirstChar, E extends string = EatFirstChar, > = I extends '' ? R : F extends ' ' - ? TokenizeSequence + ? TokenizeSequence : F extends '\n' - ? TokenizeSequence - : TokenizeInput extends infer P - ? TokenizeHelper + ? TokenizeSequence, true> + : TokenizeInput extends infer P + ? TokenizeHelper : never; -export type TokenizeHelper> = P extends Array - ? TokenizeSequence> - : P; +export type TokenizeHelper< + P, + R extends Array, + L extends number, +> = P extends Array ? TokenizeSequence, L, false> : P; -export type Tokenize = TokenizeSequence; +export type Tokenize = TokenizeSequence; diff --git a/src/tokens.ts b/src/tokens.ts index 610e452..313d32c 100644 --- a/src/tokens.ts +++ b/src/tokens.ts @@ -1,43 +1,72 @@ -export type ParenToken = { type: 'paren'; value: V }; +export type TokenData = { + precedingLinebreak: boolean; + lineNumber: number; +}; + +export type ParenToken = { + type: 'paren'; + value: V; + data: D; +}; -export type BracketToken = { type: 'bracket'; value: V }; +export type BracketToken = { + type: 'bracket'; + value: V; + data: D; +}; -export type CurlyToken = { type: 'curly'; value: V }; +export type CurlyToken = { + type: 'curly'; + value: V; + data: D; +}; -export type DotToken = { type: 'dot' }; +export type DotToken = { + type: 'dot'; + data: D; +}; -export type SemicolonToken = { type: 'semicolon' }; +export type SemicolonToken = { + type: 'semicolon'; + data: D; +}; -export type ColonToken = { type: 'colon' }; +export type ColonToken = { + type: 'colon'; + data: D; +}; -export type NumberToken = { +export type NumberToken = { type: 'number'; value: V; - precedingLinebreak: P; + data: T; }; -export type StringToken = { +export type StringToken = { type: 'string'; value: V; - precedingLinebreak: P; + data: T; }; -export type SymbolToken = { +export type SymbolToken = { type: 'symbol'; value: V; - precedingLinebreak: P; + data: T; }; -export type CommaToken = { type: 'comma' }; +export type CommaToken = { + type: 'comma'; + data: D; +}; export type Token = | NumberToken - | BracketToken + | BracketToken | StringToken | SymbolToken - | ParenToken - | CurlyToken - | DotToken - | SemicolonToken - | ColonToken - | CommaToken; + | ParenToken + | CurlyToken + | DotToken + | SemicolonToken + | ColonToken + | CommaToken; diff --git a/src/utils/math.ts b/src/utils/math.ts index 5e9cda6..e4e2397 100644 --- a/src/utils/math.ts +++ b/src/utils/math.ts @@ -1,34 +1,34 @@ type SuccTable = { - '0': 1; - '1': 2; - '2': 3; - '3': 4; - '4': 5; - '5': 6; - '6': 7; - '7': 8; - '8': 9; - '9': 10; - '10': 11; - '11': 12; - '12': 13; - '13': 14; - '14': 15; - '15': 16; - '16': 17; - '17': 18; - '18': 19; - '19': 20; - '20': 21; - '21': 22; - '22': 23; - '23': 24; - '24': 25; - '25': 26; - '26': 27; - '27': 28; - '28': 29; - '29': 30; + 0: 1; + 1: 2; + 2: 3; + 3: 4; + 4: 5; + 5: 6; + 6: 7; + 7: 8; + 8: 9; + 9: 10; + 10: 11; + 11: 12; + 12: 13; + 13: 14; + 14: 15; + 15: 16; + 16: 17; + 17: 18; + 18: 19; + 19: 20; + 20: 21; + 21: 22; + 22: 23; + 23: 24; + 24: 25; + 25: 26; + 26: 27; + 27: 28; + 28: 29; + 29: 30; }; export type Succ = T extends keyof SuccTable ? SuccTable[T] : never; From 428a354fc49f956da1b6e846a1425148c58d7a8d Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 4 Jul 2022 23:02:31 +0300 Subject: [PATCH 093/286] wip --- src/test/tokenizer.test.ts | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/test/tokenizer.test.ts b/src/test/tokenizer.test.ts index 7c8e407..b7c586e 100644 --- a/src/test/tokenizer.test.ts +++ b/src/test/tokenizer.test.ts @@ -333,6 +333,33 @@ expectType>([ }, ]); +expectType>([ + { + type: 'string', + value: 'foo', + data: { + precedingLinebreak: false, + lineNumber: 1, + }, + }, + { + type: 'paren', + value: '(', + data: { + precedingLinebreak: false, + lineNumber: 1, + }, + }, + { + type: 'paren', + value: ')', + data: { + precedingLinebreak: true, + lineNumber: 2, + }, + }, +]); + expectType>({ type: 'SyntaxError', message: 'Unterminated string literal.', From 5a161c884be82d22711a92dbe8489e7ecfa045f2 Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 4 Jul 2022 23:04:18 +0300 Subject: [PATCH 094/286] wip --- src/errors.ts | 5 +++-- src/index.ts | 2 +- src/test/tokenizer.test.ts | 11 ++++++++--- src/tokenizer.ts | 6 +++--- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/errors.ts b/src/errors.ts index 67adda2..0d5ed0e 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -1,6 +1,7 @@ -export type Error = { +export type Error = { type: T; message: M; + lineNumber: L; }; -export type SyntaxError = Error<'SyntaxError', T>; +export type SyntaxError = Error<'SyntaxError', T, L>; diff --git a/src/index.ts b/src/index.ts index 177dc83..c4a6784 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; // import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`"hello"`>; +type T = Tokenize<`"hello`>; // type R = Parse[0]['body']; // type C = Check<[R]>; diff --git a/src/test/tokenizer.test.ts b/src/test/tokenizer.test.ts index b7c586e..e358ad7 100644 --- a/src/test/tokenizer.test.ts +++ b/src/test/tokenizer.test.ts @@ -363,24 +363,29 @@ expectType>([ expectType>({ type: 'SyntaxError', message: 'Unterminated string literal.', + lineNumber: 1, }); -expectType>({ +expectType>({ type: 'SyntaxError', message: 'Unterminated string literal.', + lineNumber: 3, }); expectType>({ type: 'SyntaxError', message: 'Invalid character.', + lineNumber: 1, }); -expectType>({ +expectType>({ type: 'SyntaxError', message: 'Invalid character.', + lineNumber: 2, }); -expectType>({ +expectType>({ type: 'SyntaxError', message: 'Unterminated string literal.', + lineNumber: 2, }); diff --git a/src/tokenizer.ts b/src/tokenizer.ts index 0299ac3..70614d7 100644 --- a/src/tokenizer.ts +++ b/src/tokenizer.ts @@ -58,7 +58,7 @@ type TokenizeInput< ? TokenizeString : F extends Symbols ? TokenizeSymbol - : SyntaxError<`Invalid character.`>; + : SyntaxError<`Invalid character.`, L>; type TokenizeNumber< I extends string, @@ -75,9 +75,9 @@ type TokenizeString< G extends TokenData, > = I extends `${infer H}${W}${infer J}` ? StringContains extends true - ? SyntaxError<'Unterminated string literal.'> + ? SyntaxError<'Unterminated string literal.', G['lineNumber']> : [StringToken, J] - : SyntaxError<'Unterminated string literal.'>; + : SyntaxError<'Unterminated string literal.', G['lineNumber']>; type TokenizeSymbol< I extends string, From 6c896e2d6ca4d08bfbd3ede321a9b083d88aae64 Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 5 Jul 2022 00:03:00 +0300 Subject: [PATCH 095/286] wip --- src/ast.ts | 96 +++++++---- src/checker.ts | 438 ++++++++++++++++++++++++----------------------- src/index.ts | 6 +- src/parser.ts | 145 ++++++++++------ src/tokenizer.ts | 2 +- src/tokens.ts | 48 +++--- 6 files changed, 403 insertions(+), 332 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index 114d3c6..73aa19e 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -1,128 +1,156 @@ -export type NumericLiteral = { +export type NodeData = { + startLineNumber: number; + endLineNumber: number; +}; + +export type NumericLiteral = { type: 'NumericLiteral'; value: T; + data: D; }; -export type BooleanLiteral = { +export type BooleanLiteral = { type: 'BooleanLiteral'; value: T; + data: D; }; -export type StringLiteral = { +export type StringLiteral = { type: 'StringLiteral'; value: T; + data: D; }; -export type ArrayExpression = { +export type ArrayExpression = { type: 'ArrayExpression'; elements: T; + data: D; }; -export type ObjectExpression = { +export type ObjectExpression = { type: 'ObjectExpression'; properties: T; + data: D; }; -export type ObjectProperty = { +export type ObjectProperty = { type: 'ObjectProperty'; key: K; value: T; + data: D; }; -export type VariableDeclaration = { +export type VariableDeclaration< + H, + K extends 'const' | 'let', + D extends NodeData, +> = { type: 'VariableDeclaration'; - declarations: D; + declarations: H; kind: K; + data: D; }; -export type VariableDeclarator = { +export type VariableDeclarator = { type: 'VariableDeclarator'; id: N; init: I; + data: D; }; -export type FunctionDeclaration = { +export type FunctionDeclaration = { type: 'FunctionDeclaration'; id: I; params: P; body: B; + data: D; }; -export type Identifier = T extends null - ? { - type: 'Identifier'; - name: N; - } - : { - type: 'Identifier'; - name: N; - typeAnnotation: T; - }; +export type Identifier = { + type: 'Identifier'; + name: N; + typeAnnotation: T; + data: D; +}; -export type NullLiteral = { +export type NullLiteral = { type: 'NullLiteral'; + data: D; }; -export type ExpressionStatement = { +export type ExpressionStatement = { type: 'ExpressionStatement'; expression: E; + data: D; }; -export type CallExpression = { +export type CallExpression = { type: 'CallExpression'; callee: C; arguments: A; + data: D; }; -export type MemberExpression = { +export type MemberExpression = { type: 'MemberExpression'; object: O; property: P; + data: D; }; -export type IfStatement = { +export type IfStatement = { type: 'IfStatement'; test: T; consequent: C; + data: D; // alternate: A; }; -export type ReturnStatement = { +export type ReturnStatement = { type: 'ReturnStatement'; argument: T; + data: D; }; -export type BlockStatement = { +export type BlockStatement = { type: 'BlockStatement'; body: B; + data: D; }; -export type TypeAnnotation = { +export type TypeAnnotation = { type: 'TypeAnnotation'; typeAnnotation: T; + data: D; }; -export type StringTypeAnnotation = { +export type StringTypeAnnotation = { type: 'StringTypeAnnotation'; + data: D; }; -export type NumberTypeAnnotation = { +export type NumberTypeAnnotation = { type: 'NumberTypeAnnotation'; + data: D; }; -export type NullLiteralTypeAnnotation = { +export type NullLiteralTypeAnnotation = { type: 'NullLiteralTypeAnnotation'; + data: D; }; -export type BooleanTypeAnnotation = { +export type BooleanTypeAnnotation = { type: 'BooleanTypeAnnotation'; + data: D; }; -export type GenericTypeAnnotation = { +export type GenericTypeAnnotation = { type: 'GenericTypeAnnotation'; id: I; + data: D; }; -export type AnyTypeAnnotation = { +export type AnyTypeAnnotation = { type: 'AnyTypeAnnotation'; + data: D; }; diff --git a/src/checker.ts b/src/checker.ts index 37a8691..32f4ec2 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -1,229 +1,231 @@ -import type { - AnyTypeAnnotation, - ArrayExpression, - BlockStatement, - BooleanLiteral, - BooleanTypeAnnotation, - CallExpression, - ExpressionStatement, - FunctionDeclaration, - GenericTypeAnnotation, - Identifier, - IfStatement, - MemberExpression, - NullLiteral, - NullLiteralTypeAnnotation, - NumberTypeAnnotation, - NumericLiteral, - ObjectExpression, - ObjectProperty, - ReturnStatement, - StringLiteral, - StringTypeAnnotation, - TypeAnnotation, - VariableDeclaration, - VariableDeclarator, -} from './ast'; -import type { - AnyType, - ArrayType, - BooleanType, - FunctionType, - GenericType, - NullType, - NumberType, - ObjectType, - StringType, - UnknownType, - VoidType, -} from './types'; -import type { Concat, Reverse, Tail, Unshift } from './utils/arrayUtils'; -import type { Cast, MergeWithOverride } from './utils/generalUtils'; +export {}; -export type Check> = CheckBlock; +// import type { +// AnyTypeAnnotation, +// ArrayExpression, +// BlockStatement, +// BooleanLiteral, +// BooleanTypeAnnotation, +// CallExpression, +// ExpressionStatement, +// FunctionDeclaration, +// GenericTypeAnnotation, +// Identifier, +// IfStatement, +// MemberExpression, +// NullLiteral, +// NullLiteralTypeAnnotation, +// NumberTypeAnnotation, +// NumericLiteral, +// ObjectExpression, +// ObjectProperty, +// ReturnStatement, +// StringLiteral, +// StringTypeAnnotation, +// TypeAnnotation, +// VariableDeclaration, +// VariableDeclarator, +// } from './ast'; +// import type { +// AnyType, +// ArrayType, +// BooleanType, +// FunctionType, +// GenericType, +// NullType, +// NumberType, +// ObjectType, +// StringType, +// UnknownType, +// VoidType, +// } from './types'; +// import type { Concat, Reverse, Tail, Unshift } from './utils/arrayUtils'; +// import type { Cast, MergeWithOverride } from './utils/generalUtils'; -type InferArrayElements< - T extends Array, - S extends {}, - R extends Array = [], -> = T extends [] - ? R - : InferArrayElements, S, Unshift>>; +// export type Check> = CheckBlock; -type InferObjectValues< - T extends Array, - S extends {}, - R extends {} = {}, -> = T extends [] - ? R - : T[0] extends ObjectProperty, infer K> - ? InferObjectValues< - Tail, - S, - MergeWithOverride]: InferExpression }> - > - : never; +// type InferArrayElements< +// T extends Array, +// S extends {}, +// R extends Array = [], +// > = T extends [] +// ? R +// : InferArrayElements, S, Unshift>>; -type InferCallArguments< - T extends Array, - S extends {}, - R extends Array = [], -> = T extends [] - ? Reverse - : InferCallArguments, S, Unshift>>; +// type InferObjectValues< +// T extends Array, +// S extends {}, +// R extends {} = {}, +// > = T extends [] +// ? R +// : T[0] extends ObjectProperty, infer K> +// ? InferObjectValues< +// Tail, +// S, +// MergeWithOverride]: InferExpression }> +// > +// : never; -type AssignableTypes = A extends AnyType - ? true - : B extends A - ? true - : false; +// type InferCallArguments< +// T extends Array, +// S extends {}, +// R extends Array = [], +// > = T extends [] +// ? Reverse +// : InferCallArguments, S, Unshift>>; -type AssignableArgumentTypes< - I extends Array, - P extends Array, -> = I extends [] - ? P extends [] - ? true - : false - : AssignableTypes extends false - ? false - : AssignableArgumentTypes, Tail

>; +// type AssignableTypes = A extends AnyType +// ? true +// : B extends A +// ? true +// : false; -type InferExpression = T extends StringLiteral - ? StringType - : T extends NumericLiteral - ? NumberType - : T extends NullLiteral - ? NullType - : T extends BooleanLiteral - ? BooleanType - : T extends Identifier - ? N extends keyof S - ? S[N] - : never - : T extends ArrayExpression - ? ArrayType>, S>> - : T extends ObjectExpression - ? ObjectType>, S>> - : T extends CallExpression - ? InferCallArguments>, S> extends infer O - ? InferExpression extends infer I - ? I extends FunctionType - ? AssignableArgumentTypes< - Cast>, - Cast> - > extends true - ? R - : never - : never - : never - : never - : T extends MemberExpression> - ? InferExpression extends infer D - ? D extends ObjectType - ? P extends keyof Y - ? Y[P] - : never - : D extends StringType - ? P extends 'length' - ? NumberType - : never - : D extends NumberType - ? P extends 'toString' - ? FunctionType<[], StringType> - : never - : never - : never - : UnknownType; +// type AssignableArgumentTypes< +// I extends Array, +// P extends Array, +// > = I extends [] +// ? P extends [] +// ? true +// : false +// : AssignableTypes extends false +// ? false +// : AssignableArgumentTypes, Tail

>; -type MapTypeAnnotationToType = A extends StringTypeAnnotation - ? StringType - : A extends NumberTypeAnnotation - ? NumberType - : A extends BooleanTypeAnnotation - ? BooleanType - : A extends NullLiteralTypeAnnotation - ? NullType - : A extends AnyTypeAnnotation - ? AnyType - : A extends GenericTypeAnnotation - ? GenericType - : never; +// type InferExpression = T extends StringLiteral +// ? StringType +// : T extends NumericLiteral +// ? NumberType +// : T extends NullLiteral +// ? NullType +// : T extends BooleanLiteral +// ? BooleanType +// : T extends Identifier +// ? N extends keyof S +// ? S[N] +// : never +// : T extends ArrayExpression +// ? ArrayType>, S>> +// : T extends ObjectExpression +// ? ObjectType>, S>> +// : T extends CallExpression +// ? InferCallArguments>, S> extends infer O +// ? InferExpression extends infer I +// ? I extends FunctionType +// ? AssignableArgumentTypes< +// Cast>, +// Cast> +// > extends true +// ? R +// : never +// : never +// : never +// : never +// : T extends MemberExpression> +// ? InferExpression extends infer D +// ? D extends ObjectType +// ? P extends keyof Y +// ? Y[P] +// : never +// : D extends StringType +// ? P extends 'length' +// ? NumberType +// : never +// : D extends NumberType +// ? P extends 'toString' +// ? FunctionType<[], StringType> +// : never +// : never +// : never +// : UnknownType; -type InferFunctionParams< - T extends Array, - R extends Array = [], - G = {}, -> = T extends [] - ? [Reverse, G] - : T[0] extends Identifier> - ? InferFunctionParams< - Tail, - Unshift>, - MergeWithOverride< - G, - { [a in Cast]: MapTypeAnnotationToType } - > - > - : never; +// type MapTypeAnnotationToType = A extends StringTypeAnnotation +// ? StringType +// : A extends NumberTypeAnnotation +// ? NumberType +// : A extends BooleanTypeAnnotation +// ? BooleanType +// : A extends NullLiteralTypeAnnotation +// ? NullType +// : A extends AnyTypeAnnotation +// ? AnyType +// : A extends GenericTypeAnnotation +// ? GenericType +// : never; -type InferBlock< - T extends Array, - S extends {}, - R extends Array = [], -> = T extends [] - ? Unshift - : T[0] extends ReturnStatement - ? InferExpression extends infer G - ? G extends Array - ? Concat>> - : Unshift - : never - : T[0] extends VariableDeclaration< - [VariableDeclarator, infer I>], - any - > - ? InferBlock< - Tail, - MergeWithOverride]: InferExpression }>, - R - > - : T[0] extends FunctionDeclaration< - Identifier, - infer P, - BlockStatement - > - ? InferFunctionParams>> extends infer O - ? InferBlock< - Tail, - MergeWithOverride< - S, - { - [a in Cast]: FunctionType< - Cast>[0], - InferBlock< - Cast>, - MergeWithOverride>[1]> - > - >; - } - >, - R - > - : never - : T[0] extends IfStatement> - ? InferBlock>, S> extends infer J - ? Concat>> extends infer G - ? InferBlock, S, Cast>> - : never - : never - : InferBlock, S, R>; +// type InferFunctionParams< +// T extends Array, +// R extends Array = [], +// G = {}, +// > = T extends [] +// ? [Reverse, G] +// : T[0] extends Identifier> +// ? InferFunctionParams< +// Tail, +// Unshift>, +// MergeWithOverride< +// G, +// { [a in Cast]: MapTypeAnnotationToType } +// > +// > +// : never; -type CheckBlock< - T extends Array, - S extends {} = {}, -> = T[0] extends ExpressionStatement - ? InferExpression - : T[0] extends BlockStatement - ? InferBlock>, S> - : []; +// type InferBlock< +// T extends Array, +// S extends {}, +// R extends Array = [], +// > = T extends [] +// ? Unshift +// : T[0] extends ReturnStatement +// ? InferExpression extends infer G +// ? G extends Array +// ? Concat>> +// : Unshift +// : never +// : T[0] extends VariableDeclaration< +// [VariableDeclarator, infer I>], +// any +// > +// ? InferBlock< +// Tail, +// MergeWithOverride]: InferExpression }>, +// R +// > +// : T[0] extends FunctionDeclaration< +// Identifier, +// infer P, +// BlockStatement +// > +// ? InferFunctionParams>> extends infer O +// ? InferBlock< +// Tail, +// MergeWithOverride< +// S, +// { +// [a in Cast]: FunctionType< +// Cast>[0], +// InferBlock< +// Cast>, +// MergeWithOverride>[1]> +// > +// >; +// } +// >, +// R +// > +// : never +// : T[0] extends IfStatement> +// ? InferBlock>, S> extends infer J +// ? Concat>> extends infer G +// ? InferBlock, S, Cast>> +// : never +// : never +// : InferBlock, S, R>; + +// type CheckBlock< +// T extends Array, +// S extends {} = {}, +// > = T[0] extends ExpressionStatement +// ? InferExpression +// : T[0] extends BlockStatement +// ? InferBlock>, S> +// : []; diff --git a/src/index.ts b/src/index.ts index c4a6784..a21d708 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ import type { Tokenize } from './tokenizer'; -// import type { Parse } from './parser'; +import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`"hello`>; -// type R = Parse[0]['body']; +type T = Tokenize<`hey`>; +type R = Parse; // type C = Check<[R]>; diff --git a/src/parser.ts b/src/parser.ts index cbd348b..fafa137 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -1,45 +1,44 @@ -export {}; - -// import type { -// ArrayExpression, -// BooleanLiteral, -// NumericLiteral, -// ObjectExpression, -// StringLiteral, -// ObjectProperty, -// VariableDeclaration, -// VariableDeclarator, -// FunctionDeclaration, -// Identifier, -// NullLiteral, -// ExpressionStatement, -// CallExpression, -// MemberExpression, -// IfStatement, -// ReturnStatement, -// BlockStatement, -// TypeAnnotation, -// GenericTypeAnnotation, -// StringTypeAnnotation, -// BooleanTypeAnnotation, -// NullLiteralTypeAnnotation, -// NumberTypeAnnotation, -// AnyTypeAnnotation, -// } from './ast'; -// import type { -// BracketToken, -// ColonToken, -// CommaToken, -// CurlyToken, -// DotToken, -// NumberToken, -// ParenToken, -// StringToken, -// SymbolToken, -// Token, -// } from './tokens'; -// import type { Reverse, Tail, Unshift } from './utils/arrayUtils'; -// import type { Cast } from './utils/generalUtils'; +import type { + ArrayExpression, + BooleanLiteral, + NumericLiteral, + ObjectExpression, + StringLiteral, + ObjectProperty, + VariableDeclaration, + VariableDeclarator, + FunctionDeclaration, + Identifier, + NullLiteral, + ExpressionStatement, + CallExpression, + MemberExpression, + IfStatement, + ReturnStatement, + BlockStatement, + TypeAnnotation, + GenericTypeAnnotation, + StringTypeAnnotation, + BooleanTypeAnnotation, + NullLiteralTypeAnnotation, + NumberTypeAnnotation, + AnyTypeAnnotation, + NodeData, +} from './ast'; +import type { + BracketToken, + ColonToken, + CommaToken, + CurlyToken, + DotToken, + NumberToken, + ParenToken, + StringToken, + SymbolToken, + Token, +} from './tokens'; +import type { Push, Reverse, Tail, Unshift } from './utils/arrayUtils'; +import type { Cast } from './utils/generalUtils'; // type Wrap>]> = T[1][0] extends DotToken // ? T[1][1] extends SymbolToken @@ -305,14 +304,56 @@ export {}; // ? ParseArray>[1], Unshift>[0]>, true> // : never; -// type ParseSequence< -// T extends Array>, -// R extends Array = [], -// > = T extends [] -// ? R -// : ParseStatement extends infer P -// ? ParseSequence>[1], Unshift>[0]>> -// : never; +// F extends SymbolToken<'const'> +// ? ParseVariableDeclaration> +// : F extends SymbolToken<'function'> +// ? ParseFunctionDeclaration> +// : F extends SymbolToken<'if'> +// ? ParseIfStatement> +// : ParseExpression extends infer G +// ? [ExpressionStatement>[0]>, Cast>[1]] +// : never + +type ExtractTokenData> = T extends Token + ? { + startLineNumber: D['lineNumber']; + endLineNumber: D['lineNumber']; + } + : never; + +type ParseExpression< + T extends Array>, + F extends Token, + G extends Array> = Tail, + H extends NodeData = ExtractTokenData, +> = F extends SymbolToken<'true', any> + ? [BooleanLiteral, G] + : F extends SymbolToken<'false', any> + ? [BooleanLiteral, G] + : F extends SymbolToken<'null', any> + ? [NullLiteral, G] + : F extends NumberToken + ? [NumericLiteral, G] + : F extends StringToken + ? [StringLiteral, G] + : F extends SymbolToken + ? [Identifier, G] + : never; + +type ParseTopLevelStatement< + T extends Array>, + F extends Token = T[0], +> = ParseExpression; + +type ParseSequence< + T extends Array>, + R extends Array = [], +> = T extends [] + ? R + : ParseTopLevelStatement extends infer P + ? P extends Array + ? ParseSequence> + : never + : never; -// export type Parse>> = -// ParseSequence extends infer P ? Reverse>> : never; +export type Parse>> = ParseSequence; diff --git a/src/tokenizer.ts b/src/tokenizer.ts index 70614d7..8a3c74e 100644 --- a/src/tokenizer.ts +++ b/src/tokenizer.ts @@ -90,7 +90,7 @@ type TokenizeSymbol< export type TokenizeSequence< I extends string, - R extends Array>, + R extends Array>, L extends number, G extends boolean, F extends string = FirstChar, diff --git a/src/tokens.ts b/src/tokens.ts index 313d32c..224b4e3 100644 --- a/src/tokens.ts +++ b/src/tokens.ts @@ -3,70 +3,70 @@ export type TokenData = { lineNumber: number; }; -export type ParenToken = { +export type ParenToken = { type: 'paren'; value: V; data: D; }; -export type BracketToken = { +export type BracketToken = { type: 'bracket'; value: V; data: D; }; -export type CurlyToken = { +export type CurlyToken = { type: 'curly'; value: V; data: D; }; -export type DotToken = { +export type DotToken = { type: 'dot'; data: D; }; -export type SemicolonToken = { +export type SemicolonToken = { type: 'semicolon'; data: D; }; -export type ColonToken = { +export type ColonToken = { type: 'colon'; data: D; }; -export type NumberToken = { +export type NumberToken = { type: 'number'; value: V; - data: T; + data: D; }; -export type StringToken = { +export type StringToken = { type: 'string'; value: V; - data: T; + data: D; }; -export type SymbolToken = { +export type SymbolToken = { type: 'symbol'; value: V; - data: T; + data: D; }; -export type CommaToken = { +export type CommaToken = { type: 'comma'; data: D; }; -export type Token = - | NumberToken - | BracketToken - | StringToken - | SymbolToken - | ParenToken - | CurlyToken - | DotToken - | SemicolonToken - | ColonToken - | CommaToken; +export type Token = + | NumberToken + | BracketToken + | StringToken + | SymbolToken + | ParenToken + | CurlyToken + | DotToken + | SemicolonToken + | ColonToken + | CommaToken; From 2fbcdaef967cbae3ac2fe0aae7bf4d5aa8b2305d Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 5 Jul 2022 00:10:11 +0300 Subject: [PATCH 096/286] wip --- src/index.ts | 2 +- src/parser.ts | 11 ++++++++--- src/utils/generalUtils.ts | 8 +++----- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/index.ts b/src/index.ts index a21d708..15e4280 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`hey`>; +type T = Tokenize<`hey\nho`>; type R = Parse; // type C = Check<[R]>; diff --git a/src/parser.ts b/src/parser.ts index fafa137..12e44af 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -38,7 +38,7 @@ import type { Token, } from './tokens'; import type { Push, Reverse, Tail, Unshift } from './utils/arrayUtils'; -import type { Cast } from './utils/generalUtils'; +import type { Cast, IsNever } from './utils/generalUtils'; // type Wrap>]> = T[1][0] extends DotToken // ? T[1][1] extends SymbolToken @@ -324,8 +324,8 @@ type ExtractTokenData> = T extends Token type ParseExpression< T extends Array>, F extends Token, - G extends Array> = Tail, H extends NodeData = ExtractTokenData, + G extends Array> = Tail, > = F extends SymbolToken<'true', any> ? [BooleanLiteral, G] : F extends SymbolToken<'false', any> @@ -343,7 +343,12 @@ type ParseExpression< type ParseTopLevelStatement< T extends Array>, F extends Token = T[0], -> = ParseExpression; + H extends NodeData = ExtractTokenData, +> = ParseExpression extends infer G + ? G extends Array + ? [ExpressionStatement, G[1]] + : never + : never; type ParseSequence< T extends Array>, diff --git a/src/utils/generalUtils.ts b/src/utils/generalUtils.ts index a1a5570..00ef656 100644 --- a/src/utils/generalUtils.ts +++ b/src/utils/generalUtils.ts @@ -68,8 +68,6 @@ export type Symbols = | '8' | '9' | '_' - | '-' - | '+' - | '=' - | '|' - | '&'; + | '$'; + +export type IsNever = [T] extends [never] ? true : false; From 023def73cd3f21b51093106ee5b293596453cb40 Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 5 Jul 2022 00:10:41 +0300 Subject: [PATCH 097/286] wip --- src/parser.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 12e44af..dfc7d62 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -352,7 +352,7 @@ type ParseTopLevelStatement< type ParseSequence< T extends Array>, - R extends Array = [], + R extends Array, > = T extends [] ? R : ParseTopLevelStatement extends infer P @@ -361,4 +361,4 @@ type ParseSequence< : never : never; -export type Parse>> = ParseSequence; +export type Parse>> = ParseSequence; From 1a644a0ee72d79f541be29517ea59383c0c2bb3e Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 5 Jul 2022 00:30:06 +0300 Subject: [PATCH 098/286] wip --- src/errors.ts | 8 ++++++-- src/index.ts | 2 +- src/parser.ts | 32 +++++++++++++++++++++++++++----- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/errors.ts b/src/errors.ts index 0d5ed0e..b1b521d 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -1,7 +1,11 @@ -export type Error = { +export type Error = { type: T; message: M; lineNumber: L; }; -export type SyntaxError = Error<'SyntaxError', T, L>; +export type SyntaxError = Error< + 'SyntaxError', + M, + L +>; diff --git a/src/index.ts b/src/index.ts index 15e4280..a21d708 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`hey\nho`>; +type T = Tokenize<`hey`>; type R = Parse; // type C = Check<[R]>; diff --git a/src/parser.ts b/src/parser.ts index dfc7d62..66241aa 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -25,6 +25,7 @@ import type { AnyTypeAnnotation, NodeData, } from './ast'; +import type { SyntaxError } from './errors'; import type { BracketToken, ColonToken, @@ -33,6 +34,7 @@ import type { DotToken, NumberToken, ParenToken, + SemicolonToken, StringToken, SymbolToken, Token, @@ -342,7 +344,7 @@ type ParseExpression< type ParseTopLevelStatement< T extends Array>, - F extends Token = T[0], + F extends Token, H extends NodeData = ExtractTokenData, > = ParseExpression extends infer G ? G extends Array @@ -350,15 +352,35 @@ type ParseTopLevelStatement< : never : never; -type ParseSequence< +type ParseTopLevel< T extends Array>, R extends Array, + N extends boolean, + F extends Token = T[0], > = T extends [] ? R - : ParseTopLevelStatement extends infer P + : F extends SemicolonToken + ? ParseTopLevel, R, false> + : N extends false + ? ParseSequenceHelper + : F extends Token + ? D['precedingLinebreak'] extends true + ? ParseSequenceHelper + : SyntaxError<"';' expected.", D['lineNumber']> + : never; + +type ParseSequenceHelper< + T extends Array>, + R extends Array, + F extends Token = T[0], +> = ParseTopLevelStatement extends infer P ? P extends Array - ? ParseSequence> + ? ParseTopLevel, true> : never : never; -export type Parse>> = ParseSequence; +export type Parse>> = ParseTopLevel< + T, + [], + false +>; From 5b529906083a30bf3d0d667cff528c5804953967 Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 5 Jul 2022 00:37:49 +0300 Subject: [PATCH 099/286] wip --- src/test/parser.test.ts | 279 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 261 insertions(+), 18 deletions(-) diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index a1945cc..922f028 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -1,21 +1,264 @@ -export {}; - -// import type { Tokenize } from '../tokenizer'; -// import type { Parse } from '../parser'; -// import type { Cast } from '../utils/generalUtils'; - -// const expectType = (value: T) => {}; - -// type ParseAst = Tokenize extends infer G -// ? Parse>> -// : never; - -// expectType>([ -// { -// type: 'ExpressionStatement', -// expression: { type: 'Identifier', name: 'hello' }, -// }, -// ]); +import type { Tokenize } from '../tokenizer'; +import type { Parse } from '../parser'; +import type { Cast } from '../utils/generalUtils'; + +const expectType = (value: T) => {}; + +type ParseAst = Tokenize extends infer G + ? Parse>> + : never; + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'StringLiteral', + value: 'hello', + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'NumericLiteral', + value: '123', + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'BooleanLiteral', + value: true, + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'BooleanLiteral', + value: false, + data: { startLineNumber: 2, endLineNumber: 2 }, + }, + data: { + startLineNumber: 2, + endLineNumber: 2, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'NullLiteral', + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'NullLiteral', + data: { startLineNumber: 3, endLineNumber: 3 }, + }, + data: { + startLineNumber: 3, + endLineNumber: 3, + }, + }, +]); + +expectType>({ + type: 'SyntaxError', + message: "';' expected.", + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: "';' expected.", + lineNumber: 1, +}); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + { + type: 'ExpressionStatement', + expression: { + type: 'StringLiteral', + value: 'world', + data: { + startLineNumber: 2, + endLineNumber: 2, + }, + }, + data: { + startLineNumber: 2, + endLineNumber: 2, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + { + type: 'ExpressionStatement', + expression: { + type: 'StringLiteral', + value: 'world', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + { + type: 'ExpressionStatement', + expression: { + type: 'StringLiteral', + value: 'world', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + { + type: 'ExpressionStatement', + expression: { + type: 'StringLiteral', + value: 'world', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); // expectType>([ // { From 64abfff7f5819944194a237efca50159ab6b3dfe Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 5 Jul 2022 01:10:57 +0300 Subject: [PATCH 100/286] wip --- src/index.ts | 2 +- src/parser.ts | 67 ++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/src/index.ts b/src/index.ts index a21d708..32eb2d6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`hey`>; +type T = Tokenize<`if`>; type R = Parse; // type C = Check<[R]>; diff --git a/src/parser.ts b/src/parser.ts index 66241aa..c0bbfba 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -25,7 +25,7 @@ import type { AnyTypeAnnotation, NodeData, } from './ast'; -import type { SyntaxError } from './errors'; +import type { Error, SyntaxError } from './errors'; import type { BracketToken, ColonToken, @@ -306,16 +306,6 @@ import type { Cast, IsNever } from './utils/generalUtils'; // ? ParseArray>[1], Unshift>[0]>, true> // : never; -// F extends SymbolToken<'const'> -// ? ParseVariableDeclaration> -// : F extends SymbolToken<'function'> -// ? ParseFunctionDeclaration> -// : F extends SymbolToken<'if'> -// ? ParseIfStatement> -// : ParseExpression extends infer G -// ? [ExpressionStatement>[0]>, Cast>[1]] -// : never - type ExtractTokenData> = T extends Token ? { startLineNumber: D['lineNumber']; @@ -323,6 +313,37 @@ type ExtractTokenData> = T extends Token } : never; +// type ParseIfStatement>> = +// T[0] extends ParenToken<'('> +// ? ParseExpression> extends infer G +// ? Cast>[1] extends infer J +// ? Cast>[0] extends ParenToken<')'> +// ? Cast>[1] extends CurlyToken<'{'> +// ? ParseBlockStatement< +// Tail>>> +// > extends infer B +// ? [ +// IfStatement>[0], Cast>[0]>, +// Cast>[1], +// ] +// : never +// : never +// : never +// : never +// : never +// : never; + +type ParseIfStatement< + T extends Array>, + F extends Token, + H extends NodeData = ExtractTokenData, + G extends Array> = Tail, +> = F extends SymbolToken<'if', any> + ? T[1] extends SymbolToken<'(', any> + ? [1, []] + : SyntaxError<"'(' expected.", H['startLineNumber']> + : null; + type ParseExpression< T extends Array>, F extends Token, @@ -340,16 +361,16 @@ type ParseExpression< ? [StringLiteral, G] : F extends SymbolToken ? [Identifier, G] - : never; + : null; -type ParseTopLevelStatement< +type ParseExpressionStatement< T extends Array>, F extends Token, H extends NodeData = ExtractTokenData, > = ParseExpression extends infer G ? G extends Array ? [ExpressionStatement, G[1]] - : never + : null : never; type ParseTopLevel< @@ -362,20 +383,28 @@ type ParseTopLevel< : F extends SemicolonToken ? ParseTopLevel, R, false> : N extends false - ? ParseSequenceHelper + ? ParseTopLevelHelper : F extends Token ? D['precedingLinebreak'] extends true - ? ParseSequenceHelper + ? ParseTopLevelHelper : SyntaxError<"';' expected.", D['lineNumber']> : never; -type ParseSequenceHelper< +type ParseTopLevelHelper< T extends Array>, R extends Array, F extends Token = T[0], -> = ParseTopLevelStatement extends infer P +> = ParseIfStatement extends infer P ? P extends Array - ? ParseTopLevel, true> + ? ParseTopLevel, false> + : P extends Error + ? P + : ParseExpressionStatement extends infer P + ? P extends Array + ? ParseTopLevel, true> + : P extends Error + ? P + : never : never : never; From 293d0c51763c968456f80971dee655e89cb69562 Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 5 Jul 2022 01:50:51 +0300 Subject: [PATCH 101/286] wip --- src/index.ts | 2 +- src/parser.ts | 91 ++++++++++++++++++++++++--------------- src/utils/arrayUtils.ts | 10 ++++- src/utils/generalUtils.ts | 3 +- 4 files changed, 67 insertions(+), 39 deletions(-) diff --git a/src/index.ts b/src/index.ts index 32eb2d6..093ec12 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`if`>; +type T = Tokenize<`const aaa = "123"`>; type R = Parse; // type C = Check<[R]>; diff --git a/src/parser.ts b/src/parser.ts index c0bbfba..5428ad6 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -306,47 +306,68 @@ import type { Cast, IsNever } from './utils/generalUtils'; // ? ParseArray>[1], Unshift>[0]>, true> // : never; -type ExtractTokenData> = T extends Token - ? { - startLineNumber: D['lineNumber']; - endLineNumber: D['lineNumber']; - } +type ExtractTokenData< + T extends Token, + R extends Token = T, +> = T extends Token + ? R extends Token + ? { + startLineNumber: D['lineNumber']; + endLineNumber: H['lineNumber']; + } + : never : never; -// type ParseIfStatement>> = -// T[0] extends ParenToken<'('> -// ? ParseExpression> extends infer G -// ? Cast>[1] extends infer J -// ? Cast>[0] extends ParenToken<')'> -// ? Cast>[1] extends CurlyToken<'{'> -// ? ParseBlockStatement< -// Tail>>> -// > extends infer B -// ? [ -// IfStatement>[0], Cast>[0]>, -// Cast>[1], -// ] -// : never -// : never -// : never -// : never -// : never -// : never; - -type ParseIfStatement< +type ParseVariableDeclaration< T extends Array>, F extends Token, - H extends NodeData = ExtractTokenData, - G extends Array> = Tail, -> = F extends SymbolToken<'if', any> - ? T[1] extends SymbolToken<'(', any> - ? [1, []] - : SyntaxError<"'(' expected.", H['startLineNumber']> +> = F extends SymbolToken<'const', infer F_> + ? T[1] extends SymbolToken + ? T[2] extends SymbolToken<'=', infer K_> + ? ParseExpression>>> extends infer L + ? L extends Array + ? [ + VariableDeclaration< + [ + VariableDeclarator< + Identifier< + N, + null, + { + startLineNumber: N_['lineNumber']; + endLineNumber: N_['lineNumber']; + } + >, + L[0], + { + startLineNumber: N_['lineNumber']; + endLineNumber: L[0]['data']['endLineNumber']; + } + >, + ], + 'const', + { + startLineNumber: F_['lineNumber']; + endLineNumber: L[0]['data']['endLineNumber']; + } + >, + L[1], + ] + : SyntaxError<'Expression expected.', K_['lineNumber']> + : never + : SyntaxError< + "'const' declarations must be initialized.", + N_['lineNumber'] + > + : SyntaxError< + 'Variable declaration list cannot be empty.', + F_['lineNumber'] + > : null; type ParseExpression< T extends Array>, - F extends Token, + F extends Token = T[0], H extends NodeData = ExtractTokenData, G extends Array> = Tail, > = F extends SymbolToken<'true', any> @@ -394,9 +415,9 @@ type ParseTopLevelHelper< T extends Array>, R extends Array, F extends Token = T[0], -> = ParseIfStatement extends infer P +> = ParseVariableDeclaration extends infer P ? P extends Array - ? ParseTopLevel, false> + ? ParseTopLevel, true> : P extends Error ? P : ParseExpressionStatement extends infer P diff --git a/src/utils/arrayUtils.ts b/src/utils/arrayUtils.ts index 71c318d..c703a25 100644 --- a/src/utils/arrayUtils.ts +++ b/src/utils/arrayUtils.ts @@ -1,5 +1,3 @@ -import type { Cast } from './generalUtils'; - export type Tail> = ((...t: T) => void) extends ( h: any, ...rest: infer R @@ -29,3 +27,11 @@ export type Concat, T2 extends Array> = [ ...T1, ...T2, ]; + +export type TailBy< + T extends Array, + B extends any, + A extends Array = [], +> = B extends A['length'] ? T : TailBy, B, Push>; + +type R = TailBy<[1, 2, 3, 4, 5], 2>; diff --git a/src/utils/generalUtils.ts b/src/utils/generalUtils.ts index 00ef656..02feaa7 100644 --- a/src/utils/generalUtils.ts +++ b/src/utils/generalUtils.ts @@ -68,6 +68,7 @@ export type Symbols = | '8' | '9' | '_' - | '$'; + | '$' + | '='; export type IsNever = [T] extends [never] ? true : false; From a4ba2f8f7f85426f22c5d4cc255fcd21d198b4b8 Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 5 Jul 2022 01:53:16 +0300 Subject: [PATCH 102/286] wip --- src/utils/arrayUtils.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/utils/arrayUtils.ts b/src/utils/arrayUtils.ts index c703a25..f51c51b 100644 --- a/src/utils/arrayUtils.ts +++ b/src/utils/arrayUtils.ts @@ -30,8 +30,6 @@ export type Concat, T2 extends Array> = [ export type TailBy< T extends Array, - B extends any, + B extends number, A extends Array = [], > = B extends A['length'] ? T : TailBy, B, Push>; - -type R = TailBy<[1, 2, 3, 4, 5], 2>; From 0683f2bd59dd721c0d3fc1da9140fef9f6980e4c Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 5 Jul 2022 21:07:40 +0300 Subject: [PATCH 103/286] wip --- src/index.ts | 2 +- src/test/parser.test.ts | 3 +-- src/test/tokenizer.test.ts | 3 +-- src/test/utils.ts | 1 + 4 files changed, 4 insertions(+), 5 deletions(-) create mode 100644 src/test/utils.ts diff --git a/src/index.ts b/src/index.ts index 093ec12..889b740 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`const aaa = "123"`>; +type T = Tokenize<`"hello"`>; type R = Parse; // type C = Check<[R]>; diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index 922f028..b5dd6c1 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -1,8 +1,7 @@ import type { Tokenize } from '../tokenizer'; import type { Parse } from '../parser'; import type { Cast } from '../utils/generalUtils'; - -const expectType = (value: T) => {}; +import { expectType } from './utils'; type ParseAst = Tokenize extends infer G ? Parse>> diff --git a/src/test/tokenizer.test.ts b/src/test/tokenizer.test.ts index e358ad7..d171458 100644 --- a/src/test/tokenizer.test.ts +++ b/src/test/tokenizer.test.ts @@ -1,6 +1,5 @@ import type { Tokenize } from '../tokenizer'; - -const expectType = (value: T) => {}; +import { expectType } from './utils'; expectType>([ { diff --git a/src/test/utils.ts b/src/test/utils.ts new file mode 100644 index 0000000..2916b9e --- /dev/null +++ b/src/test/utils.ts @@ -0,0 +1 @@ +export const expectType = (_: T): any => {}; From 84a6d1ff573155336cc2690e53faf37fe311d318 Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 5 Jul 2022 23:55:26 +0300 Subject: [PATCH 104/286] wip --- src/ast.ts | 81 ++++++++++++++++++------------ src/index.ts | 2 +- src/parser.ts | 90 +++++++++++++++------------------ src/test/parser.test.ts | 107 +++++++++++++++++++++++++++++----------- src/tokenizer.ts | 8 +-- src/tokens.ts | 28 +++++------ 6 files changed, 189 insertions(+), 127 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index 73aa19e..5ae3c70 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -1,39 +1,44 @@ -export type NodeData = { - startLineNumber: number; - endLineNumber: number; +export type NodeData = { + startLineNumber: S; + endLineNumber: E; }; -export type NumericLiteral = { +export type NullLiteral> = { + type: 'NullLiteral'; + data: D; +}; + +export type NumericLiteral> = { type: 'NumericLiteral'; value: T; data: D; }; -export type BooleanLiteral = { +export type BooleanLiteral> = { type: 'BooleanLiteral'; value: T; data: D; }; -export type StringLiteral = { +export type StringLiteral> = { type: 'StringLiteral'; value: T; data: D; }; -export type ArrayExpression = { +export type ArrayExpression> = { type: 'ArrayExpression'; elements: T; data: D; }; -export type ObjectExpression = { +export type ObjectExpression> = { type: 'ObjectExpression'; properties: T; data: D; }; -export type ObjectProperty = { +export type ObjectProperty> = { type: 'ObjectProperty'; key: K; value: T; @@ -43,7 +48,7 @@ export type ObjectProperty = { export type VariableDeclaration< H, K extends 'const' | 'let', - D extends NodeData, + D extends NodeData, > = { type: 'VariableDeclaration'; declarations: H; @@ -51,14 +56,14 @@ export type VariableDeclaration< data: D; }; -export type VariableDeclarator = { +export type VariableDeclarator> = { type: 'VariableDeclarator'; id: N; init: I; data: D; }; -export type FunctionDeclaration = { +export type FunctionDeclaration> = { type: 'FunctionDeclaration'; id: I; params: P; @@ -66,39 +71,34 @@ export type FunctionDeclaration = { data: D; }; -export type Identifier = { +export type Identifier> = { type: 'Identifier'; name: N; typeAnnotation: T; data: D; }; -export type NullLiteral = { - type: 'NullLiteral'; - data: D; -}; - -export type ExpressionStatement = { +export type ExpressionStatement> = { type: 'ExpressionStatement'; expression: E; data: D; }; -export type CallExpression = { +export type CallExpression> = { type: 'CallExpression'; callee: C; arguments: A; data: D; }; -export type MemberExpression = { +export type MemberExpression> = { type: 'MemberExpression'; object: O; property: P; data: D; }; -export type IfStatement = { +export type IfStatement> = { type: 'IfStatement'; test: T; consequent: C; @@ -106,51 +106,70 @@ export type IfStatement = { // alternate: A; }; -export type ReturnStatement = { +export type ReturnStatement> = { type: 'ReturnStatement'; argument: T; data: D; }; -export type BlockStatement = { +export type BlockStatement> = { type: 'BlockStatement'; body: B; data: D; }; -export type TypeAnnotation = { +export type TypeAnnotation> = { type: 'TypeAnnotation'; typeAnnotation: T; data: D; }; -export type StringTypeAnnotation = { +export type StringTypeAnnotation> = { type: 'StringTypeAnnotation'; data: D; }; -export type NumberTypeAnnotation = { +export type NumberTypeAnnotation> = { type: 'NumberTypeAnnotation'; data: D; }; -export type NullLiteralTypeAnnotation = { +export type NullLiteralTypeAnnotation> = { type: 'NullLiteralTypeAnnotation'; data: D; }; -export type BooleanTypeAnnotation = { +export type BooleanTypeAnnotation> = { type: 'BooleanTypeAnnotation'; data: D; }; -export type GenericTypeAnnotation = { +export type GenericTypeAnnotation> = { type: 'GenericTypeAnnotation'; id: I; data: D; }; -export type AnyTypeAnnotation = { +export type AnyTypeAnnotation> = { type: 'AnyTypeAnnotation'; data: D; }; + +export type Node> = + | NumericLiteral + | BooleanLiteral + | StringLiteral + | ArrayExpression + | ObjectExpression + | ObjectProperty + | VariableDeclaration + | VariableDeclarator + | FunctionDeclaration + | Identifier + | NullLiteral + | ExpressionStatement + | CallExpression + | MemberExpression + | IfStatement + | ReturnStatement + | BlockStatement; diff --git a/src/index.ts b/src/index.ts index 889b740..093ec12 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`"hello"`>; +type T = Tokenize<`const aaa = "123"`>; type R = Parse; // type C = Check<[R]>; diff --git a/src/parser.ts b/src/parser.ts index 5428ad6..85ff543 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -24,6 +24,7 @@ import type { NumberTypeAnnotation, AnyTypeAnnotation, NodeData, + Node, } from './ast'; import type { Error, SyntaxError } from './errors'; import type { @@ -38,8 +39,9 @@ import type { StringToken, SymbolToken, Token, + TokenData, } from './tokens'; -import type { Push, Reverse, Tail, Unshift } from './utils/arrayUtils'; +import type { Push, Reverse, Tail, TailBy, Unshift } from './utils/arrayUtils'; import type { Cast, IsNever } from './utils/generalUtils'; // type Wrap>]> = T[1][0] extends DotToken @@ -311,64 +313,54 @@ type ExtractTokenData< R extends Token = T, > = T extends Token ? R extends Token - ? { - startLineNumber: D['lineNumber']; - endLineNumber: H['lineNumber']; - } + ? NodeData : never : never; +type ParseVariableDeclarationHelper< + T extends Array>, + N extends string, + NL extends number, + FL extends number, + K extends Node, +> = K extends Node> + ? [ + VariableDeclaration< + [ + VariableDeclarator< + Identifier>, + K, + NodeData + >, + ], + 'const', + NodeData + >, + T, + ] + : never; + type ParseVariableDeclaration< T extends Array>, F extends Token, -> = F extends SymbolToken<'const', infer F_> - ? T[1] extends SymbolToken - ? T[2] extends SymbolToken<'=', infer K_> - ? ParseExpression>>> extends infer L - ? L extends Array - ? [ - VariableDeclaration< - [ - VariableDeclarator< - Identifier< - N, - null, - { - startLineNumber: N_['lineNumber']; - endLineNumber: N_['lineNumber']; - } - >, - L[0], - { - startLineNumber: N_['lineNumber']; - endLineNumber: L[0]['data']['endLineNumber']; - } - >, - ], - 'const', - { - startLineNumber: F_['lineNumber']; - endLineNumber: L[0]['data']['endLineNumber']; - } - >, - L[1], - ] - : SyntaxError<'Expression expected.', K_['lineNumber']> - : never - : SyntaxError< - "'const' declarations must be initialized.", - N_['lineNumber'] - > - : SyntaxError< - 'Variable declaration list cannot be empty.', - F_['lineNumber'] - > +> = F extends SymbolToken<'const', TokenData> + ? T[1] extends SymbolToken> + ? T[2] extends SymbolToken<'=', TokenData> + ? ParseExpression> extends [infer L, infer T] + ? T extends Array + ? L extends Node + ? ParseVariableDeclarationHelper + : never + : never + : SyntaxError<'Expression expected.', KL> + : SyntaxError<"'const' declarations must be initialized.", NL> + : SyntaxError<'Variable declaration list cannot be empty.', FL> : null; type ParseExpression< T extends Array>, F extends Token = T[0], - H extends NodeData = ExtractTokenData, + H extends NodeData = ExtractTokenData, G extends Array> = Tail, > = F extends SymbolToken<'true', any> ? [BooleanLiteral, G] @@ -387,7 +379,7 @@ type ParseExpression< type ParseExpressionStatement< T extends Array>, F extends Token, - H extends NodeData = ExtractTokenData, + H extends NodeData = ExtractTokenData, > = ParseExpression extends infer G ? G extends Array ? [ExpressionStatement, G[1]] diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index b5dd6c1..0912704 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -258,6 +258,85 @@ expectType>([ }, }, ]); +expectType>([ + { + type: 'VariableDeclaration', + kind: 'const', + declarations: [ + { + type: 'VariableDeclarator', + init: { + type: 'StringLiteral', + value: 'world', + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + id: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'VariableDeclaration', + kind: 'const', + declarations: [ + { + type: 'VariableDeclarator', + init: { + type: 'NumericLiteral', + value: '123', + data: { startLineNumber: 5, endLineNumber: 5 }, + }, + id: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { startLineNumber: 3, endLineNumber: 3 }, + }, + data: { startLineNumber: 3, endLineNumber: 5 }, + }, + ], + data: { startLineNumber: 2, endLineNumber: 5 }, + }, +]); + +expectType>({ + type: 'SyntaxError', + message: 'Variable declaration list cannot be empty.', + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: "'const' declarations must be initialized.", + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: 'Expression expected.', + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: 'Expression expected.', + lineNumber: 2, +}); // expectType>([ // { @@ -632,34 +711,6 @@ expectType>([ // }, // ]); -// expectType>([ -// { -// type: 'VariableDeclaration', -// kind: 'const', -// declarations: [ -// { -// type: 'VariableDeclarator', -// init: { type: 'StringLiteral', value: 'world' }, -// id: { type: 'Identifier', name: 'hello' }, -// }, -// ], -// }, -// ]); - -// expectType>([ -// { -// type: 'VariableDeclaration', -// kind: 'const', -// declarations: [ -// { -// type: 'VariableDeclarator', -// init: { type: 'NumericLiteral', value: '123' }, -// id: { type: 'Identifier', name: 'hello' }, -// }, -// ], -// }, -// ]); - // expectType>([ // { // type: 'VariableDeclaration', diff --git a/src/tokenizer.ts b/src/tokenizer.ts index 8a3c74e..e744cb2 100644 --- a/src/tokenizer.ts +++ b/src/tokenizer.ts @@ -29,7 +29,7 @@ type TokenizeInput< E extends string, G extends boolean, L extends number, - D extends TokenData = { precedingLinebreak: G; lineNumber: L }, + D extends TokenData = TokenData, > = F extends ',' ? [CommaToken, E] : F extends '(' @@ -63,7 +63,7 @@ type TokenizeInput< type TokenizeNumber< I extends string, A extends string, - G extends TokenData, + G extends TokenData, C extends string = FirstChar, > = C extends Numbers ? TokenizeNumber, ConcatStrings, G> @@ -72,7 +72,7 @@ type TokenizeNumber< type TokenizeString< I, W extends '"' | "'", - G extends TokenData, + G extends TokenData, > = I extends `${infer H}${W}${infer J}` ? StringContains extends true ? SyntaxError<'Unterminated string literal.', G['lineNumber']> @@ -82,7 +82,7 @@ type TokenizeString< type TokenizeSymbol< I extends string, A extends string, - G extends TokenData, + G extends TokenData, C extends string = FirstChar, > = C extends Symbols ? TokenizeSymbol, ConcatStrings, G> diff --git a/src/tokens.ts b/src/tokens.ts index 224b4e3..78a6f33 100644 --- a/src/tokens.ts +++ b/src/tokens.ts @@ -1,65 +1,65 @@ -export type TokenData = { - precedingLinebreak: boolean; - lineNumber: number; +export type TokenData

= { + precedingLinebreak: P; + lineNumber: L; }; -export type ParenToken = { +export type ParenToken> = { type: 'paren'; value: V; data: D; }; -export type BracketToken = { +export type BracketToken> = { type: 'bracket'; value: V; data: D; }; -export type CurlyToken = { +export type CurlyToken> = { type: 'curly'; value: V; data: D; }; -export type DotToken = { +export type DotToken> = { type: 'dot'; data: D; }; -export type SemicolonToken = { +export type SemicolonToken> = { type: 'semicolon'; data: D; }; -export type ColonToken = { +export type ColonToken> = { type: 'colon'; data: D; }; -export type NumberToken = { +export type NumberToken> = { type: 'number'; value: V; data: D; }; -export type StringToken = { +export type StringToken> = { type: 'string'; value: V; data: D; }; -export type SymbolToken = { +export type SymbolToken> = { type: 'symbol'; value: V; data: D; }; -export type CommaToken = { +export type CommaToken> = { type: 'comma'; data: D; }; -export type Token = +export type Token> = | NumberToken | BracketToken | StringToken From cb393b7c060fceced395346289e87f0878a6204c Mon Sep 17 00:00:00 2001 From: ronami Date: Wed, 6 Jul 2022 00:08:28 +0300 Subject: [PATCH 105/286] wip --- src/ast.ts | 9 ++++++++- src/parser.ts | 48 ++++++++++++++++++++++-------------------------- src/tokenizer.ts | 2 +- src/tokens.ts | 14 +++++++------- 4 files changed, 38 insertions(+), 35 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index 5ae3c70..fbe3cf7 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -172,4 +172,11 @@ export type Node> = | MemberExpression | IfStatement | ReturnStatement - | BlockStatement; + | BlockStatement + | TypeAnnotation + | StringTypeAnnotation + | NumberTypeAnnotation + | NullLiteralTypeAnnotation + | BooleanTypeAnnotation + | GenericTypeAnnotation + | AnyTypeAnnotation; diff --git a/src/parser.ts b/src/parser.ts index 85ff543..a2411e3 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -309,16 +309,16 @@ import type { Cast, IsNever } from './utils/generalUtils'; // : never; type ExtractTokenData< - T extends Token, - R extends Token = T, -> = T extends Token - ? R extends Token - ? NodeData + T extends Token, + R extends Token = T, +> = T extends Token> + ? R extends Token> + ? NodeData : never : never; type ParseVariableDeclarationHelper< - T extends Array>, + T extends Array>, N extends string, NL extends number, FL extends number, @@ -341,13 +341,13 @@ type ParseVariableDeclarationHelper< : never; type ParseVariableDeclaration< - T extends Array>, - F extends Token, + T extends Array>, + F extends Token, > = F extends SymbolToken<'const', TokenData> ? T[1] extends SymbolToken> ? T[2] extends SymbolToken<'=', TokenData> ? ParseExpression> extends [infer L, infer T] - ? T extends Array + ? T extends Array> ? L extends Node ? ParseVariableDeclarationHelper : never @@ -358,10 +358,10 @@ type ParseVariableDeclaration< : null; type ParseExpression< - T extends Array>, - F extends Token = T[0], + T extends Array>, + F extends Token = T[0], H extends NodeData = ExtractTokenData, - G extends Array> = Tail, + G extends Array> = Tail, > = F extends SymbolToken<'true', any> ? [BooleanLiteral, G] : F extends SymbolToken<'false', any> @@ -377,8 +377,8 @@ type ParseExpression< : null; type ParseExpressionStatement< - T extends Array>, - F extends Token, + T extends Array>, + F extends Token, H extends NodeData = ExtractTokenData, > = ParseExpression extends infer G ? G extends Array @@ -387,26 +387,26 @@ type ParseExpressionStatement< : never; type ParseTopLevel< - T extends Array>, - R extends Array, + T extends Array>, + R extends Array>, N extends boolean, - F extends Token = T[0], + F extends Token = T[0], > = T extends [] ? R : F extends SemicolonToken ? ParseTopLevel, R, false> : N extends false ? ParseTopLevelHelper - : F extends Token + : F extends Token ? D['precedingLinebreak'] extends true ? ParseTopLevelHelper : SyntaxError<"';' expected.", D['lineNumber']> : never; type ParseTopLevelHelper< - T extends Array>, - R extends Array, - F extends Token = T[0], + T extends Array>, + R extends Array>, + F extends Token = T[0], > = ParseVariableDeclaration extends infer P ? P extends Array ? ParseTopLevel, true> @@ -421,8 +421,4 @@ type ParseTopLevelHelper< : never : never; -export type Parse>> = ParseTopLevel< - T, - [], - false ->; +export type Parse>> = ParseTopLevel; diff --git a/src/tokenizer.ts b/src/tokenizer.ts index e744cb2..bb00fd4 100644 --- a/src/tokenizer.ts +++ b/src/tokenizer.ts @@ -90,7 +90,7 @@ type TokenizeSymbol< export type TokenizeSequence< I extends string, - R extends Array>, + R extends Array>, L extends number, G extends boolean, F extends string = FirstChar, diff --git a/src/tokens.ts b/src/tokens.ts index 78a6f33..6543a35 100644 --- a/src/tokens.ts +++ b/src/tokens.ts @@ -59,13 +59,13 @@ export type CommaToken> = { data: D; }; -export type Token> = - | NumberToken - | BracketToken - | StringToken - | SymbolToken - | ParenToken - | CurlyToken +export type Token> = + | NumberToken + | BracketToken + | StringToken + | SymbolToken + | ParenToken + | CurlyToken | DotToken | SemicolonToken | ColonToken From 402c4d529435ecd8743fd9168fdc2ab7362f2c16 Mon Sep 17 00:00:00 2001 From: ronami Date: Wed, 6 Jul 2022 00:17:00 +0300 Subject: [PATCH 106/286] wip --- src/parser.ts | 72 +++++++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 39 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index a2411e3..3dcdf1f 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -318,18 +318,18 @@ type ExtractTokenData< : never; type ParseVariableDeclarationHelper< - T extends Array>, + L extends Node, N extends string, NL extends number, FL extends number, - K extends Node, -> = K extends Node> + T extends Array>, +> = L extends Node> ? [ VariableDeclaration< [ VariableDeclarator< Identifier>, - K, + L, NodeData >, ], @@ -340,47 +340,43 @@ type ParseVariableDeclarationHelper< ] : never; -type ParseVariableDeclaration< - T extends Array>, - F extends Token, -> = F extends SymbolToken<'const', TokenData> - ? T[1] extends SymbolToken> - ? T[2] extends SymbolToken<'=', TokenData> - ? ParseExpression> extends [infer L, infer T] - ? T extends Array> +type ParseVariableDeclaration>> = + T[0] extends SymbolToken<'const', TokenData> + ? T[1] extends SymbolToken> + ? T[2] extends SymbolToken<'=', TokenData> + ? ParseExpression> extends [infer L, infer T] ? L extends Node - ? ParseVariableDeclarationHelper + ? T extends Array> + ? ParseVariableDeclarationHelper + : never : never - : never - : SyntaxError<'Expression expected.', KL> - : SyntaxError<"'const' declarations must be initialized.", NL> - : SyntaxError<'Variable declaration list cannot be empty.', FL> - : null; + : SyntaxError<'Expression expected.', KL> + : SyntaxError<"'const' declarations must be initialized.", NL> + : SyntaxError<'Variable declaration list cannot be empty.', FL> + : null; type ParseExpression< T extends Array>, - F extends Token = T[0], - H extends NodeData = ExtractTokenData, + H extends NodeData = ExtractTokenData, G extends Array> = Tail, -> = F extends SymbolToken<'true', any> +> = T[0] extends SymbolToken<'true', any> ? [BooleanLiteral, G] - : F extends SymbolToken<'false', any> + : T[0] extends SymbolToken<'false', any> ? [BooleanLiteral, G] - : F extends SymbolToken<'null', any> + : T[0] extends SymbolToken<'null', any> ? [NullLiteral, G] - : F extends NumberToken + : T[0] extends NumberToken ? [NumericLiteral, G] - : F extends StringToken + : T[0] extends StringToken ? [StringLiteral, G] - : F extends SymbolToken + : T[0] extends SymbolToken ? [Identifier, G] : null; type ParseExpressionStatement< T extends Array>, - F extends Token, - H extends NodeData = ExtractTokenData, -> = ParseExpression extends infer G + H extends NodeData = ExtractTokenData, +> = ParseExpression extends infer G ? G extends Array ? [ExpressionStatement, G[1]] : null @@ -390,29 +386,27 @@ type ParseTopLevel< T extends Array>, R extends Array>, N extends boolean, - F extends Token = T[0], > = T extends [] ? R - : F extends SemicolonToken + : T[0] extends SemicolonToken ? ParseTopLevel, R, false> : N extends false - ? ParseTopLevelHelper - : F extends Token - ? D['precedingLinebreak'] extends true - ? ParseTopLevelHelper - : SyntaxError<"';' expected.", D['lineNumber']> + ? ParseTopLevelHelper + : T[0] extends Token> + ? P extends true + ? ParseTopLevelHelper + : SyntaxError<"';' expected.", L> : never; type ParseTopLevelHelper< T extends Array>, R extends Array>, - F extends Token = T[0], -> = ParseVariableDeclaration extends infer P +> = ParseVariableDeclaration extends infer P ? P extends Array ? ParseTopLevel, true> : P extends Error ? P - : ParseExpressionStatement extends infer P + : ParseExpressionStatement extends infer P ? P extends Array ? ParseTopLevel, true> : P extends Error From f69c054714ba990b0671b0ef59d1a03581f13ca6 Mon Sep 17 00:00:00 2001 From: ronami Date: Wed, 6 Jul 2022 22:00:26 +0300 Subject: [PATCH 107/286] wip --- src/index.ts | 2 +- src/parser.ts | 82 ++++++++++++++++++-- src/test/parser.test.ts | 161 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 236 insertions(+), 9 deletions(-) diff --git a/src/index.ts b/src/index.ts index 093ec12..5a6636a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`const aaa = "123"`>; +type T = Tokenize<`foo.`>; type R = Parse; // type C = Check<[R]>; diff --git a/src/parser.ts b/src/parser.ts index 3dcdf1f..f91df2e 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -355,10 +355,74 @@ type ParseVariableDeclaration>> = : SyntaxError<'Variable declaration list cannot be empty.', FL> : null; +// type ParseCallExpression>> = T[0] extends ParenToken< +// '(', +// any +// > +// ? T[1] +// : null; + +type ParseMemberExpression< + O extends Node, + T extends Array>, +> = T[0] extends DotToken> + ? T[1] extends SymbolToken> + ? O extends Node> + ? [ + MemberExpression< + O, + Identifier>, + NodeData + >, + TailBy, + ] + : never + : SyntaxError<'Identifier expected.', E> + : null; + +// T[1][0] extends DotToken +// ? T[1][1] extends SymbolToken +// ? Wrap<[MemberExpression>, Tail>]> +// : T +// : T[1][0] extends ParenToken<'('> +// ? ParseFunctionArguments> extends infer G +// ? Wrap< +// [CallExpression>[0]>, Cast>[1]] +// > +// : never +// : T; + +type CheckExpression< + O extends Node, + T extends Array>, +> = ParseMemberExpression extends infer G + ? G extends [infer O, infer T] + ? O extends Node + ? T extends Array> + ? CheckExpression + : never + : never + : G extends Error + ? G + : [O, T] + : never; + type ParseExpression< T extends Array>, H extends NodeData = ExtractTokenData, G extends Array> = Tail, +> = ParseExpressionHelper extends [infer O, infer T] + ? O extends Node + ? T extends Array> + ? CheckExpression + : never + : never + : null; + +type ParseExpressionHelper< + T extends Array>, + H extends NodeData = ExtractTokenData, + G extends Array> = Tail, > = T[0] extends SymbolToken<'true', any> ? [BooleanLiteral, G] : T[0] extends SymbolToken<'false', any> @@ -373,14 +437,16 @@ type ParseExpression< ? [Identifier, G] : null; -type ParseExpressionStatement< - T extends Array>, - H extends NodeData = ExtractTokenData, -> = ParseExpression extends infer G - ? G extends Array - ? [ExpressionStatement, G[1]] - : null - : never; +type ParseExpressionStatement>> = + ParseExpression extends infer G + ? G extends Array + ? G[0] extends Node + ? [ExpressionStatement, G[1]] + : never + : G extends Error + ? G + : null + : never; type ParseTopLevel< T extends Array>, diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index 0912704..24718f8 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -338,6 +338,167 @@ expectType>({ lineNumber: 2, }); +expectType>({ + type: 'SyntaxError', + message: 'Identifier expected.', + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: 'Identifier expected.', + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: 'Identifier expected.', + lineNumber: 2, +}); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + object: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + property: { + type: 'Identifier', + name: 'world', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + object: { + type: 'MemberExpression', + object: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + property: { + type: 'Identifier', + name: 'world', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + property: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + object: { + type: 'MemberExpression', + object: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + property: { + type: 'Identifier', + name: 'world', + typeAnnotation: null, + data: { + startLineNumber: 2, + endLineNumber: 2, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 2, + }, + }, + property: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 3, + endLineNumber: 3, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 3, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 3, + }, + }, +]); + +expectType>({ + type: 'SyntaxError', + message: 'Identifier expected.', + lineNumber: 2, +}); + // expectType>([ // { // type: 'ExpressionStatement', From 7e94e2359a493d0950fc1c16dcebd1d30938d118 Mon Sep 17 00:00:00 2001 From: ronami Date: Wed, 6 Jul 2022 22:01:56 +0300 Subject: [PATCH 108/286] wip --- src/parser.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index f91df2e..6a00642 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -41,8 +41,8 @@ import type { Token, TokenData, } from './tokens'; -import type { Push, Reverse, Tail, TailBy, Unshift } from './utils/arrayUtils'; -import type { Cast, IsNever } from './utils/generalUtils'; +import type { Push, Tail, TailBy } from './utils/arrayUtils'; +import type { IsNever } from './utils/generalUtils'; // type Wrap>]> = T[1][0] extends DotToken // ? T[1][1] extends SymbolToken From 73c6f394167f516ea79a009ba49977596a51b12b Mon Sep 17 00:00:00 2001 From: ronami Date: Wed, 6 Jul 2022 22:06:19 +0300 Subject: [PATCH 109/286] wip --- src/parser.ts | 7 ----- src/test/parser.test.ts | 60 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 6a00642..11d5e86 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -355,13 +355,6 @@ type ParseVariableDeclaration>> = : SyntaxError<'Variable declaration list cannot be empty.', FL> : null; -// type ParseCallExpression>> = T[0] extends ParenToken< -// '(', -// any -// > -// ? T[1] -// : null; - type ParseMemberExpression< O extends Node, T extends Array>, diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index 24718f8..b73d511 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -499,6 +499,66 @@ expectType>({ lineNumber: 2, }); +expectType>({ + type: 'SyntaxError', + message: 'Identifier expected.', + lineNumber: 2, +}); + +expectType>([ + { + type: 'VariableDeclaration', + declarations: [ + { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + init: { + type: 'MemberExpression', + object: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + property: { + type: 'Identifier', + name: 'bar', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + kind: 'const', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + // expectType>([ // { // type: 'ExpressionStatement', From 90dda6329912e1f53b77a387c4d406ec6c28be74 Mon Sep 17 00:00:00 2001 From: ronami Date: Wed, 6 Jul 2022 22:38:23 +0300 Subject: [PATCH 110/286] wip --- src/index.ts | 2 +- src/parser.ts | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 5a6636a..032ea66 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`foo.`>; +type T = Tokenize<`foo`>; type R = Parse; // type C = Check<[R]>; diff --git a/src/parser.ts b/src/parser.ts index 11d5e86..61d928b 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -373,6 +373,44 @@ type ParseMemberExpression< : SyntaxError<'Identifier expected.', E> : null; +type ParseCallExpression< + O extends Node, + T extends Array>, +> = T[0] extends ParenToken<'(', TokenData> + ? ParseCallExpressionArguments, E> extends infer G + ? G extends Array + ? [CallExpression>, G[1]] + : G + : never + : null; + +type ParseCallExpressionArguments< + T extends Array>, + E extends number, + N extends boolean = false, + R extends Array> = [], +> = T[0] extends ParenToken<')', any> + ? [R, Tail] + : T extends [] + ? SyntaxError<"Parsing error: ')' expected.", E> + : N extends true + ? T[0] extends CommaToken + ? ParseCallExpressionArgumentsHelper, E, R> + : T[0] extends Token> + ? SyntaxError<"Parsing error: ',' expected.", L> + : never + : ParseCallExpressionArgumentsHelper; + +type ParseCallExpressionArgumentsHelper< + T extends Array>, + E extends number, + R extends Array = [], +> = ParseExpression extends infer G + ? G extends Array + ? ParseCallExpressionArguments> + : G + : never; + // T[1][0] extends DotToken // ? T[1][1] extends SymbolToken // ? Wrap<[MemberExpression>, Tail>]> @@ -397,7 +435,17 @@ type CheckExpression< : never : G extends Error ? G - : [O, T] + : ParseCallExpression extends infer G + ? G extends [infer O, infer T] + ? O extends Node + ? T extends Array> + ? CheckExpression + : never + : never + : G extends Error + ? G + : [O, T] + : never : never; type ParseExpression< From dff7cd42c3786a68503052a7ca9d09cb4b44c9e0 Mon Sep 17 00:00:00 2001 From: ronami Date: Wed, 6 Jul 2022 22:42:38 +0300 Subject: [PATCH 111/286] wip --- src/parser.ts | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 61d928b..8a6df74 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -411,18 +411,6 @@ type ParseCallExpressionArgumentsHelper< : G : never; -// T[1][0] extends DotToken -// ? T[1][1] extends SymbolToken -// ? Wrap<[MemberExpression>, Tail>]> -// : T -// : T[1][0] extends ParenToken<'('> -// ? ParseFunctionArguments> extends infer G -// ? Wrap< -// [CallExpression>[0]>, Cast>[1]] -// > -// : never -// : T; - type CheckExpression< O extends Node, T extends Array>, @@ -484,9 +472,7 @@ type ParseExpressionStatement>> = ? G[0] extends Node ? [ExpressionStatement, G[1]] : never - : G extends Error - ? G - : null + : G : never; type ParseTopLevel< From 6ee4ba697b05151ca7140ba5e6fbc6d3c4ccba70 Mon Sep 17 00:00:00 2001 From: ronami Date: Wed, 6 Jul 2022 22:52:51 +0300 Subject: [PATCH 112/286] wip --- src/parser.ts | 8 +- src/test/parser.test.ts | 304 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 310 insertions(+), 2 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 8a6df74..8036b1c 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -379,7 +379,11 @@ type ParseCallExpression< > = T[0] extends ParenToken<'(', TokenData> ? ParseCallExpressionArguments, E> extends infer G ? G extends Array - ? [CallExpression>, G[1]] + ? O extends Node> + ? G[2] extends Token> + ? [CallExpression>, G[1]] + : never + : never : G : never : null; @@ -390,7 +394,7 @@ type ParseCallExpressionArguments< N extends boolean = false, R extends Array> = [], > = T[0] extends ParenToken<')', any> - ? [R, Tail] + ? [R, Tail, T[0]] : T extends [] ? SyntaxError<"Parsing error: ')' expected.", E> : N extends true diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index b73d511..645a0c0 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -559,6 +559,310 @@ expectType>([ }, ]); +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + arguments: [], + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + arguments: [], + data: { startLineNumber: 1, endLineNumber: 2 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 2, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + arguments: [ + { + type: 'NumericLiteral', + value: '1', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + arguments: [ + { + type: 'NumericLiteral', + value: '1', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + { + type: 'StringLiteral', + value: '2', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + arguments: [ + { + type: 'NumericLiteral', + value: '1', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + { + type: 'NullLiteral', + data: { + startLineNumber: 2, + endLineNumber: 2, + }, + }, + { + type: 'BooleanLiteral', + value: true, + data: { + startLineNumber: 3, + endLineNumber: 3, + }, + }, + ], + data: { startLineNumber: 1, endLineNumber: 3 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 3, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + property: { + type: 'Identifier', + name: 'world', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + arguments: [ + { + type: 'NumericLiteral', + value: '1', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + property: { + type: 'Identifier', + name: 'world', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + arguments: [ + { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + arguments: [ + { + type: 'NumericLiteral', + value: '1', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>({ + type: 'SyntaxError', + message: "Parsing error: ')' expected.", + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: "Parsing error: ',' expected.", + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: "Parsing error: ',' expected.", + lineNumber: 2, +}); + // expectType>([ // { // type: 'ExpressionStatement', From ae502754f36028822de65f98ced57f0ef9b291dc Mon Sep 17 00:00:00 2001 From: ronami Date: Wed, 6 Jul 2022 22:53:40 +0300 Subject: [PATCH 113/286] wip --- src/parser.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 8036b1c..32936f0 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -44,18 +44,6 @@ import type { import type { Push, Tail, TailBy } from './utils/arrayUtils'; import type { IsNever } from './utils/generalUtils'; -// type Wrap>]> = T[1][0] extends DotToken -// ? T[1][1] extends SymbolToken -// ? Wrap<[MemberExpression>, Tail>]> -// : T -// : T[1][0] extends ParenToken<'('> -// ? ParseFunctionArguments> extends infer G -// ? Wrap< -// [CallExpression>[0]>, Cast>[1]] -// > -// : never -// : T; - // type DoParseExpression< // T extends Array>, // F = T[0], From 53356f319505d0d1991ec9b4f01302b744a31feb Mon Sep 17 00:00:00 2001 From: ronami Date: Wed, 6 Jul 2022 23:28:53 +0300 Subject: [PATCH 114/286] wip --- src/index.ts | 4 +- src/parser.ts | 53 ++++++++--- src/test/parser.test.ts | 198 +++++++++++++++++++++++++++++++++++++++- src/tokens.ts | 14 +-- 4 files changed, 246 insertions(+), 23 deletions(-) diff --git a/src/index.ts b/src/index.ts index 032ea66..816c939 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`foo`>; -type R = Parse; +type T = Tokenize<`[\ntrue, \nnull\n]`>; +type R = Parse[0]['data']; // type C = Check<[R]>; diff --git a/src/parser.ts b/src/parser.ts index 32936f0..4328cf6 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -365,7 +365,12 @@ type ParseCallExpression< O extends Node, T extends Array>, > = T[0] extends ParenToken<'(', TokenData> - ? ParseCallExpressionArguments, E> extends infer G + ? ParseCallExpressionArguments< + Tail, + E, + ')', + ParenToken<')', any> + > extends infer G ? G extends Array ? O extends Node> ? G[2] extends Token> @@ -379,27 +384,31 @@ type ParseCallExpression< type ParseCallExpressionArguments< T extends Array>, E extends number, + J extends string, + F extends Token, N extends boolean = false, R extends Array> = [], -> = T[0] extends ParenToken<')', any> +> = T[0] extends F ? [R, Tail, T[0]] : T extends [] - ? SyntaxError<"Parsing error: ')' expected.", E> + ? SyntaxError<`Parsing error: '${J}' expected.`, E> : N extends true ? T[0] extends CommaToken - ? ParseCallExpressionArgumentsHelper, E, R> + ? ParseCallExpressionArgumentsHelper, E, J, F, R> : T[0] extends Token> ? SyntaxError<"Parsing error: ',' expected.", L> : never - : ParseCallExpressionArgumentsHelper; + : ParseCallExpressionArgumentsHelper; type ParseCallExpressionArgumentsHelper< T extends Array>, E extends number, + J extends string, + F extends Token, R extends Array = [], > = ParseExpression extends infer G ? G extends Array - ? ParseCallExpressionArguments> + ? ParseCallExpressionArguments> : G : never; @@ -432,13 +441,13 @@ type ParseExpression< T extends Array>, H extends NodeData = ExtractTokenData, G extends Array> = Tail, -> = ParseExpressionHelper extends [infer O, infer T] - ? O extends Node - ? T extends Array> - ? CheckExpression - : never - : never - : null; +> = ParseExpressionHelper extends infer P + ? P extends Array + ? CheckExpression + : P extends Error + ? P + : null + : never; type ParseExpressionHelper< T extends Array>, @@ -456,8 +465,26 @@ type ParseExpressionHelper< ? [StringLiteral, G] : T[0] extends SymbolToken ? [Identifier, G] + : T[0] extends BracketToken<'[', TokenData> + ? ParseArrayExpression : null; +type ParseArrayExpression< + T extends Array>, + E extends number, +> = ParseCallExpressionArguments< + Tail, + E, + ']', + BracketToken<']', any> +> extends infer A + ? A extends Array + ? A[2] extends Token> + ? [ArrayExpression>, A[1]] + : never + : A + : never; + type ParseExpressionStatement>> = ParseExpression extends infer G ? G extends Array diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index 645a0c0..c661bc4 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -857,11 +857,207 @@ expectType>({ lineNumber: 1, }); -expectType>({ +expectType>({ type: 'SyntaxError', message: "Parsing error: ',' expected.", lineNumber: 2, }); +expectType>({ + type: 'SyntaxError', + message: "Parsing error: ']' expected.", + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: "Parsing error: ',' expected.", + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: "Parsing error: ',' expected.", + lineNumber: 2, +}); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'ArrayExpression', + elements: [], + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'ArrayExpression', + elements: [ + { + type: 'NumericLiteral', + value: '1', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'ArrayExpression', + elements: [ + { + type: 'NumericLiteral', + value: '1', + data: { + startLineNumber: 2, + endLineNumber: 2, + }, + }, + ], + data: { startLineNumber: 1, endLineNumber: 2 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 2, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'ArrayExpression', + elements: [ + { + type: 'NumericLiteral', + value: '1', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + { + type: 'StringLiteral', + value: 'hello', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'ArrayExpression', + elements: [ + { + type: 'NumericLiteral', + value: '1', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + { + type: 'ArrayExpression', + elements: [ + { + type: 'NumericLiteral', + value: '2', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'VariableDeclaration', + declarations: [ + { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'array', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + init: { + type: 'ArrayExpression', + elements: [ + { + type: 'NumericLiteral', + value: '1', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + kind: 'const', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); // expectType>([ // { diff --git a/src/tokens.ts b/src/tokens.ts index 6543a35..eb77c88 100644 --- a/src/tokens.ts +++ b/src/tokens.ts @@ -59,13 +59,13 @@ export type CommaToken> = { data: D; }; -export type Token> = - | NumberToken - | BracketToken - | StringToken - | SymbolToken - | ParenToken - | CurlyToken +export type Token, V extends string = string> = + | NumberToken + | BracketToken + | StringToken + | SymbolToken + | ParenToken + | CurlyToken | DotToken | SemicolonToken | ColonToken From 1c9f90a617fae4bec53dae089a8e22f2079f2cbd Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 7 Jul 2022 00:27:47 +0300 Subject: [PATCH 115/286] wip --- src/index.ts | 4 +- src/parser.ts | 107 ++++++++------- src/test/parser.test.ts | 291 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 346 insertions(+), 56 deletions(-) diff --git a/src/index.ts b/src/index.ts index 816c939..5341687 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`[\ntrue, \nnull\n]`>; -type R = Parse[0]['data']; +type T = Tokenize<`{ aaa: `>; +type R = Parse; // type C = Check<[R]>; diff --git a/src/parser.ts b/src/parser.ts index 4328cf6..b23ed80 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -244,58 +244,6 @@ import type { IsNever } from './utils/generalUtils'; // : never // : never; -// type ParseObject< -// T extends Array>, -// R extends Array = [], -// N extends boolean = false, -// F extends Token = T[0], -// > = F extends CurlyToken<'}'> -// ? [ObjectExpression>, Tail] -// : T extends [] -// ? never -// : N extends true -// ? F extends CommaToken -// ? ParseObjectItem, R> -// : never -// : ParseObjectItem; - -// type ParseObjectItem< -// T extends Array>, -// R extends Array = [], -// > = T[0] extends SymbolToken -// ? T[1] extends ColonToken -// ? ParseExpression>> extends infer G -// ? ParseObject< -// Cast>[1], -// Unshift, Cast>[0]>>, -// true -// > -// : never -// : never -// : never; - -// type ParseArray< -// T extends Array>, -// R extends Array = [], -// N extends boolean = false, -// F extends Token = T[0], -// > = F extends BracketToken<']'> -// ? [ArrayExpression>, Tail] -// : T extends [] -// ? never -// : N extends true -// ? F extends CommaToken -// ? ParseArrayItem, R> -// : never -// : ParseArrayItem; - -// type ParseArrayItem< -// T extends Array>, -// R extends Array = [], -// > = ParseExpression extends infer G -// ? ParseArray>[1], Unshift>[0]>, true> -// : never; - type ExtractTokenData< T extends Token, R extends Token = T, @@ -466,14 +414,65 @@ type ParseExpressionHelper< : T[0] extends SymbolToken ? [Identifier, G] : T[0] extends BracketToken<'[', TokenData> - ? ParseArrayExpression + ? ParseArrayExpression, E> + : T[0] extends CurlyToken<'{', TokenData> + ? ParseObject, E> : null; +// [ObjectExpression<[], NodeData<1, 1>>, []] + +type ParseObject< + T extends Array>, + E extends number, + R extends Array = [], + N extends boolean = false, +> = T[0] extends CurlyToken<'}', TokenData> + ? [ObjectExpression>, Tail] + : T extends [] + ? SyntaxError<"'}' expected.", E> + : N extends true + ? T[0] extends CommaToken + ? ParseObjectItem, E, R> + : T[0] extends Token> + ? SyntaxError<"',' expected.", L> + : never + : ParseObjectItem; + +type ParseObjectItem< + T extends Array>, + E extends number, + R extends Array = [], +> = T[0] extends SymbolToken> + ? T[1] extends ColonToken + ? ParseExpression> extends infer G + ? G extends Array + ? G[0] extends Node> + ? ParseObject< + G[1], + E, + Push< + R, + ObjectProperty< + Identifier>, + G[0], + NodeData + > + >, + true + > + : never + : G extends Error + ? G + : SyntaxError<'Expression expected.', E> + : never + : SyntaxError<"Parsing error: '}' expected.", E> + : SyntaxError<"Parsing error: '}' expected.", E>; + type ParseArrayExpression< T extends Array>, E extends number, > = ParseCallExpressionArguments< - Tail, + T, E, ']', BracketToken<']', any> diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index c661bc4..c6f879e 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -1059,6 +1059,297 @@ expectType>([ }, ]); +expectType>({ + type: 'SyntaxError', + message: "'}' expected.", + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: "Parsing error: '}' expected.", + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: "Parsing error: '}' expected.", + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: "Parsing error: '}' expected.", + lineNumber: 1, +}); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'ObjectExpression', + properties: [], + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'ObjectExpression', + properties: [ + { + type: 'ObjectProperty', + key: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + value: { + type: 'StringLiteral', + value: 'world', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'ObjectExpression', + properties: [ + { + type: 'ObjectProperty', + key: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + value: { + type: 'StringLiteral', + value: 'world', + data: { + startLineNumber: 3, + endLineNumber: 3, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 3, + }, + }, + ], + data: { startLineNumber: 1, endLineNumber: 4 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 4, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'ObjectExpression', + properties: [ + { + type: 'ObjectProperty', + key: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + value: { + type: 'StringLiteral', + value: 'hello', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + { + type: 'ObjectProperty', + key: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + value: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'bar', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + arguments: [], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'ObjectExpression', + properties: [ + { + type: 'ObjectProperty', + key: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + value: { + type: 'ObjectExpression', + properties: [], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'VariableDeclaration', + declarations: [ + { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'array', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + init: { + type: 'ObjectExpression', + properties: [ + { + type: 'ObjectProperty', + key: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + value: { + type: 'StringLiteral', + value: 'world', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + kind: 'const', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + // expectType>([ // { // type: 'ExpressionStatement', From 8a72e2ed6c7cc89fa5856a4cb9e1ec47ce18c6ec Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 7 Jul 2022 00:27:58 +0300 Subject: [PATCH 116/286] wip --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 5341687..f42a94c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`{ aaa: `>; +type T = Tokenize<`{ aaa: "aa" }`>; type R = Parse; // type C = Check<[R]>; From 499392b51745a8fdde950c176ba1a5e848196046 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 7 Jul 2022 00:29:08 +0300 Subject: [PATCH 117/286] wip --- src/parser.ts | 8 ++++---- src/test/parser.test.ts | 18 +++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index b23ed80..6ca35d4 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -339,12 +339,12 @@ type ParseCallExpressionArguments< > = T[0] extends F ? [R, Tail, T[0]] : T extends [] - ? SyntaxError<`Parsing error: '${J}' expected.`, E> + ? SyntaxError<`'${J}' expected.`, E> : N extends true ? T[0] extends CommaToken ? ParseCallExpressionArgumentsHelper, E, J, F, R> : T[0] extends Token> - ? SyntaxError<"Parsing error: ',' expected.", L> + ? SyntaxError<"',' expected.", L> : never : ParseCallExpressionArgumentsHelper; @@ -465,8 +465,8 @@ type ParseObjectItem< ? G : SyntaxError<'Expression expected.', E> : never - : SyntaxError<"Parsing error: '}' expected.", E> - : SyntaxError<"Parsing error: '}' expected.", E>; + : SyntaxError<"'}' expected.", E> + : SyntaxError<"'}' expected.", E>; type ParseArrayExpression< T extends Array>, diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index c6f879e..3114eda 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -847,36 +847,36 @@ expectType>([ expectType>({ type: 'SyntaxError', - message: "Parsing error: ')' expected.", + message: "')' expected.", lineNumber: 1, }); expectType>({ type: 'SyntaxError', - message: "Parsing error: ',' expected.", + message: "',' expected.", lineNumber: 1, }); expectType>({ type: 'SyntaxError', - message: "Parsing error: ',' expected.", + message: "',' expected.", lineNumber: 2, }); expectType>({ type: 'SyntaxError', - message: "Parsing error: ']' expected.", + message: "']' expected.", lineNumber: 1, }); expectType>({ type: 'SyntaxError', - message: "Parsing error: ',' expected.", + message: "',' expected.", lineNumber: 1, }); expectType>({ type: 'SyntaxError', - message: "Parsing error: ',' expected.", + message: "',' expected.", lineNumber: 2, }); @@ -1067,19 +1067,19 @@ expectType>({ expectType>({ type: 'SyntaxError', - message: "Parsing error: '}' expected.", + message: "'}' expected.", lineNumber: 1, }); expectType>({ type: 'SyntaxError', - message: "Parsing error: '}' expected.", + message: "'}' expected.", lineNumber: 1, }); expectType>({ type: 'SyntaxError', - message: "Parsing error: '}' expected.", + message: "'}' expected.", lineNumber: 1, }); From 94051ae9693214709e13fcdb0fd48a5f5de51f7a Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 7 Jul 2022 00:33:24 +0300 Subject: [PATCH 118/286] wip --- src/parser.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 6ca35d4..fa6db1e 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -42,7 +42,6 @@ import type { TokenData, } from './tokens'; import type { Push, Tail, TailBy } from './utils/arrayUtils'; -import type { IsNever } from './utils/generalUtils'; // type DoParseExpression< // T extends Array>, @@ -419,8 +418,6 @@ type ParseExpressionHelper< ? ParseObject, E> : null; -// [ObjectExpression<[], NodeData<1, 1>>, []] - type ParseObject< T extends Array>, E extends number, From 469fc7a51b2dee29d535c4f3badace77a7980954 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 7 Jul 2022 19:15:01 +0300 Subject: [PATCH 119/286] wip --- src/parser.ts | 50 ++++++++++++-------------------------- src/test/tokenizer.test.ts | 26 +++++++++++--------- src/tokenizer.ts | 28 +++++++++------------ src/tokens.ts | 46 +++-------------------------------- 4 files changed, 45 insertions(+), 105 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index fa6db1e..5f3b84a 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -28,14 +28,8 @@ import type { } from './ast'; import type { Error, SyntaxError } from './errors'; import type { - BracketToken, - ColonToken, - CommaToken, - CurlyToken, - DotToken, + GenericToken, NumberToken, - ParenToken, - SemicolonToken, StringToken, SymbolToken, Token, @@ -293,7 +287,7 @@ type ParseVariableDeclaration>> = type ParseMemberExpression< O extends Node, T extends Array>, -> = T[0] extends DotToken> +> = T[0] extends GenericToken<'.', TokenData> ? T[1] extends SymbolToken> ? O extends Node> ? [ @@ -311,13 +305,8 @@ type ParseMemberExpression< type ParseCallExpression< O extends Node, T extends Array>, -> = T[0] extends ParenToken<'(', TokenData> - ? ParseCallExpressionArguments< - Tail, - E, - ')', - ParenToken<')', any> - > extends infer G +> = T[0] extends GenericToken<'(', TokenData> + ? ParseCallExpressionArguments, E, ')'> extends infer G ? G extends Array ? O extends Node> ? G[2] extends Token> @@ -332,30 +321,28 @@ type ParseCallExpressionArguments< T extends Array>, E extends number, J extends string, - F extends Token, N extends boolean = false, R extends Array> = [], -> = T[0] extends F +> = T[0] extends GenericToken ? [R, Tail, T[0]] : T extends [] ? SyntaxError<`'${J}' expected.`, E> : N extends true - ? T[0] extends CommaToken - ? ParseCallExpressionArgumentsHelper, E, J, F, R> + ? T[0] extends GenericToken<',', any> + ? ParseCallExpressionArgumentsHelper, E, J, R> : T[0] extends Token> ? SyntaxError<"',' expected.", L> : never - : ParseCallExpressionArgumentsHelper; + : ParseCallExpressionArgumentsHelper; type ParseCallExpressionArgumentsHelper< T extends Array>, E extends number, J extends string, - F extends Token, R extends Array = [], > = ParseExpression extends infer G ? G extends Array - ? ParseCallExpressionArguments> + ? ParseCallExpressionArguments> : G : never; @@ -412,9 +399,9 @@ type ParseExpressionHelper< ? [StringLiteral, G] : T[0] extends SymbolToken ? [Identifier, G] - : T[0] extends BracketToken<'[', TokenData> + : T[0] extends GenericToken<'[', TokenData> ? ParseArrayExpression, E> - : T[0] extends CurlyToken<'{', TokenData> + : T[0] extends GenericToken<'{', TokenData> ? ParseObject, E> : null; @@ -423,12 +410,12 @@ type ParseObject< E extends number, R extends Array = [], N extends boolean = false, -> = T[0] extends CurlyToken<'}', TokenData> +> = T[0] extends GenericToken<'}', TokenData> ? [ObjectExpression>, Tail] : T extends [] ? SyntaxError<"'}' expected.", E> : N extends true - ? T[0] extends CommaToken + ? T[0] extends GenericToken<',', any> ? ParseObjectItem, E, R> : T[0] extends Token> ? SyntaxError<"',' expected.", L> @@ -440,7 +427,7 @@ type ParseObjectItem< E extends number, R extends Array = [], > = T[0] extends SymbolToken> - ? T[1] extends ColonToken + ? T[1] extends GenericToken<':', any> ? ParseExpression> extends infer G ? G extends Array ? G[0] extends Node> @@ -468,12 +455,7 @@ type ParseObjectItem< type ParseArrayExpression< T extends Array>, E extends number, -> = ParseCallExpressionArguments< - T, - E, - ']', - BracketToken<']', any> -> extends infer A +> = ParseCallExpressionArguments extends infer A ? A extends Array ? A[2] extends Token> ? [ArrayExpression>, A[1]] @@ -496,7 +478,7 @@ type ParseTopLevel< N extends boolean, > = T extends [] ? R - : T[0] extends SemicolonToken + : T[0] extends GenericToken<';', any> ? ParseTopLevel, R, false> : N extends false ? ParseTopLevelHelper diff --git a/src/test/tokenizer.test.ts b/src/test/tokenizer.test.ts index d171458..9d6c421 100644 --- a/src/test/tokenizer.test.ts +++ b/src/test/tokenizer.test.ts @@ -196,7 +196,7 @@ expectType>([ expectType>([ { - type: 'bracket', + type: 'generic', value: '[', data: { precedingLinebreak: false, @@ -212,7 +212,8 @@ expectType>([ }, }, { - type: 'comma', + type: 'generic', + value: ',', data: { precedingLinebreak: false, lineNumber: 1, @@ -227,7 +228,8 @@ expectType>([ }, }, { - type: 'comma', + type: 'generic', + value: ',', data: { precedingLinebreak: false, lineNumber: 1, @@ -242,7 +244,7 @@ expectType>([ }, }, { - type: 'bracket', + type: 'generic', value: ']', data: { precedingLinebreak: false, @@ -261,7 +263,7 @@ expectType>([ }, }, { - type: 'paren', + type: 'generic', value: '(', data: { precedingLinebreak: false, @@ -269,7 +271,7 @@ expectType>([ }, }, { - type: 'paren', + type: 'generic', value: ')', data: { precedingLinebreak: false, @@ -288,7 +290,7 @@ expectType>([ }, }, { - type: 'paren', + type: 'generic', value: '(', data: { precedingLinebreak: false, @@ -296,7 +298,7 @@ expectType>([ }, }, { - type: 'paren', + type: 'generic', value: ')', data: { precedingLinebreak: false, @@ -315,7 +317,7 @@ expectType>([ }, }, { - type: 'paren', + type: 'generic', value: '(', data: { precedingLinebreak: true, @@ -323,7 +325,7 @@ expectType>([ }, }, { - type: 'paren', + type: 'generic', value: ')', data: { precedingLinebreak: false, @@ -342,7 +344,7 @@ expectType>([ }, }, { - type: 'paren', + type: 'generic', value: '(', data: { precedingLinebreak: false, @@ -350,7 +352,7 @@ expectType>([ }, }, { - type: 'paren', + type: 'generic', value: ')', data: { precedingLinebreak: true, diff --git a/src/tokenizer.ts b/src/tokenizer.ts index bb00fd4..f74a4a7 100644 --- a/src/tokenizer.ts +++ b/src/tokenizer.ts @@ -7,18 +7,12 @@ import type { } from './utils/stringUtils'; import type { Numbers, Symbols } from './utils/generalUtils'; import type { - CurlyToken, - ParenToken, - DotToken, - SemicolonToken, - ColonToken, Token, NumberToken, SymbolToken, StringToken, - BracketToken, - CommaToken, TokenData, + GenericToken, } from './tokens'; import type { SyntaxError } from './errors'; import type { Succ } from './utils/math'; @@ -31,25 +25,25 @@ type TokenizeInput< L extends number, D extends TokenData = TokenData, > = F extends ',' - ? [CommaToken, E] + ? [GenericToken<',', D>, E] : F extends '(' - ? [ParenToken<'(', D>, E] + ? [GenericToken<'(', D>, E] : F extends ')' - ? [ParenToken<')', D>, E] + ? [GenericToken<')', D>, E] : F extends '[' - ? [BracketToken<'[', D>, E] + ? [GenericToken<'[', D>, E] : F extends ']' - ? [BracketToken<']', D>, E] + ? [GenericToken<']', D>, E] : F extends '{' - ? [CurlyToken<'{', D>, E] + ? [GenericToken<'{', D>, E] : F extends '}' - ? [CurlyToken<'}', D>, E] + ? [GenericToken<'}', D>, E] : F extends '.' - ? [DotToken, E] + ? [GenericToken<'.', D>, E] : F extends ';' - ? [SemicolonToken, E] + ? [GenericToken<';', D>, E] : F extends ':' - ? [ColonToken, E] + ? [GenericToken<':', D>, E] : F extends Numbers ? TokenizeNumber : F extends '"' diff --git a/src/tokens.ts b/src/tokens.ts index eb77c88..bb360d1 100644 --- a/src/tokens.ts +++ b/src/tokens.ts @@ -3,39 +3,12 @@ export type TokenData

= { lineNumber: L; }; -export type ParenToken> = { - type: 'paren'; +export type GenericToken> = { + type: 'generic'; value: V; data: D; }; -export type BracketToken> = { - type: 'bracket'; - value: V; - data: D; -}; - -export type CurlyToken> = { - type: 'curly'; - value: V; - data: D; -}; - -export type DotToken> = { - type: 'dot'; - data: D; -}; - -export type SemicolonToken> = { - type: 'semicolon'; - data: D; -}; - -export type ColonToken> = { - type: 'colon'; - data: D; -}; - export type NumberToken> = { type: 'number'; value: V; @@ -54,19 +27,8 @@ export type SymbolToken> = { data: D; }; -export type CommaToken> = { - type: 'comma'; - data: D; -}; - export type Token, V extends string = string> = + | GenericToken | NumberToken - | BracketToken | StringToken - | SymbolToken - | ParenToken - | CurlyToken - | DotToken - | SemicolonToken - | ColonToken - | CommaToken; + | SymbolToken; From 8b6e24b86137131c7b48a8b309df2bb68c67b74a Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 8 Jul 2022 13:00:27 +0300 Subject: [PATCH 120/286] wip --- src/index.ts | 2 +- src/parser.ts | 125 ++++++++++++++++++++++++-------------------------- 2 files changed, 62 insertions(+), 65 deletions(-) diff --git a/src/index.ts b/src/index.ts index f42a94c..370cbf5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`{ aaa: "aa" }`>; +type T = Tokenize<`function foo () {}`>; type R = Parse; // type C = Check<[R]>; diff --git a/src/parser.ts b/src/parser.ts index 5f3b84a..3764a47 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -128,52 +128,6 @@ import type { Push, Tail, TailBy } from './utils/arrayUtils'; // > // : never; -// type ParseFunctionDeclaration>> = -// T[0] extends SymbolToken -// ? T[1] extends ParenToken<'('> -// ? ParseFunctionParams>> extends infer G -// ? ParseBlockStatement>[1]> extends infer H -// ? [ -// FunctionDeclaration< -// Identifier, -// Cast>[0], -// Cast>[0] -// >, -// Cast>[1], -// ] -// : never -// : never -// : never -// : never; - -// type ParseBlockStatement< -// T extends Array>, -// R extends Array = [], -// > = T[0] extends CurlyToken<'}'> -// ? [BlockStatement>, Tail] -// : ParseFunctionStatement extends infer F -// ? ParseBlockStatement< -// Cast>[1], -// Unshift>[0]> -// > -// : never; - -// type ParseFunctionParams< -// T extends Array>, -// R extends Array = [], -// N extends boolean = false, -// > = T[0] extends ParenToken<')'> -// ? T[1] extends CurlyToken<'{'> -// ? [Reverse, Tail>] -// : never -// : T extends [] -// ? never -// : N extends true -// ? T[0] extends CommaToken -// ? ParseFunctionParamsItem, R> -// : never -// : ParseFunctionParamsItem; - // type ParseTypeAnnotation>> = // T[0] extends SymbolToken<'string'> // ? [TypeAnnotation, Tail] @@ -189,21 +143,6 @@ import type { Push, Tail, TailBy } from './utils/arrayUtils'; // ? [TypeAnnotation>, Tail] // : never; -// type ParseFunctionParamsItem< -// T extends Array>, -// R extends Array = [], -// > = T[0] extends SymbolToken -// ? T[1] extends ColonToken -// ? ParseTypeAnnotation>> extends infer G -// ? ParseFunctionParams< -// Cast>[1], -// Unshift>[0]>>, -// true -// > -// : never -// : ParseFunctionParams, Unshift>, true> -// : never; - // type ParseVariableDeclarationHelper< // T extends Array>, // K, @@ -472,6 +411,58 @@ type ParseExpressionStatement>> = : G : never; +type ParseFunctionDeclaration>> = + T[0] extends SymbolToken<'function', any> + ? T[1] extends SymbolToken + ? T[2] extends GenericToken<'(', any> + ? ParseFunctionParams> extends infer G + ? G extends Array + ? [[], []] extends infer H + ? H extends Array + ? [ + FunctionDeclaration< + Identifier>, + G[0], + H[0], + NodeData<1, 1> + >, + H[1], + ] + : never + : never + : never + : never + : never + : never + : null; + +type ParseFunctionParams< + T extends Array>, + R extends Array = [], + N extends boolean = false, +> = T[0] extends GenericToken<')', any> + ? T[1] extends GenericToken<'{', any> + ? [R, TailBy] + : never + : T extends [] + ? never + : N extends true + ? T[0] extends GenericToken<',', any> + ? ParseFunctionParamsHelper, R> + : never + : ParseFunctionParamsHelper; + +type ParseFunctionParamsHelper< + T extends Array>, + R extends Array = [], +> = T[0] extends SymbolToken + ? ParseFunctionParams< + Tail, + Push>>, + true + > + : never; + type ParseTopLevel< T extends Array>, R extends Array>, @@ -491,16 +482,22 @@ type ParseTopLevel< type ParseTopLevelHelper< T extends Array>, R extends Array>, -> = ParseVariableDeclaration extends infer P +> = ParseFunctionDeclaration extends infer P ? P extends Array - ? ParseTopLevel, true> + ? ParseTopLevel, false> : P extends Error ? P - : ParseExpressionStatement extends infer P + : ParseVariableDeclaration extends infer P ? P extends Array ? ParseTopLevel, true> : P extends Error ? P + : ParseExpressionStatement extends infer P + ? P extends Array + ? ParseTopLevel, true> + : P extends Error + ? P + : never : never : never : never; From 251800a44e8be9fd0456d9e756a510e88f731afc Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 8 Jul 2022 13:20:04 +0300 Subject: [PATCH 121/286] wip --- src/index.ts | 2 +- src/parser.ts | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/index.ts b/src/index.ts index 370cbf5..89babce 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`function foo () {}`>; +type T = Tokenize<`function foo (a) {}`>; type R = Parse; // type C = Check<[R]>; diff --git a/src/parser.ts b/src/parser.ts index 3764a47..97fd433 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -412,8 +412,8 @@ type ParseExpressionStatement>> = : never; type ParseFunctionDeclaration>> = - T[0] extends SymbolToken<'function', any> - ? T[1] extends SymbolToken + T[0] extends SymbolToken<'function', TokenData> + ? T[1] extends SymbolToken> ? T[2] extends GenericToken<'(', any> ? ParseFunctionParams> extends infer G ? G extends Array @@ -430,26 +430,26 @@ type ParseFunctionDeclaration>> = ] : never : never - : never + : G : never - : never - : never + : SyntaxError<"'(' expected.", O> + : SyntaxError<'Identifier expected.', L> : null; type ParseFunctionParams< T extends Array>, R extends Array = [], N extends boolean = false, -> = T[0] extends GenericToken<')', any> +> = T[0] extends GenericToken<')', TokenData> ? T[1] extends GenericToken<'{', any> ? [R, TailBy] - : never + : SyntaxError<"'{' expected.", L> : T extends [] - ? never + ? SyntaxError<"')' expected.", 1> : N extends true ? T[0] extends GenericToken<',', any> ? ParseFunctionParamsHelper, R> - : never + : SyntaxError<"',' expected.", 1> : ParseFunctionParamsHelper; type ParseFunctionParamsHelper< @@ -461,7 +461,7 @@ type ParseFunctionParamsHelper< Push>>, true > - : never; + : SyntaxError<'Identifier expected.', 1>; type ParseTopLevel< T extends Array>, From c07c3d88de6dfa7196dee9657609f0885e9c834a Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 8 Jul 2022 15:56:24 +0300 Subject: [PATCH 122/286] wip --- src/index.ts | 2 +- src/parser.ts | 72 ++- src/test/parser.test.ts | 1106 ++++++++++++++------------------------- 3 files changed, 437 insertions(+), 743 deletions(-) diff --git a/src/index.ts b/src/index.ts index 89babce..9543c74 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`function foo (a) {}`>; +type T = Tokenize<`function foo () {} console.log()`>; type R = Parse; // type C = Check<[R]>; diff --git a/src/parser.ts b/src/parser.ts index 97fd433..c8c4dae 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -417,7 +417,7 @@ type ParseFunctionDeclaration>> = ? T[2] extends GenericToken<'(', any> ? ParseFunctionParams> extends infer G ? G extends Array - ? [[], []] extends infer H + ? ParseBlockStatement extends infer H ? H extends Array ? [ FunctionDeclaration< @@ -428,7 +428,7 @@ type ParseFunctionDeclaration>> = >, H[1], ] - : never + : H : never : G : never @@ -463,43 +463,59 @@ type ParseFunctionParamsHelper< > : SyntaxError<'Identifier expected.', 1>; +type ParseBlockStatement< + T extends Array>, + R extends Array> = [], + N extends boolean = false, +> = T extends [] + ? SyntaxError<"'}' expected.", 1> + : T[0] extends GenericToken<'}', any> + ? [BlockStatement>, Tail] + : T[0] extends GenericToken<';', any> + ? ParseBlockStatement, R, false> + : N extends false + ? ParseBlockStatementErrorHelper, R> + : T[0] extends Token> + ? P extends true + ? ParseBlockStatementErrorHelper, R> + : SyntaxError<"';' expected.", L> + : never; + type ParseTopLevel< T extends Array>, - R extends Array>, - N extends boolean, + R extends Array> = [], + N extends boolean = false, > = T extends [] ? R : T[0] extends GenericToken<';', any> ? ParseTopLevel, R, false> : N extends false - ? ParseTopLevelHelper + ? ParseTopLevelErrorHelper, R> : T[0] extends Token> ? P extends true - ? ParseTopLevelHelper + ? ParseTopLevelErrorHelper, R> : SyntaxError<"';' expected.", L> : never; -type ParseTopLevelHelper< - T extends Array>, +type ParseBlockStatementErrorHelper< + T, R extends Array>, -> = ParseFunctionDeclaration extends infer P - ? P extends Array - ? ParseTopLevel, false> - : P extends Error - ? P - : ParseVariableDeclaration extends infer P - ? P extends Array - ? ParseTopLevel, true> - : P extends Error - ? P - : ParseExpressionStatement extends infer P - ? P extends Array - ? ParseTopLevel, true> - : P extends Error - ? P - : never - : never - : never - : never; +> = T extends Array ? ParseBlockStatement, true> : T; + +type ParseTopLevelErrorHelper< + T, + R extends Array>, +> = T extends Array ? ParseTopLevel, true> : T; + +type ParseTopLevelHelper>> = + ParseFunctionDeclaration extends infer P + ? P extends null + ? ParseVariableDeclaration extends infer P + ? P extends null + ? ParseExpressionStatement + : P + : P + : P + : never; -export type Parse>> = ParseTopLevel; +export type Parse>> = ParseTopLevel; diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index 3114eda..7468484 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -1350,717 +1350,395 @@ expectType>([ }, ]); -// expectType>([ -// { -// type: 'ExpressionStatement', -// expression: { -// type: 'MemberExpression', -// object: { type: 'Identifier', name: 'hello' }, -// property: { type: 'Identifier', name: 'world' }, -// }, -// }, -// ]); - -// expectType>([ -// { -// type: 'ExpressionStatement', -// expression: { -// type: 'MemberExpression', -// object: { type: 'StringLiteral', value: 'hello' }, -// property: { type: 'Identifier', name: 'world' }, -// }, -// }, -// ]); - -// expectType>([ -// { -// type: 'ExpressionStatement', -// expression: { -// type: 'MemberExpression', -// object: { type: 'NullLiteral' }, -// property: { type: 'Identifier', name: 'world' }, -// }, -// }, -// ]); - -// expectType>([ -// { -// type: 'ExpressionStatement', -// expression: { -// type: 'CallExpression', -// callee: { type: 'StringLiteral', value: 'hello' }, -// arguments: [], -// }, -// }, -// ]); - -// expectType>([ -// { -// type: 'ExpressionStatement', -// expression: { -// type: 'CallExpression', -// callee: { -// type: 'Identifier', -// name: 'hello', -// }, -// arguments: [], -// }, -// }, -// ]); - -// expectType>([ -// { -// type: 'ExpressionStatement', -// expression: { -// type: 'CallExpression', -// callee: { -// type: 'CallExpression', -// callee: { -// type: 'Identifier', -// name: 'hello', -// }, -// arguments: [], -// }, -// arguments: [], -// }, -// }, -// ]); - -// expectType>([ -// { -// type: 'ExpressionStatement', -// expression: { -// type: 'CallExpression', -// callee: { -// type: 'MemberExpression', -// object: { -// type: 'CallExpression', -// callee: { type: 'Identifier', name: 'hello' }, -// arguments: [], -// }, -// property: { -// type: 'Identifier', -// name: 'world', -// }, -// }, -// arguments: [], -// }, -// }, -// ]); - -// expectType>([ -// { -// type: 'ExpressionStatement', -// expression: { -// type: 'CallExpression', -// callee: { -// type: 'Identifier', -// name: 'hello', -// }, -// arguments: [ -// { -// type: 'CallExpression', -// callee: { type: 'Identifier', name: 'world' }, -// arguments: [ -// { -// type: 'NumericLiteral', -// value: '1', -// }, -// ], -// }, -// ], -// }, -// }, -// ]); - -// expectType>([ -// { -// type: 'ExpressionStatement', -// expression: { -// type: 'CallExpression', -// callee: { -// type: 'Identifier', -// name: 'hello', -// }, -// arguments: [ -// { -// type: 'CallExpression', -// callee: { type: 'StringLiteral', value: 'world' }, -// arguments: [ -// { -// type: 'NumericLiteral', -// value: '1', -// }, -// ], -// }, -// ], -// }, -// }, -// ]); - -// expectType>([ -// { -// type: 'ExpressionStatement', -// expression: { -// type: 'CallExpression', -// callee: { -// type: 'Identifier', -// name: 'hello', -// }, -// arguments: [ -// { type: 'NumericLiteral', value: '1' }, -// { type: 'BooleanLiteral', value: true }, -// ], -// }, -// }, -// ]); - -// expectType>([ -// { -// type: 'ExpressionStatement', -// expression: { -// type: 'CallExpression', -// callee: { -// type: 'MemberExpression', -// object: { -// type: 'Identifier', -// name: 'hello', -// }, -// property: { -// type: 'Identifier', -// name: 'world', -// }, -// }, -// arguments: [ -// { type: 'NumericLiteral', value: '1' }, -// { type: 'BooleanLiteral', value: true }, -// ], -// }, -// }, -// ]); - -// expectType>([ -// { -// type: 'FunctionDeclaration', -// id: { -// type: 'Identifier', -// name: 'foo', -// }, -// params: [], -// body: { -// type: 'BlockStatement', -// body: [], -// }, -// }, -// ]); - -// expectType>([ -// { -// type: 'FunctionDeclaration', -// id: { -// type: 'Identifier', -// name: 'foo', -// }, -// params: [ -// { type: 'Identifier', name: 'first' }, -// { type: 'Identifier', name: 'last' }, -// ], -// body: { -// type: 'BlockStatement', -// body: [], -// }, -// }, -// ]); - -// expectType>([ -// { -// type: 'FunctionDeclaration', -// id: { -// type: 'Identifier', -// name: 'foo', -// }, -// params: [], -// body: { -// type: 'BlockStatement', -// body: [ -// { -// type: 'ReturnStatement', -// argument: { -// type: 'NumericLiteral', -// value: '5', -// }, -// }, -// ], -// }, -// }, -// ]); - -// expectType>([ -// { -// type: 'FunctionDeclaration', -// id: { -// type: 'Identifier', -// name: 'foo', -// }, -// params: [], -// body: { -// type: 'BlockStatement', -// body: [ -// { -// type: 'ReturnStatement', -// argument: { -// type: 'CallExpression', -// callee: { -// type: 'Identifier', -// name: 'bar', -// }, -// arguments: [], -// }, -// }, -// ], -// }, -// }, -// ]); - -// expectType>([ -// { -// type: 'FunctionDeclaration', -// id: { -// type: 'Identifier', -// name: 'foo', -// }, -// params: [ -// { type: 'Identifier', name: 'first' }, -// { type: 'Identifier', name: 'last' }, -// ], -// body: { -// type: 'BlockStatement', -// body: [ -// { -// type: 'ExpressionStatement', -// expression: { -// type: 'CallExpression', -// callee: { -// type: 'MemberExpression', -// object: { type: 'Identifier', name: 'console' }, -// property: { type: 'Identifier', name: 'log' }, -// }, -// arguments: [ -// { -// type: 'NumericLiteral', -// value: '1', -// }, -// ], -// }, -// }, -// ], -// }, -// }, -// ]); - -// expectType< -// ParseAst<` -// function foo(foo) { -// console.log(foo) - -// function bar() { -// console.log(foo) -// } -// } -// `> -// >([ -// { -// type: 'FunctionDeclaration', -// id: { -// type: 'Identifier', -// name: 'foo', -// }, -// params: [{ type: 'Identifier', name: 'foo' }], -// body: { -// type: 'BlockStatement', -// body: [ -// { -// type: 'ExpressionStatement', -// expression: { -// type: 'CallExpression', -// callee: { -// type: 'MemberExpression', -// object: { type: 'Identifier', name: 'console' }, -// property: { type: 'Identifier', name: 'log' }, -// }, -// arguments: [ -// { -// type: 'Identifier', -// name: 'foo', -// }, -// ], -// }, -// }, -// { -// type: 'FunctionDeclaration', -// id: { type: 'Identifier', name: 'bar' }, -// params: [], -// body: { -// type: 'BlockStatement', -// body: [ -// { -// type: 'ExpressionStatement', -// expression: { -// type: 'CallExpression', -// callee: { -// type: 'MemberExpression', -// object: { type: 'Identifier', name: 'console' }, -// property: { type: 'Identifier', name: 'log' }, -// }, -// arguments: [{ type: 'Identifier', name: 'foo' }], -// }, -// }, -// ], -// }, -// }, -// ], -// }, -// }, -// ]); - -// expectType>([ -// { -// type: 'VariableDeclaration', -// kind: 'const', -// declarations: [ -// { -// type: 'VariableDeclarator', -// init: { -// type: 'ArrayExpression', -// elements: [ -// { type: 'NumericLiteral', value: '1' }, -// { type: 'NumericLiteral', value: '2' }, -// { type: 'NumericLiteral', value: '3' }, -// ], -// }, -// id: { type: 'Identifier', name: 'hello' }, -// }, -// ], -// }, -// ]); - -// expectType>([ -// { -// type: 'VariableDeclaration', -// kind: 'const', -// declarations: [ -// { -// type: 'VariableDeclarator', -// init: { -// type: 'ObjectExpression', -// properties: [ -// { -// type: 'ObjectProperty', -// key: { type: 'Identifier', name: 'hey' }, -// value: { type: 'StringLiteral', value: 'ho' }, -// }, -// ], -// }, -// id: { type: 'Identifier', name: 'hello' }, -// }, -// ], -// }, -// ]); - -// expectType>([ -// { -// type: 'VariableDeclaration', -// kind: 'const', -// declarations: [ -// { -// type: 'VariableDeclarator', -// init: { -// type: 'CallExpression', -// callee: { -// type: 'Identifier', -// name: 'foo', -// }, -// arguments: [], -// }, -// id: { type: 'Identifier', name: 'hello' }, -// }, -// ], -// }, -// ]); - -// expectType>([ -// { -// type: 'IfStatement', -// test: { -// type: 'Identifier', -// name: 'a', -// }, -// consequent: { -// type: 'BlockStatement', -// body: [], -// }, -// }, -// ]); - -// expectType>([ -// { -// type: 'IfStatement', -// test: { -// type: 'StringLiteral', -// value: 'a', -// }, -// consequent: { -// type: 'BlockStatement', -// body: [], -// }, -// }, -// ]); - -// expectType>([ -// { -// type: 'IfStatement', -// test: { -// type: 'CallExpression', -// callee: { -// type: 'Identifier', -// name: 'a', -// }, -// arguments: [], -// }, -// consequent: { -// type: 'BlockStatement', -// body: [], -// }, -// }, -// ]); - -// expectType>([ -// { -// type: 'IfStatement', -// test: { -// type: 'Identifier', -// name: 'a', -// }, -// consequent: { -// type: 'BlockStatement', -// body: [ -// { -// type: 'ExpressionStatement', -// expression: { -// type: 'CallExpression', -// callee: { -// type: 'MemberExpression', -// object: { -// type: 'Identifier', -// name: 'console', -// }, -// property: { -// type: 'Identifier', -// name: 'log', -// }, -// }, -// arguments: [], -// }, -// }, -// ], -// }, -// }, -// ]); - -// expectType>([ -// { -// type: 'VariableDeclaration', -// kind: 'const', -// declarations: [ -// { -// type: 'VariableDeclarator', -// init: { type: 'StringLiteral', value: 'world' }, -// id: { -// type: 'Identifier', -// name: 'hello', -// typeAnnotation: { -// type: 'TypeAnnotation', -// typeAnnotation: { type: 'StringTypeAnnotation' }, -// }, -// }, -// }, -// ], -// }, -// ]); - -// expectType>([ -// { -// type: 'VariableDeclaration', -// kind: 'const', -// declarations: [ -// { -// type: 'VariableDeclarator', -// init: { type: 'StringLiteral', value: 'world' }, -// id: { -// type: 'Identifier', -// name: 'hello', -// typeAnnotation: { -// type: 'TypeAnnotation', -// typeAnnotation: { type: 'NumberTypeAnnotation' }, -// }, -// }, -// }, -// ], -// }, -// ]); - -// expectType>([ -// { -// type: 'VariableDeclaration', -// kind: 'const', -// declarations: [ -// { -// type: 'VariableDeclarator', -// init: { type: 'BooleanLiteral', value: true }, -// id: { -// type: 'Identifier', -// name: 'hello', -// typeAnnotation: { -// type: 'TypeAnnotation', -// typeAnnotation: { type: 'BooleanTypeAnnotation' }, -// }, -// }, -// }, -// ], -// }, -// ]); - -// expectType>([ -// { -// type: 'VariableDeclaration', -// kind: 'const', -// declarations: [ -// { -// type: 'VariableDeclarator', -// init: { type: 'StringLiteral', value: 'world' }, -// id: { -// type: 'Identifier', -// name: 'hello', -// typeAnnotation: { -// type: 'TypeAnnotation', -// typeAnnotation: { type: 'NullLiteralTypeAnnotation' }, -// }, -// }, -// }, -// ], -// }, -// ]); - -// expectType>([ -// { -// type: 'FunctionDeclaration', -// id: { -// type: 'Identifier', -// name: 'foo', -// }, -// params: [ -// { -// type: 'Identifier', -// name: 'bar', -// typeAnnotation: { -// type: 'TypeAnnotation', -// typeAnnotation: { -// type: 'StringTypeAnnotation', -// }, -// }, -// }, -// ], -// body: { -// type: 'BlockStatement', -// body: [], -// }, -// }, -// ]); - -// expectType>([ -// { -// type: 'FunctionDeclaration', -// id: { -// type: 'Identifier', -// name: 'foo', -// }, -// params: [ -// { -// type: 'Identifier', -// name: 'bar', -// typeAnnotation: { -// type: 'TypeAnnotation', -// typeAnnotation: { -// type: 'BooleanTypeAnnotation', -// }, -// }, -// }, -// ], -// body: { -// type: 'BlockStatement', -// body: [], -// }, -// }, -// ]); - -// expectType>([ -// { -// type: 'FunctionDeclaration', -// id: { -// type: 'Identifier', -// name: 'foo', -// }, -// params: [ -// { -// type: 'Identifier', -// name: 'bar', -// typeAnnotation: { -// type: 'TypeAnnotation', -// typeAnnotation: { -// type: 'NumberTypeAnnotation', -// }, -// }, -// }, -// ], -// body: { -// type: 'BlockStatement', -// body: [], -// }, -// }, -// ]); - -// expectType>([ -// { -// type: 'FunctionDeclaration', -// id: { -// type: 'Identifier', -// name: 'foo', -// }, -// params: [ -// { -// type: 'Identifier', -// name: 'bar', -// typeAnnotation: { -// type: 'TypeAnnotation', -// typeAnnotation: { -// type: 'StringTypeAnnotation', -// }, -// }, -// }, -// { -// type: 'Identifier', -// name: 'baz', -// typeAnnotation: { -// type: 'TypeAnnotation', -// typeAnnotation: { -// type: 'NullLiteralTypeAnnotation', -// }, -// }, -// }, -// ], -// body: { -// type: 'BlockStatement', -// body: [], -// }, -// }, -// ]); +expectType>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + params: [], + body: { + type: 'BlockStatement', + body: [], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + params: [ + { + type: 'Identifier', + name: 'a', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + body: { + type: 'BlockStatement', + body: [], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + params: [ + { + type: 'Identifier', + name: 'a', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + { + type: 'Identifier', + name: 'b', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + body: { + type: 'BlockStatement', + body: [], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + params: [ + { + type: 'Identifier', + name: 'a', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + { + type: 'Identifier', + name: 'b', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + body: { + type: 'BlockStatement', + body: [ + { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + arguments: [], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + params: [ + { + type: 'Identifier', + name: 'a', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + { + type: 'Identifier', + name: 'b', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + body: { + type: 'BlockStatement', + body: [ + { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + arguments: [], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + { + type: 'ExpressionStatement', + expression: { + type: 'StringLiteral', + value: 'bar', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + params: [ + { + type: 'Identifier', + name: 'a', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + { + type: 'Identifier', + name: 'b', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + body: { + type: 'BlockStatement', + body: [ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'bar', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + body: { + type: 'BlockStatement', + body: [], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + params: [], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>({ + type: 'SyntaxError', + message: 'Identifier expected.', + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: "'(' expected.", + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: "')' expected.", + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: "'{' expected.", + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: "'{' expected.", + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: "'}' expected.", + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: 'Identifier expected.', + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: "',' expected.", + lineNumber: 1, +}); From 679cd73774b2b30c43a6a176f0e5d038f50ab099 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 8 Jul 2022 15:58:34 +0300 Subject: [PATCH 123/286] wip --- src/parser.ts | 6 +++++- src/test/parser.test.ts | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/parser.ts b/src/parser.ts index c8c4dae..2b4fbcd 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -512,7 +512,11 @@ type ParseTopLevelHelper>> = ? P extends null ? ParseVariableDeclaration extends infer P ? P extends null - ? ParseExpressionStatement + ? ParseExpressionStatement extends infer P + ? P extends null + ? SyntaxError<'Declaration or statement expected.', 1> + : P + : P : P : P : P diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index 7468484..1149f07 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -1742,3 +1742,9 @@ expectType>({ message: "',' expected.", lineNumber: 1, }); + +expectType>({ + type: 'SyntaxError', + message: 'Declaration or statement expected.', + lineNumber: 1, +}); From f3b5429a28dc7cc3a9fd4c55803013000766dff7 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 8 Jul 2022 18:48:47 +0300 Subject: [PATCH 124/286] wip --- src/parser.ts | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 2b4fbcd..d334194 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -474,10 +474,10 @@ type ParseBlockStatement< : T[0] extends GenericToken<';', any> ? ParseBlockStatement, R, false> : N extends false - ? ParseBlockStatementErrorHelper, R> + ? ParseBlockStatementHelper, R> : T[0] extends Token> ? P extends true - ? ParseBlockStatementErrorHelper, R> + ? ParseBlockStatementHelper, R> : SyntaxError<"';' expected.", L> : never; @@ -490,24 +490,23 @@ type ParseTopLevel< : T[0] extends GenericToken<';', any> ? ParseTopLevel, R, false> : N extends false - ? ParseTopLevelErrorHelper, R> + ? ParseTopLevelHelper, R> : T[0] extends Token> ? P extends true - ? ParseTopLevelErrorHelper, R> + ? ParseTopLevelHelper, R> : SyntaxError<"';' expected.", L> : never; -type ParseBlockStatementErrorHelper< +type ParseBlockStatementHelper< T, R extends Array>, > = T extends Array ? ParseBlockStatement, true> : T; -type ParseTopLevelErrorHelper< - T, - R extends Array>, -> = T extends Array ? ParseTopLevel, true> : T; +type ParseTopLevelHelper>> = T extends Array + ? ParseTopLevel, true> + : T; -type ParseTopLevelHelper>> = +type ParseStatementHelper>> = ParseFunctionDeclaration extends infer P ? P extends null ? ParseVariableDeclaration extends infer P From d4019be778b0341d2dda9e981c1d1d8403aeda63 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 8 Jul 2022 18:52:58 +0300 Subject: [PATCH 125/286] wip --- src/parser.ts | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index d334194..6a9a836 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -474,10 +474,10 @@ type ParseBlockStatement< : T[0] extends GenericToken<';', any> ? ParseBlockStatement, R, false> : N extends false - ? ParseBlockStatementHelper, R> + ? ParseBlockStatementHelper : T[0] extends Token> ? P extends true - ? ParseBlockStatementHelper, R> + ? ParseBlockStatementHelper : SyntaxError<"';' expected.", L> : never; @@ -490,21 +490,30 @@ type ParseTopLevel< : T[0] extends GenericToken<';', any> ? ParseTopLevel, R, false> : N extends false - ? ParseTopLevelHelper, R> + ? ParseTopLevelHelper : T[0] extends Token> ? P extends true - ? ParseTopLevelHelper, R> + ? ParseTopLevelHelper : SyntaxError<"';' expected.", L> : never; type ParseBlockStatementHelper< - T, + T extends Array>, R extends Array>, -> = T extends Array ? ParseBlockStatement, true> : T; +> = ParseStatementHelper extends infer G + ? G extends Array + ? ParseBlockStatement, true> + : G + : never; -type ParseTopLevelHelper>> = T extends Array - ? ParseTopLevel, true> - : T; +type ParseTopLevelHelper< + T extends Array>, + R extends Array>, +> = ParseStatementHelper extends infer G + ? G extends Array + ? ParseTopLevel, true> + : G + : never; type ParseStatementHelper>> = ParseFunctionDeclaration extends infer P From 26e28310e44caa8e1839a4b40506695555d433c8 Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 9 Jul 2022 00:39:37 +0300 Subject: [PATCH 126/286] wip --- src/parser.ts | 30 +++++---- src/test/parser.test.ts | 142 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 160 insertions(+), 12 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 6a9a836..27da17a 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -511,23 +511,29 @@ type ParseTopLevelHelper< R extends Array>, > = ParseStatementHelper extends infer G ? G extends Array - ? ParseTopLevel, true> + ? ParseTopLevel, G[2]> : G : never; type ParseStatementHelper>> = ParseFunctionDeclaration extends infer P - ? P extends null - ? ParseVariableDeclaration extends infer P - ? P extends null - ? ParseExpressionStatement extends infer P - ? P extends null - ? SyntaxError<'Declaration or statement expected.', 1> - : P - : P - : P - : P - : P + ? P extends Array + ? [...P, false] + : P extends Error + ? P + : ParseVariableDeclaration extends infer P + ? P extends Array + ? [...P, true] + : P extends Error + ? P + : ParseExpressionStatement extends infer P + ? P extends Array + ? [...P, true] + : P extends Error + ? P + : SyntaxError<'Declaration or statement expected.', 1> + : never + : never : never; export type Parse>> = ParseTopLevel; diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index 1149f07..cc0ce5f 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -1748,3 +1748,145 @@ expectType>({ message: 'Declaration or statement expected.', lineNumber: 1, }); + +expectType>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + params: [ + { + type: 'Identifier', + name: 'a', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + { + type: 'Identifier', + name: 'b', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + body: { + type: 'BlockStatement', + body: [], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + arguments: [], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + params: [ + { + type: 'Identifier', + name: 'a', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + { + type: 'Identifier', + name: 'b', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + body: { + type: 'BlockStatement', + body: [], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + arguments: [], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); From cfb67a285e93d1b9a9a22ae536c859493f54f7e2 Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 9 Jul 2022 01:11:34 +0300 Subject: [PATCH 127/286] wip --- src/index.ts | 2 +- src/parser.ts | 39 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/index.ts b/src/index.ts index 9543c74..bff9fb1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`function foo () {} console.log()`>; +type T = Tokenize<`if (1) {}`>; type R = Parse; // type C = Check<[R]>; diff --git a/src/parser.ts b/src/parser.ts index 27da17a..5d26e62 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -515,6 +515,33 @@ type ParseTopLevelHelper< : G : never; +type ParseIfStatement>> = T[0] extends SymbolToken< + 'if', + any +> + ? T[1] extends GenericToken<'(', any> + ? ParseExpression> extends infer G + ? G extends Array + ? ParseIfStatementHelper + : G extends Error + ? G + : SyntaxError<'Expression expected.', 1> + : never + : SyntaxError<"'(' expected.", 1> + : null; + +type ParseIfStatementHelper> = G[1] extends Array + ? G[1][0] extends GenericToken<')', any> + ? G[1][1] extends GenericToken<'{', any> + ? ParseBlockStatement> extends infer B + ? B extends Array + ? [IfStatement>, B[1]] + : B + : never + : SyntaxError<"'{' expected.", 1> + : SyntaxError<"')' expected.", 1> + : never; + type ParseStatementHelper>> = ParseFunctionDeclaration extends infer P ? P extends Array @@ -526,12 +553,18 @@ type ParseStatementHelper>> = ? [...P, true] : P extends Error ? P - : ParseExpressionStatement extends infer P + : ParseIfStatement extends infer P ? P extends Array - ? [...P, true] + ? [...P, false] : P extends Error ? P - : SyntaxError<'Declaration or statement expected.', 1> + : ParseExpressionStatement extends infer P + ? P extends Array + ? [...P, true] + : P extends Error + ? P + : SyntaxError<'Declaration or statement expected.', 1> + : never : never : never : never; From e20f05577dbac3c114d84e6801472f04bf5bc7f7 Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 9 Jul 2022 01:17:50 +0300 Subject: [PATCH 128/286] wip --- src/test/parser.test.ts | 242 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index cc0ce5f..d7b684e 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -1890,3 +1890,245 @@ expectType>([ }, }, ]); + +expectType>([ + { + type: 'IfStatement', + test: { + type: 'Identifier', + name: 'a', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + consequent: { + type: 'BlockStatement', + body: [], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'IfStatement', + test: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + arguments: [], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + consequent: { + type: 'BlockStatement', + body: [], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'IfStatement', + test: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + arguments: [], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + consequent: { + type: 'BlockStatement', + body: [ + { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'bar', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + arguments: [], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'IfStatement', + test: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + arguments: [], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + consequent: { + type: 'BlockStatement', + body: [ + { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'bar', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + arguments: [], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'bazz', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + arguments: [], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>({ + type: 'SyntaxError', + message: "'(' expected.", + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: 'Expression expected.', + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: "')' expected.", + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: "'{' expected.", + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: "'}' expected.", + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: 'Expression expected.', + lineNumber: 1, +}); From 94763c468675691c37805bb77ab3ca430a11a48e Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 9 Jul 2022 01:27:37 +0300 Subject: [PATCH 129/286] wip --- src/parser.ts | 139 -------------------------------------------------- 1 file changed, 139 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 5d26e62..e2d863e 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -37,145 +37,6 @@ import type { } from './tokens'; import type { Push, Tail, TailBy } from './utils/arrayUtils'; -// type DoParseExpression< -// T extends Array>, -// F = T[0], -// > = F extends SymbolToken<'true'> -// ? [BooleanLiteral, Tail] -// : F extends SymbolToken<'false'> -// ? [BooleanLiteral, Tail] -// : F extends SymbolToken<'null'> -// ? [NullLiteral, Tail] -// : F extends NumberToken -// ? [NumericLiteral, Tail] -// : F extends StringToken -// ? [StringLiteral, Tail] -// : F extends BracketToken<'['> -// ? ParseArray> -// : F extends CurlyToken<'{'> -// ? ParseObject> -// : F extends SymbolToken -// ? [Identifier, Tail] -// : [never, []]; - -// type ParseExpression>> = -// DoParseExpression extends infer G -// ? Wrap]>> -// : never; - -// type ParseStatement< -// T extends Array>, -// F = T[0], -// > = F extends SymbolToken<'const'> -// ? ParseVariableDeclaration> -// : F extends SymbolToken<'function'> -// ? ParseFunctionDeclaration> -// : F extends SymbolToken<'if'> -// ? ParseIfStatement> -// : ParseExpression extends infer G -// ? [ExpressionStatement>[0]>, Cast>[1]] -// : never; - -// type ParseFunctionStatement>> = -// T[0] extends SymbolToken<'return'> -// ? ParseExpression> extends infer G -// ? [ReturnStatement>[0]>, Cast>[1]] -// : never -// : ParseStatement; - -// type ParseIfStatement>> = -// T[0] extends ParenToken<'('> -// ? ParseExpression> extends infer G -// ? Cast>[1] extends infer J -// ? Cast>[0] extends ParenToken<')'> -// ? Cast>[1] extends CurlyToken<'{'> -// ? ParseBlockStatement< -// Tail>>> -// > extends infer B -// ? [ -// IfStatement>[0], Cast>[0]>, -// Cast>[1], -// ] -// : never -// : never -// : never -// : never -// : never -// : never; - -// type ParseFunctionArguments< -// T extends Array>, -// R extends Array = [], -// N extends boolean = false, -// > = T[0] extends ParenToken<')'> -// ? [Reverse, Tail] -// : T extends [] -// ? never -// : N extends true -// ? T[0] extends CommaToken -// ? ParseFunctionArgumentsItem, R> -// : never -// : ParseFunctionArgumentsItem; - -// type ParseFunctionArgumentsItem< -// T extends Array>, -// R extends Array = [], -// > = ParseExpression extends infer G -// ? ParseFunctionArguments< -// Cast>[1], -// Unshift>[0]>, -// true -// > -// : never; - -// type ParseTypeAnnotation>> = -// T[0] extends SymbolToken<'string'> -// ? [TypeAnnotation, Tail] -// : T[0] extends SymbolToken<'boolean'> -// ? [TypeAnnotation, Tail] -// : T[0] extends SymbolToken<'null'> -// ? [TypeAnnotation, Tail] -// : T[0] extends SymbolToken<'number'> -// ? [TypeAnnotation, Tail] -// : T[0] extends SymbolToken<'any'> -// ? [TypeAnnotation, Tail] -// : T[0] extends SymbolToken -// ? [TypeAnnotation>, Tail] -// : never; - -// type ParseVariableDeclarationHelper< -// T extends Array>, -// K, -// Q = null, -// > = ParseExpression extends infer G -// ? [ -// VariableDeclaration< -// [VariableDeclarator, Cast>[0]>], -// 'const' -// >, -// Cast>[1], -// ] -// : never; - -// type ParseVariableDeclaration>> = -// T[0] extends SymbolToken -// ? T[1] extends ColonToken -// ? ParseTypeAnnotation>> extends infer G -// ? Cast>[1][0] extends SymbolToken<'='> -// ? Cast>[1] extends infer J -// ? ParseVariableDeclarationHelper< -// Tail>>, -// K, -// Cast>[0] -// > -// : never -// : never -// : never -// : T[1] extends SymbolToken<'='> -// ? ParseVariableDeclarationHelper>, K> -// : never -// : never; - type ExtractTokenData< T extends Token, R extends Token = T, From d49f7f61bad1d327cbd70b622d899267d2a9fb9f Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 9 Jul 2022 10:45:47 +0300 Subject: [PATCH 130/286] wip --- src/index.ts | 2 +- src/parser.ts | 28 ++++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/index.ts b/src/index.ts index bff9fb1..4e58e9d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`if (1) {}`>; +type T = Tokenize<`return 123;`>; type R = Parse; // type C = Check<[R]>; diff --git a/src/parser.ts b/src/parser.ts index e2d863e..e3a9f6e 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -391,6 +391,24 @@ type ParseIfStatement>> = T[0] extends SymbolToken< : SyntaxError<"'(' expected.", 1> : null; +type ParseReturnStatementHelper>> = + T[0] extends GenericToken<';', any> + ? [ReturnStatement>, Tail] + : ParseExpression extends infer G + ? G extends Array + ? [ReturnStatement>, G[1]] + : G + : never; + +type ParseReturnStatement>> = + T[0] extends SymbolToken<'return', any> + ? T[1] extends Token, any> + ? P extends false + ? ParseReturnStatementHelper> + : [ReturnStatement>, Tail] + : [ReturnStatement>, []] + : null; + type ParseIfStatementHelper> = G[1] extends Array ? G[1][0] extends GenericToken<')', any> ? G[1][1] extends GenericToken<'{', any> @@ -419,12 +437,18 @@ type ParseStatementHelper>> = ? [...P, false] : P extends Error ? P - : ParseExpressionStatement extends infer P + : ParseReturnStatement extends infer P ? P extends Array ? [...P, true] : P extends Error ? P - : SyntaxError<'Declaration or statement expected.', 1> + : ParseExpressionStatement extends infer P + ? P extends Array + ? [...P, true] + : P extends Error + ? P + : SyntaxError<'Declaration or statement expected.', 1> + : never : never : never : never From 81325a751fcf85896ae0a48f9ed54c111860d098 Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 9 Jul 2022 11:11:07 +0300 Subject: [PATCH 131/286] wip --- src/index.ts | 2 +- src/parser.ts | 87 +++++++++++++++++++++++++++++---------------------- 2 files changed, 51 insertions(+), 38 deletions(-) diff --git a/src/index.ts b/src/index.ts index 4e58e9d..f1cfa89 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`return 123;`>; +type T = Tokenize<`function \n\nfoo() {\n\n\n\n}`>; type R = Parse; // type C = Check<[R]>; diff --git a/src/parser.ts b/src/parser.ts index e3a9f6e..2e44331 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -278,17 +278,19 @@ type ParseFunctionDeclaration>> = ? T[2] extends GenericToken<'(', any> ? ParseFunctionParams> extends infer G ? G extends Array - ? ParseBlockStatement extends infer H + ? ParseBlockStatement extends infer H ? H extends Array - ? [ - FunctionDeclaration< - Identifier>, - G[0], - H[0], - NodeData<1, 1> - >, - H[1], - ] + ? H[0] extends Node> + ? [ + FunctionDeclaration< + Identifier>, + G[0], + H[0], + NodeData + >, + H[1], + ] + : never : H : never : G @@ -302,8 +304,8 @@ type ParseFunctionParams< R extends Array = [], N extends boolean = false, > = T[0] extends GenericToken<')', TokenData> - ? T[1] extends GenericToken<'{', any> - ? [R, TailBy] + ? T[1] extends GenericToken<'{', TokenData> + ? [R, TailBy, K] : SyntaxError<"'{' expected.", L> : T extends [] ? SyntaxError<"')' expected.", 1> @@ -316,29 +318,30 @@ type ParseFunctionParams< type ParseFunctionParamsHelper< T extends Array>, R extends Array = [], -> = T[0] extends SymbolToken +> = T[0] extends SymbolToken> ? ParseFunctionParams< Tail, - Push>>, + Push>>, true > : SyntaxError<'Identifier expected.', 1>; type ParseBlockStatement< T extends Array>, + L extends number, R extends Array> = [], N extends boolean = false, > = T extends [] ? SyntaxError<"'}' expected.", 1> - : T[0] extends GenericToken<'}', any> - ? [BlockStatement>, Tail] + : T[0] extends GenericToken<'}', TokenData> + ? [BlockStatement>, Tail] : T[0] extends GenericToken<';', any> - ? ParseBlockStatement, R, false> + ? ParseBlockStatement, L, R, false> : N extends false - ? ParseBlockStatementHelper + ? ParseBlockStatementHelper : T[0] extends Token> ? P extends true - ? ParseBlockStatementHelper + ? ParseBlockStatementHelper : SyntaxError<"';' expected.", L> : never; @@ -360,10 +363,11 @@ type ParseTopLevel< type ParseBlockStatementHelper< T extends Array>, + L extends number, R extends Array>, > = ParseStatementHelper extends infer G ? G extends Array - ? ParseBlockStatement, true> + ? ParseBlockStatement, true> : G : never; @@ -378,12 +382,12 @@ type ParseTopLevelHelper< type ParseIfStatement>> = T[0] extends SymbolToken< 'if', - any + TokenData > ? T[1] extends GenericToken<'(', any> ? ParseExpression> extends infer G ? G extends Array - ? ParseIfStatementHelper + ? ParseIfStatementHelper : G extends Error ? G : SyntaxError<'Expression expected.', 1> @@ -391,30 +395,39 @@ type ParseIfStatement>> = T[0] extends SymbolToken< : SyntaxError<"'(' expected.", 1> : null; -type ParseReturnStatementHelper>> = - T[0] extends GenericToken<';', any> - ? [ReturnStatement>, Tail] - : ParseExpression extends infer G - ? G extends Array - ? [ReturnStatement>, G[1]] +type ParseReturnStatementHelper< + T extends Array>, + L extends number, +> = T[0] extends GenericToken<';', TokenData> + ? [ReturnStatement>, Tail] + : ParseExpression extends infer G + ? G extends Array + ? G[0] extends Node> + ? [ReturnStatement>, G[1]] : G - : never; + : never + : never; type ParseReturnStatement>> = - T[0] extends SymbolToken<'return', any> + T[0] extends SymbolToken<'return', TokenData> ? T[1] extends Token, any> ? P extends false - ? ParseReturnStatementHelper> - : [ReturnStatement>, Tail] - : [ReturnStatement>, []] + ? ParseReturnStatementHelper, L> + : [ReturnStatement>, Tail] + : [ReturnStatement>, []] : null; -type ParseIfStatementHelper> = G[1] extends Array +type ParseIfStatementHelper< + G extends Array, + L extends number, +> = G[1] extends Array ? G[1][0] extends GenericToken<')', any> - ? G[1][1] extends GenericToken<'{', any> - ? ParseBlockStatement> extends infer B + ? G[1][1] extends GenericToken<'{', TokenData> + ? ParseBlockStatement, H> extends infer B ? B extends Array - ? [IfStatement>, B[1]] + ? B[0] extends Node> + ? [IfStatement>, B[1]] + : never : B : never : SyntaxError<"'{' expected.", 1> From c72df4c7eefb67f03974ecd76c3e7683ec9b3220 Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 9 Jul 2022 11:18:29 +0300 Subject: [PATCH 132/286] wip --- src/index.ts | 2 +- src/parser.ts | 76 ++++++++++++++++++++++++----------------- src/test/parser.test.ts | 18 ++++++++++ 3 files changed, 63 insertions(+), 33 deletions(-) diff --git a/src/index.ts b/src/index.ts index f1cfa89..675ecc8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`function \n\nfoo() {\n\n\n\n}`>; +type T = Tokenize<`function foo () { return 1 }`>; type R = Parse; // type C = Check<[R]>; diff --git a/src/parser.ts b/src/parser.ts index 2e44331..9052bac 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -278,7 +278,7 @@ type ParseFunctionDeclaration>> = ? T[2] extends GenericToken<'(', any> ? ParseFunctionParams> extends infer G ? G extends Array - ? ParseBlockStatement extends infer H + ? ParseBlockStatement extends infer H ? H extends Array ? H[0] extends Node> ? [ @@ -329,6 +329,7 @@ type ParseFunctionParamsHelper< type ParseBlockStatement< T extends Array>, L extends number, + F extends boolean, R extends Array> = [], N extends boolean = false, > = T extends [] @@ -336,12 +337,12 @@ type ParseBlockStatement< : T[0] extends GenericToken<'}', TokenData> ? [BlockStatement>, Tail] : T[0] extends GenericToken<';', any> - ? ParseBlockStatement, L, R, false> + ? ParseBlockStatement, L, F, R, false> : N extends false - ? ParseBlockStatementHelper + ? ParseBlockStatementHelper : T[0] extends Token> ? P extends true - ? ParseBlockStatementHelper + ? ParseBlockStatementHelper : SyntaxError<"';' expected.", L> : never; @@ -364,30 +365,31 @@ type ParseTopLevel< type ParseBlockStatementHelper< T extends Array>, L extends number, + F extends boolean, R extends Array>, -> = ParseStatementHelper extends infer G +> = ParseStatementHelper extends infer G ? G extends Array - ? ParseBlockStatement, true> + ? ParseBlockStatement, true> : G : never; type ParseTopLevelHelper< T extends Array>, R extends Array>, -> = ParseStatementHelper extends infer G +> = ParseStatementHelper extends infer G ? G extends Array ? ParseTopLevel, G[2]> : G : never; -type ParseIfStatement>> = T[0] extends SymbolToken< - 'if', - TokenData -> +type ParseIfStatement< + T extends Array>, + F extends boolean, +> = T[0] extends SymbolToken<'if', TokenData> ? T[1] extends GenericToken<'(', any> ? ParseExpression> extends infer G ? G extends Array - ? ParseIfStatementHelper + ? ParseIfStatementHelper : G extends Error ? G : SyntaxError<'Expression expected.', 1> @@ -408,22 +410,30 @@ type ParseReturnStatementHelper< : never : never; -type ParseReturnStatement>> = - T[0] extends SymbolToken<'return', TokenData> +type ParseReturnStatement< + T extends Array>, + F extends boolean, +> = T[0] extends SymbolToken<'return', TokenData> + ? F extends true ? T[1] extends Token, any> ? P extends false ? ParseReturnStatementHelper, L> : [ReturnStatement>, Tail] : [ReturnStatement>, []] - : null; + : SyntaxError< + "A 'return' statement can only be used within a function body.", + L + > + : null; type ParseIfStatementHelper< G extends Array, L extends number, + F extends boolean, > = G[1] extends Array ? G[1][0] extends GenericToken<')', any> ? G[1][1] extends GenericToken<'{', TokenData> - ? ParseBlockStatement, H> extends infer B + ? ParseBlockStatement, H, F> extends infer B ? B extends Array ? B[0] extends Node> ? [IfStatement>, B[1]] @@ -434,37 +444,39 @@ type ParseIfStatementHelper< : SyntaxError<"')' expected.", 1> : never; -type ParseStatementHelper>> = - ParseFunctionDeclaration extends infer P +type ParseStatementHelper< + T extends Array>, + F extends boolean, +> = ParseFunctionDeclaration extends infer P + ? P extends Array + ? [...P, false] + : P extends Error + ? P + : ParseVariableDeclaration extends infer P ? P extends Array - ? [...P, false] + ? [...P, true] : P extends Error ? P - : ParseVariableDeclaration extends infer P + : ParseIfStatement extends infer P ? P extends Array - ? [...P, true] + ? [...P, false] : P extends Error ? P - : ParseIfStatement extends infer P + : ParseReturnStatement extends infer P ? P extends Array - ? [...P, false] + ? [...P, true] : P extends Error ? P - : ParseReturnStatement extends infer P + : ParseExpressionStatement extends infer P ? P extends Array ? [...P, true] : P extends Error ? P - : ParseExpressionStatement extends infer P - ? P extends Array - ? [...P, true] - : P extends Error - ? P - : SyntaxError<'Declaration or statement expected.', 1> - : never + : SyntaxError<'Declaration or statement expected.', 1> : never : never : never - : never; + : never + : never; export type Parse>> = ParseTopLevel; diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index d7b684e..e3b4dd4 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -2132,3 +2132,21 @@ expectType>({ message: 'Expression expected.', lineNumber: 1, }); + +expectType>({ + type: 'SyntaxError', + message: "A 'return' statement can only be used within a function body.", + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: "A 'return' statement can only be used within a function body.", + lineNumber: 1, +}); + +expectType>({ + type: 'SyntaxError', + message: "A 'return' statement can only be used within a function body.", + lineNumber: 1, +}); From 883869ded2a43e253b9798a2fe55716f2c70caaa Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 9 Jul 2022 11:21:48 +0300 Subject: [PATCH 133/286] wip --- src/test/parser.test.ts | 162 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index e3b4dd4..e7028b0 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -2150,3 +2150,165 @@ expectType>({ message: "A 'return' statement can only be used within a function body.", lineNumber: 1, }); + +expectType>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + params: [], + body: { + type: 'BlockStatement', + body: [ + { + type: 'ReturnStatement', + argument: { + type: 'NumericLiteral', + value: '1', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + params: [], + body: { + type: 'BlockStatement', + body: [ + { + type: 'ReturnStatement', + argument: { + type: 'NumericLiteral', + value: '1', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + params: [], + body: { + type: 'BlockStatement', + body: [ + { + type: 'ReturnStatement', + argument: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + params: [], + body: { + type: 'BlockStatement', + body: [ + { + type: 'ReturnStatement', + argument: null, + data: { + startLineNumber: 2, + endLineNumber: 2, + }, + }, + ], + data: { + startLineNumber: 1, + endLineNumber: 3, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 3, + }, + }, +]); From 8aff4a73732bb6071b0c0d8708e88c6f27cf2e01 Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 9 Jul 2022 18:12:26 +0300 Subject: [PATCH 134/286] wip --- src/index.ts | 2 +- src/parser.ts | 78 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 48 insertions(+), 32 deletions(-) diff --git a/src/index.ts b/src/index.ts index 675ecc8..744ad09 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`function foo () { return 1 }`>; +type T = Tokenize<`const hello: number = 1`>; type R = Parse; // type C = Check<[R]>; diff --git a/src/parser.ts b/src/parser.ts index 9052bac..afa26c0 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -46,42 +46,58 @@ type ExtractTokenData< : never : never; -type ParseVariableDeclarationHelper< - L extends Node, - N extends string, - NL extends number, - FL extends number, +type ParseIdentifier< T extends Array>, -> = L extends Node> - ? [ - VariableDeclaration< - [ - VariableDeclarator< - Identifier>, - L, - NodeData + O extends boolean, +> = T[0] extends SymbolToken> + ? O extends true + ? T[1] extends GenericToken<':', TokenData> + ? T[2] extends SymbolToken + ? [ + Identifier>, NodeData>, + TailBy, + ] + : SyntaxError<'Type expected.', G> + : [Identifier>, Tail] + : [Identifier>, Tail] + : null; + +type ParseVariableDeclarationHelper< + R extends Array>, + N extends Node, + L extends number, + S extends number, + K extends number, +> = ParseExpression> extends infer G + ? G extends Array + ? G[0] extends Node> + ? [ + VariableDeclaration< + [VariableDeclarator>], + 'const', + NodeData >, - ], - 'const', - NodeData - >, - T, - ] + G[1], + ] + : never + : G extends null + ? SyntaxError<'Expression expected.', K> + : G : never; type ParseVariableDeclaration>> = - T[0] extends SymbolToken<'const', TokenData> - ? T[1] extends SymbolToken> - ? T[2] extends SymbolToken<'=', TokenData> - ? ParseExpression> extends [infer L, infer T] - ? L extends Node - ? T extends Array> - ? ParseVariableDeclarationHelper - : never - : never - : SyntaxError<'Expression expected.', KL> - : SyntaxError<"'const' declarations must be initialized.", NL> - : SyntaxError<'Variable declaration list cannot be empty.', FL> + T[0] extends SymbolToken<'const', TokenData> + ? ParseIdentifier, true> extends infer N + ? N extends [Node>, infer R] + ? R extends Array + ? R[0] extends SymbolToken<'=', TokenData> + ? ParseVariableDeclarationHelper + : SyntaxError<"'const' declarations must be initialized.", S> + : never + : N extends null + ? SyntaxError<'Variable declaration list cannot be empty.', L> + : N + : never : null; type ParseMemberExpression< From c94fdaf18a80ee1ca00146f08ba72393ce80ae3c Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 9 Jul 2022 19:08:17 +0300 Subject: [PATCH 135/286] wip --- src/parser.ts | 52 +++++++-- src/test/parser.test.ts | 230 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 276 insertions(+), 6 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index afa26c0..404084c 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -52,12 +52,13 @@ type ParseIdentifier< > = T[0] extends SymbolToken> ? O extends true ? T[1] extends GenericToken<':', TokenData> - ? T[2] extends SymbolToken - ? [ - Identifier>, NodeData>, - TailBy, - ] - : SyntaxError<'Type expected.', G> + ? ParseTypeAnnotation> extends infer J + ? J extends Array + ? [Identifier>, J[1]] + : J extends Error + ? J + : SyntaxError<'Type expected.', G> + : never : [Identifier>, Tail] : [Identifier>, Tail] : null; @@ -85,6 +86,45 @@ type ParseVariableDeclarationHelper< : G : never; +type ParseTypeAnnotation>> = + T[0] extends SymbolToken<'string', TokenData> + ? [ + TypeAnnotation>, NodeData>, + Tail, + ] + : T[0] extends SymbolToken<'boolean', TokenData> + ? [ + TypeAnnotation>, NodeData>, + Tail, + ] + : T[0] extends SymbolToken<'null', TokenData> + ? [ + TypeAnnotation< + NullLiteralTypeAnnotation>, + NodeData + >, + Tail, + ] + : T[0] extends SymbolToken<'number', TokenData> + ? [ + TypeAnnotation>, NodeData>, + Tail, + ] + : T[0] extends SymbolToken<'any', TokenData> + ? [ + TypeAnnotation>, NodeData>, + Tail, + ] + : T[0] extends SymbolToken> + ? [ + TypeAnnotation< + GenericTypeAnnotation>, + NodeData + >, + Tail, + ] + : never; + type ParseVariableDeclaration>> = T[0] extends SymbolToken<'const', TokenData> ? ParseIdentifier, true> extends infer N diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index e7028b0..8aeb798 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -258,6 +258,7 @@ expectType>([ }, }, ]); + expectType>([ { type: 'VariableDeclaration', @@ -2312,3 +2313,232 @@ expectType>([ }, }, ]); + +expectType>([ + { + type: 'VariableDeclaration', + kind: 'const', + declarations: [ + { + type: 'VariableDeclarator', + init: { + type: 'StringLiteral', + value: 'world', + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + id: { + type: 'Identifier', + name: 'hello', + typeAnnotation: { + type: 'TypeAnnotation', + typeAnnotation: { + type: 'StringTypeAnnotation', + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + data: { startLineNumber: 1, endLineNumber: 1 }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'VariableDeclaration', + kind: 'const', + declarations: [ + { + type: 'VariableDeclarator', + init: { + type: 'StringLiteral', + value: 'world', + data: { startLineNumber: 4, endLineNumber: 4 }, + }, + id: { + type: 'Identifier', + name: 'hello', + typeAnnotation: { + type: 'TypeAnnotation', + typeAnnotation: { + type: 'NumberTypeAnnotation', + data: { startLineNumber: 3, endLineNumber: 3 }, + }, + data: { startLineNumber: 3, endLineNumber: 3 }, + }, + data: { startLineNumber: 2, endLineNumber: 2 }, + }, + data: { + startLineNumber: 2, + endLineNumber: 4, + }, + }, + ], + data: { + startLineNumber: 1, + endLineNumber: 4, + }, + }, +]); + +expectType>([ + { + type: 'VariableDeclaration', + kind: 'const', + declarations: [ + { + type: 'VariableDeclarator', + init: { + type: 'StringLiteral', + value: 'world', + data: { startLineNumber: 4, endLineNumber: 4 }, + }, + id: { + type: 'Identifier', + name: 'hello', + typeAnnotation: { + type: 'TypeAnnotation', + typeAnnotation: { + type: 'NullLiteralTypeAnnotation', + data: { startLineNumber: 3, endLineNumber: 3 }, + }, + data: { startLineNumber: 3, endLineNumber: 3 }, + }, + data: { startLineNumber: 2, endLineNumber: 2 }, + }, + data: { + startLineNumber: 2, + endLineNumber: 4, + }, + }, + ], + data: { + startLineNumber: 1, + endLineNumber: 4, + }, + }, +]); + +expectType>([ + { + type: 'VariableDeclaration', + kind: 'const', + declarations: [ + { + type: 'VariableDeclarator', + init: { + type: 'StringLiteral', + value: 'world', + data: { startLineNumber: 4, endLineNumber: 4 }, + }, + id: { + type: 'Identifier', + name: 'hello', + typeAnnotation: { + type: 'TypeAnnotation', + typeAnnotation: { + type: 'BooleanTypeAnnotation', + data: { startLineNumber: 3, endLineNumber: 3 }, + }, + data: { startLineNumber: 3, endLineNumber: 3 }, + }, + data: { startLineNumber: 2, endLineNumber: 2 }, + }, + data: { + startLineNumber: 2, + endLineNumber: 4, + }, + }, + ], + data: { + startLineNumber: 1, + endLineNumber: 4, + }, + }, +]); + +expectType>([ + { + type: 'VariableDeclaration', + kind: 'const', + declarations: [ + { + type: 'VariableDeclarator', + init: { + type: 'StringLiteral', + value: 'world', + data: { startLineNumber: 4, endLineNumber: 4 }, + }, + id: { + type: 'Identifier', + name: 'hello', + typeAnnotation: { + type: 'TypeAnnotation', + typeAnnotation: { + type: 'AnyTypeAnnotation', + data: { startLineNumber: 3, endLineNumber: 3 }, + }, + data: { startLineNumber: 3, endLineNumber: 3 }, + }, + data: { startLineNumber: 2, endLineNumber: 2 }, + }, + data: { + startLineNumber: 2, + endLineNumber: 4, + }, + }, + ], + data: { + startLineNumber: 1, + endLineNumber: 4, + }, + }, +]); + +expectType>([ + { + type: 'VariableDeclaration', + kind: 'const', + declarations: [ + { + type: 'VariableDeclarator', + init: { + type: 'StringLiteral', + value: 'world', + data: { startLineNumber: 4, endLineNumber: 4 }, + }, + id: { + type: 'Identifier', + name: 'hello', + typeAnnotation: { + type: 'TypeAnnotation', + typeAnnotation: { + type: 'GenericTypeAnnotation', + id: 'Foo', + data: { startLineNumber: 3, endLineNumber: 3 }, + }, + data: { startLineNumber: 3, endLineNumber: 3 }, + }, + data: { startLineNumber: 2, endLineNumber: 2 }, + }, + data: { + startLineNumber: 2, + endLineNumber: 4, + }, + }, + ], + data: { + startLineNumber: 1, + endLineNumber: 4, + }, + }, +]); From 7dd60730a81c4c7b523ad3a73e0cc63b8a550aa2 Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 9 Jul 2022 19:17:11 +0300 Subject: [PATCH 136/286] wip --- src/index.ts | 2 +- src/parser.ts | 14 ++-- src/test/parser.test.ts | 175 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+), 8 deletions(-) diff --git a/src/index.ts b/src/index.ts index 744ad09..bb86d8c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`const hello: number = 1`>; +type T = Tokenize<`function foo(a: string) {}`>; type R = Parse; // type C = Check<[R]>; diff --git a/src/parser.ts b/src/parser.ts index 404084c..04755c5 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -374,13 +374,13 @@ type ParseFunctionParams< type ParseFunctionParamsHelper< T extends Array>, R extends Array = [], -> = T[0] extends SymbolToken> - ? ParseFunctionParams< - Tail, - Push>>, - true - > - : SyntaxError<'Identifier expected.', 1>; +> = ParseIdentifier extends infer G + ? G extends Array + ? ParseFunctionParams, true> + : G extends Error + ? G + : SyntaxError<'Identifier expected.', 1> + : never; type ParseBlockStatement< T extends Array>, diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index 8aeb798..0bd6870 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -2542,3 +2542,178 @@ expectType>([ }, }, ]); + +expectType>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + params: [ + { + type: 'Identifier', + name: 'a', + typeAnnotation: { + type: 'TypeAnnotation', + typeAnnotation: { + type: 'StringTypeAnnotation', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + ], + body: { + type: 'BlockStatement', + body: [], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 2, + endLineNumber: 2, + }, + }, + params: [ + { + type: 'Identifier', + name: 'a', + typeAnnotation: { + type: 'TypeAnnotation', + typeAnnotation: { + type: 'NumberTypeAnnotation', + data: { + startLineNumber: 4, + endLineNumber: 4, + }, + }, + data: { + startLineNumber: 4, + endLineNumber: 4, + }, + }, + data: { + startLineNumber: 4, + endLineNumber: 4, + }, + }, + ], + body: { + type: 'BlockStatement', + body: [], + data: { + startLineNumber: 5, + endLineNumber: 6, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 6, + }, + }, +]); + +expectType>([ + { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'foo', + typeAnnotation: null, + data: { + startLineNumber: 2, + endLineNumber: 2, + }, + }, + params: [ + { + type: 'Identifier', + name: 'a', + typeAnnotation: { + type: 'TypeAnnotation', + typeAnnotation: { + type: 'NullLiteralTypeAnnotation', + data: { + startLineNumber: 4, + endLineNumber: 4, + }, + }, + data: { + startLineNumber: 4, + endLineNumber: 4, + }, + }, + data: { + startLineNumber: 4, + endLineNumber: 4, + }, + }, + { + type: 'Identifier', + name: 'b', + typeAnnotation: { + type: 'TypeAnnotation', + typeAnnotation: { + type: 'BooleanTypeAnnotation', + data: { + startLineNumber: 5, + endLineNumber: 5, + }, + }, + data: { + startLineNumber: 5, + endLineNumber: 5, + }, + }, + data: { + startLineNumber: 5, + endLineNumber: 5, + }, + }, + ], + body: { + type: 'BlockStatement', + body: [], + data: { + startLineNumber: 6, + endLineNumber: 7, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 7, + }, + }, +]); From 0786dde6e046a4c4bd798ed468fdf2793d8d5e43 Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 9 Jul 2022 23:33:31 +0300 Subject: [PATCH 137/286] wip --- src/index.ts | 2 +- src/parser.ts | 47 ++++++++++++++++++++++++++++------------------- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/src/index.ts b/src/index.ts index bb86d8c..fea41ec 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; // import type { Check } from './checker'; -type T = Tokenize<`function foo(a: string) {}`>; +type T = Tokenize<`function foo(a) {}`>; type R = Parse; // type C = Check<[R]>; diff --git a/src/parser.ts b/src/parser.ts index 04755c5..386e031 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -35,7 +35,7 @@ import type { Token, TokenData, } from './tokens'; -import type { Push, Tail, TailBy } from './utils/arrayUtils'; +import type { Head, Push, Tail, TailBy } from './utils/arrayUtils'; type ExtractTokenData< T extends Token, @@ -331,8 +331,8 @@ type ParseExpressionStatement>> = type ParseFunctionDeclaration>> = T[0] extends SymbolToken<'function', TokenData> ? T[1] extends SymbolToken> - ? T[2] extends GenericToken<'(', any> - ? ParseFunctionParams> extends infer G + ? T[2] extends GenericToken<'(', TokenData> + ? ParseFunctionParams, I> extends infer G ? G extends Array ? ParseBlockStatement extends infer H ? H extends Array @@ -357,6 +357,7 @@ type ParseFunctionDeclaration>> = type ParseFunctionParams< T extends Array>, + I extends number, R extends Array = [], N extends boolean = false, > = T[0] extends GenericToken<')', TokenData> @@ -364,22 +365,25 @@ type ParseFunctionParams< ? [R, TailBy, K] : SyntaxError<"'{' expected.", L> : T extends [] - ? SyntaxError<"')' expected.", 1> + ? SyntaxError<"')' expected.", I> : N extends true ? T[0] extends GenericToken<',', any> - ? ParseFunctionParamsHelper, R> - : SyntaxError<"',' expected.", 1> - : ParseFunctionParamsHelper; + ? ParseFunctionParamsHelper, I, R> + : Head extends Node> + ? SyntaxError<"',' expected.", I> + : never + : ParseFunctionParamsHelper; type ParseFunctionParamsHelper< T extends Array>, + I extends number, R extends Array = [], > = ParseIdentifier extends infer G ? G extends Array - ? ParseFunctionParams, true> + ? ParseFunctionParams, true> : G extends Error ? G - : SyntaxError<'Identifier expected.', 1> + : SyntaxError<'Identifier expected.', I> : never; type ParseBlockStatement< @@ -389,7 +393,9 @@ type ParseBlockStatement< R extends Array> = [], N extends boolean = false, > = T extends [] - ? SyntaxError<"'}' expected.", 1> + ? Head extends Node> + ? SyntaxError<"'}' expected.", S> + : SyntaxError<"'}' expected.", L> : T[0] extends GenericToken<'}', TokenData> ? [BlockStatement>, Tail] : T[0] extends GenericToken<';', any> @@ -442,15 +448,17 @@ type ParseIfStatement< T extends Array>, F extends boolean, > = T[0] extends SymbolToken<'if', TokenData> - ? T[1] extends GenericToken<'(', any> + ? T[1] extends GenericToken<'(', TokenData> ? ParseExpression> extends infer G ? G extends Array - ? ParseIfStatementHelper - : G extends Error - ? G - : SyntaxError<'Expression expected.', 1> + ? G[0] extends Node> + ? ParseIfStatementHelper + : G extends Error + ? G + : never + : SyntaxError<'Expression expected.', H> : never - : SyntaxError<"'(' expected.", 1> + : SyntaxError<"'(' expected.", L> : null; type ParseReturnStatementHelper< @@ -486,8 +494,9 @@ type ParseIfStatementHelper< G extends Array, L extends number, F extends boolean, + E extends number, > = G[1] extends Array - ? G[1][0] extends GenericToken<')', any> + ? G[1][0] extends GenericToken<')', TokenData> ? G[1][1] extends GenericToken<'{', TokenData> ? ParseBlockStatement, H, F> extends infer B ? B extends Array @@ -496,8 +505,8 @@ type ParseIfStatementHelper< : never : B : never - : SyntaxError<"'{' expected.", 1> - : SyntaxError<"')' expected.", 1> + : SyntaxError<"'{' expected.", I> + : SyntaxError<"')' expected.", E> : never; type ParseStatementHelper< From 936a91f79ee357d50d16b6afebbc1a45a85065d0 Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 9 Jul 2022 23:36:03 +0300 Subject: [PATCH 138/286] wip --- src/checker.ts | 6 +++--- src/index.ts | 4 ++-- src/parser.ts | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 32f4ec2..2229aaf 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -1,5 +1,3 @@ -export {}; - // import type { // AnyTypeAnnotation, // ArrayExpression, @@ -42,7 +40,9 @@ export {}; // import type { Concat, Reverse, Tail, Unshift } from './utils/arrayUtils'; // import type { Cast, MergeWithOverride } from './utils/generalUtils'; -// export type Check> = CheckBlock; +import type { Node } from './ast'; + +export type Check>> = T; // type InferArrayElements< // T extends Array, diff --git a/src/index.ts b/src/index.ts index fea41ec..ea5d349 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; -// import type { Check } from './checker'; +import type { Check } from './checker'; type T = Tokenize<`function foo(a) {}`>; type R = Parse; -// type C = Check<[R]>; +type C = Check; diff --git a/src/parser.ts b/src/parser.ts index 386e031..0f53917 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -195,7 +195,7 @@ type ParseCallExpressionArgumentsHelper< T extends Array>, E extends number, J extends string, - R extends Array = [], + R extends Array> = [], > = ParseExpression extends infer G ? G extends Array ? ParseCallExpressionArguments> @@ -264,7 +264,7 @@ type ParseExpressionHelper< type ParseObject< T extends Array>, E extends number, - R extends Array = [], + R extends Array> = [], N extends boolean = false, > = T[0] extends GenericToken<'}', TokenData> ? [ObjectExpression>, Tail] @@ -281,7 +281,7 @@ type ParseObject< type ParseObjectItem< T extends Array>, E extends number, - R extends Array = [], + R extends Array> = [], > = T[0] extends SymbolToken> ? T[1] extends GenericToken<':', any> ? ParseExpression> extends infer G @@ -358,7 +358,7 @@ type ParseFunctionDeclaration>> = type ParseFunctionParams< T extends Array>, I extends number, - R extends Array = [], + R extends Array> = [], N extends boolean = false, > = T[0] extends GenericToken<')', TokenData> ? T[1] extends GenericToken<'{', TokenData> @@ -377,7 +377,7 @@ type ParseFunctionParams< type ParseFunctionParamsHelper< T extends Array>, I extends number, - R extends Array = [], + R extends Array> = [], > = ParseIdentifier extends infer G ? G extends Array ? ParseFunctionParams, true> From bac70cfa88bcc8a7e1fc87bad76bb487f5a61236 Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 10 Jul 2022 01:41:08 +0300 Subject: [PATCH 139/286] wip --- src/ast.ts | 6 ++--- src/checker.ts | 68 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/index.ts | 6 ++--- src/types.ts | 19 ++++++++++++-- 4 files changed, 89 insertions(+), 10 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index fbe3cf7..d37edd9 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -8,19 +8,19 @@ export type NullLiteral> = { data: D; }; -export type NumericLiteral> = { +export type NumericLiteral> = { type: 'NumericLiteral'; value: T; data: D; }; -export type BooleanLiteral> = { +export type BooleanLiteral> = { type: 'BooleanLiteral'; value: T; data: D; }; -export type StringLiteral> = { +export type StringLiteral> = { type: 'StringLiteral'; value: T; data: D; diff --git a/src/checker.ts b/src/checker.ts index 2229aaf..50265c3 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -40,9 +40,73 @@ // import type { Concat, Reverse, Tail, Unshift } from './utils/arrayUtils'; // import type { Cast, MergeWithOverride } from './utils/generalUtils'; -import type { Node } from './ast'; +import type { + BooleanLiteral, + Node, + NullLiteral, + NumericLiteral, + StringLiteral, +} from './ast'; +import type { + BooleanLiteralType, + NullType, + NumberLiteralType, + StringLiteralType, + UnknownType, +} from './types'; -export type Check>> = T; +export type Check>> = InferExpression; + +type InferExpression< + T extends Node, + S extends {}, +> = T extends StringLiteral + ? StringLiteralType + : T extends NumericLiteral + ? NumberLiteralType + : T extends NullLiteral + ? NullType + : T extends BooleanLiteral + ? BooleanLiteralType + : UnknownType; +// T extends Identifier +// ? N extends keyof S +// ? S[N] +// : never +// : T extends ArrayExpression +// ? ArrayType>, S>> +// : T extends ObjectExpression +// ? ObjectType>, S>> +// : T extends CallExpression +// ? InferCallArguments>, S> extends infer O +// ? InferExpression extends infer I +// ? I extends FunctionType +// ? AssignableArgumentTypes< +// Cast>, +// Cast> +// > extends true +// ? R +// : never +// : never +// : never +// : never +// : T extends MemberExpression> +// ? InferExpression extends infer D +// ? D extends ObjectType +// ? P extends keyof Y +// ? Y[P] +// : never +// : D extends StringType +// ? P extends 'length' +// ? NumberType +// : never +// : D extends NumberType +// ? P extends 'toString' +// ? FunctionType<[], StringType> +// : never +// : never +// : never +// : UnknownType; // type InferArrayElements< // T extends Array, diff --git a/src/index.ts b/src/index.ts index ea5d349..2d7a683 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; import type { Check } from './checker'; -type T = Tokenize<`function foo(a) {}`>; -type R = Parse; -type C = Check; +type T = Tokenize<`123`>; +type R = Parse[0]['expression']; +type C = Check<[R]>; diff --git a/src/types.ts b/src/types.ts index 9c478d8..929a8c3 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2,18 +2,33 @@ export type StringType = { type: 'StringType'; }; +export type StringLiteralType = { + type: 'StringLiteralType'; + value: V; +}; + export type NumberType = { type: 'NumberType'; }; -export type NullType = { - type: 'NullType'; +export type NumberLiteralType = { + type: 'NumberLiteralType'; + value: V; }; export type BooleanType = { type: 'BooleanType'; }; +export type BooleanLiteralType = { + type: 'BooleanLiteralType'; + value: V; +}; + +export type NullType = { + type: 'NullType'; +}; + export type UnknownType = { type: 'UnknownType'; }; From 792cc407a5fdb751a85cf660a85a938990c11792 Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 10 Jul 2022 20:12:19 +0300 Subject: [PATCH 140/286] wip --- src/index.ts | 6 +++--- src/types.ts | 48 ++++++++++++++++++++++++++++++++---------------- 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/index.ts b/src/index.ts index 2d7a683..67886b6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; import type { Check } from './checker'; -type T = Tokenize<`123`>; -type R = Parse[0]['expression']; -type C = Check<[R]>; +type T = Tokenize<`"hello"`>; +type R = Parse; +type C = Check<[R[0]['expression']]>; diff --git a/src/types.ts b/src/types.ts index 929a8c3..687df67 100644 --- a/src/types.ts +++ b/src/types.ts @@ -47,22 +47,38 @@ export type FunctionType = { return: R; }; -export type ObjectType = { - type: 'ObjectType'; - keys: O; -}; +// export type ObjectType = { +// type: 'ObjectType'; +// keys: O; +// }; -export type ArrayType = { - type: 'ArrayType'; - value: V; -}; +// export type ArrayType = { +// type: 'ArrayType'; +// value: V; +// }; -export type UnionType = { - type: 'UnionType'; - values: V; -}; +// export type UnionType = { +// type: 'UnionType'; +// values: V; +// }; -export type GenericType = { - type: 'GenericType'; - id: T; -}; +// export type GenericType = { +// type: 'GenericType'; +// id: T; +// }; + +export type StaticType = + | StringType + | StringLiteralType + | NumberType + | NumberLiteralType + | BooleanType + | BooleanLiteralType + | UnknownType + | VoidType + | AnyType + | FunctionType; +// | ObjectType +// | ArrayType +// | UnionType +// | GenericType; From 0974dbae6f9adbc7feaf2109771eddc9828f8c4a Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 10 Jul 2022 20:12:58 +0300 Subject: [PATCH 141/286] wip --- src/ast.ts | 13 ++++++++++--- src/checker.ts | 31 +++++++++++++++++++++++++++---- src/index.ts | 2 +- src/parser.ts | 4 ++-- src/types.ts | 12 ++++++------ 5 files changed, 46 insertions(+), 16 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index d37edd9..9d53291 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -32,13 +32,20 @@ export type ArrayExpression> = { data: D; }; -export type ObjectExpression> = { +export type ObjectExpression< + T extends Array>, + D extends NodeData, +> = { type: 'ObjectExpression'; properties: T; data: D; }; -export type ObjectProperty> = { +export type ObjectProperty< + K, + T extends Node, + D extends NodeData, +> = { type: 'ObjectProperty'; key: K; value: T; @@ -71,7 +78,7 @@ export type FunctionDeclaration> = { data: D; }; -export type Identifier> = { +export type Identifier> = { type: 'Identifier'; name: N; typeAnnotation: T; diff --git a/src/checker.ts b/src/checker.ts index 50265c3..04fa907 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -42,18 +42,24 @@ import type { BooleanLiteral, + Identifier, Node, NullLiteral, NumericLiteral, + ObjectExpression, + ObjectProperty, StringLiteral, } from './ast'; +import type { Error, SyntaxError } from './errors'; import type { BooleanLiteralType, NullType, NumberLiteralType, + ObjectType, StringLiteralType, UnknownType, } from './types'; +import type { Push, Tail } from './utils/arrayUtils'; export type Check>> = InferExpression; @@ -68,11 +74,28 @@ type InferExpression< ? NullType : T extends BooleanLiteral ? BooleanLiteralType + : T extends Identifier + ? N extends keyof S + ? S[N] + : SyntaxError<`Cannot find name '${N}'.`, 1> + : T extends ObjectExpression + ? InferObjectProperties : UnknownType; -// T extends Identifier -// ? N extends keyof S -// ? S[N] -// : never + +type InferObjectProperties< + T extends Array>, + S extends {}, + R extends {} = {}, +> = T extends [] + ? ObjectType + : T[0] extends ObjectProperty, infer V, any> + ? InferExpression extends infer J + ? J extends Error + ? J + : InferObjectProperties, S, R & { [a in K]: J }> + : never + : never; + // : T extends ArrayExpression // ? ArrayType>, S>> // : T extends ObjectExpression diff --git a/src/index.ts b/src/index.ts index 67886b6..5e3491a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; import type { Check } from './checker'; -type T = Tokenize<`"hello"`>; +type T = Tokenize<`a`>; type R = Parse; type C = Check<[R[0]['expression']]>; diff --git a/src/parser.ts b/src/parser.ts index 0f53917..d031910 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -264,7 +264,7 @@ type ParseExpressionHelper< type ParseObject< T extends Array>, E extends number, - R extends Array> = [], + R extends Array> = [], N extends boolean = false, > = T[0] extends GenericToken<'}', TokenData> ? [ObjectExpression>, Tail] @@ -281,7 +281,7 @@ type ParseObject< type ParseObjectItem< T extends Array>, E extends number, - R extends Array> = [], + R extends Array> = [], > = T[0] extends SymbolToken> ? T[1] extends GenericToken<':', any> ? ParseExpression> extends infer G diff --git a/src/types.ts b/src/types.ts index 687df67..5be7a2b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -47,10 +47,10 @@ export type FunctionType = { return: R; }; -// export type ObjectType = { -// type: 'ObjectType'; -// keys: O; -// }; +export type ObjectType = { + type: 'ObjectType'; + object: O; +}; // export type ArrayType = { // type: 'ArrayType'; @@ -77,8 +77,8 @@ export type StaticType = | UnknownType | VoidType | AnyType - | FunctionType; -// | ObjectType + | FunctionType + | ObjectType; // | ArrayType // | UnionType // | GenericType; From 31c4e47fa8ad28b9eb7b5e04dd2e6ac56d88ce37 Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 10 Jul 2022 20:18:55 +0300 Subject: [PATCH 142/286] wip --- src/index.ts | 2 +- src/parser.ts | 2 +- src/test/parser.test.ts | 6 ++++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 5e3491a..67886b6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; import type { Check } from './checker'; -type T = Tokenize<`a`>; +type T = Tokenize<`"hello"`>; type R = Parse; type C = Check<[R[0]['expression']]>; diff --git a/src/parser.ts b/src/parser.ts index d031910..ffeb67b 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -123,7 +123,7 @@ type ParseTypeAnnotation>> = >, Tail, ] - : never; + : null; type ParseVariableDeclaration>> = T[0] extends SymbolToken<'const', TokenData> diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index 0bd6870..0b98fcc 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -339,6 +339,12 @@ expectType>({ lineNumber: 2, }); +expectType>({ + type: 'SyntaxError', + message: 'Type expected.', + lineNumber: 1, +}); + expectType>({ type: 'SyntaxError', message: 'Identifier expected.', From 0ec2115bc3c324130aac2580001a27e5b0f7ac05 Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 10 Jul 2022 21:15:33 +0300 Subject: [PATCH 143/286] wip --- src/ast.ts | 5 ++++- src/checker.ts | 31 ++++++++++++++++++++++++++++--- src/index.ts | 4 ++-- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index 9d53291..2d5d7d8 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -85,7 +85,10 @@ export type Identifier> = { data: D; }; -export type ExpressionStatement> = { +export type ExpressionStatement< + E extends Node, + D extends NodeData, +> = { type: 'ExpressionStatement'; expression: E; data: D; diff --git a/src/checker.ts b/src/checker.ts index 04fa907..8b48057 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -42,8 +42,10 @@ import type { BooleanLiteral, + ExpressionStatement, Identifier, Node, + NodeData, NullLiteral, NumericLiteral, ObjectExpression, @@ -61,7 +63,30 @@ import type { } from './types'; import type { Push, Tail } from './utils/arrayUtils'; -export type Check>> = InferExpression; +export type Check< + T extends Array>, + S extends {} = {}, + R extends Array = [], +> = T extends [] + ? R + : T[0] extends ExpressionStatement + ? InferExpressionStatement extends infer G + ? G extends Error + ? Check, S, Push> + : Check, S, R> + : never + : never; + +type InferExpressionStatement< + O extends ExpressionStatement, + S extends {}, +> = O extends ExpressionStatement + ? InferExpression extends infer G + ? G extends Error + ? G + : null + : never + : never; type InferExpression< T extends Node, @@ -74,10 +99,10 @@ type InferExpression< ? NullType : T extends BooleanLiteral ? BooleanLiteralType - : T extends Identifier + : T extends Identifier> ? N extends keyof S ? S[N] - : SyntaxError<`Cannot find name '${N}'.`, 1> + : SyntaxError<`Cannot find name '${N}'.`, S> : T extends ObjectExpression ? InferObjectProperties : UnknownType; diff --git a/src/index.ts b/src/index.ts index 67886b6..e1de1c1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,6 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; import type { Check } from './checker'; -type T = Tokenize<`"hello"`>; +type T = Tokenize<`"hello"; foo`>; type R = Parse; -type C = Check<[R[0]['expression']]>; +type C = Check; From 52ea8d7caea56121479543f3e3ee0757058922fe Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 10 Jul 2022 21:30:02 +0300 Subject: [PATCH 144/286] wip --- src/ast.ts | 8 ++++++-- src/checker.ts | 46 +++++++++++++++++++++++++++++++++++----------- src/index.ts | 7 ++++++- 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index 2d5d7d8..6e863c7 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -53,7 +53,7 @@ export type ObjectProperty< }; export type VariableDeclaration< - H, + H extends Array>, K extends 'const' | 'let', D extends NodeData, > = { @@ -63,7 +63,11 @@ export type VariableDeclaration< data: D; }; -export type VariableDeclarator> = { +export type VariableDeclarator< + N, + I extends Node, + D extends NodeData, +> = { type: 'VariableDeclarator'; id: N; init: I; diff --git a/src/checker.ts b/src/checker.ts index 8b48057..1f1f7f3 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -51,6 +51,8 @@ import type { ObjectExpression, ObjectProperty, StringLiteral, + VariableDeclaration, + VariableDeclarator, } from './ast'; import type { Error, SyntaxError } from './errors'; import type { @@ -62,6 +64,7 @@ import type { UnknownType, } from './types'; import type { Push, Tail } from './utils/arrayUtils'; +import type { MergeWithOverride } from './utils/generalUtils'; export type Check< T extends Array>, @@ -71,9 +74,30 @@ export type Check< ? R : T[0] extends ExpressionStatement ? InferExpressionStatement extends infer G + ? G extends Array + ? Check, G[1], R> + : Check, S, Push> + : never + : T[0] extends VariableDeclaration + ? InferVariableDeclaration extends infer G + ? G extends Array + ? Check, G[1], R> + : Check, S, Push> + : never + : never; + +type InferVariableDeclaration< + O extends VariableDeclaration, + S extends {}, +> = O extends VariableDeclaration< + [VariableDeclarator, infer I, any>], + any, + any +> + ? InferExpression extends infer G ? G extends Error - ? Check, S, Push> - : Check, S, R> + ? G + : [null, MergeWithOverride] : never : never; @@ -84,25 +108,25 @@ type InferExpressionStatement< ? InferExpression extends infer G ? G extends Error ? G - : null + : [null, S] : never : never; type InferExpression< T extends Node, S extends {}, -> = T extends StringLiteral - ? StringLiteralType - : T extends NumericLiteral - ? NumberLiteralType +> = T extends StringLiteral + ? StringLiteralType + : T extends NumericLiteral + ? NumberLiteralType : T extends NullLiteral ? NullType - : T extends BooleanLiteral - ? BooleanLiteralType - : T extends Identifier> + : T extends BooleanLiteral + ? BooleanLiteralType + : T extends Identifier> ? N extends keyof S ? S[N] - : SyntaxError<`Cannot find name '${N}'.`, S> + : SyntaxError<`Cannot find name '${N}'.`, I> : T extends ObjectExpression ? InferObjectProperties : UnknownType; diff --git a/src/index.ts b/src/index.ts index e1de1c1..057dc8d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,11 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; import type { Check } from './checker'; -type T = Tokenize<`"hello"; foo`>; +type T = Tokenize<` + +const a = 1; +const b = a; + +`>; type R = Parse; type C = Check; From 00569d8a6d4bb5b777bd33fe6cd57ca998ff8428 Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 10 Jul 2022 21:35:38 +0300 Subject: [PATCH 145/286] wip --- src/ast.ts | 29 +++++++++++++++++++++++------ src/checker.ts | 3 +++ src/index.ts | 5 +++-- src/parser.ts | 4 ++-- 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index 6e863c7..d49c87f 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -42,7 +42,7 @@ export type ObjectExpression< }; export type ObjectProperty< - K, + K extends Identifier, T extends Node, D extends NodeData, > = { @@ -64,7 +64,7 @@ export type VariableDeclaration< }; export type VariableDeclarator< - N, + N extends Identifier, I extends Node, D extends NodeData, > = { @@ -74,7 +74,12 @@ export type VariableDeclarator< data: D; }; -export type FunctionDeclaration> = { +export type FunctionDeclaration< + I extends Identifier, + P extends Array>, + B extends BlockStatement, + D extends NodeData, +> = { type: 'FunctionDeclaration'; id: I; params: P; @@ -82,7 +87,11 @@ export type FunctionDeclaration> = { data: D; }; -export type Identifier> = { +export type Identifier< + N extends string, + T extends TypeAnnotation | null, + D extends NodeData, +> = { type: 'Identifier'; name: N; typeAnnotation: T; @@ -105,14 +114,22 @@ export type CallExpression> = { data: D; }; -export type MemberExpression> = { +export type MemberExpression< + O extends Node, + P extends Node, + D extends NodeData, +> = { type: 'MemberExpression'; object: O; property: P; data: D; }; -export type IfStatement> = { +export type IfStatement< + T extends Node, + C extends Node, + D extends NodeData, +> = { type: 'IfStatement'; test: T; consequent: C; diff --git a/src/checker.ts b/src/checker.ts index 1f1f7f3..06293dd 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -44,6 +44,7 @@ import type { BooleanLiteral, ExpressionStatement, Identifier, + MemberExpression, Node, NodeData, NullLiteral, @@ -129,6 +130,8 @@ type InferExpression< : SyntaxError<`Cannot find name '${N}'.`, I> : T extends ObjectExpression ? InferObjectProperties + : T extends MemberExpression + ? 1 : UnknownType; type InferObjectProperties< diff --git a/src/index.ts b/src/index.ts index 057dc8d..4bd9da2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,8 +4,9 @@ import type { Check } from './checker'; type T = Tokenize<` -const a = 1; -const b = a; +const foo = { + hello: "world" +}; `>; type R = Parse; diff --git a/src/parser.ts b/src/parser.ts index ffeb67b..d7160c6 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -65,7 +65,7 @@ type ParseIdentifier< type ParseVariableDeclarationHelper< R extends Array>, - N extends Node, + N extends Identifier, L extends number, S extends number, K extends number, @@ -128,7 +128,7 @@ type ParseTypeAnnotation>> = type ParseVariableDeclaration>> = T[0] extends SymbolToken<'const', TokenData> ? ParseIdentifier, true> extends infer N - ? N extends [Node>, infer R] + ? N extends [Identifier>, infer R] ? R extends Array ? R[0] extends SymbolToken<'=', TokenData> ? ParseVariableDeclarationHelper From 07cf981def57111030ab351ca7d7efa6fb54d4ff Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 10 Jul 2022 21:52:52 +0300 Subject: [PATCH 146/286] wip --- src/ast.ts | 2 +- src/checker.ts | 18 +++++++++++++++++- src/index.ts | 2 ++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index d49c87f..3f6a5b2 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -116,7 +116,7 @@ export type CallExpression> = { export type MemberExpression< O extends Node, - P extends Node, + P extends Identifier, D extends NodeData, > = { type: 'MemberExpression'; diff --git a/src/checker.ts b/src/checker.ts index 06293dd..25c8556 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -131,9 +131,25 @@ type InferExpression< : T extends ObjectExpression ? InferObjectProperties : T extends MemberExpression - ? 1 + ? InferMemberExpression : UnknownType; +type InferMemberExpression< + O extends Node, + P extends Identifier, + S extends {}, +> = InferExpression extends infer J + ? J extends Error + ? J + : P extends Identifier> + ? J extends ObjectType + ? N extends keyof Y + ? Y[N] + : SyntaxError<`Property '${N}' does not exist on type '{}'.`, S> + : never + : never + : never; + type InferObjectProperties< T extends Array>, S extends {}, diff --git a/src/index.ts b/src/index.ts index 4bd9da2..f79c34e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,6 +8,8 @@ const foo = { hello: "world" }; +foo.hello; + `>; type R = Parse; type C = Check; From 1dd8f4bf41b6c655296cbde1f4611965e5652705 Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 10 Jul 2022 23:26:48 +0300 Subject: [PATCH 147/286] wip --- src/checker.ts | 46 +++++++++++++++++++++++----------------------- src/index.ts | 6 ++++-- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 25c8556..2784700 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -96,9 +96,9 @@ type InferVariableDeclaration< any > ? InferExpression extends infer G - ? G extends Error - ? G - : [null, MergeWithOverride] + ? G extends Array + ? [null, MergeWithOverride] + : G : never : never; @@ -107,9 +107,9 @@ type InferExpressionStatement< S extends {}, > = O extends ExpressionStatement ? InferExpression extends infer G - ? G extends Error - ? G - : [null, S] + ? G extends Array + ? [null, S] + : G : never : never; @@ -117,16 +117,16 @@ type InferExpression< T extends Node, S extends {}, > = T extends StringLiteral - ? StringLiteralType + ? [StringLiteralType, S] : T extends NumericLiteral - ? NumberLiteralType + ? [NumberLiteralType, S] : T extends NullLiteral - ? NullType + ? [NullType, S] : T extends BooleanLiteral - ? BooleanLiteralType + ? [BooleanLiteralType, S] : T extends Identifier> ? N extends keyof S - ? S[N] + ? [S[N], S] : SyntaxError<`Cannot find name '${N}'.`, I> : T extends ObjectExpression ? InferObjectProperties @@ -139,15 +139,15 @@ type InferMemberExpression< P extends Identifier, S extends {}, > = InferExpression extends infer J - ? J extends Error - ? J - : P extends Identifier> - ? J extends ObjectType - ? N extends keyof Y - ? Y[N] - : SyntaxError<`Property '${N}' does not exist on type '{}'.`, S> + ? J extends Array + ? P extends Identifier> + ? J[0] extends ObjectType + ? N extends keyof Y + ? [Y[N], S] + : SyntaxError<`Property '${N}' does not exist on type '{}'.`, S> + : SyntaxError<`Property '${N}' does not exist on type '...'.`, S> : never - : never + : J : never; type InferObjectProperties< @@ -155,12 +155,12 @@ type InferObjectProperties< S extends {}, R extends {} = {}, > = T extends [] - ? ObjectType + ? [ObjectType, S] : T[0] extends ObjectProperty, infer V, any> ? InferExpression extends infer J - ? J extends Error - ? J - : InferObjectProperties, S, R & { [a in K]: J }> + ? J extends Array + ? InferObjectProperties, S, R & { [a in K]: J[0] }> + : J : never : never; diff --git a/src/index.ts b/src/index.ts index f79c34e..27cbe91 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,10 +5,12 @@ import type { Check } from './checker'; type T = Tokenize<` const foo = { - hello: "world" + hello: { foo: "bar" } }; -foo.hello; +const a = foo.hello; + +a.foo `>; type R = Parse; From ac895203c6b52fd388e44a27278ed74cd7739cfa Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 10 Jul 2022 23:51:51 +0300 Subject: [PATCH 148/286] wip --- src/ast.ts | 5 +++- src/checker.ts | 63 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/index.ts | 8 ++----- src/types.ts | 1 + 4 files changed, 68 insertions(+), 9 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index 3f6a5b2..5a21e6c 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -149,7 +149,10 @@ export type BlockStatement> = { data: D; }; -export type TypeAnnotation> = { +export type TypeAnnotation< + T extends Node, + D extends NodeData, +> = { type: 'TypeAnnotation'; typeAnnotation: T; data: D; diff --git a/src/checker.ts b/src/checker.ts index 2784700..45bcd60 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -41,27 +41,39 @@ // import type { Cast, MergeWithOverride } from './utils/generalUtils'; import type { + AnyTypeAnnotation, BooleanLiteral, + BooleanTypeAnnotation, ExpressionStatement, + GenericTypeAnnotation, Identifier, MemberExpression, Node, NodeData, NullLiteral, + NullLiteralTypeAnnotation, + NumberTypeAnnotation, NumericLiteral, ObjectExpression, ObjectProperty, StringLiteral, + StringTypeAnnotation, + TypeAnnotation, VariableDeclaration, VariableDeclarator, } from './ast'; import type { Error, SyntaxError } from './errors'; import type { + AnyType, BooleanLiteralType, + BooleanType, NullType, NumberLiteralType, + NumberType, ObjectType, + StaticType, StringLiteralType, + StringType, UnknownType, } from './types'; import type { Push, Tail } from './utils/arrayUtils'; @@ -87,17 +99,64 @@ export type Check< : never : never; +type MatchType = A extends AnyType + ? true + : A extends B + ? B extends A + ? true + : false + : A extends StringType + ? B extends StringLiteralType + ? true + : false + : A extends BooleanType + ? B extends BooleanLiteralType + ? true + : false + : A extends NumberType + ? B extends NumberLiteralType + ? true + : false + : false; + +type MapAnnotationToType> = + A extends StringTypeAnnotation + ? StringType + : A extends NumberTypeAnnotation + ? NumberType + : A extends BooleanTypeAnnotation + ? BooleanType + : A extends NullLiteralTypeAnnotation + ? NullType + : A extends AnyTypeAnnotation + ? AnyType + : never; + type InferVariableDeclaration< O extends VariableDeclaration, S extends {}, > = O extends VariableDeclaration< - [VariableDeclarator, infer I, any>], + [ + VariableDeclarator< + Identifier>, + infer I, + any + >, + ], any, any > ? InferExpression extends infer G ? G extends Array - ? [null, MergeWithOverride] + ? T extends TypeAnnotation + ? MapAnnotationToType extends infer P + ? P extends StaticType + ? MatchType extends true + ? [null, MergeWithOverride] + : SyntaxError<`Type '...' is not assignable to type '...'.`, L> + : never + : never + : [null, MergeWithOverride] : G : never : never; diff --git a/src/index.ts b/src/index.ts index 27cbe91..2b19450 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,13 +4,9 @@ import type { Check } from './checker'; type T = Tokenize<` -const foo = { - hello: { foo: "bar" } -}; +const a = 123; -const a = foo.hello; - -a.foo +const foo: string = a; `>; type R = Parse; diff --git a/src/types.ts b/src/types.ts index 5be7a2b..1c25217 100644 --- a/src/types.ts +++ b/src/types.ts @@ -77,6 +77,7 @@ export type StaticType = | UnknownType | VoidType | AnyType + | NullType | FunctionType | ObjectType; // | ArrayType From 8c8fb62eba81bc9e65800515a1104348c3f2d65b Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 10 Jul 2022 23:54:22 +0300 Subject: [PATCH 149/286] wip --- src/index.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/index.ts b/src/index.ts index 2b19450..7860aa1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,9 +4,8 @@ import type { Check } from './checker'; type T = Tokenize<` -const a = 123; - -const foo: string = a; +const a = { b: true } +const b: boolean = a.b `>; type R = Parse; From 8ab33961202ee71939b8d75c8a2235d4d0819865 Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 11 Jul 2022 01:04:13 +0300 Subject: [PATCH 150/286] wip --- src/ast.ts | 6 ++- src/checker.ts | 35 ++++++++++---- src/index.ts | 9 +++- src/parser.ts | 25 ++++++++-- src/test/parser.test.ts | 104 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 161 insertions(+), 18 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index 5a21e6c..028cfdf 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -116,12 +116,14 @@ export type CallExpression> = { export type MemberExpression< O extends Node, - P extends Identifier, + P extends Node, + C extends boolean, D extends NodeData, > = { type: 'MemberExpression'; object: O; property: P; + computed: C; data: D; }; @@ -203,7 +205,7 @@ export type Node> = | NullLiteral | ExpressionStatement | CallExpression - | MemberExpression + | MemberExpression | IfStatement | ReturnStatement | BlockStatement diff --git a/src/checker.ts b/src/checker.ts index 45bcd60..e5de298 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -189,26 +189,43 @@ type InferExpression< : SyntaxError<`Cannot find name '${N}'.`, I> : T extends ObjectExpression ? InferObjectProperties - : T extends MemberExpression - ? InferMemberExpression + : T extends MemberExpression + ? InferMemberExpression : UnknownType; type InferMemberExpression< O extends Node, - P extends Identifier, + P extends Node, + C extends boolean, S extends {}, > = InferExpression extends infer J ? J extends Array - ? P extends Identifier> - ? J[0] extends ObjectType - ? N extends keyof Y - ? [Y[N], S] - : SyntaxError<`Property '${N}' does not exist on type '{}'.`, S> - : SyntaxError<`Property '${N}' does not exist on type '...'.`, S> + ? C extends false + ? P extends Identifier> + ? InferMemberExpressionHelper + : never + : InferExpression extends infer G + ? G extends Array + ? G[0] extends StringLiteralType + ? InferMemberExpressionHelper + : SyntaxError<`Property '...' does not exist on type '{}'.`, 1> + : G extends null + ? never + : G : never : J : never; +type InferMemberExpressionHelper< + O extends ObjectType, + N extends string, + S extends {}, +> = O extends ObjectType + ? N extends keyof Y + ? [Y[N], S] + : SyntaxError<`Property '${N}' does not exist on type '{}'.`, 1> + : SyntaxError<`Property '${N}' does not exist on type '...'.`, 1>; + type InferObjectProperties< T extends Array>, S extends {}, diff --git a/src/index.ts b/src/index.ts index 7860aa1..0db46d0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,8 +4,13 @@ import type { Check } from './checker'; type T = Tokenize<` -const a = { b: true } -const b: boolean = a.b +const a = { + hello: 1 +} + +const foo = "world" + +a[1] `>; type R = Parse; diff --git a/src/parser.ts b/src/parser.ts index d7160c6..cc576dd 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -143,20 +143,35 @@ type ParseVariableDeclaration>> = type ParseMemberExpression< O extends Node, T extends Array>, -> = T[0] extends GenericToken<'.', TokenData> - ? T[1] extends SymbolToken> - ? O extends Node> +> = O extends Node> + ? T[0] extends GenericToken<'.', TokenData> + ? T[1] extends SymbolToken> ? [ MemberExpression< O, Identifier>, + false, NodeData >, TailBy, ] + : SyntaxError<'Identifier expected.', E> + : T[0] extends GenericToken<'[', TokenData> + ? ParseExpression> extends infer G + ? G extends [infer Q, infer W] + ? Q extends Node> + ? W extends Array> + ? W[0] extends GenericToken<']', TokenData> + ? [MemberExpression>, Tail] + : SyntaxError<"']' expected.", S> + : never + : never + : G extends null + ? SyntaxError<'Expression expected.', E> + : G : never - : SyntaxError<'Identifier expected.', E> - : null; + : null + : never; type ParseCallExpression< O extends Node, diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index 0b98fcc..0cc9a14 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -386,6 +386,7 @@ expectType>([ endLineNumber: 1, }, }, + computed: false, data: { startLineNumber: 1, endLineNumber: 1, @@ -423,6 +424,7 @@ expectType>([ endLineNumber: 1, }, }, + computed: false, data: { startLineNumber: 1, endLineNumber: 1, @@ -437,6 +439,7 @@ expectType>([ endLineNumber: 1, }, }, + computed: false, data: { startLineNumber: 1, endLineNumber: 1, @@ -474,6 +477,7 @@ expectType>([ endLineNumber: 2, }, }, + computed: false, data: { startLineNumber: 1, endLineNumber: 2, @@ -488,6 +492,7 @@ expectType>([ endLineNumber: 3, }, }, + computed: false, data: { startLineNumber: 1, endLineNumber: 3, @@ -547,6 +552,7 @@ expectType>([ endLineNumber: 1, }, }, + computed: false, data: { startLineNumber: 1, endLineNumber: 1, @@ -761,6 +767,7 @@ expectType>([ endLineNumber: 1, }, }, + computed: false, data: { startLineNumber: 1, endLineNumber: 1, @@ -810,6 +817,7 @@ expectType>([ endLineNumber: 1, }, }, + computed: false, data: { startLineNumber: 1, endLineNumber: 1, @@ -2723,3 +2731,99 @@ expectType>([ }, }, ]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + object: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + property: { + type: 'Identifier', + name: 'world', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + computed: true, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); + +expectType>([ + { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + object: { + type: 'MemberExpression', + object: { + type: 'Identifier', + name: 'hello', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + property: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'world', + typeAnnotation: null, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + arguments: [], + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + computed: true, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + property: { + type: 'StringLiteral', + value: 'foo', + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + computed: true, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, + data: { + startLineNumber: 1, + endLineNumber: 1, + }, + }, +]); From 46924392c00d77c271dbe678221566e8bfbc2969 Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 11 Jul 2022 12:53:58 +0300 Subject: [PATCH 151/286] wip --- src/checker.ts | 25 ++- src/test/checker.test.ts | 423 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 437 insertions(+), 11 deletions(-) create mode 100644 src/test/checker.test.ts diff --git a/src/checker.ts b/src/checker.ts index e5de298..385babc 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -201,17 +201,19 @@ type InferMemberExpression< > = InferExpression extends infer J ? J extends Array ? C extends false - ? P extends Identifier> - ? InferMemberExpressionHelper + ? P extends Identifier> + ? InferMemberExpressionHelper : never : InferExpression extends infer G - ? G extends Array - ? G[0] extends StringLiteralType - ? InferMemberExpressionHelper - : SyntaxError<`Property '...' does not exist on type '{}'.`, 1> - : G extends null - ? never - : G + ? P extends Node> + ? G extends Array + ? G[0] extends StringLiteralType + ? InferMemberExpressionHelper + : SyntaxError<`Type '{}' cannot be used as an index type.`, L> + : G extends null + ? never + : G + : never : never : J : never; @@ -220,11 +222,12 @@ type InferMemberExpressionHelper< O extends ObjectType, N extends string, S extends {}, + L extends number, > = O extends ObjectType ? N extends keyof Y ? [Y[N], S] - : SyntaxError<`Property '${N}' does not exist on type '{}'.`, 1> - : SyntaxError<`Property '${N}' does not exist on type '...'.`, 1>; + : SyntaxError<`Property '${N}' does not exist on type '{}'.`, L> + : SyntaxError<`Property '${N}' does not exist on type '...'.`, L>; type InferObjectProperties< T extends Array>, diff --git a/src/test/checker.test.ts b/src/test/checker.test.ts new file mode 100644 index 0000000..d086ee0 --- /dev/null +++ b/src/test/checker.test.ts @@ -0,0 +1,423 @@ +import type { Tokenize } from '../tokenizer'; +import type { Parse } from '../parser'; +import type { Check } from '../checker'; +import { expectType } from './utils'; + +type TypeCheck = Tokenize extends infer G + ? G extends Array + ? Parse extends infer J + ? J extends Array + ? Check + : never + : never + : never + : never; + +expectType< + TypeCheck<` + +hello + +`> +>([ + { + type: 'SyntaxError', + message: "Cannot find name 'hello'.", + lineNumber: 3, + }, +]); + +expectType< + TypeCheck<` + +world; + +`> +>([ + { + type: 'SyntaxError', + message: "Cannot find name 'world'.", + lineNumber: 3, + }, +]); + +expectType< + TypeCheck<` + +"string" + +`> +>([]); + +expectType< + TypeCheck<` + +123; + +`> +>([]); + +expectType< + TypeCheck<` + +const a = null + +`> +>([]); + +expectType< + TypeCheck<` + +const b = "world"; + +`> +>([]); + +expectType< + TypeCheck<` + +const hello = 1; +hello; + +`> +>([]); + +expectType< + TypeCheck<` + +const hello = { foo: "bar" }; +hello.world + +`> +>([ + { + type: 'SyntaxError', + message: "Property 'world' does not exist on type '{}'.", + lineNumber: 4, + }, +]); + +expectType< + TypeCheck<` + +const hello = { foo: "bar" }; +hello.foo; + +`> +>([]); + +expectType< + TypeCheck<` + +const hello = { + foo: { + bar: "bazz" + } +}; + +hello.foo.bar; + +`> +>([]); + +expectType< + TypeCheck<` + +const hello = { + foo: { + bar: "bazz" + } +}; + +hello + .foo + .hey; + +`> +>([ + { + type: 'SyntaxError', + message: "Property 'hey' does not exist on type '{}'.", + lineNumber: 11, + }, +]); + +expectType< + TypeCheck<` + +const hello = "world"; + +hello.foo + +`> +>([ + { + type: 'SyntaxError', + message: "Property 'foo' does not exist on type '...'.", + lineNumber: 5, + }, +]); + +expectType< + TypeCheck<` + +const hello = "world"; +const foo = hello; + +`> +>([]); + +expectType< + TypeCheck<` + +const hello = "world"; +const foo = hello; + +foo; + +`> +>([]); + +expectType< + TypeCheck<` + +const hello: string = "hello"; + +`> +>([]); + +expectType< + TypeCheck<` + +const hello: number = 123; + +`> +>([]); + +expectType< + TypeCheck<` + +const hello: number = "hello"; + +`> +>([ + { + type: 'SyntaxError', + message: "Type '...' is not assignable to type '...'.", + lineNumber: 3, + }, +]); + +expectType< + TypeCheck<` + +const hello: string = 123; + +`> +>([ + { + type: 'SyntaxError', + message: "Type '...' is not assignable to type '...'.", + lineNumber: 3, + }, +]); + +expectType< + TypeCheck<` + +const hello = "world"; +const foo: number = hello; + +`> +>([ + { + type: 'SyntaxError', + message: "Type '...' is not assignable to type '...'.", + lineNumber: 4, + }, +]); + +expectType< + TypeCheck<` + +const hello = "world"; + +const foo: string = hello; + +`> +>([]); + +expectType< + TypeCheck<` + +const hello = {hey: "world"}; + +const foo: number = hello; + +`> +>([ + { + type: 'SyntaxError', + message: "Type '...' is not assignable to type '...'.", + lineNumber: 5, + }, +]); + +expectType< + TypeCheck<` + +const hello = {hey: "world"}; + +const foo: number = hello.hey; + +`> +>([ + { + type: 'SyntaxError', + message: "Type '...' is not assignable to type '...'.", + lineNumber: 5, + }, +]); + +expectType< + TypeCheck<` + +const hello = {hey: "world"}; + +const foo: string = hello.hey; + +`> +>([]); + +expectType< + TypeCheck<` + +const o = {}; + +o["hey"]; + +`> +>([ + { + type: 'SyntaxError', + message: "Property 'hey' does not exist on type '{}'.", + lineNumber: 5, + }, +]); + +expectType< + TypeCheck<` + +const o = {hey: "ho"}; + +o["hey"]; + +`> +>([]); + +expectType< + TypeCheck<` + +const o = {}; +const k = "hey"; + +o + [k]; + +`> +>([ + { + type: 'SyntaxError', + message: "Property 'hey' does not exist on type '{}'.", + lineNumber: 7, + }, +]); + +expectType< + TypeCheck<` + +const o = {hey: "ho"}; +const k = "hey"; + +o[k]; + +`> +>([]); + +expectType< + TypeCheck<` + +const o = { + hey: { + ho:"let's go" + } +}; + +const k = "hey"; + +o[k]["ho"]; + +`> +>([]); + +expectType< + TypeCheck<` + +const o = { + hey: { + ho:"let's go" + } +}; + +const k = "hey"; + +o[k]["hi"]; + +`> +>([ + { + type: 'SyntaxError', + message: "Property 'hi' does not exist on type '{}'.", + lineNumber: 11, + }, +]); + +expectType< + TypeCheck<` + +const o = { + hey: { + ho:"let's go" + } +}; + +const k = "hey"; + +o[k][{}]; + +`> +>([ + { + type: 'SyntaxError', + message: "Type '{}' cannot be used as an index type.", + lineNumber: 11, + }, +]); + +expectType< + TypeCheck<` + +const o = { + hey: "ho:" +}; + +o[true]; + +`> +>([ + { + type: 'SyntaxError', + message: "Type '{}' cannot be used as an index type.", + lineNumber: 7, + }, +]); From 4a1256a6f8c1419c6e3d04a2cf9d0d2ad6a6717c Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 11 Jul 2022 12:58:08 +0300 Subject: [PATCH 152/286] wip --- src/ast.ts | 5 ++++- src/checker.ts | 18 ++++++++++++++++++ src/index.ts | 8 +------- src/types.ts | 22 +++++++++++----------- 4 files changed, 34 insertions(+), 19 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index 028cfdf..9099129 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -26,7 +26,10 @@ export type StringLiteral> = { data: D; }; -export type ArrayExpression> = { +export type ArrayExpression< + T extends Array>, + D extends NodeData, +> = { type: 'ArrayExpression'; elements: T; data: D; diff --git a/src/checker.ts b/src/checker.ts index 385babc..e3e2f8c 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -42,6 +42,7 @@ import type { AnyTypeAnnotation, + ArrayExpression, BooleanLiteral, BooleanTypeAnnotation, ExpressionStatement, @@ -65,6 +66,7 @@ import type { import type { Error, SyntaxError } from './errors'; import type { AnyType, + ArrayType, BooleanLiteralType, BooleanType, NullType, @@ -191,8 +193,24 @@ type InferExpression< ? InferObjectProperties : T extends MemberExpression ? InferMemberExpression + : T extends ArrayExpression + ? InferArrayElements : UnknownType; +type InferArrayElements< + T extends Array>, + S extends {}, + R extends StaticType = AnyType, +> = T extends [] + ? [ArrayType, S] + : T[0] extends Node + ? InferExpression extends infer J + ? J extends Array + ? InferArrayElements, S, J[0]> + : J + : never + : never; + type InferMemberExpression< O extends Node, P extends Node, diff --git a/src/index.ts b/src/index.ts index 0db46d0..2692458 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,13 +4,7 @@ import type { Check } from './checker'; type T = Tokenize<` -const a = { - hello: 1 -} - -const foo = "world" - -a[1] +[1, 2, 3] `>; type R = Parse; diff --git a/src/types.ts b/src/types.ts index 1c25217..fc44543 100644 --- a/src/types.ts +++ b/src/types.ts @@ -52,15 +52,15 @@ export type ObjectType = { object: O; }; -// export type ArrayType = { -// type: 'ArrayType'; -// value: V; -// }; +export type ArrayType = { + type: 'ArrayType'; + elements: V; +}; -// export type UnionType = { -// type: 'UnionType'; -// values: V; -// }; +export type UnionType> = { + type: 'UnionType'; + types: V; +}; // export type GenericType = { // type: 'GenericType'; @@ -79,7 +79,7 @@ export type StaticType = | AnyType | NullType | FunctionType - | ObjectType; -// | ArrayType -// | UnionType + | ObjectType + | ArrayType + | UnionType; // | GenericType; From a2814dce2a9fc79c4265c1e875e21b1598da4685 Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 11 Jul 2022 14:24:58 +0300 Subject: [PATCH 153/286] wip --- src/ast.ts | 10 +++++++-- src/checker.ts | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/index.ts | 4 +++- src/types.ts | 5 ++++- 4 files changed, 70 insertions(+), 4 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index 9099129..039f2a5 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -142,13 +142,19 @@ export type IfStatement< // alternate: A; }; -export type ReturnStatement> = { +export type ReturnStatement< + T extends Node | null, + D extends NodeData, +> = { type: 'ReturnStatement'; argument: T; data: D; }; -export type BlockStatement> = { +export type BlockStatement< + B extends Array>, + D extends NodeData, +> = { type: 'BlockStatement'; body: B; data: D; diff --git a/src/checker.ts b/src/checker.ts index e3e2f8c..2625d63 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -43,9 +43,11 @@ import type { AnyTypeAnnotation, ArrayExpression, + BlockStatement, BooleanLiteral, BooleanTypeAnnotation, ExpressionStatement, + FunctionDeclaration, GenericTypeAnnotation, Identifier, MemberExpression, @@ -57,6 +59,7 @@ import type { NumericLiteral, ObjectExpression, ObjectProperty, + ReturnStatement, StringLiteral, StringTypeAnnotation, TypeAnnotation, @@ -69,6 +72,7 @@ import type { ArrayType, BooleanLiteralType, BooleanType, + FunctionType, NullType, NumberLiteralType, NumberType, @@ -77,6 +81,7 @@ import type { StringLiteralType, StringType, UnknownType, + VoidType, } from './types'; import type { Push, Tail } from './utils/arrayUtils'; import type { MergeWithOverride } from './utils/generalUtils'; @@ -99,6 +104,56 @@ export type Check< ? Check, G[1], R> : Check, S, Push> : never + : T[0] extends FunctionDeclaration + ? InferFunctionDeclaration extends infer G + ? G extends Array + ? Check, G[1], R> + : Check, S, Push> + : never + : never; + +type InferFunctionDeclaration< + O extends FunctionDeclaration, + S extends {}, +> = O extends FunctionDeclaration< + Identifier>, + infer P, + BlockStatement, + any +> + ? InferBlockStatement extends infer G + ? G extends Array + ? [null, MergeWithOverride }>] + : G + : never + : never; + +type InferBlockStatement< + T extends Array>, + S extends {} = {}, + R extends StaticType = VoidType, +> = T extends [] + ? [R, S] + : T[0] extends ExpressionStatement + ? InferExpressionStatement extends infer G + ? G extends Array + ? InferBlockStatement, G[1], R> + : G + : never + : T[0] extends VariableDeclaration + ? InferVariableDeclaration extends infer G + ? G extends Array + ? InferBlockStatement, G[1], R> + : G + : never + : T[0] extends ReturnStatement + ? F extends Node + ? InferExpression extends infer G + ? G extends Array + ? InferBlockStatement<[], G[1], G[0]> + : G + : never + : InferBlockStatement, S, VoidType> : never; type MatchType = A extends AnyType diff --git a/src/index.ts b/src/index.ts index 2692458..2165a6e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,7 +4,9 @@ import type { Check } from './checker'; type T = Tokenize<` -[1, 2, 3] +function foo(a: string) { + return a; +} `>; type R = Parse; diff --git a/src/types.ts b/src/types.ts index fc44543..1e4c7fc 100644 --- a/src/types.ts +++ b/src/types.ts @@ -41,7 +41,10 @@ export type AnyType = { type: 'AnyType'; }; -export type FunctionType = { +export type FunctionType< + P extends Array, + R extends Array, +> = { type: 'FunctionType'; params: P; return: R; From 2c549aa92fef218dd5efa63c6ca516f7ddd3a373 Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 11 Jul 2022 14:51:37 +0300 Subject: [PATCH 154/286] wip --- src/checker.ts | 54 ++++++++++++++++++++++++++++++++++---------------- src/index.ts | 2 +- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 2625d63..ae3e449 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -112,6 +112,35 @@ export type Check< : never : never; +type MapAnnotationToType> = + A extends StringTypeAnnotation + ? StringType + : A extends NumberTypeAnnotation + ? NumberType + : A extends BooleanTypeAnnotation + ? BooleanType + : A extends NullLiteralTypeAnnotation + ? NullType + : A extends AnyTypeAnnotation + ? AnyType + : never; + +type InferFunctionParams< + T extends Array>, + S extends {}, + R extends Array = [], + H extends Record = {}, +> = T extends [] + ? [R, H, S] + : T[0] extends Identifier, any> + ? InferFunctionParams< + Tail, + S, + Push>, + MergeWithOverride }> + > + : never; + type InferFunctionDeclaration< O extends FunctionDeclaration, S extends {}, @@ -121,10 +150,14 @@ type InferFunctionDeclaration< BlockStatement, any > - ? InferBlockStatement extends infer G - ? G extends Array - ? [null, MergeWithOverride }>] - : G + ? InferFunctionParams extends infer H + ? H extends Array + ? InferBlockStatement> extends infer G + ? G extends Array + ? [null, MergeWithOverride }>] + : G + : never + : H : never : never; @@ -176,19 +209,6 @@ type MatchType = A extends AnyType : false : false; -type MapAnnotationToType> = - A extends StringTypeAnnotation - ? StringType - : A extends NumberTypeAnnotation - ? NumberType - : A extends BooleanTypeAnnotation - ? BooleanType - : A extends NullLiteralTypeAnnotation - ? NullType - : A extends AnyTypeAnnotation - ? AnyType - : never; - type InferVariableDeclaration< O extends VariableDeclaration, S extends {}, diff --git a/src/index.ts b/src/index.ts index 2165a6e..4a05580 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,7 +4,7 @@ import type { Check } from './checker'; type T = Tokenize<` -function foo(a: string) { +function foo(a: string, ab: number) { return a; } From c4bfd897f882ab5c595c19446a14b9faa718343f Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 11 Jul 2022 15:48:53 +0300 Subject: [PATCH 155/286] wip --- src/ast.ts | 6 ++++- src/checker.ts | 69 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/index.ts | 6 ++++- src/types.ts | 5 +--- 4 files changed, 78 insertions(+), 8 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index 039f2a5..7bdbd6c 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -110,7 +110,11 @@ export type ExpressionStatement< data: D; }; -export type CallExpression> = { +export type CallExpression< + C extends Node, + A extends Array>, + D extends NodeData, +> = { type: 'CallExpression'; callee: C; arguments: A; diff --git a/src/checker.ts b/src/checker.ts index ae3e449..61bb6fb 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -46,9 +46,9 @@ import type { BlockStatement, BooleanLiteral, BooleanTypeAnnotation, + CallExpression, ExpressionStatement, FunctionDeclaration, - GenericTypeAnnotation, Identifier, MemberExpression, Node, @@ -154,7 +154,7 @@ type InferFunctionDeclaration< ? H extends Array ? InferBlockStatement> extends infer G ? G extends Array - ? [null, MergeWithOverride }>] + ? [null, MergeWithOverride }>] : G : never : H @@ -209,6 +209,19 @@ type MatchType = A extends AnyType : false : false; +type MatchTypeArrays< + T extends Array, + H extends Array, + L extends number, +> = T extends [] + ? true + : MatchType extends true + ? MatchTypeArrays, Tail, L> + : SyntaxError< + `Argument of type '...' is not assignable to parameter of type '...'.`, + L + >; + type InferVariableDeclaration< O extends VariableDeclaration, S extends {}, @@ -270,8 +283,60 @@ type InferExpression< ? InferMemberExpression : T extends ArrayExpression ? InferArrayElements + : T extends CallExpression + ? InferCallExpression : UnknownType; +type InferCallExpression< + C extends Node, + A extends Array>, + S extends {}, +> = C extends Node> + ? InferExpression extends infer G + ? G extends Array + ? G[0] extends FunctionType + ? InferExpressionsArray extends infer H + ? H extends Array + ? InferCallExpressionHelper + : H + : never + : SyntaxError< + `This expression is not callable. Type '...' has no call signatures.`, + L + > + : G + : never + : never; + +type InferCallExpressionHelper< + P extends Array, + H extends Array, + R extends StaticType, + S extends {}, + L extends number, +> = P['length'] extends H['length'] + ? MatchTypeArrays extends infer W + ? W extends true + ? [R, S] + : W + : never + : SyntaxError< + `Expected ${P['length']} arguments, but got ${H['length']}.`, + L + >; + +type InferExpressionsArray< + T extends Array>, + S extends {}, + R extends Array = [], +> = T extends [] + ? [R, S] + : InferExpression extends infer H + ? H extends Array + ? InferExpressionsArray, MergeWithOverride, Push> + : H + : never; + type InferArrayElements< T extends Array>, S extends {}, diff --git a/src/index.ts b/src/index.ts index 4a05580..8b84460 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,10 +4,14 @@ import type { Check } from './checker'; type T = Tokenize<` -function foo(a: string, ab: number) { +function foo(a: string) { return a; } +const bar = foo; + +const w = bar(false); + `>; type R = Parse; type C = Check; diff --git a/src/types.ts b/src/types.ts index 1e4c7fc..4f831c4 100644 --- a/src/types.ts +++ b/src/types.ts @@ -41,10 +41,7 @@ export type AnyType = { type: 'AnyType'; }; -export type FunctionType< - P extends Array, - R extends Array, -> = { +export type FunctionType

, R extends StaticType> = { type: 'FunctionType'; params: P; return: R; From 9571ef1ef19cb4c4ef04db2e7badf49753e75afe Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 11 Jul 2022 16:17:37 +0300 Subject: [PATCH 156/286] wip --- src/checker.ts | 27 ++++++++++++++++++++------- src/index.ts | 6 +++--- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 61bb6fb..4abbd92 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -132,15 +132,26 @@ type InferFunctionParams< H extends Record = {}, > = T extends [] ? [R, H, S] - : T[0] extends Identifier, any> - ? InferFunctionParams< - Tail, - S, - Push>, - MergeWithOverride }> - > + : T[0] extends Identifier + ? K extends TypeAnnotation + ? InferFunctionParamsHelper, N> + : InferFunctionParamsHelper : never; +type InferFunctionParamsHelper< + T extends Array>, + S extends {}, + R extends Array, + H extends Record, + V extends StaticType, + N extends string, +> = InferFunctionParams< + Tail, + S, + Push, + MergeWithOverride +>; + type InferFunctionDeclaration< O extends FunctionDeclaration, S extends {}, @@ -190,6 +201,8 @@ type InferBlockStatement< : never; type MatchType = A extends AnyType + ? true + : B extends AnyType ? true : A extends B ? B extends A diff --git a/src/index.ts b/src/index.ts index 8b84460..32125b0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,13 +4,13 @@ import type { Check } from './checker'; type T = Tokenize<` -function foo(a: string) { +function foo(a) { return a; } -const bar = foo; +const bar: any = foo(1) -const w = bar(false); +const bazz: number = bar; `>; type R = Parse; From bd44c5064f732dcbc70e45b866072817fd3c6764 Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 11 Jul 2022 16:52:30 +0300 Subject: [PATCH 157/286] wip --- src/checker.ts | 30 ++++++++++++++++++++++++++++-- src/index.ts | 8 +------- src/utils/arrayUtils.ts | 6 ++++++ 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 4abbd92..dc1787f 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -80,10 +80,11 @@ import type { StaticType, StringLiteralType, StringType, + UnionType, UnknownType, VoidType, } from './types'; -import type { Push, Tail } from './utils/arrayUtils'; +import type { Includes, Push, Tail } from './utils/arrayUtils'; import type { MergeWithOverride } from './utils/generalUtils'; export type Check< @@ -359,11 +360,36 @@ type InferArrayElements< : T[0] extends Node ? InferExpression extends infer J ? J extends Array - ? InferArrayElements, S, J[0]> + ? MapLiteralToType extends infer E + ? E extends StaticType + ? InferArrayElements, J[1], InferArrayElementsHelper> + : never + : never : J : never : never; +type InferArrayElementsHelper< + R extends StaticType, + E extends StaticType, +> = R extends AnyType + ? E + : R extends E + ? E + : R extends UnionType + ? Includes extends true + ? R + : UnionType> + : UnionType<[R, E]>; + +type MapLiteralToType = T extends NumberLiteralType + ? NumberType + : T extends StringLiteralType + ? StringType + : T extends BooleanLiteralType + ? BooleanType + : T; + type InferMemberExpression< O extends Node, P extends Node, diff --git a/src/index.ts b/src/index.ts index 32125b0..fb5bc8c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,13 +4,7 @@ import type { Check } from './checker'; type T = Tokenize<` -function foo(a) { - return a; -} - -const bar: any = foo(1) - -const bazz: number = bar; +[1, "hey", 2, 3, "foo", "bazz", false] `>; type R = Parse; diff --git a/src/utils/arrayUtils.ts b/src/utils/arrayUtils.ts index f51c51b..ffd7f6b 100644 --- a/src/utils/arrayUtils.ts +++ b/src/utils/arrayUtils.ts @@ -33,3 +33,9 @@ export type TailBy< B extends number, A extends Array = [], > = B extends A['length'] ? T : TailBy, B, Push>; + +export type Includes, E> = T extends [] + ? false + : T[0] extends E + ? true + : Includes, E>; From 01f90ed0c8737c89075cdedac580010e2f9b89b7 Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 11 Jul 2022 17:01:26 +0300 Subject: [PATCH 158/286] wip --- src/checker.ts | 10 +++++++--- src/index.ts | 5 ++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index dc1787f..811b431 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -405,6 +405,8 @@ type InferMemberExpression< ? P extends Node> ? G extends Array ? G[0] extends StringLiteralType + ? InferMemberExpressionHelper + : G[0] extends NumberLiteralType ? InferMemberExpressionHelper : SyntaxError<`Type '{}' cannot be used as an index type.`, L> : G extends null @@ -420,10 +422,12 @@ type InferMemberExpressionHelper< N extends string, S extends {}, L extends number, -> = O extends ObjectType - ? N extends keyof Y - ? [Y[N], S] +> = O extends ObjectType + ? N extends keyof V + ? [V[N], S] : SyntaxError<`Property '${N}' does not exist on type '{}'.`, L> + : O extends ArrayType + ? [V, S] : SyntaxError<`Property '${N}' does not exist on type '...'.`, L>; type InferObjectProperties< diff --git a/src/index.ts b/src/index.ts index fb5bc8c..f87806a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,7 +4,10 @@ import type { Check } from './checker'; type T = Tokenize<` -[1, "hey", 2, 3, "foo", "bazz", false] +const a = [1, "2", 3]; +const b = a[0]; + +const c: number = b; `>; type R = Parse; From 926f31233b61a178277b32996293c6593cad0414 Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 11 Jul 2022 17:15:22 +0300 Subject: [PATCH 159/286] wip --- src/checker.ts | 14 +++++++++++--- src/index.ts | 6 ++++-- src/utils/arrayUtils.ts | 6 ++++++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 811b431..6cd68a8 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -84,7 +84,7 @@ import type { UnknownType, VoidType, } from './types'; -import type { Includes, Push, Tail } from './utils/arrayUtils'; +import type { Includes, Push, Tail, Uniq } from './utils/arrayUtils'; import type { MergeWithOverride } from './utils/generalUtils'; export type Check< @@ -362,7 +362,11 @@ type InferArrayElements< ? J extends Array ? MapLiteralToType extends infer E ? E extends StaticType - ? InferArrayElements, J[1], InferArrayElementsHelper> + ? InferArrayElementsHelper extends infer U + ? U extends StaticType + ? InferArrayElements, J[1], U> + : never + : never : never : never : J @@ -377,9 +381,13 @@ type InferArrayElementsHelper< : R extends E ? E : R extends UnionType - ? Includes extends true + ? E extends UnionType + ? UnionType> + : Includes extends true ? R : UnionType> + : E extends UnionType + ? UnionType> : UnionType<[R, E]>; type MapLiteralToType = T extends NumberLiteralType diff --git a/src/index.ts b/src/index.ts index f87806a..70d3367 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,10 +4,12 @@ import type { Check } from './checker'; type T = Tokenize<` -const a = [1, "2", 3]; +const a = [1, "2"]; const b = a[0]; +const c = [true, "3", b]; +const d = c[0] -const c: number = b; +d() `>; type R = Parse; diff --git a/src/utils/arrayUtils.ts b/src/utils/arrayUtils.ts index ffd7f6b..3c5b553 100644 --- a/src/utils/arrayUtils.ts +++ b/src/utils/arrayUtils.ts @@ -39,3 +39,9 @@ export type Includes, E> = T extends [] : T[0] extends E ? true : Includes, E>; + +export type Uniq, R extends Array = []> = T extends [] + ? R + : Includes extends true + ? Uniq, R> + : Uniq, Push>; From 6a98df4ea0f0248303dddb21928ca94382bc7c06 Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 11 Jul 2022 17:57:03 +0300 Subject: [PATCH 160/286] wip --- src/checker.ts | 4 ++++ src/index.ts | 8 +++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 6cd68a8..88d0bc8 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -396,6 +396,10 @@ type MapLiteralToType = T extends NumberLiteralType ? StringType : T extends BooleanLiteralType ? BooleanType + : T extends ObjectType + ? ObjectType<{ + [P in keyof O]: O[P] extends StaticType ? MapLiteralToType : never; + }> : T; type InferMemberExpression< diff --git a/src/index.ts b/src/index.ts index 70d3367..e1deb50 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,12 +4,10 @@ import type { Check } from './checker'; type T = Tokenize<` -const a = [1, "2"]; -const b = a[0]; -const c = [true, "3", b]; -const d = c[0] +const b = [1, { a: 'b' }, { a: 1 }]; +const a = b[1] -d() +a() `>; type R = Parse; From 2e13bf69c264c0d4513f3c9d80e27abef63412e9 Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 11 Jul 2022 20:43:42 +0300 Subject: [PATCH 161/286] wip --- src/checker.ts | 18 +++++++++++++++++- src/index.ts | 7 ++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 88d0bc8..5191606 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -430,7 +430,7 @@ type InferMemberExpression< : never; type InferMemberExpressionHelper< - O extends ObjectType, + O extends StaticType, N extends string, S extends {}, L extends number, @@ -440,8 +440,24 @@ type InferMemberExpressionHelper< : SyntaxError<`Property '${N}' does not exist on type '{}'.`, L> : O extends ArrayType ? [V, S] + : O extends UnionType + ? InferMemberExpressionUnionHelper : SyntaxError<`Property '${N}' does not exist on type '...'.`, L>; +type InferMemberExpressionUnionHelper< + U extends Array, + N extends string, + S extends {}, + L extends number, + R extends Array = [], +> = U extends [] + ? [UnionType, S] + : InferMemberExpressionHelper extends infer H + ? H extends Array + ? InferMemberExpressionUnionHelper, N, H[1], L, Push> + : H + : never; + type InferObjectProperties< T extends Array>, S extends {}, diff --git a/src/index.ts b/src/index.ts index e1deb50..388addc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,10 +4,11 @@ import type { Check } from './checker'; type T = Tokenize<` -const b = [1, { a: 'b' }, { a: 1 }]; -const a = b[1] +const a = [{ a: 'b' }, { a: '1' }]; +const b = a[1] +const c = b.a; -a() +const d: string = c; `>; type R = Parse; From 9a8b956c3967ad65e9b34d776bf4a26f7c71adda Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 11 Jul 2022 21:34:57 +0300 Subject: [PATCH 162/286] wip --- TODO.md | 1 - src/index.ts | 7 ++++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/TODO.md b/TODO.md index b23269c..0ebdaf7 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,5 @@ ### TODOs -- Adjut parser/tokenizer to using line-breaks and `;` when parsing expressions - Fully implement type checks include object/array types that require parser/tokenizer work - Re-organize tests from a long list into reasonable groups - Add comments to explain the implementation diff --git a/src/index.ts b/src/index.ts index 388addc..acd7af4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,11 +4,12 @@ import type { Check } from './checker'; type T = Tokenize<` -const a = [{ a: 'b' }, { a: '1' }]; +const a = ['b', 1]; const b = a[1] -const c = b.a; -const d: string = c; +function foo(c: number) {} + +foo(b); `>; type R = Parse; From ceb9b0cb6e61a394136747c2fee498b2ed7ceb91 Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 12 Jul 2022 00:29:10 +0300 Subject: [PATCH 163/286] wip --- src/serializer.ts | 64 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/serializer.ts diff --git a/src/serializer.ts b/src/serializer.ts new file mode 100644 index 0000000..d3e8ed4 --- /dev/null +++ b/src/serializer.ts @@ -0,0 +1,64 @@ +import type { + ArrayType, + BooleanType, + NullType, + NumberType, + ObjectType, + StaticType, + StringType, + UnionType, +} from './types'; +import type { Tail } from './utils/arrayUtils'; + +export type Serialize< + T extends StaticType, + N extends boolean = false, +> = T extends StringType + ? 'string' + : T extends BooleanType + ? 'boolean' + : T extends NumberType + ? 'number' + : T extends NullType + ? 'null' + : T extends ArrayType + ? SerializeArray + : T extends UnionType + ? SerializeUnion + : T extends ObjectType + ? { [P in keyof O]: O[P] extends StaticType ? Serialize : never } + : never; + +type SerializeArray = Serialize extends infer H + ? H extends string + ? `${H}[]` + : never + : never; + +type SerializeUnion< + U extends Array, + N extends boolean, + R extends string = '', +> = U extends [] + ? N extends true + ? `(${R})` + : R + : U[0] extends StaticType + ? Serialize extends infer H + ? H extends string + ? SerializeUnion< + Tail, + N, + U['length'] extends 1 ? `${R}${H}` : `${R}${H} | ` + > + : never + : never + : never; + +type R = Serialize< + ArrayType< + UnionType< + [StringType, NumberType, ArrayType>] + > + > +>; From 6896f35a4596a52366147012f01f591b15319d8e Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 12 Jul 2022 18:18:23 +0300 Subject: [PATCH 164/286] wip --- src/checker.ts | 265 +------------------------------------------------ 1 file changed, 1 insertion(+), 264 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 5191606..031f871 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -1,45 +1,3 @@ -// import type { -// AnyTypeAnnotation, -// ArrayExpression, -// BlockStatement, -// BooleanLiteral, -// BooleanTypeAnnotation, -// CallExpression, -// ExpressionStatement, -// FunctionDeclaration, -// GenericTypeAnnotation, -// Identifier, -// IfStatement, -// MemberExpression, -// NullLiteral, -// NullLiteralTypeAnnotation, -// NumberTypeAnnotation, -// NumericLiteral, -// ObjectExpression, -// ObjectProperty, -// ReturnStatement, -// StringLiteral, -// StringTypeAnnotation, -// TypeAnnotation, -// VariableDeclaration, -// VariableDeclarator, -// } from './ast'; -// import type { -// AnyType, -// ArrayType, -// BooleanType, -// FunctionType, -// GenericType, -// NullType, -// NumberType, -// ObjectType, -// StringType, -// UnknownType, -// VoidType, -// } from './types'; -// import type { Concat, Reverse, Tail, Unshift } from './utils/arrayUtils'; -// import type { Cast, MergeWithOverride } from './utils/generalUtils'; - import type { AnyTypeAnnotation, ArrayExpression, @@ -66,7 +24,7 @@ import type { VariableDeclaration, VariableDeclarator, } from './ast'; -import type { Error, SyntaxError } from './errors'; +import type { SyntaxError } from './errors'; import type { AnyType, ArrayType, @@ -471,224 +429,3 @@ type InferObjectProperties< : J : never : never; - -// : T extends ArrayExpression -// ? ArrayType>, S>> -// : T extends ObjectExpression -// ? ObjectType>, S>> -// : T extends CallExpression -// ? InferCallArguments>, S> extends infer O -// ? InferExpression extends infer I -// ? I extends FunctionType -// ? AssignableArgumentTypes< -// Cast>, -// Cast> -// > extends true -// ? R -// : never -// : never -// : never -// : never -// : T extends MemberExpression> -// ? InferExpression extends infer D -// ? D extends ObjectType -// ? P extends keyof Y -// ? Y[P] -// : never -// : D extends StringType -// ? P extends 'length' -// ? NumberType -// : never -// : D extends NumberType -// ? P extends 'toString' -// ? FunctionType<[], StringType> -// : never -// : never -// : never -// : UnknownType; - -// type InferArrayElements< -// T extends Array, -// S extends {}, -// R extends Array = [], -// > = T extends [] -// ? R -// : InferArrayElements, S, Unshift>>; - -// type InferObjectValues< -// T extends Array, -// S extends {}, -// R extends {} = {}, -// > = T extends [] -// ? R -// : T[0] extends ObjectProperty, infer K> -// ? InferObjectValues< -// Tail, -// S, -// MergeWithOverride]: InferExpression }> -// > -// : never; - -// type InferCallArguments< -// T extends Array, -// S extends {}, -// R extends Array = [], -// > = T extends [] -// ? Reverse -// : InferCallArguments, S, Unshift>>; - -// type AssignableTypes = A extends AnyType -// ? true -// : B extends A -// ? true -// : false; - -// type AssignableArgumentTypes< -// I extends Array, -// P extends Array, -// > = I extends [] -// ? P extends [] -// ? true -// : false -// : AssignableTypes extends false -// ? false -// : AssignableArgumentTypes, Tail

>; - -// type InferExpression = T extends StringLiteral -// ? StringType -// : T extends NumericLiteral -// ? NumberType -// : T extends NullLiteral -// ? NullType -// : T extends BooleanLiteral -// ? BooleanType -// : T extends Identifier -// ? N extends keyof S -// ? S[N] -// : never -// : T extends ArrayExpression -// ? ArrayType>, S>> -// : T extends ObjectExpression -// ? ObjectType>, S>> -// : T extends CallExpression -// ? InferCallArguments>, S> extends infer O -// ? InferExpression extends infer I -// ? I extends FunctionType -// ? AssignableArgumentTypes< -// Cast>, -// Cast> -// > extends true -// ? R -// : never -// : never -// : never -// : never -// : T extends MemberExpression> -// ? InferExpression extends infer D -// ? D extends ObjectType -// ? P extends keyof Y -// ? Y[P] -// : never -// : D extends StringType -// ? P extends 'length' -// ? NumberType -// : never -// : D extends NumberType -// ? P extends 'toString' -// ? FunctionType<[], StringType> -// : never -// : never -// : never -// : UnknownType; - -// type MapTypeAnnotationToType = A extends StringTypeAnnotation -// ? StringType -// : A extends NumberTypeAnnotation -// ? NumberType -// : A extends BooleanTypeAnnotation -// ? BooleanType -// : A extends NullLiteralTypeAnnotation -// ? NullType -// : A extends AnyTypeAnnotation -// ? AnyType -// : A extends GenericTypeAnnotation -// ? GenericType -// : never; - -// type InferFunctionParams< -// T extends Array, -// R extends Array = [], -// G = {}, -// > = T extends [] -// ? [Reverse, G] -// : T[0] extends Identifier> -// ? InferFunctionParams< -// Tail, -// Unshift>, -// MergeWithOverride< -// G, -// { [a in Cast]: MapTypeAnnotationToType } -// > -// > -// : never; - -// type InferBlock< -// T extends Array, -// S extends {}, -// R extends Array = [], -// > = T extends [] -// ? Unshift -// : T[0] extends ReturnStatement -// ? InferExpression extends infer G -// ? G extends Array -// ? Concat>> -// : Unshift -// : never -// : T[0] extends VariableDeclaration< -// [VariableDeclarator, infer I>], -// any -// > -// ? InferBlock< -// Tail, -// MergeWithOverride]: InferExpression }>, -// R -// > -// : T[0] extends FunctionDeclaration< -// Identifier, -// infer P, -// BlockStatement -// > -// ? InferFunctionParams>> extends infer O -// ? InferBlock< -// Tail, -// MergeWithOverride< -// S, -// { -// [a in Cast]: FunctionType< -// Cast>[0], -// InferBlock< -// Cast>, -// MergeWithOverride>[1]> -// > -// >; -// } -// >, -// R -// > -// : never -// : T[0] extends IfStatement> -// ? InferBlock>, S> extends infer J -// ? Concat>> extends infer G -// ? InferBlock, S, Cast>> -// : never -// : never -// : InferBlock, S, R>; - -// type CheckBlock< -// T extends Array, -// S extends {} = {}, -// > = T[0] extends ExpressionStatement -// ? InferExpression -// : T[0] extends BlockStatement -// ? InferBlock>, S> -// : []; From 2b58b022f7b14665be56550099e3f1a8f48af8d2 Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 12 Jul 2022 18:40:03 +0300 Subject: [PATCH 165/286] wip --- src/checker.ts | 21 +++++++++++++---- src/index.ts | 7 ++---- src/serializer.ts | 51 ++++++++++++++++++++++++++++------------ src/test/checker.test.ts | 10 ++++---- 4 files changed, 60 insertions(+), 29 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 031f871..fdb4bb1 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -25,6 +25,7 @@ import type { VariableDeclarator, } from './ast'; import type { SyntaxError } from './errors'; +import type { Serialize } from './serializer'; import type { AnyType, ArrayType, @@ -190,7 +191,9 @@ type MatchTypeArrays< : MatchType extends true ? MatchTypeArrays, Tail, L> : SyntaxError< - `Argument of type '...' is not assignable to parameter of type '...'.`, + `Argument of type '${Serialize< + H[0] + >}' is not assignable to parameter of type '${Serialize}'.`, L >; @@ -215,7 +218,12 @@ type InferVariableDeclaration< ? P extends StaticType ? MatchType extends true ? [null, MergeWithOverride] - : SyntaxError<`Type '...' is not assignable to type '...'.`, L> + : SyntaxError< + `Type '${Serialize< + G[0] + >}' is not assignable to type '${Serialize

}'.`, + L + > : never : never : [null, MergeWithOverride] @@ -273,7 +281,9 @@ type InferCallExpression< : H : never : SyntaxError< - `This expression is not callable. Type '...' has no call signatures.`, + `This expression is not callable. Type '${Serialize< + G[0] + >}' has no call signatures.`, L > : G @@ -378,7 +388,10 @@ type InferMemberExpression< ? InferMemberExpressionHelper : G[0] extends NumberLiteralType ? InferMemberExpressionHelper - : SyntaxError<`Type '{}' cannot be used as an index type.`, L> + : SyntaxError< + `Type '${Serialize}' cannot be used as an index type.`, + L + > : G extends null ? never : G diff --git a/src/index.ts b/src/index.ts index acd7af4..300c992 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,12 +4,9 @@ import type { Check } from './checker'; type T = Tokenize<` -const a = ['b', 1]; -const b = a[1] +const hello = {hey: "world"}; -function foo(c: number) {} - -foo(b); +const foo: number = hello; `>; type R = Parse; diff --git a/src/serializer.ts b/src/serializer.ts index d3e8ed4..f5e63a1 100644 --- a/src/serializer.ts +++ b/src/serializer.ts @@ -1,10 +1,13 @@ import type { ArrayType, + BooleanLiteralType, BooleanType, NullType, + NumberLiteralType, NumberType, ObjectType, StaticType, + StringLiteralType, StringType, UnionType, } from './types'; @@ -13,22 +16,36 @@ import type { Tail } from './utils/arrayUtils'; export type Serialize< T extends StaticType, N extends boolean = false, -> = T extends StringType - ? 'string' - : T extends BooleanType - ? 'boolean' - : T extends NumberType - ? 'number' - : T extends NullType - ? 'null' - : T extends ArrayType - ? SerializeArray - : T extends UnionType - ? SerializeUnion - : T extends ObjectType - ? { [P in keyof O]: O[P] extends StaticType ? Serialize : never } +> = MapLiteralToType extends infer H + ? H extends StringType + ? 'string' + : H extends BooleanType + ? 'boolean' + : H extends NumberType + ? 'number' + : H extends NullType + ? 'null' + : H extends ArrayType + ? SerializeArray + : H extends UnionType + ? SerializeUnion + : H extends ObjectType + ? { [P in keyof O]: O[P] extends StaticType ? Serialize : never } + : never : never; +type MapLiteralToType = T extends NumberLiteralType + ? NumberType + : T extends StringLiteralType + ? StringType + : T extends BooleanLiteralType + ? BooleanType + : T extends ObjectType + ? ObjectType<{ + [P in keyof O]: O[P] extends StaticType ? MapLiteralToType : never; + }> + : T; + type SerializeArray = Serialize extends infer H ? H extends string ? `${H}[]` @@ -58,7 +75,11 @@ type SerializeUnion< type R = Serialize< ArrayType< UnionType< - [StringType, NumberType, ArrayType>] + [ + StringLiteralType<'hello'>, + NumberLiteralType<'2'>, + ArrayType>, + ] > > >; diff --git a/src/test/checker.test.ts b/src/test/checker.test.ts index d086ee0..685997f 100644 --- a/src/test/checker.test.ts +++ b/src/test/checker.test.ts @@ -203,7 +203,7 @@ const hello: number = "hello"; >([ { type: 'SyntaxError', - message: "Type '...' is not assignable to type '...'.", + message: "Type 'string' is not assignable to type 'number'.", lineNumber: 3, }, ]); @@ -217,7 +217,7 @@ const hello: string = 123; >([ { type: 'SyntaxError', - message: "Type '...' is not assignable to type '...'.", + message: "Type 'number' is not assignable to type 'string'.", lineNumber: 3, }, ]); @@ -232,7 +232,7 @@ const foo: number = hello; >([ { type: 'SyntaxError', - message: "Type '...' is not assignable to type '...'.", + message: "Type 'string' is not assignable to type 'number'.", lineNumber: 4, }, ]); @@ -274,7 +274,7 @@ const foo: number = hello.hey; >([ { type: 'SyntaxError', - message: "Type '...' is not assignable to type '...'.", + message: "Type 'string' is not assignable to type 'number'.", lineNumber: 5, }, ]); @@ -417,7 +417,7 @@ o[true]; >([ { type: 'SyntaxError', - message: "Type '{}' cannot be used as an index type.", + message: "Type 'boolean' cannot be used as an index type.", lineNumber: 7, }, ]); From 6569d3033834b44a00dd53fbe40d48bba38cae0b Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 12 Jul 2022 19:27:41 +0300 Subject: [PATCH 166/286] wip --- src/checker.ts | 21 ++++++++++++++++----- src/index.ts | 4 +--- src/types.ts | 2 +- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index fdb4bb1..f982848 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -400,15 +400,26 @@ type InferMemberExpression< : J : never; +type InferObjectMemberExpressionHelper< + V extends Array<[string, StaticType]>, + N extends string, +> = V extends [] + ? null + : V[0][0] extends N + ? V[0][1] + : InferObjectMemberExpressionHelper, N>; + type InferMemberExpressionHelper< O extends StaticType, N extends string, S extends {}, L extends number, > = O extends ObjectType - ? N extends keyof V - ? [V[N], S] - : SyntaxError<`Property '${N}' does not exist on type '{}'.`, L> + ? InferObjectMemberExpressionHelper extends infer I + ? I extends null + ? SyntaxError<`Property '${N}' does not exist on type '{}'.`, L> + : [I, S] + : never : O extends ArrayType ? [V, S] : O extends UnionType @@ -432,13 +443,13 @@ type InferMemberExpressionUnionHelper< type InferObjectProperties< T extends Array>, S extends {}, - R extends {} = {}, + R extends Array = [], > = T extends [] ? [ObjectType, S] : T[0] extends ObjectProperty, infer V, any> ? InferExpression extends infer J ? J extends Array - ? InferObjectProperties, S, R & { [a in K]: J[0] }> + ? InferObjectProperties, S, Push> : J : never : never; diff --git a/src/index.ts b/src/index.ts index 300c992..697f1f8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,9 +4,7 @@ import type { Check } from './checker'; type T = Tokenize<` -const hello = {hey: "world"}; - -const foo: number = hello; +const hello: string = {hello: "world", foo: "bar"}; `>; type R = Parse; diff --git a/src/types.ts b/src/types.ts index 4f831c4..9920fc0 100644 --- a/src/types.ts +++ b/src/types.ts @@ -47,7 +47,7 @@ export type FunctionType

, R extends StaticType> = { return: R; }; -export type ObjectType = { +export type ObjectType> = { type: 'ObjectType'; object: O; }; From 26d6f0693336ce7590b95ecca218b382e0939e31 Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 12 Jul 2022 19:30:09 +0300 Subject: [PATCH 167/286] wip --- src/checker.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index f982848..cb74dc4 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -400,14 +400,14 @@ type InferMemberExpression< : J : never; -type InferObjectMemberExpressionHelper< +type InferMemberExpressionObjectHelper< V extends Array<[string, StaticType]>, N extends string, > = V extends [] ? null : V[0][0] extends N ? V[0][1] - : InferObjectMemberExpressionHelper, N>; + : InferMemberExpressionObjectHelper, N>; type InferMemberExpressionHelper< O extends StaticType, @@ -415,7 +415,7 @@ type InferMemberExpressionHelper< S extends {}, L extends number, > = O extends ObjectType - ? InferObjectMemberExpressionHelper extends infer I + ? InferMemberExpressionObjectHelper extends infer I ? I extends null ? SyntaxError<`Property '${N}' does not exist on type '{}'.`, L> : [I, S] From c2193881029a84a81ec0b02fabf03ab562d08f8e Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 12 Jul 2022 19:50:48 +0300 Subject: [PATCH 168/286] wip --- src/index.ts | 4 +++- src/serializer.ts | 36 +++++++++++++++++++----------------- src/test/checker.test.ts | 2 +- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/index.ts b/src/index.ts index 697f1f8..5342dda 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,7 +4,9 @@ import type { Check } from './checker'; type T = Tokenize<` -const hello: string = {hello: "world", foo: "bar"}; +const a = [1, "a"][0] + +const hello: string = {hello: "world", foo: a}; `>; type R = Parse; diff --git a/src/serializer.ts b/src/serializer.ts index f5e63a1..a44bd3e 100644 --- a/src/serializer.ts +++ b/src/serializer.ts @@ -30,7 +30,7 @@ export type Serialize< : H extends UnionType ? SerializeUnion : H extends ObjectType - ? { [P in keyof O]: O[P] extends StaticType ? Serialize : never } + ? SerializeObject : never : never; @@ -40,13 +40,9 @@ type MapLiteralToType = T extends NumberLiteralType ? StringType : T extends BooleanLiteralType ? BooleanType - : T extends ObjectType - ? ObjectType<{ - [P in keyof O]: O[P] extends StaticType ? MapLiteralToType : never; - }> : T; -type SerializeArray = Serialize extends infer H +type SerializeArray = Serialize extends infer H ? H extends string ? `${H}[]` : never @@ -72,14 +68,20 @@ type SerializeUnion< : never : never; -type R = Serialize< - ArrayType< - UnionType< - [ - StringLiteralType<'hello'>, - NumberLiteralType<'2'>, - ArrayType>, - ] - > - > ->; +type SerializeObject< + U extends Array<[string, StaticType]>, + R extends string = '', +> = U extends [] + ? R extends '' + ? '{}' + : `{ ${R} }` + : U[0] extends [string, StaticType] + ? `${U[0][0]}: ${Serialize}` extends infer H + ? H extends string + ? SerializeObject< + Tail, + U['length'] extends 1 ? `${R}${H};` : `${R}${H}; ` + > + : never + : never + : never; diff --git a/src/test/checker.test.ts b/src/test/checker.test.ts index 685997f..9e0e171 100644 --- a/src/test/checker.test.ts +++ b/src/test/checker.test.ts @@ -258,7 +258,7 @@ const foo: number = hello; >([ { type: 'SyntaxError', - message: "Type '...' is not assignable to type '...'.", + message: "Type '{ hey: string; }' is not assignable to type 'number'.", lineNumber: 5, }, ]); From fdea3f028fb9b47278932cd66720089bac2c2ad2 Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 12 Jul 2022 20:27:38 +0300 Subject: [PATCH 169/286] wip --- src/serializer.ts | 2 +- src/test/checker.test.ts | 64 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/serializer.ts b/src/serializer.ts index a44bd3e..b86e660 100644 --- a/src/serializer.ts +++ b/src/serializer.ts @@ -42,7 +42,7 @@ type MapLiteralToType = T extends NumberLiteralType ? BooleanType : T; -type SerializeArray = Serialize extends infer H +type SerializeArray = Serialize extends infer H ? H extends string ? `${H}[]` : never diff --git a/src/test/checker.test.ts b/src/test/checker.test.ts index 9e0e171..1b3d47a 100644 --- a/src/test/checker.test.ts +++ b/src/test/checker.test.ts @@ -421,3 +421,67 @@ o[true]; lineNumber: 7, }, ]); + +expectType< + TypeCheck<` + +const a = [1,2,3]; + +const b: string = a; + +`> +>([ + { + type: 'SyntaxError', + message: "Type 'number[]' is not assignable to type 'string'.", + lineNumber: 5, + }, +]); + +expectType< + TypeCheck<` + +const a = [1,2,'3']; + +const b: string = a; + +`> +>([ + { + type: 'SyntaxError', + message: "Type '(number | string)[]' is not assignable to type 'string'.", + lineNumber: 5, + }, +]); + +expectType< + TypeCheck<` + +const a = [1,2,'3'][0]; + +const b: string = a; + +`> +>([ + { + type: 'SyntaxError', + message: "Type 'number | string' is not assignable to type 'string'.", + lineNumber: 5, + }, +]); + +expectType< + TypeCheck<` + +const a = [[1, 2]]; + +const b: string = a; + +`> +>([ + { + type: 'SyntaxError', + message: "Type 'number[][]' is not assignable to type 'string'.", + lineNumber: 5, + }, +]); From c8ee85cca2feeabcbbe61b5a5a6ee5a469b55530 Mon Sep 17 00:00:00 2001 From: ronami Date: Wed, 13 Jul 2022 18:52:49 +0300 Subject: [PATCH 170/286] wip --- README.md | 39 ++++++++++++++------------------------- src/checker.ts | 7 +++++-- src/index.ts | 6 ++++-- src/test/checker.test.ts | 8 ++++---- 4 files changed, 27 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index d558612..5b41690 100644 --- a/README.md +++ b/README.md @@ -8,34 +8,34 @@ This project includes a (very) simplified implementation of [TypeScript](https:/ The implementation uses types only — with no runtime code whatsoever, and to see it in action you'll need to hover your mouse over the resulting type. -You enter TypeScript code as string and get possible type errors back: +You enter TypeScript code as string and get possible type errors back (**[See the live demo]()**): ```typescript import type { TypeCheck } from 'hypescript'; type Errors = TypeCheck<` -function foo(name: string) { +function foo(name: number) { return name } -const result = foo() +foo('not a number') `>; // Errors is now equal to the following type: -type Expected = ["Expected 1 arguments, but got 0."]; +type Expected = ["Line 7: Argument of type 'string' is not assignable to parameter of type 'number'."]; ``` -The project contains a tokenizer, parser and type-checker and includes comments explaining how everything works. +The implementation includes a tokenizer, parser, and a type-checker and includes comments explaining how everything works. *☝ Please note that this project is meant to be used for fun and learning purposes and not for practical use.* ### Try running the code -See it live on your browser on the [TypeScript Playground](). +See a live demo in your browser on the [TypeScript Playground](). -Alternatively, install `hypescript` in your own project with `yarn` or `npm` ([TypeScript](https://github.com/microsoft/TypeScript) 4.1 or later is required): +Alternatively, install `hypescript` in your own project with `yarn` or `npm` ([TypeScript](https://github.com/microsoft/TypeScript) 4.7 or later is required): ``` yarn add hypescript @@ -43,25 +43,14 @@ yarn add hypescript ### Supported features and syntax -Some syntax or type checking features aren't supported (yet), here are some example for what currently works (see demo link for each). +Some TypeScript syntax and features haven't been implemented and won't work. Here's a list of examples (with demo links) for some of the capabilites: -#### Calling a function with missing arguments - -The following would result in the `Errors` type showing the following error: `Expected 1 arguments, but got 0.` - -```typescript -import type { TypeCheck } from 'hypescript'; - -type Errors = TypeCheck<` - -function foo(name: string) { - return name -} - -const result = foo() - -`>; -``` +- [Calling a function with insufficient arguments]() +- [Calling a function with wrong argument types]() +- [Trying to access a variable that haven't been defined]() +- [Accessing a property that doesn't exist on an object]() +- [Trying to assign a value to a variable that doesn't match its type annotation]() +- [Trying to access a variable that haven't been defined]() ### Additional links diff --git a/src/checker.ts b/src/checker.ts index cb74dc4..4cec811 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -417,14 +417,17 @@ type InferMemberExpressionHelper< > = O extends ObjectType ? InferMemberExpressionObjectHelper extends infer I ? I extends null - ? SyntaxError<`Property '${N}' does not exist on type '{}'.`, L> + ? SyntaxError< + `Property '${N}' does not exist on type '${Serialize}'.`, + L + > : [I, S] : never : O extends ArrayType ? [V, S] : O extends UnionType ? InferMemberExpressionUnionHelper - : SyntaxError<`Property '${N}' does not exist on type '...'.`, L>; + : SyntaxError<`Property '${N}' does not exist on type '${Serialize}'.`, L>; type InferMemberExpressionUnionHelper< U extends Array, diff --git a/src/index.ts b/src/index.ts index 5342dda..19ea8ec 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,9 +4,11 @@ import type { Check } from './checker'; type T = Tokenize<` -const a = [1, "a"][0] +function foo(a: number) {} -const hello: string = {hello: "world", foo: a}; +const a = foo + +foo(a) `>; type R = Parse; diff --git a/src/test/checker.test.ts b/src/test/checker.test.ts index 1b3d47a..d332792 100644 --- a/src/test/checker.test.ts +++ b/src/test/checker.test.ts @@ -92,7 +92,7 @@ hello.world >([ { type: 'SyntaxError', - message: "Property 'world' does not exist on type '{}'.", + message: "Property 'world' does not exist on type '{ foo: string; }'.", lineNumber: 4, }, ]); @@ -137,7 +137,7 @@ hello >([ { type: 'SyntaxError', - message: "Property 'hey' does not exist on type '{}'.", + message: "Property 'hey' does not exist on type '{ bar: string; }'.", lineNumber: 11, }, ]); @@ -153,7 +153,7 @@ hello.foo >([ { type: 'SyntaxError', - message: "Property 'foo' does not exist on type '...'.", + message: "Property 'foo' does not exist on type 'string'.", lineNumber: 5, }, ]); @@ -377,7 +377,7 @@ o[k]["hi"]; >([ { type: 'SyntaxError', - message: "Property 'hi' does not exist on type '{}'.", + message: "Property 'hi' does not exist on type '{ ho: string; }'.", lineNumber: 11, }, ]); From 8ea466cb858a2c11052dd97c6fd79e298672fca7 Mon Sep 17 00:00:00 2001 From: ronami Date: Wed, 13 Jul 2022 18:53:31 +0300 Subject: [PATCH 171/286] wip --- src/checker.ts | 14 ++++---- src/index.ts | 6 ++-- src/serializer.ts | 91 +++++++++++++++++++++++++++++++++-------------- src/types.ts | 5 ++- 4 files changed, 78 insertions(+), 38 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 4cec811..3758d14 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -88,7 +88,7 @@ type MapAnnotationToType> = type InferFunctionParams< T extends Array>, S extends {}, - R extends Array = [], + R extends Array<[string, StaticType]> = [], H extends Record = {}, > = T extends [] ? [R, H, S] @@ -101,14 +101,14 @@ type InferFunctionParams< type InferFunctionParamsHelper< T extends Array>, S extends {}, - R extends Array, + R extends Array<[string, StaticType]>, H extends Record, V extends StaticType, N extends string, > = InferFunctionParams< Tail, S, - Push, + Push, MergeWithOverride >; @@ -183,17 +183,17 @@ type MatchType = A extends AnyType : false; type MatchTypeArrays< - T extends Array, + T extends Array<[string, StaticType]>, H extends Array, L extends number, > = T extends [] ? true - : MatchType extends true + : MatchType extends true ? MatchTypeArrays, Tail, L> : SyntaxError< `Argument of type '${Serialize< H[0] - >}' is not assignable to parameter of type '${Serialize}'.`, + >}' is not assignable to parameter of type '${Serialize}'.`, L >; @@ -291,7 +291,7 @@ type InferCallExpression< : never; type InferCallExpressionHelper< - P extends Array, + P extends Array<[string, StaticType]>, H extends Array, R extends StaticType, S extends {}, diff --git a/src/index.ts b/src/index.ts index 19ea8ec..bc4243a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,11 +4,9 @@ import type { Check } from './checker'; type T = Tokenize<` -function foo(a: number) {} +function foo(hey: number, ho: string) {} -const a = foo - -foo(a) +foo([foo], 'a') `>; type R = Parse; diff --git a/src/serializer.ts b/src/serializer.ts index b86e660..72b2bfe 100644 --- a/src/serializer.ts +++ b/src/serializer.ts @@ -2,6 +2,7 @@ import type { ArrayType, BooleanLiteralType, BooleanType, + FunctionType, NullType, NumberLiteralType, NumberType, @@ -10,27 +11,61 @@ import type { StringLiteralType, StringType, UnionType, + VoidType, } from './types'; import type { Tail } from './utils/arrayUtils'; -export type Serialize< - T extends StaticType, - N extends boolean = false, -> = MapLiteralToType extends infer H - ? H extends StringType - ? 'string' - : H extends BooleanType - ? 'boolean' - : H extends NumberType - ? 'number' - : H extends NullType - ? 'null' - : H extends ArrayType - ? SerializeArray - : H extends UnionType - ? SerializeUnion - : H extends ObjectType - ? SerializeObject +export type Serialize = + MapLiteralToType extends infer H + ? H extends StringType + ? 'string' + : H extends BooleanType + ? 'boolean' + : H extends NumberType + ? 'number' + : H extends NullType + ? 'null' + : H extends VoidType + ? 'void' + : H extends ArrayType + ? SerializeArray + : H extends UnionType + ? SerializeUnion + : H extends ObjectType + ? SerializeObject + : H extends FunctionType + ? SerializeFunction + : never + : never; + +type SerializeFunction< + P extends Array<[string, StaticType]>, + R extends StaticType, +> = SerializeFunctionParams

extends infer H + ? H extends string + ? `(${H}) => ${Serialize}` + : never + : never; + +type SerializeFunctionParams< + P extends Array<[string, StaticType]>, + R extends string = '', +> = P extends [] + ? R + : P[0] extends [infer K, infer V] + ? V extends StaticType + ? K extends string + ? SerializeFunctionParams< + Tail

, + `${R}${K}: ${Serialize}` extends infer U + ? U extends string + ? P['length'] extends 1 + ? `${U}` + : `${U}, ` + : never + : never + > + : never : never : never; @@ -42,26 +77,30 @@ type MapLiteralToType = T extends NumberLiteralType ? BooleanType : T; -type SerializeArray = Serialize extends infer H +type ShouldUseParens = I extends UnionType + ? true + : I extends FunctionType + ? true + : false; + +type SerializeArray = Serialize extends infer H ? H extends string - ? `${H}[]` + ? ShouldUseParens extends true + ? `(${H})[]` + : `${H}[]` : never : never; type SerializeUnion< U extends Array, - N extends boolean, R extends string = '', > = U extends [] - ? N extends true - ? `(${R})` - : R + ? R : U[0] extends StaticType - ? Serialize extends infer H + ? Serialize extends infer H ? H extends string ? SerializeUnion< Tail, - N, U['length'] extends 1 ? `${R}${H}` : `${R}${H} | ` > : never diff --git a/src/types.ts b/src/types.ts index 9920fc0..0b12321 100644 --- a/src/types.ts +++ b/src/types.ts @@ -41,7 +41,10 @@ export type AnyType = { type: 'AnyType'; }; -export type FunctionType

, R extends StaticType> = { +export type FunctionType< + P extends Array<[string, StaticType]>, + R extends StaticType, +> = { type: 'FunctionType'; params: P; return: R; From a3fe4866315833aadfe19c039c5a16b788055c95 Mon Sep 17 00:00:00 2001 From: ronami Date: Wed, 13 Jul 2022 18:56:58 +0300 Subject: [PATCH 172/286] wip --- src/index.ts | 2 +- src/serializer.ts | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index bc4243a..3b6900c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,7 +4,7 @@ import type { Check } from './checker'; type T = Tokenize<` -function foo(hey: number, ho: string) {} +function foo(hey: number, ho: any) {} foo([foo], 'a') diff --git a/src/serializer.ts b/src/serializer.ts index 72b2bfe..29bb4fd 100644 --- a/src/serializer.ts +++ b/src/serializer.ts @@ -1,4 +1,5 @@ import type { + AnyType, ArrayType, BooleanLiteralType, BooleanType, @@ -11,6 +12,7 @@ import type { StringLiteralType, StringType, UnionType, + UnknownType, VoidType, } from './types'; import type { Tail } from './utils/arrayUtils'; @@ -27,6 +29,10 @@ export type Serialize = ? 'null' : H extends VoidType ? 'void' + : H extends AnyType + ? 'any' + : H extends UnknownType + ? 'unknown' : H extends ArrayType ? SerializeArray : H extends UnionType From dc93533596da219479abc080eac6a0809db945f9 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 14 Jul 2022 18:22:07 +0300 Subject: [PATCH 173/286] wip --- README.md | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 5b41690..2ba1127 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,9 @@ ### Introduction -This project includes a (very) simplified implementation of [TypeScript](https://github.com/microsoft/TypeScript)'s type-system that's written in [TypeScript](https://github.com/microsoft/TypeScript)'s own type-system. +This is a simplified implementation of [TypeScript](https://github.com/microsoft/TypeScript)'s type-system that's written in [TypeScript](https://github.com/microsoft/TypeScript)'s type annotations. This means that it uses types only — with no runtime code whatsoever. -The implementation uses types only — with no runtime code whatsoever, and to see it in action you'll need to hover your mouse over the resulting type. - -You enter TypeScript code as string and get possible type errors back (**[See the live demo]()**): +You pass [TypeScript](https://github.com/microsoft/TypeScript) code as string to the `TypeCheck` generic and get possible type errors back (**[See the live demo]()**): ```typescript import type { TypeCheck } from 'hypescript'; @@ -16,19 +14,19 @@ import type { TypeCheck } from 'hypescript'; type Errors = TypeCheck<` function foo(name: number) { - return name + return name; } -foo('not a number') +foo('not a number'); `>; // Errors is now equal to the following type: -type Expected = ["Line 7: Argument of type 'string' is not assignable to parameter of type 'number'."]; +type Expected = [ + "Line 7: Argument of type 'string' is not assignable to parameter of type 'number'." +]; ``` -The implementation includes a tokenizer, parser, and a type-checker and includes comments explaining how everything works. - *☝ Please note that this project is meant to be used for fun and learning purposes and not for practical use.* ### Try running the code @@ -43,7 +41,7 @@ yarn add hypescript ### Supported features and syntax -Some TypeScript syntax and features haven't been implemented and won't work. Here's a list of examples (with demo links) for some of the capabilites: +Some [TypeScript](https://github.com/microsoft/TypeScript) syntax and features haven't been implemented and won't work. Here's a list of examples (with browser demo links) for some of the capabilites: - [Calling a function with insufficient arguments]() - [Calling a function with wrong argument types]() From 2c9ffd69d5dcd4c01b10b306a5cf7035546673a6 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 14 Jul 2022 21:17:57 +0300 Subject: [PATCH 174/286] wip --- src/checker.ts | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 3758d14..6b4cb55 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -48,7 +48,7 @@ import type { MergeWithOverride } from './utils/generalUtils'; export type Check< T extends Array>, - S extends {} = {}, + S extends Record = {}, R extends Array = [], > = T extends [] ? R @@ -87,7 +87,7 @@ type MapAnnotationToType> = type InferFunctionParams< T extends Array>, - S extends {}, + S extends Record, R extends Array<[string, StaticType]> = [], H extends Record = {}, > = T extends [] @@ -100,7 +100,7 @@ type InferFunctionParams< type InferFunctionParamsHelper< T extends Array>, - S extends {}, + S extends Record, R extends Array<[string, StaticType]>, H extends Record, V extends StaticType, @@ -114,7 +114,7 @@ type InferFunctionParamsHelper< type InferFunctionDeclaration< O extends FunctionDeclaration, - S extends {}, + S extends Record, > = O extends FunctionDeclaration< Identifier>, infer P, @@ -134,7 +134,7 @@ type InferFunctionDeclaration< type InferBlockStatement< T extends Array>, - S extends {} = {}, + S extends Record = {}, R extends StaticType = VoidType, > = T extends [] ? [R, S] @@ -199,7 +199,7 @@ type MatchTypeArrays< type InferVariableDeclaration< O extends VariableDeclaration, - S extends {}, + S extends Record, > = O extends VariableDeclaration< [ VariableDeclarator< @@ -233,7 +233,7 @@ type InferVariableDeclaration< type InferExpressionStatement< O extends ExpressionStatement, - S extends {}, + S extends Record, > = O extends ExpressionStatement ? InferExpression extends infer G ? G extends Array @@ -244,7 +244,7 @@ type InferExpressionStatement< type InferExpression< T extends Node, - S extends {}, + S extends Record, > = T extends StringLiteral ? [StringLiteralType, S] : T extends NumericLiteral @@ -270,7 +270,7 @@ type InferExpression< type InferCallExpression< C extends Node, A extends Array>, - S extends {}, + S extends Record, > = C extends Node> ? InferExpression extends infer G ? G extends Array @@ -294,7 +294,7 @@ type InferCallExpressionHelper< P extends Array<[string, StaticType]>, H extends Array, R extends StaticType, - S extends {}, + S extends Record, L extends number, > = P['length'] extends H['length'] ? MatchTypeArrays extends infer W @@ -309,7 +309,7 @@ type InferCallExpressionHelper< type InferExpressionsArray< T extends Array>, - S extends {}, + S extends Record, R extends Array = [], > = T extends [] ? [R, S] @@ -321,7 +321,7 @@ type InferExpressionsArray< type InferArrayElements< T extends Array>, - S extends {}, + S extends Record, R extends StaticType = AnyType, > = T extends [] ? [ArrayType, S] @@ -374,7 +374,7 @@ type InferMemberExpression< O extends Node, P extends Node, C extends boolean, - S extends {}, + S extends Record, > = InferExpression extends infer J ? J extends Array ? C extends false @@ -412,7 +412,7 @@ type InferMemberExpressionObjectHelper< type InferMemberExpressionHelper< O extends StaticType, N extends string, - S extends {}, + S extends Record, L extends number, > = O extends ObjectType ? InferMemberExpressionObjectHelper extends infer I @@ -432,7 +432,7 @@ type InferMemberExpressionHelper< type InferMemberExpressionUnionHelper< U extends Array, N extends string, - S extends {}, + S extends Record, L extends number, R extends Array = [], > = U extends [] @@ -445,7 +445,7 @@ type InferMemberExpressionUnionHelper< type InferObjectProperties< T extends Array>, - S extends {}, + S extends Record, R extends Array = [], > = T extends [] ? [ObjectType, S] From 8fb30997f0271648a9a1bb67b8c5b5a7108f8c3a Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 14 Jul 2022 21:18:40 +0300 Subject: [PATCH 175/286] wip --- src/checker.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 6b4cb55..f1d5549 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -87,27 +87,24 @@ type MapAnnotationToType> = type InferFunctionParams< T extends Array>, - S extends Record, R extends Array<[string, StaticType]> = [], H extends Record = {}, > = T extends [] - ? [R, H, S] + ? [R, H] : T[0] extends Identifier ? K extends TypeAnnotation - ? InferFunctionParamsHelper, N> - : InferFunctionParamsHelper + ? InferFunctionParamsHelper, N> + : InferFunctionParamsHelper : never; type InferFunctionParamsHelper< T extends Array>, - S extends Record, R extends Array<[string, StaticType]>, H extends Record, V extends StaticType, N extends string, > = InferFunctionParams< Tail, - S, Push, MergeWithOverride >; @@ -121,7 +118,7 @@ type InferFunctionDeclaration< BlockStatement, any > - ? InferFunctionParams extends infer H + ? InferFunctionParams

extends infer H ? H extends Array ? InferBlockStatement> extends infer G ? G extends Array From 725eea117e42c21972d63473b7f53d049efed786 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 14 Jul 2022 21:25:49 +0300 Subject: [PATCH 176/286] wip --- src/checker.ts | 15 ++++++++------- src/errors.ts | 6 ++++++ src/utils/utilityTypes.ts | 13 +++++++++++++ 3 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 src/utils/utilityTypes.ts diff --git a/src/checker.ts b/src/checker.ts index f1d5549..31bf825 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -24,7 +24,7 @@ import type { VariableDeclaration, VariableDeclarator, } from './ast'; -import type { SyntaxError } from './errors'; +import type { TypeError } from './errors'; import type { Serialize } from './serializer'; import type { AnyType, @@ -45,6 +45,7 @@ import type { } from './types'; import type { Includes, Push, Tail, Uniq } from './utils/arrayUtils'; import type { MergeWithOverride } from './utils/generalUtils'; +import type { TypeResult } from './utils/utilityTypes'; export type Check< T extends Array>, @@ -243,17 +244,17 @@ type InferExpression< T extends Node, S extends Record, > = T extends StringLiteral - ? [StringLiteralType, S] + ? TypeResult, S> : T extends NumericLiteral - ? [NumberLiteralType, S] + ? TypeResult, S> : T extends NullLiteral - ? [NullType, S] + ? TypeResult : T extends BooleanLiteral - ? [BooleanLiteralType, S] + ? TypeResult, S> : T extends Identifier> ? N extends keyof S - ? [S[N], S] - : SyntaxError<`Cannot find name '${N}'.`, I> + ? TypeResult + : TypeResult]> : T extends ObjectExpression ? InferObjectProperties : T extends MemberExpression diff --git a/src/errors.ts b/src/errors.ts index b1b521d..ee1d554 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -9,3 +9,9 @@ export type SyntaxError = Error< M, L >; + +export type TypeError = Error< + 'TypeError', + M, + L +>; diff --git a/src/utils/utilityTypes.ts b/src/utils/utilityTypes.ts new file mode 100644 index 0000000..70dfe5a --- /dev/null +++ b/src/utils/utilityTypes.ts @@ -0,0 +1,13 @@ +import type { StaticType } from '../types'; +import type { TypeError } from '../errors'; + +export type TypeResult< + Value extends StaticType, + State extends Record, + Errors extends Array> = [], +> = { + type: 'TypeResult'; + value: Value; + state: State; + errors: Errors; +}; From dc2d7338bead678c0767e6653eeacd7b02a7a62d Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 11:51:08 +0300 Subject: [PATCH 177/286] wip --- src/ast.ts | 30 +++++++++--------- src/checker.ts | 85 ++++++++++++++++++++++++++++---------------------- 2 files changed, 62 insertions(+), 53 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index 7bdbd6c..d3bba17 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -27,7 +27,7 @@ export type StringLiteral> = { }; export type ArrayExpression< - T extends Array>, + T extends Array>, D extends NodeData, > = { type: 'ArrayExpression'; @@ -46,7 +46,7 @@ export type ObjectExpression< export type ObjectProperty< K extends Identifier, - T extends Node, + T extends BaseNode, D extends NodeData, > = { type: 'ObjectProperty'; @@ -68,7 +68,7 @@ export type VariableDeclaration< export type VariableDeclarator< N extends Identifier, - I extends Node, + I extends BaseNode, D extends NodeData, > = { type: 'VariableDeclarator'; @@ -79,7 +79,7 @@ export type VariableDeclarator< export type FunctionDeclaration< I extends Identifier, - P extends Array>, + P extends Array>, B extends BlockStatement, D extends NodeData, > = { @@ -102,7 +102,7 @@ export type Identifier< }; export type ExpressionStatement< - E extends Node, + E extends BaseNode, D extends NodeData, > = { type: 'ExpressionStatement'; @@ -111,8 +111,8 @@ export type ExpressionStatement< }; export type CallExpression< - C extends Node, - A extends Array>, + C extends BaseNode, + A extends Array>, D extends NodeData, > = { type: 'CallExpression'; @@ -122,8 +122,8 @@ export type CallExpression< }; export type MemberExpression< - O extends Node, - P extends Node, + O extends BaseNode, + P extends BaseNode, C extends boolean, D extends NodeData, > = { @@ -135,8 +135,8 @@ export type MemberExpression< }; export type IfStatement< - T extends Node, - C extends Node, + T extends BaseNode, + C extends BaseNode, D extends NodeData, > = { type: 'IfStatement'; @@ -147,7 +147,7 @@ export type IfStatement< }; export type ReturnStatement< - T extends Node | null, + T extends BaseNode | null, D extends NodeData, > = { type: 'ReturnStatement'; @@ -156,7 +156,7 @@ export type ReturnStatement< }; export type BlockStatement< - B extends Array>, + B extends Array>, D extends NodeData, > = { type: 'BlockStatement'; @@ -165,7 +165,7 @@ export type BlockStatement< }; export type TypeAnnotation< - T extends Node, + T extends BaseNode, D extends NodeData, > = { type: 'TypeAnnotation'; @@ -204,7 +204,7 @@ export type AnyTypeAnnotation> = { data: D; }; -export type Node> = +export type BaseNode> = | NumericLiteral | BooleanLiteral | StringLiteral diff --git a/src/checker.ts b/src/checker.ts index 31bf825..179bb27 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -9,7 +9,7 @@ import type { FunctionDeclaration, Identifier, MemberExpression, - Node, + BaseNode, NodeData, NullLiteral, NullLiteralTypeAnnotation, @@ -48,7 +48,7 @@ import type { MergeWithOverride } from './utils/generalUtils'; import type { TypeResult } from './utils/utilityTypes'; export type Check< - T extends Array>, + T extends Array>, S extends Record = {}, R extends Array = [], > = T extends [] @@ -73,7 +73,7 @@ export type Check< : never : never; -type MapAnnotationToType> = +type MapAnnotationToType> = A extends StringTypeAnnotation ? StringType : A extends NumberTypeAnnotation @@ -87,7 +87,7 @@ type MapAnnotationToType> = : never; type InferFunctionParams< - T extends Array>, + T extends Array>, R extends Array<[string, StaticType]> = [], H extends Record = {}, > = T extends [] @@ -99,7 +99,7 @@ type InferFunctionParams< : never; type InferFunctionParamsHelper< - T extends Array>, + T extends Array>, R extends Array<[string, StaticType]>, H extends Record, V extends StaticType, @@ -131,7 +131,7 @@ type InferFunctionDeclaration< : never; type InferBlockStatement< - T extends Array>, + T extends Array>, S extends Record = {}, R extends StaticType = VoidType, > = T extends [] @@ -149,7 +149,7 @@ type InferBlockStatement< : G : never : T[0] extends ReturnStatement - ? F extends Node + ? F extends BaseNode ? InferExpression extends infer G ? G extends Array ? InferBlockStatement<[], G[1], G[0]> @@ -241,35 +241,44 @@ type InferExpressionStatement< : never; type InferExpression< - T extends Node, - S extends Record, -> = T extends StringLiteral - ? TypeResult, S> - : T extends NumericLiteral - ? TypeResult, S> - : T extends NullLiteral - ? TypeResult - : T extends BooleanLiteral - ? TypeResult, S> - : T extends Identifier> - ? N extends keyof S - ? TypeResult - : TypeResult]> - : T extends ObjectExpression - ? InferObjectProperties - : T extends MemberExpression - ? InferMemberExpression - : T extends ArrayExpression - ? InferArrayElements - : T extends CallExpression - ? InferCallExpression + Node extends BaseNode, + State extends Record, +> = Node extends StringLiteral + ? TypeResult, State> + : Node extends NumericLiteral + ? TypeResult, State> + : Node extends NullLiteral + ? TypeResult + : Node extends BooleanLiteral + ? TypeResult, State> + : Node extends Identifier> + ? Name extends keyof State + ? TypeResult + : TypeResult< + AnyType, + State, + [TypeError<`Cannot find name '${Name}'.`, StartLine>] + > + : Node extends ObjectExpression + ? InferObjectProperties + : Node extends MemberExpression< + infer Object, + infer Properties, + infer Computed, + any + > + ? InferMemberExpression + : Node extends ArrayExpression + ? InferArrayElements + : Node extends CallExpression + ? InferCallExpression : UnknownType; type InferCallExpression< - C extends Node, - A extends Array>, + C extends BaseNode, + A extends Array>, S extends Record, -> = C extends Node> +> = C extends BaseNode> ? InferExpression extends infer G ? G extends Array ? G[0] extends FunctionType @@ -306,7 +315,7 @@ type InferCallExpressionHelper< >; type InferExpressionsArray< - T extends Array>, + T extends Array>, S extends Record, R extends Array = [], > = T extends [] @@ -318,12 +327,12 @@ type InferExpressionsArray< : never; type InferArrayElements< - T extends Array>, + T extends Array>, S extends Record, R extends StaticType = AnyType, > = T extends [] ? [ArrayType, S] - : T[0] extends Node + : T[0] extends BaseNode ? InferExpression extends infer J ? J extends Array ? MapLiteralToType extends infer E @@ -369,8 +378,8 @@ type MapLiteralToType = T extends NumberLiteralType : T; type InferMemberExpression< - O extends Node, - P extends Node, + O extends BaseNode, + P extends BaseNode, C extends boolean, S extends Record, > = InferExpression extends infer J @@ -380,7 +389,7 @@ type InferMemberExpression< ? InferMemberExpressionHelper : never : InferExpression extends infer G - ? P extends Node> + ? P extends BaseNode> ? G extends Array ? G[0] extends StringLiteralType ? InferMemberExpressionHelper From d796e3460c2b7033fbde12271cff0c7f1c6b0557 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 12:11:53 +0300 Subject: [PATCH 178/286] wip --- src/checker.ts | 34 +++++++++++++++++++++++----------- src/index.ts | 4 +--- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 179bb27..1d234d8 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -43,7 +43,7 @@ import type { UnknownType, VoidType, } from './types'; -import type { Includes, Push, Tail, Uniq } from './utils/arrayUtils'; +import type { Concat, Includes, Push, Tail, Uniq } from './utils/arrayUtils'; import type { MergeWithOverride } from './utils/generalUtils'; import type { TypeResult } from './utils/utilityTypes'; @@ -451,15 +451,27 @@ type InferMemberExpressionUnionHelper< : never; type InferObjectProperties< - T extends Array>, - S extends Record, - R extends Array = [], -> = T extends [] - ? [ObjectType, S] - : T[0] extends ObjectProperty, infer V, any> - ? InferExpression extends infer J - ? J extends Array - ? InferObjectProperties, S, Push> - : J + Properties extends Array>, + State extends Record, + Result extends Array = [], + Errors extends Array> = [], +> = Properties extends [] + ? TypeResult, State, Errors> + : Properties[0] extends ObjectProperty< + Identifier, + infer Value, + any + > + ? InferExpression extends TypeResult< + infer ExpressionValue, + infer ExpressionState, + infer ExpressionErrors + > + ? InferObjectProperties< + Tail, + ExpressionState, + Push, + Concat + > : never : never; diff --git a/src/index.ts b/src/index.ts index 3b6900c..e04f7ca 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,9 +4,7 @@ import type { Check } from './checker'; type T = Tokenize<` -function foo(hey: number, ho: any) {} - -foo([foo], 'a') +const a = {foo: bar, hello: world} `>; type R = Parse; From a8a76886c5b252cac30fe993aa4514e7cc18cb05 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 12:31:36 +0300 Subject: [PATCH 179/286] wip --- src/checker.ts | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 1d234d8..0afd284 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -327,24 +327,32 @@ type InferExpressionsArray< : never; type InferArrayElements< - T extends Array>, - S extends Record, - R extends StaticType = AnyType, -> = T extends [] - ? [ArrayType, S] - : T[0] extends BaseNode - ? InferExpression extends infer J - ? J extends Array - ? MapLiteralToType extends infer E - ? E extends StaticType - ? InferArrayElementsHelper extends infer U - ? U extends StaticType - ? InferArrayElements, J[1], U> - : never + Elements extends Array>, + State extends Record, + Result extends StaticType = AnyType, + Errors extends Array> = [], +> = Elements extends [] + ? TypeResult, State, Errors> + : Elements[0] extends BaseNode + ? InferExpression extends TypeResult< + infer ExpressionValue, + infer ExpressionState, + infer ExpressionErrors + > + ? MapLiteralToType extends infer E + ? E extends StaticType + ? InferArrayElementsHelper extends infer U + ? U extends StaticType + ? InferArrayElements< + Tail, + ExpressionState, + U, + Concat + > : never : never : never - : J + : never : never : never; From a7e4efdd14e3d47a9df68ad7045c90b4c7e9b6d2 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 12:35:27 +0300 Subject: [PATCH 180/286] wip --- src/checker.ts | 34 +++++++++++++++++----------------- src/utils/utilityTypes.ts | 2 ++ 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 0afd284..7eedde3 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -45,11 +45,11 @@ import type { } from './types'; import type { Concat, Includes, Push, Tail, Uniq } from './utils/arrayUtils'; import type { MergeWithOverride } from './utils/generalUtils'; -import type { TypeResult } from './utils/utilityTypes'; +import type { StateType, TypeResult } from './utils/utilityTypes'; export type Check< T extends Array>, - S extends Record = {}, + S extends StateType = {}, R extends Array = [], > = T extends [] ? R @@ -89,7 +89,7 @@ type MapAnnotationToType> = type InferFunctionParams< T extends Array>, R extends Array<[string, StaticType]> = [], - H extends Record = {}, + H extends StateType = {}, > = T extends [] ? [R, H] : T[0] extends Identifier @@ -101,7 +101,7 @@ type InferFunctionParams< type InferFunctionParamsHelper< T extends Array>, R extends Array<[string, StaticType]>, - H extends Record, + H extends StateType, V extends StaticType, N extends string, > = InferFunctionParams< @@ -112,7 +112,7 @@ type InferFunctionParamsHelper< type InferFunctionDeclaration< O extends FunctionDeclaration, - S extends Record, + S extends StateType, > = O extends FunctionDeclaration< Identifier>, infer P, @@ -132,7 +132,7 @@ type InferFunctionDeclaration< type InferBlockStatement< T extends Array>, - S extends Record = {}, + S extends StateType = {}, R extends StaticType = VoidType, > = T extends [] ? [R, S] @@ -197,7 +197,7 @@ type MatchTypeArrays< type InferVariableDeclaration< O extends VariableDeclaration, - S extends Record, + S extends StateType, > = O extends VariableDeclaration< [ VariableDeclarator< @@ -231,7 +231,7 @@ type InferVariableDeclaration< type InferExpressionStatement< O extends ExpressionStatement, - S extends Record, + S extends StateType, > = O extends ExpressionStatement ? InferExpression extends infer G ? G extends Array @@ -242,7 +242,7 @@ type InferExpressionStatement< type InferExpression< Node extends BaseNode, - State extends Record, + State extends StateType, > = Node extends StringLiteral ? TypeResult, State> : Node extends NumericLiteral @@ -277,7 +277,7 @@ type InferExpression< type InferCallExpression< C extends BaseNode, A extends Array>, - S extends Record, + S extends StateType, > = C extends BaseNode> ? InferExpression extends infer G ? G extends Array @@ -301,7 +301,7 @@ type InferCallExpressionHelper< P extends Array<[string, StaticType]>, H extends Array, R extends StaticType, - S extends Record, + S extends StateType, L extends number, > = P['length'] extends H['length'] ? MatchTypeArrays extends infer W @@ -316,7 +316,7 @@ type InferCallExpressionHelper< type InferExpressionsArray< T extends Array>, - S extends Record, + S extends StateType, R extends Array = [], > = T extends [] ? [R, S] @@ -328,7 +328,7 @@ type InferExpressionsArray< type InferArrayElements< Elements extends Array>, - State extends Record, + State extends StateType, Result extends StaticType = AnyType, Errors extends Array> = [], > = Elements extends [] @@ -389,7 +389,7 @@ type InferMemberExpression< O extends BaseNode, P extends BaseNode, C extends boolean, - S extends Record, + S extends StateType, > = InferExpression extends infer J ? J extends Array ? C extends false @@ -427,7 +427,7 @@ type InferMemberExpressionObjectHelper< type InferMemberExpressionHelper< O extends StaticType, N extends string, - S extends Record, + S extends StateType, L extends number, > = O extends ObjectType ? InferMemberExpressionObjectHelper extends infer I @@ -447,7 +447,7 @@ type InferMemberExpressionHelper< type InferMemberExpressionUnionHelper< U extends Array, N extends string, - S extends Record, + S extends StateType, L extends number, R extends Array = [], > = U extends [] @@ -460,7 +460,7 @@ type InferMemberExpressionUnionHelper< type InferObjectProperties< Properties extends Array>, - State extends Record, + State extends StateType, Result extends Array = [], Errors extends Array> = [], > = Properties extends [] diff --git a/src/utils/utilityTypes.ts b/src/utils/utilityTypes.ts index 70dfe5a..622b8d2 100644 --- a/src/utils/utilityTypes.ts +++ b/src/utils/utilityTypes.ts @@ -11,3 +11,5 @@ export type TypeResult< state: State; errors: Errors; }; + +export type StateType = Record; From fda901edf7aa9c2a10699322d8559b66e388948a Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 13:56:47 +0300 Subject: [PATCH 181/286] wip --- src/checker.ts | 180 +++++++++++++++++++++++++++++++++---------------- src/index.ts | 2 +- src/types.ts | 4 +- 3 files changed, 124 insertions(+), 62 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 7eedde3..b469faf 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -263,11 +263,11 @@ type InferExpression< ? InferObjectProperties : Node extends MemberExpression< infer Object, - infer Properties, + infer Property, infer Computed, any > - ? InferMemberExpression + ? InferMemberExpression : Node extends ArrayExpression ? InferArrayElements : Node extends CallExpression @@ -386,75 +386,137 @@ type MapLiteralToType = T extends NumberLiteralType : T; type InferMemberExpression< - O extends BaseNode, - P extends BaseNode, - C extends boolean, - S extends StateType, -> = InferExpression extends infer J - ? J extends Array - ? C extends false - ? P extends Identifier> - ? InferMemberExpressionHelper - : never - : InferExpression extends infer G - ? P extends BaseNode> - ? G extends Array - ? G[0] extends StringLiteralType - ? InferMemberExpressionHelper - : G[0] extends NumberLiteralType - ? InferMemberExpressionHelper - : SyntaxError< - `Type '${Serialize}' cannot be used as an index type.`, - L + Object extends BaseNode, + Property extends BaseNode, + Computed extends boolean, + State extends StateType, +> = InferExpression extends TypeResult< + infer ObjectExpressionValue, + infer ObjectExpressionState, + infer ObjectExpressionErrors +> + ? Computed extends false + ? Property extends Identifier< + infer Name, + any, + NodeData + > + ? InferMemberExpressionHelper< + ObjectExpressionValue, + Name, + ObjectExpressionState, + StartLine, + ObjectExpressionErrors + > + : never + : InferExpression extends TypeResult< + infer PropertyExpressionValue, + infer PropertyExpressionState, + infer PropertyExpressionErrors + > + ? Property extends BaseNode> + ? PropertyExpressionValue extends StringLiteralType + ? InferMemberExpressionHelper< + ObjectExpressionValue, + Value, + PropertyExpressionState, + StartLine, + Concat + > + : PropertyExpressionValue extends NumberLiteralType + ? InferMemberExpressionHelper< + ObjectExpressionValue, + Value, + PropertyExpressionState, + StartLine, + Concat + > + : TypeResult< + AnyType, + PropertyExpressionState, + Push< + Concat, + TypeError< + `Type '${Serialize}' cannot be used as an index type.`, + StartLine > - : G extends null - ? never - : G - : never + > + > : never - : J + : never : never; -type InferMemberExpressionObjectHelper< - V extends Array<[string, StaticType]>, - N extends string, -> = V extends [] +type GetObjectValueByKey< + ObjectProperties extends Array<[string, StaticType]>, + Key extends string, +> = ObjectProperties extends [] ? null - : V[0][0] extends N - ? V[0][1] - : InferMemberExpressionObjectHelper, N>; + : ObjectProperties[0] extends [infer PropertyName, infer PropertyValue] + ? PropertyName extends Key + ? PropertyValue + : GetObjectValueByKey, Key> + : never; type InferMemberExpressionHelper< - O extends StaticType, - N extends string, - S extends StateType, - L extends number, -> = O extends ObjectType - ? InferMemberExpressionObjectHelper extends infer I - ? I extends null - ? SyntaxError< - `Property '${N}' does not exist on type '${Serialize}'.`, - L + Object extends StaticType, + Key extends string, + State extends StateType, + StartLine extends number, + Errors extends Array>, +> = Object extends ObjectType + ? GetObjectValueByKey< + ObjectProperties, + Key + > extends infer MemberExpressionValue + ? MemberExpressionValue extends StaticType + ? TypeResult + : TypeResult< + NullType, + State, + Push< + Errors, + TypeError< + `Property '${Key}' does not exist on type '${Serialize}'.`, + StartLine + > + > > - : [I, S] : never - : O extends ArrayType - ? [V, S] - : O extends UnionType - ? InferMemberExpressionUnionHelper - : SyntaxError<`Property '${N}' does not exist on type '${Serialize}'.`, L>; + : Object extends ArrayType + ? TypeResult + : Object extends UnionType + ? InferMemberExpressionUnionHelper + : Object extends AnyType + ? TypeResult + : TypeError< + `Property '${Key}' does not exist on type '${Serialize}'.`, + StartLine + >; type InferMemberExpressionUnionHelper< - U extends Array, - N extends string, - S extends StateType, - L extends number, - R extends Array = [], -> = U extends [] - ? [UnionType, S] - : InferMemberExpressionHelper extends infer H + UnionTypes extends Array, + Key extends string, + State extends StateType, + StartLine extends number, + Errors extends Array>, + Result extends Array = [], +> = UnionTypes extends [] + ? TypeResult, State, Errors> + : InferMemberExpressionHelper< + UnionTypes[0], + Key, + State, + StartLine, + Errors + > extends infer H ? H extends Array - ? InferMemberExpressionUnionHelper, N, H[1], L, Push> + ? InferMemberExpressionUnionHelper< + Tail, + Key, + H[1], + StartLine, + Push + > : H : never; diff --git a/src/index.ts b/src/index.ts index e04f7ca..a1acf76 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,7 +4,7 @@ import type { Check } from './checker'; type T = Tokenize<` -const a = {foo: bar, hello: world} +foo.bar.hello `>; type R = Parse; diff --git a/src/types.ts b/src/types.ts index 0b12321..ba8358d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -50,9 +50,9 @@ export type FunctionType< return: R; }; -export type ObjectType> = { +export type ObjectType> = { type: 'ObjectType'; - object: O; + properties: Properties; }; export type ArrayType = { From 3e14578386aa3ab50d98c6cee6291fa3e4cf9f56 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 14:00:12 +0300 Subject: [PATCH 182/286] wip --- src/checker.ts | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index b469faf..90bf32d 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -508,16 +508,19 @@ type InferMemberExpressionUnionHelper< State, StartLine, Errors - > extends infer H - ? H extends Array - ? InferMemberExpressionUnionHelper< - Tail, - Key, - H[1], - StartLine, - Push - > - : H + > extends TypeResult< + infer ExpressionValue, + infer ExpressionState, + infer ExpressionErrors + > + ? InferMemberExpressionUnionHelper< + Tail, + Key, + ExpressionState, + StartLine, + Concat, + Push + > : never; type InferObjectProperties< From 4f0bded96006f51011d3883027639bac137c3271 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 14:18:57 +0300 Subject: [PATCH 183/286] wip --- src/ast.ts | 2 +- src/checker.ts | 69 ++++++++++++++++++++++++++++++-------------------- 2 files changed, 42 insertions(+), 29 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index d3bba17..1555770 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -147,7 +147,7 @@ export type IfStatement< }; export type ReturnStatement< - T extends BaseNode | null, + T extends BaseNode, D extends NodeData, > = { type: 'ReturnStatement'; diff --git a/src/checker.ts b/src/checker.ts index 90bf32d..8a15fa7 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -73,6 +73,47 @@ export type Check< : never : never; +type InferBlockStatement< + NodeList extends Array>, + Result extends StaticType = VoidType, + State extends StateType = {}, + Errors extends Array> = [], +> = NodeList extends [] + ? TypeResult + : NodeList[0] extends ExpressionStatement + ? InferExpression extends TypeResult< + any, + infer ExpressionState, + infer ExpressionErrors + > + ? InferBlockStatement< + Tail, + Result, + ExpressionState, + Concat + > + : never + : NodeList[0] extends VariableDeclaration + ? InferVariableDeclaration extends infer G + ? G extends Array + ? InferBlockStatement, G[1], Result> + : G + : never + : NodeList[0] extends ReturnStatement + ? InferExpression extends TypeResult< + infer ExpressionValue, + infer ExpressionState, + infer ExpressionErrors + > + ? InferBlockStatement< + [], + ExpressionValue, + ExpressionState, + Concat + > + : never + : InferBlockStatement, VoidType, State, Errors>; + type MapAnnotationToType> = A extends StringTypeAnnotation ? StringType @@ -130,34 +171,6 @@ type InferFunctionDeclaration< : never : never; -type InferBlockStatement< - T extends Array>, - S extends StateType = {}, - R extends StaticType = VoidType, -> = T extends [] - ? [R, S] - : T[0] extends ExpressionStatement - ? InferExpressionStatement extends infer G - ? G extends Array - ? InferBlockStatement, G[1], R> - : G - : never - : T[0] extends VariableDeclaration - ? InferVariableDeclaration extends infer G - ? G extends Array - ? InferBlockStatement, G[1], R> - : G - : never - : T[0] extends ReturnStatement - ? F extends BaseNode - ? InferExpression extends infer G - ? G extends Array - ? InferBlockStatement<[], G[1], G[0]> - : G - : never - : InferBlockStatement, S, VoidType> - : never; - type MatchType = A extends AnyType ? true : B extends AnyType From 8ef061214101d1c240fc450f8bb66ddb6496e4ec Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 14:21:39 +0300 Subject: [PATCH 184/286] wip --- src/checker.ts | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 8a15fa7..95c3a85 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -47,31 +47,10 @@ import type { Concat, Includes, Push, Tail, Uniq } from './utils/arrayUtils'; import type { MergeWithOverride } from './utils/generalUtils'; import type { StateType, TypeResult } from './utils/utilityTypes'; -export type Check< - T extends Array>, - S extends StateType = {}, - R extends Array = [], -> = T extends [] - ? R - : T[0] extends ExpressionStatement - ? InferExpressionStatement extends infer G - ? G extends Array - ? Check, G[1], R> - : Check, S, Push> - : never - : T[0] extends VariableDeclaration - ? InferVariableDeclaration extends infer G - ? G extends Array - ? Check, G[1], R> - : Check, S, Push> - : never - : T[0] extends FunctionDeclaration - ? InferFunctionDeclaration extends infer G - ? G extends Array - ? Check, G[1], R> - : Check, S, Push> - : never - : never; +export type Check>> = + InferBlockStatement extends TypeResult + ? Errors + : never; type InferBlockStatement< NodeList extends Array>, From c2e144e7044710b2f02e601f4ba87c678f8bf9b4 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 14:23:43 +0300 Subject: [PATCH 185/286] wip --- src/checker.ts | 6 ++++++ src/index.ts | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/checker.ts b/src/checker.ts index 95c3a85..ffa9833 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -423,6 +423,12 @@ type InferMemberExpression< StartLine, Concat > + : PropertyExpressionValue extends AnyType + ? TypeResult< + AnyType, + PropertyExpressionState, + Concat + > : TypeResult< AnyType, PropertyExpressionState, diff --git a/src/index.ts b/src/index.ts index a1acf76..562aa4d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,7 +4,7 @@ import type { Check } from './checker'; type T = Tokenize<` -foo.bar.hello +foo[hey].bar `>; type R = Parse; From 205a9022270a304f6970cca642e6d883757eaaee Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 14:35:55 +0300 Subject: [PATCH 186/286] wip --- src/ast.ts | 12 +++--- src/checker.ts | 115 ++++++++++++++++++++++++++++--------------------- 2 files changed, 72 insertions(+), 55 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index 1555770..0c6c7d9 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -91,14 +91,14 @@ export type FunctionDeclaration< }; export type Identifier< - N extends string, - T extends TypeAnnotation | null, - D extends NodeData, + Name extends string, + Annotation extends TypeAnnotation | null, + Data extends NodeData, > = { type: 'Identifier'; - name: N; - typeAnnotation: T; - data: D; + name: Name; + typeAnnotation: Annotation; + data: Data; }; export type ExpressionStatement< diff --git a/src/checker.ts b/src/checker.ts index ffa9833..fe2daa0 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -72,8 +72,28 @@ type InferBlockStatement< Concat > : never - : NodeList[0] extends VariableDeclaration - ? InferVariableDeclaration extends infer G + : NodeList[0] extends VariableDeclaration< + [ + VariableDeclarator< + Identifier< + infer Name, + infer Annotation, + NodeData + >, + infer Init, + any + >, + ], + any, + any + > + ? InferVariableDeclaration< + Name, + Annotation, + Init, + State, + StartLine + > extends infer G ? G extends Array ? InferBlockStatement, G[1], Result> : G @@ -93,18 +113,18 @@ type InferBlockStatement< : never : InferBlockStatement, VoidType, State, Errors>; -type MapAnnotationToType> = - A extends StringTypeAnnotation +type MapAnnotationToType> = + AnnotationValue extends StringTypeAnnotation ? StringType - : A extends NumberTypeAnnotation + : AnnotationValue extends NumberTypeAnnotation ? NumberType - : A extends BooleanTypeAnnotation + : AnnotationValue extends BooleanTypeAnnotation ? BooleanType - : A extends NullLiteralTypeAnnotation + : AnnotationValue extends NullLiteralTypeAnnotation ? NullType - : A extends AnyTypeAnnotation + : AnnotationValue extends AnyTypeAnnotation ? AnyType - : never; + : UnknownType; type InferFunctionParams< T extends Array>, @@ -188,48 +208,45 @@ type MatchTypeArrays< >; type InferVariableDeclaration< - O extends VariableDeclaration, - S extends StateType, -> = O extends VariableDeclaration< - [ - VariableDeclarator< - Identifier>, - infer I, - any - >, - ], - any, - any + Name extends string, + Annotation extends TypeAnnotation | null, + Init extends BaseNode, + State extends StateType, + StartLine extends number, +> = InferExpression extends TypeResult< + infer InitExpressionValue, + infer InitExpressionState, + infer InitExpressionErrors > - ? InferExpression extends infer G - ? G extends Array - ? T extends TypeAnnotation - ? MapAnnotationToType extends infer P - ? P extends StaticType - ? MatchType extends true - ? [null, MergeWithOverride] - : SyntaxError< - `Type '${Serialize< - G[0] - >}' is not assignable to type '${Serialize

}'.`, - L + ? Annotation extends TypeAnnotation + ? MapAnnotationToType extends infer ExpectedType + ? ExpectedType extends StaticType + ? MatchType extends true + ? TypeResult< + NullType, + MergeWithOverride< + InitExpressionState, + { [a in Name]: ExpectedType } + >, + InitExpressionErrors + > + : TypeResult< + NullType, + MergeWithOverride< + InitExpressionState, + { [a in Name]: ExpectedType } + >, + Push< + InitExpressionErrors, + TypeError< + `Type '${Serialize}' is not assignable to type '${Serialize}'.`, + StartLine > - : never - : never - : [null, MergeWithOverride] - : G - : never - : never; - -type InferExpressionStatement< - O extends ExpressionStatement, - S extends StateType, -> = O extends ExpressionStatement - ? InferExpression extends infer G - ? G extends Array - ? [null, S] - : G - : never + > + > + : never + : never + : [null, MergeWithOverride] : never; type InferExpression< From 562482d885a89c991eeaa004a82fd63006047512 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 14:39:10 +0300 Subject: [PATCH 187/286] wip --- src/checker.ts | 6 +++++- src/index.ts | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index fe2daa0..caf8b27 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -246,7 +246,11 @@ type InferVariableDeclaration< > : never : never - : [null, MergeWithOverride] + : TypeResult< + NullType, + MergeWithOverride, + InitExpressionErrors + > : never; type InferExpression< diff --git a/src/index.ts b/src/index.ts index 562aa4d..8646a43 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,7 +4,8 @@ import type { Check } from './checker'; type T = Tokenize<` -foo[hey].bar +const a: number = '123' +const b: string = a `>; type R = Parse; From 496e0b2477b5e166473c3ecf4951b7a7d09df793 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 14:43:29 +0300 Subject: [PATCH 188/286] wip --- src/checker.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index caf8b27..da7cf14 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -93,10 +93,13 @@ type InferBlockStatement< Init, State, StartLine - > extends infer G - ? G extends Array - ? InferBlockStatement, G[1], Result> - : G + > extends TypeResult + ? InferBlockStatement< + Tail, + Result, + DeclarationState, + Concat + > : never : NodeList[0] extends ReturnStatement ? InferExpression extends TypeResult< From 3dc7bccb4c77db4698497060e10c350d685d8daa Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 15:20:48 +0300 Subject: [PATCH 189/286] wip --- src/checker.ts | 120 ++++++++++++++++++++++++++++++++----------------- src/index.ts | 7 ++- 2 files changed, 84 insertions(+), 43 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index da7cf14..5db54d4 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -47,15 +47,17 @@ import type { Concat, Includes, Push, Tail, Uniq } from './utils/arrayUtils'; import type { MergeWithOverride } from './utils/generalUtils'; import type { StateType, TypeResult } from './utils/utilityTypes'; -export type Check>> = - InferBlockStatement extends TypeResult - ? Errors - : never; +export type Check>> = InferBlockStatement< + NodeList, + {} +> extends TypeResult + ? Errors + : never; type InferBlockStatement< NodeList extends Array>, + State extends StateType, Result extends StaticType = VoidType, - State extends StateType = {}, Errors extends Array> = [], > = NodeList extends [] ? TypeResult @@ -67,8 +69,8 @@ type InferBlockStatement< > ? InferBlockStatement< Tail, - Result, ExpressionState, + Result, Concat > : never @@ -96,11 +98,18 @@ type InferBlockStatement< > extends TypeResult ? InferBlockStatement< Tail, - Result, DeclarationState, + Result, Concat > : never + : NodeList[0] extends FunctionDeclaration< + Identifier>, + infer Params, + BlockStatement, + any + > + ? InferFunctionDeclaration : NodeList[0] extends ReturnStatement ? InferExpression extends TypeResult< infer ExpressionValue, @@ -109,12 +118,12 @@ type InferBlockStatement< > ? InferBlockStatement< [], - ExpressionValue, ExpressionState, + ExpressionValue, Concat > : never - : InferBlockStatement, VoidType, State, Errors>; + : InferBlockStatement, State, VoidType, Errors>; type MapAnnotationToType> = AnnotationValue extends StringTypeAnnotation @@ -130,46 +139,75 @@ type MapAnnotationToType> = : UnknownType; type InferFunctionParams< - T extends Array>, - R extends Array<[string, StaticType]> = [], - H extends StateType = {}, -> = T extends [] - ? [R, H] - : T[0] extends Identifier - ? K extends TypeAnnotation - ? InferFunctionParamsHelper, N> - : InferFunctionParamsHelper + Params extends Array>, + FunctionParams extends Array<[string, StaticType]> = [], + ParamsByName extends StateType = {}, +> = Params extends [] + ? [FunctionParams, ParamsByName] + : Params[0] extends Identifier + ? Annotation extends TypeAnnotation + ? InferFunctionParamsHelper< + Params, + FunctionParams, + ParamsByName, + MapAnnotationToType, + Name + > + : InferFunctionParamsHelper< + Params, + FunctionParams, + ParamsByName, + AnyType, + Name + > : never; type InferFunctionParamsHelper< - T extends Array>, - R extends Array<[string, StaticType]>, - H extends StateType, - V extends StaticType, - N extends string, + Params extends Array>, + FunctionParams extends Array<[string, StaticType]>, + ParamsByName extends StateType, + Type extends StaticType, + Name extends string, > = InferFunctionParams< - Tail, - Push, - MergeWithOverride + Tail, + Push, + MergeWithOverride >; type InferFunctionDeclaration< - O extends FunctionDeclaration, - S extends StateType, -> = O extends FunctionDeclaration< - Identifier>, - infer P, - BlockStatement, - any -> - ? InferFunctionParams

extends infer H - ? H extends Array - ? InferBlockStatement> extends infer G - ? G extends Array - ? [null, MergeWithOverride }>] - : G + Name extends string, + Params extends Array>, + Body extends Array>, + State extends StateType, +> = InferFunctionParams extends [ + infer FunctionParams, + infer ParamsByName, +] + ? FunctionParams extends Array<[string, StaticType]> + ? ParamsByName extends StateType + ? InferBlockStatement< + Body, + MergeWithOverride + > extends TypeResult< + infer BlockStatementReturnType, + any, + infer BlockStatementErrors + > + ? TypeResult< + NullType, + MergeWithOverride< + State, + { + [a in Name]: FunctionType< + FunctionParams, + BlockStatementReturnType + >; + } + >, + BlockStatementErrors + > : never - : H + : never : never : never; diff --git a/src/index.ts b/src/index.ts index 8646a43..adce753 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,8 +4,11 @@ import type { Check } from './checker'; type T = Tokenize<` -const a: number = '123' -const b: string = a +function foo() { + +} + +const a: string = foo `>; type R = Parse; From 392b9c3cf19e25f5818197e5744f7db7ec636f16 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 15:32:27 +0300 Subject: [PATCH 190/286] wip --- src/checker.ts | 78 +++++++++++++++++++++++++++++++------------------- src/index.ts | 6 ++-- 2 files changed, 51 insertions(+), 33 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 5db54d4..6552674 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -104,12 +104,23 @@ type InferBlockStatement< > : never : NodeList[0] extends FunctionDeclaration< - Identifier>, + Identifier, infer Params, BlockStatement, any > - ? InferFunctionDeclaration + ? InferFunctionDeclaration extends TypeResult< + any, + infer DeclarationState, + infer DeclarationErrors + > + ? InferBlockStatement< + Tail, + DeclarationState, + Result, + Concat + > + : never : NodeList[0] extends ReturnStatement ? InferExpression extends TypeResult< infer ExpressionValue, @@ -324,30 +335,39 @@ type InferExpression< ? InferMemberExpression : Node extends ArrayExpression ? InferArrayElements - : Node extends CallExpression - ? InferCallExpression + : Node extends CallExpression< + infer Callee, + infer Arguments, + NodeData + > + ? InferCallExpression : UnknownType; type InferCallExpression< - C extends BaseNode, - A extends Array>, - S extends StateType, -> = C extends BaseNode> - ? InferExpression extends infer G - ? G extends Array - ? G[0] extends FunctionType - ? InferExpressionsArray extends infer H - ? H extends Array - ? InferCallExpressionHelper - : H - : never - : SyntaxError< - `This expression is not callable. Type '${Serialize< - G[0] - >}' has no call signatures.`, - L - > - : G + Callee extends BaseNode, + Arguments extends Array>, + State extends StateType, + StartLine extends number, +> = InferExpression extends TypeResult< + infer CalleeValue, + infer CalleeState, + infer CalleeErrors +> + ? InferExpressionsArray extends infer H + ? CalleeValue extends FunctionType + ? H extends Array + ? InferCallExpressionHelper + : H + : TypeResult< + AnyType, + State, + [ + TypeError< + `This expression is not callable. Type '${Serialize}' has no call signatures.`, + StartLine + >, + ] + > : never : never; @@ -355,17 +375,17 @@ type InferCallExpressionHelper< P extends Array<[string, StaticType]>, H extends Array, R extends StaticType, - S extends StateType, - L extends number, + State extends StateType, + StartLine extends number, > = P['length'] extends H['length'] - ? MatchTypeArrays extends infer W + ? MatchTypeArrays extends infer W ? W extends true - ? [R, S] + ? [R, State] : W : never - : SyntaxError< + : TypeError< `Expected ${P['length']} arguments, but got ${H['length']}.`, - L + StartLine >; type InferExpressionsArray< diff --git a/src/index.ts b/src/index.ts index adce753..53f5014 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,11 +4,9 @@ import type { Check } from './checker'; type T = Tokenize<` -function foo() { - -} +function foo() {} -const a: string = foo +foo() `>; type R = Parse; From 26c169dc3e4bf9e21a92af4f4ac7074ed6043037 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 16:11:58 +0300 Subject: [PATCH 191/286] wip --- src/checker.ts | 119 ++++++++++++++++++++++++++-------------- src/index.ts | 4 +- src/parser.ts | 52 +++++++++--------- src/test/parser.test.ts | 12 ++-- src/types.ts | 8 ++- src/utils/arrayUtils.ts | 7 +-- 6 files changed, 120 insertions(+), 82 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 6552674..5fe2e5d 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -31,6 +31,7 @@ import type { ArrayType, BooleanLiteralType, BooleanType, + CallArgumentsType, FunctionType, NullType, NumberLiteralType, @@ -43,7 +44,14 @@ import type { UnknownType, VoidType, } from './types'; -import type { Concat, Includes, Push, Tail, Uniq } from './utils/arrayUtils'; +import type { + Concat, + Includes, + Push, + Tail, + Uniq, + Unshift, +} from './utils/arrayUtils'; import type { MergeWithOverride } from './utils/generalUtils'; import type { StateType, TypeResult } from './utils/utilityTypes'; @@ -245,18 +253,20 @@ type MatchType = A extends AnyType : false; type MatchTypeArrays< - T extends Array<[string, StaticType]>, - H extends Array, - L extends number, -> = T extends [] + ParamsType extends Array<[string, StaticType]>, + ArgumentsType extends Array, + StartLine extends number, +> = ParamsType extends [] ? true - : MatchType extends true - ? MatchTypeArrays, Tail, L> - : SyntaxError< + : MatchType extends true + ? MatchTypeArrays, Tail, StartLine> + : TypeError< `Argument of type '${Serialize< - H[0] - >}' is not assignable to parameter of type '${Serialize}'.`, - L + ArgumentsType[0] + >}' is not assignable to parameter of type '${Serialize< + ParamsType[0][1] + >}'.`, + StartLine >; type InferVariableDeclaration< @@ -353,51 +363,78 @@ type InferCallExpression< infer CalleeState, infer CalleeErrors > - ? InferExpressionsArray extends infer H - ? CalleeValue extends FunctionType - ? H extends Array - ? InferCallExpressionHelper - : H + ? InferExpressionsArray extends TypeResult< + CallArgumentsType, + infer ArgumentsState, + infer ArgumentsErrors + > + ? CalleeValue extends FunctionType + ? InferCallExpressionHelper< + ParamsType, + ArgumentsType, + ReturnType, + ArgumentsState, + Concat, + StartLine + > : TypeResult< AnyType, - State, - [ + ArgumentsState, + Unshift< + ArgumentsErrors, TypeError< `This expression is not callable. Type '${Serialize}' has no call signatures.`, StartLine - >, - ] + > + > > : never : never; type InferCallExpressionHelper< - P extends Array<[string, StaticType]>, - H extends Array, - R extends StaticType, + ParamsType extends Array<[string, StaticType]>, + ArgumentsType extends Array, + ReturnType extends StaticType, State extends StateType, + Errors extends Array>, StartLine extends number, -> = P['length'] extends H['length'] - ? MatchTypeArrays extends infer W - ? W extends true - ? [R, State] - : W - : never - : TypeError< - `Expected ${P['length']} arguments, but got ${H['length']}.`, - StartLine +> = ParamsType['length'] extends ArgumentsType['length'] + ? MatchTypeArrays extends TypeError< + infer Message, + infer StartLine + > + ? TypeResult>> + : TypeResult + : TypeResult< + AnyType, + State, + Push< + Errors, + TypeError< + `Expected ${ParamsType['length']} arguments, but got ${ArgumentsType['length']}.`, + StartLine + > + > >; type InferExpressionsArray< - T extends Array>, - S extends StateType, - R extends Array = [], -> = T extends [] - ? [R, S] - : InferExpression extends infer H - ? H extends Array - ? InferExpressionsArray, MergeWithOverride, Push> - : H + NodeList extends Array>, + State extends StateType, + Result extends Array = [], + Errors extends Array> = [], +> = NodeList extends [] + ? TypeResult, State, Errors> + : InferExpression extends TypeResult< + infer ExpressionValue, + infer ExpressionState, + infer ExpressionErrors + > + ? InferExpressionsArray< + Tail, + MergeWithOverride, + Push, + Concat + > : never; type InferArrayElements< diff --git a/src/index.ts b/src/index.ts index 53f5014..d7e4d21 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,9 +4,9 @@ import type { Check } from './checker'; type T = Tokenize<` -function foo() {} +function foo(a: number) {} -foo() +foo('a', bar, bazz) `>; type R = Parse; diff --git a/src/parser.ts b/src/parser.ts index cc576dd..2c41e9e 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -24,7 +24,7 @@ import type { NumberTypeAnnotation, AnyTypeAnnotation, NodeData, - Node, + BaseNode, } from './ast'; import type { Error, SyntaxError } from './errors'; import type { @@ -71,7 +71,7 @@ type ParseVariableDeclarationHelper< K extends number, > = ParseExpression> extends infer G ? G extends Array - ? G[0] extends Node> + ? G[0] extends BaseNode> ? [ VariableDeclaration< [VariableDeclarator>], @@ -141,9 +141,9 @@ type ParseVariableDeclaration>> = : null; type ParseMemberExpression< - O extends Node, + O extends BaseNode, T extends Array>, -> = O extends Node> +> = O extends BaseNode> ? T[0] extends GenericToken<'.', TokenData> ? T[1] extends SymbolToken> ? [ @@ -159,7 +159,7 @@ type ParseMemberExpression< : T[0] extends GenericToken<'[', TokenData> ? ParseExpression> extends infer G ? G extends [infer Q, infer W] - ? Q extends Node> + ? Q extends BaseNode> ? W extends Array> ? W[0] extends GenericToken<']', TokenData> ? [MemberExpression>, Tail] @@ -174,12 +174,12 @@ type ParseMemberExpression< : never; type ParseCallExpression< - O extends Node, + O extends BaseNode, T extends Array>, > = T[0] extends GenericToken<'(', TokenData> ? ParseCallExpressionArguments, E, ')'> extends infer G ? G extends Array - ? O extends Node> + ? O extends BaseNode> ? G[2] extends Token> ? [CallExpression>, G[1]] : never @@ -193,7 +193,7 @@ type ParseCallExpressionArguments< E extends number, J extends string, N extends boolean = false, - R extends Array> = [], + R extends Array> = [], > = T[0] extends GenericToken ? [R, Tail, T[0]] : T extends [] @@ -210,7 +210,7 @@ type ParseCallExpressionArgumentsHelper< T extends Array>, E extends number, J extends string, - R extends Array> = [], + R extends Array> = [], > = ParseExpression extends infer G ? G extends Array ? ParseCallExpressionArguments> @@ -218,11 +218,11 @@ type ParseCallExpressionArgumentsHelper< : never; type CheckExpression< - O extends Node, + O extends BaseNode, T extends Array>, > = ParseMemberExpression extends infer G ? G extends [infer O, infer T] - ? O extends Node + ? O extends BaseNode ? T extends Array> ? CheckExpression : never @@ -231,7 +231,7 @@ type CheckExpression< ? G : ParseCallExpression extends infer G ? G extends [infer O, infer T] - ? O extends Node + ? O extends BaseNode ? T extends Array> ? CheckExpression : never @@ -301,7 +301,7 @@ type ParseObjectItem< ? T[1] extends GenericToken<':', any> ? ParseExpression> extends infer G ? G extends Array - ? G[0] extends Node> + ? G[0] extends BaseNode> ? ParseObject< G[1], E, @@ -337,7 +337,7 @@ type ParseArrayExpression< type ParseExpressionStatement>> = ParseExpression extends infer G ? G extends Array - ? G[0] extends Node + ? G[0] extends BaseNode ? [ExpressionStatement, G[1]] : never : G @@ -351,7 +351,7 @@ type ParseFunctionDeclaration>> = ? G extends Array ? ParseBlockStatement extends infer H ? H extends Array - ? H[0] extends Node> + ? H[0] extends BaseNode> ? [ FunctionDeclaration< Identifier>, @@ -373,7 +373,7 @@ type ParseFunctionDeclaration>> = type ParseFunctionParams< T extends Array>, I extends number, - R extends Array> = [], + R extends Array> = [], N extends boolean = false, > = T[0] extends GenericToken<')', TokenData> ? T[1] extends GenericToken<'{', TokenData> @@ -384,7 +384,7 @@ type ParseFunctionParams< : N extends true ? T[0] extends GenericToken<',', any> ? ParseFunctionParamsHelper, I, R> - : Head extends Node> + : Head extends BaseNode> ? SyntaxError<"',' expected.", I> : never : ParseFunctionParamsHelper; @@ -392,7 +392,7 @@ type ParseFunctionParams< type ParseFunctionParamsHelper< T extends Array>, I extends number, - R extends Array> = [], + R extends Array> = [], > = ParseIdentifier extends infer G ? G extends Array ? ParseFunctionParams, true> @@ -405,10 +405,10 @@ type ParseBlockStatement< T extends Array>, L extends number, F extends boolean, - R extends Array> = [], + R extends Array> = [], N extends boolean = false, > = T extends [] - ? Head extends Node> + ? Head extends BaseNode> ? SyntaxError<"'}' expected.", S> : SyntaxError<"'}' expected.", L> : T[0] extends GenericToken<'}', TokenData> @@ -425,7 +425,7 @@ type ParseBlockStatement< type ParseTopLevel< T extends Array>, - R extends Array> = [], + R extends Array> = [], N extends boolean = false, > = T extends [] ? R @@ -443,7 +443,7 @@ type ParseBlockStatementHelper< T extends Array>, L extends number, F extends boolean, - R extends Array>, + R extends Array>, > = ParseStatementHelper extends infer G ? G extends Array ? ParseBlockStatement, true> @@ -452,7 +452,7 @@ type ParseBlockStatementHelper< type ParseTopLevelHelper< T extends Array>, - R extends Array>, + R extends Array>, > = ParseStatementHelper extends infer G ? G extends Array ? ParseTopLevel, G[2]> @@ -466,7 +466,7 @@ type ParseIfStatement< ? T[1] extends GenericToken<'(', TokenData> ? ParseExpression> extends infer G ? G extends Array - ? G[0] extends Node> + ? G[0] extends BaseNode> ? ParseIfStatementHelper : G extends Error ? G @@ -483,7 +483,7 @@ type ParseReturnStatementHelper< ? [ReturnStatement>, Tail] : ParseExpression extends infer G ? G extends Array - ? G[0] extends Node> + ? G[0] extends BaseNode> ? [ReturnStatement>, G[1]] : G : never @@ -515,7 +515,7 @@ type ParseIfStatementHelper< ? G[1][1] extends GenericToken<'{', TokenData> ? ParseBlockStatement, H, F> extends infer B ? B extends Array - ? B[0] extends Node> + ? B[0] extends BaseNode> ? [IfStatement>, B[1]] : never : B diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index 0cc9a14..360680a 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -596,7 +596,7 @@ expectType>([ }, ]); -expectType>([ +expectType>([ { type: 'ExpressionStatement', expression: { @@ -606,16 +606,16 @@ expectType>([ name: 'hello', typeAnnotation: null, data: { - startLineNumber: 1, - endLineNumber: 1, + startLineNumber: 3, + endLineNumber: 3, }, }, arguments: [], - data: { startLineNumber: 1, endLineNumber: 2 }, + data: { startLineNumber: 3, endLineNumber: 4 }, }, data: { - startLineNumber: 1, - endLineNumber: 2, + startLineNumber: 3, + endLineNumber: 4, }, }, ]); diff --git a/src/types.ts b/src/types.ts index ba8358d..8246567 100644 --- a/src/types.ts +++ b/src/types.ts @@ -65,6 +65,11 @@ export type UnionType> = { types: V; }; +export type CallArgumentsType> = { + type: 'CallArgumentsType'; + arguments: Arguments; +}; + // export type GenericType = { // type: 'GenericType'; // id: T; @@ -84,5 +89,6 @@ export type StaticType = | FunctionType | ObjectType | ArrayType - | UnionType; + | UnionType + | CallArgumentsType; // | GenericType; diff --git a/src/utils/arrayUtils.ts b/src/utils/arrayUtils.ts index 3c5b553..95fd425 100644 --- a/src/utils/arrayUtils.ts +++ b/src/utils/arrayUtils.ts @@ -7,12 +7,7 @@ export type Tail> = ((...t: T) => void) extends ( export type Push, E> = [...T, E]; -export type Unshift, E> = (( - h: E, - ...t: T -) => void) extends (...t: infer R) => void - ? R - : never; +export type Unshift, E> = [E, ...T]; export type Reverse< T extends Array, From 89e5f00e1daf0e472cee17793d8e178ecd768f11 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 17:07:36 +0300 Subject: [PATCH 192/286] wip --- src/tokenizer.ts | 168 +++++++++++++++++++++------------------ src/utils/stringUtils.ts | 2 +- 2 files changed, 92 insertions(+), 78 deletions(-) diff --git a/src/tokenizer.ts b/src/tokenizer.ts index f74a4a7..de8a2fd 100644 --- a/src/tokenizer.ts +++ b/src/tokenizer.ts @@ -1,7 +1,7 @@ import type { Push } from './utils/arrayUtils'; import type { EatFirstChar, - FirstChar, + GetFirstChar, ConcatStrings, StringContains, } from './utils/stringUtils'; @@ -18,91 +18,105 @@ import type { SyntaxError } from './errors'; import type { Succ } from './utils/math'; type TokenizeInput< - I extends string, - F extends string, - E extends string, - G extends boolean, - L extends number, - D extends TokenData = TokenData, -> = F extends ',' - ? [GenericToken<',', D>, E] - : F extends '(' - ? [GenericToken<'(', D>, E] - : F extends ')' - ? [GenericToken<')', D>, E] - : F extends '[' - ? [GenericToken<'[', D>, E] - : F extends ']' - ? [GenericToken<']', D>, E] - : F extends '{' - ? [GenericToken<'{', D>, E] - : F extends '}' - ? [GenericToken<'}', D>, E] - : F extends '.' - ? [GenericToken<'.', D>, E] - : F extends ';' - ? [GenericToken<';', D>, E] - : F extends ':' - ? [GenericToken<':', D>, E] - : F extends Numbers - ? TokenizeNumber - : F extends '"' - ? TokenizeString - : F extends "'" - ? TokenizeString - : F extends Symbols - ? TokenizeSymbol - : SyntaxError<`Invalid character.`, L>; + Input extends string, + FirstChar extends string, + InputTail extends string, + PrecedingLinebreak extends boolean, + LineNumber extends number, + Data extends TokenData = TokenData, +> = FirstChar extends ',' + ? [GenericToken<',', Data>, InputTail] + : FirstChar extends '(' + ? [GenericToken<'(', Data>, InputTail] + : FirstChar extends ')' + ? [GenericToken<')', Data>, InputTail] + : FirstChar extends '[' + ? [GenericToken<'[', Data>, InputTail] + : FirstChar extends ']' + ? [GenericToken<']', Data>, InputTail] + : FirstChar extends '{' + ? [GenericToken<'{', Data>, InputTail] + : FirstChar extends '}' + ? [GenericToken<'}', Data>, InputTail] + : FirstChar extends '.' + ? [GenericToken<'.', Data>, InputTail] + : FirstChar extends ';' + ? [GenericToken<';', Data>, InputTail] + : FirstChar extends ':' + ? [GenericToken<':', Data>, InputTail] + : FirstChar extends Numbers + ? TokenizeNumber + : FirstChar extends '"' + ? TokenizeString + : FirstChar extends "'" + ? TokenizeString + : FirstChar extends Symbols + ? TokenizeSymbol + : SyntaxError<`Invalid character.`, LineNumber>; type TokenizeNumber< - I extends string, - A extends string, - G extends TokenData, - C extends string = FirstChar, -> = C extends Numbers - ? TokenizeNumber, ConcatStrings, G> - : [NumberToken, I]; + Input extends string, + Result extends string, + PrecedingLinebreak extends TokenData, + FirstChar extends string = GetFirstChar, +> = FirstChar extends Numbers + ? TokenizeNumber< + EatFirstChar, + ConcatStrings, + PrecedingLinebreak + > + : [NumberToken, Input]; type TokenizeString< - I, - W extends '"' | "'", - G extends TokenData, -> = I extends `${infer H}${W}${infer J}` - ? StringContains extends true - ? SyntaxError<'Unterminated string literal.', G['lineNumber']> - : [StringToken, J] - : SyntaxError<'Unterminated string literal.', G['lineNumber']>; + Input extends string, + QuoteType extends '"' | "'", + Data extends TokenData, +> = Input extends `${infer Before}${QuoteType}${infer After}` + ? StringContains extends true + ? SyntaxError<'Unterminated string literal.', Data['lineNumber']> + : [StringToken, After] + : SyntaxError<'Unterminated string literal.', Data['lineNumber']>; type TokenizeSymbol< - I extends string, - A extends string, - G extends TokenData, - C extends string = FirstChar, -> = C extends Symbols - ? TokenizeSymbol, ConcatStrings, G> - : [SymbolToken, I]; + Input extends string, + Result extends string, + PrecedingLinebreak extends TokenData, + FirstChar extends string = GetFirstChar, +> = FirstChar extends Symbols + ? TokenizeSymbol< + EatFirstChar, + ConcatStrings, + PrecedingLinebreak + > + : [SymbolToken, Input]; -export type TokenizeSequence< - I extends string, - R extends Array>, - L extends number, - G extends boolean, - F extends string = FirstChar, - E extends string = EatFirstChar, -> = I extends '' - ? R - : F extends ' ' - ? TokenizeSequence - : F extends '\n' - ? TokenizeSequence, true> - : TokenizeInput extends infer P - ? TokenizeHelper +export type Tokenize< + Input extends string, + Result extends Array> = [], + LineNumber extends number = 1, + PrecedingLinebreak extends boolean = false, + FirstChar extends string = GetFirstChar, + InputTail extends string = EatFirstChar, +> = Input extends '' + ? Result + : FirstChar extends ' ' + ? Tokenize + : FirstChar extends '\n' + ? Tokenize, true> + : TokenizeInput< + Input, + FirstChar, + InputTail, + PrecedingLinebreak, + LineNumber + > extends infer TokenizeResult + ? TokenizeHelper : never; export type TokenizeHelper< - P, + TokenizeResult, R extends Array, L extends number, -> = P extends Array ? TokenizeSequence, L, false> : P; - -export type Tokenize = TokenizeSequence; +> = TokenizeResult extends Array + ? Tokenize, L, false> + : TokenizeResult; diff --git a/src/utils/stringUtils.ts b/src/utils/stringUtils.ts index cfd89c4..0295832 100644 --- a/src/utils/stringUtils.ts +++ b/src/utils/stringUtils.ts @@ -1,6 +1,6 @@ export type EatFirstChar = T extends `${infer A}${infer B}` ? B : ''; -export type FirstChar = T extends `${infer A}${infer B}` ? A : ''; +export type GetFirstChar = T extends `${infer A}${infer B}` ? A : ''; export type ConcatStrings = `${A}${B}`; From b01cba9edc92e7280ea516d42e589aa1f5a3e719 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 17:11:16 +0300 Subject: [PATCH 193/286] wip --- src/checker.ts | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 5fe2e5d..74b2686 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -484,17 +484,20 @@ type InferArrayElementsHelper< ? UnionType> : UnionType<[R, E]>; -type MapLiteralToType = T extends NumberLiteralType - ? NumberType - : T extends StringLiteralType - ? StringType - : T extends BooleanLiteralType - ? BooleanType - : T extends ObjectType - ? ObjectType<{ - [P in keyof O]: O[P] extends StaticType ? MapLiteralToType : never; - }> - : T; +type MapLiteralToType = + Type extends NumberLiteralType + ? NumberType + : Type extends StringLiteralType + ? StringType + : Type extends BooleanLiteralType + ? BooleanType + : Type extends ObjectType + ? ObjectType<{ + [P in keyof Properties]: Properties[P] extends StaticType + ? MapLiteralToType + : never; + }> + : Type; type InferMemberExpression< Object extends BaseNode, From 2dba94a1e40542fe7b76a4fa073ea43c29ee84b3 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 17:23:05 +0300 Subject: [PATCH 194/286] wip --- src/ast.ts | 8 ++++---- src/checker.ts | 15 ++++++++++++++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index 0c6c7d9..dda276a 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -147,12 +147,12 @@ export type IfStatement< }; export type ReturnStatement< - T extends BaseNode, - D extends NodeData, + Argument extends BaseNode | null, + Data extends NodeData, > = { type: 'ReturnStatement'; - argument: T; - data: D; + argument: Argument; + data: Data; }; export type BlockStatement< diff --git a/src/checker.ts b/src/checker.ts index 74b2686..2002f8c 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -130,7 +130,7 @@ type InferBlockStatement< > : never : NodeList[0] extends ReturnStatement - ? InferExpression extends TypeResult< + ? InferReturnStatement extends TypeResult< infer ExpressionValue, infer ExpressionState, infer ExpressionErrors @@ -144,6 +144,19 @@ type InferBlockStatement< : never : InferBlockStatement, State, VoidType, Errors>; +type InferReturnStatement< + ReturnExpression extends BaseNode | null, + State extends StateType, +> = ReturnExpression extends BaseNode + ? InferExpression extends TypeResult< + infer ExpressionValue, + infer ExpressionState, + infer ExpressionErrors + > + ? TypeResult + : never + : TypeResult; + type MapAnnotationToType> = AnnotationValue extends StringTypeAnnotation ? StringType From a0d2c5363a43ee3582cbe94a609a3c1c54b2391a Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 17:30:31 +0300 Subject: [PATCH 195/286] wip --- src/ast.ts | 247 +++++++++++++++++++++++++++-------------------------- 1 file changed, 128 insertions(+), 119 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index dda276a..eb7fb48 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -1,93 +1,102 @@ -export type NodeData = { - startLineNumber: S; - endLineNumber: E; +export type NodeData = { + startLineNumber: StartLine; + endLineNumber: EndLine; }; -export type NullLiteral> = { +export type NullLiteral> = { type: 'NullLiteral'; - data: D; + data: Data; }; -export type NumericLiteral> = { +export type NumericLiteral< + Value extends string, + Data extends NodeData, +> = { type: 'NumericLiteral'; - value: T; - data: D; + value: Value; + data: Data; }; -export type BooleanLiteral> = { +export type BooleanLiteral< + Value extends boolean, + Data extends NodeData, +> = { type: 'BooleanLiteral'; - value: T; - data: D; + value: Value; + data: Data; }; -export type StringLiteral> = { +export type StringLiteral< + Value extends string, + Data extends NodeData, +> = { type: 'StringLiteral'; - value: T; - data: D; + value: Value; + data: Data; }; export type ArrayExpression< - T extends Array>, - D extends NodeData, + Elements extends Array>, + Data extends NodeData, > = { type: 'ArrayExpression'; - elements: T; - data: D; + elements: Elements; + data: Data; }; export type ObjectExpression< - T extends Array>, - D extends NodeData, + Properties extends Array>, + Data extends NodeData, > = { type: 'ObjectExpression'; - properties: T; - data: D; + properties: Properties; + data: Data; }; export type ObjectProperty< - K extends Identifier, - T extends BaseNode, - D extends NodeData, + Key extends Identifier, + Value extends BaseNode, + Data extends NodeData, > = { type: 'ObjectProperty'; - key: K; - value: T; - data: D; + key: Key; + value: Value; + data: Data; }; export type VariableDeclaration< - H extends Array>, - K extends 'const' | 'let', - D extends NodeData, + Declarations extends Array>, + Kind extends 'const' | 'let', + Data extends NodeData, > = { type: 'VariableDeclaration'; - declarations: H; - kind: K; - data: D; + declarations: Declarations; + kind: Kind; + data: Data; }; export type VariableDeclarator< - N extends Identifier, - I extends BaseNode, - D extends NodeData, + Id extends Identifier, + Init extends BaseNode, + Data extends NodeData, > = { type: 'VariableDeclarator'; - id: N; - init: I; - data: D; + id: Id; + init: Init; + data: Data; }; export type FunctionDeclaration< - I extends Identifier, - P extends Array>, - B extends BlockStatement, - D extends NodeData, + Id extends Identifier, + Params extends Array>, + Body extends BlockStatement, + Data extends NodeData, > = { type: 'FunctionDeclaration'; - id: I; - params: P; - body: B; - data: D; + id: Id; + params: Params; + body: Body; + data: Data; }; export type Identifier< @@ -102,47 +111,47 @@ export type Identifier< }; export type ExpressionStatement< - E extends BaseNode, - D extends NodeData, + Expression extends BaseNode, + Data extends NodeData, > = { type: 'ExpressionStatement'; - expression: E; - data: D; + expression: Expression; + data: Data; }; export type CallExpression< - C extends BaseNode, - A extends Array>, - D extends NodeData, + Callee extends BaseNode, + Arguments extends Array>, + Data extends NodeData, > = { type: 'CallExpression'; - callee: C; - arguments: A; - data: D; + callee: Callee; + arguments: Arguments; + data: Data; }; export type MemberExpression< - O extends BaseNode, - P extends BaseNode, - C extends boolean, - D extends NodeData, + Object extends BaseNode, + Property extends BaseNode, + Computed extends boolean, + Data extends NodeData, > = { type: 'MemberExpression'; - object: O; - property: P; - computed: C; - data: D; + object: Object; + property: Property; + computed: Computed; + data: Data; }; export type IfStatement< - T extends BaseNode, - C extends BaseNode, - D extends NodeData, + Test extends BaseNode, + Consequent extends BaseNode, + Data extends NodeData, > = { type: 'IfStatement'; - test: T; - consequent: C; - data: D; + test: Test; + consequent: Consequent; + data: Data; // alternate: A; }; @@ -156,76 +165,76 @@ export type ReturnStatement< }; export type BlockStatement< - B extends Array>, - D extends NodeData, + Body extends Array>, + Data extends NodeData, > = { type: 'BlockStatement'; - body: B; - data: D; + body: Body; + data: Data; }; export type TypeAnnotation< - T extends BaseNode, - D extends NodeData, + Annotation extends BaseNode, + Data extends NodeData, > = { type: 'TypeAnnotation'; - typeAnnotation: T; - data: D; + typeAnnotation: Annotation; + data: Data; }; -export type StringTypeAnnotation> = { +export type StringTypeAnnotation> = { type: 'StringTypeAnnotation'; - data: D; + data: Data; }; -export type NumberTypeAnnotation> = { +export type NumberTypeAnnotation> = { type: 'NumberTypeAnnotation'; - data: D; + data: Data; }; -export type NullLiteralTypeAnnotation> = { +export type NullLiteralTypeAnnotation> = { type: 'NullLiteralTypeAnnotation'; - data: D; + data: Data; }; -export type BooleanTypeAnnotation> = { +export type BooleanTypeAnnotation> = { type: 'BooleanTypeAnnotation'; - data: D; + data: Data; }; -export type GenericTypeAnnotation> = { +export type GenericTypeAnnotation> = { type: 'GenericTypeAnnotation'; id: I; - data: D; + data: Data; }; -export type AnyTypeAnnotation> = { +export type AnyTypeAnnotation> = { type: 'AnyTypeAnnotation'; - data: D; -}; - -export type BaseNode> = - | NumericLiteral - | BooleanLiteral - | StringLiteral - | ArrayExpression - | ObjectExpression - | ObjectProperty - | VariableDeclaration - | VariableDeclarator - | FunctionDeclaration - | Identifier - | NullLiteral - | ExpressionStatement - | CallExpression - | MemberExpression - | IfStatement - | ReturnStatement - | BlockStatement - | TypeAnnotation - | StringTypeAnnotation - | NumberTypeAnnotation - | NullLiteralTypeAnnotation - | BooleanTypeAnnotation - | GenericTypeAnnotation - | AnyTypeAnnotation; + data: Data; +}; + +export type BaseNode> = + | NumericLiteral + | BooleanLiteral + | StringLiteral + | ArrayExpression + | ObjectExpression + | ObjectProperty + | VariableDeclaration + | VariableDeclarator + | FunctionDeclaration + | Identifier + | NullLiteral + | ExpressionStatement + | CallExpression + | MemberExpression + | IfStatement + | ReturnStatement + | BlockStatement + | TypeAnnotation + | StringTypeAnnotation + | NumberTypeAnnotation + | NullLiteralTypeAnnotation + | BooleanTypeAnnotation + | GenericTypeAnnotation + | AnyTypeAnnotation; From 45903782f92ac01fb0b0bcc232501ef537d3a7f8 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 17:39:11 +0300 Subject: [PATCH 196/286] wip --- src/parser.ts | 25 +++++++++++----------- src/tokens.ts | 58 +++++++++++++++++++++++++++++++++------------------ 2 files changed, 51 insertions(+), 32 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 2c41e9e..9211315 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -424,18 +424,18 @@ type ParseBlockStatement< : never; type ParseTopLevel< - T extends Array>, - R extends Array> = [], - N extends boolean = false, -> = T extends [] - ? R - : T[0] extends GenericToken<';', any> - ? ParseTopLevel, R, false> - : N extends false - ? ParseTopLevelHelper - : T[0] extends Token> + TokenList extends Array>, + Result extends Array> = [], + NeedSemicolon extends boolean = false, +> = TokenList extends [] + ? Result + : TokenList[0] extends GenericToken<';', any> + ? ParseTopLevel, Result, false> + : NeedSemicolon extends false + ? ParseTopLevelHelper + : TokenList[0] extends Token> ? P extends true - ? ParseTopLevelHelper + ? ParseTopLevelHelper : SyntaxError<"';' expected.", L> : never; @@ -559,4 +559,5 @@ type ParseStatementHelper< : never : never; -export type Parse>> = ParseTopLevel; +export type Parse>> = + ParseTopLevel; diff --git a/src/tokens.ts b/src/tokens.ts index bb360d1..fe03b29 100644 --- a/src/tokens.ts +++ b/src/tokens.ts @@ -1,34 +1,52 @@ -export type TokenData

= { - precedingLinebreak: P; - lineNumber: L; +export type TokenData< + PrecedingLinebreak extends boolean, + LineNumber extends number, +> = { + precedingLinebreak: PrecedingLinebreak; + lineNumber: LineNumber; }; -export type GenericToken> = { +export type GenericToken< + Value extends string, + Data extends TokenData, +> = { type: 'generic'; - value: V; - data: D; + value: Value; + data: Data; }; -export type NumberToken> = { +export type NumberToken< + Value extends string, + Data extends TokenData, +> = { type: 'number'; - value: V; - data: D; + value: Value; + data: Data; }; -export type StringToken> = { +export type StringToken< + Value extends string, + Data extends TokenData, +> = { type: 'string'; - value: V; - data: D; + value: Value; + data: Data; }; -export type SymbolToken> = { +export type SymbolToken< + Value extends string, + Data extends TokenData, +> = { type: 'symbol'; - value: V; - data: D; + value: Value; + data: Data; }; -export type Token, V extends string = string> = - | GenericToken - | NumberToken - | StringToken - | SymbolToken; +export type Token< + Data extends TokenData, + Value extends string = string, +> = + | GenericToken + | NumberToken + | StringToken + | SymbolToken; From dc0e1960b5968ac24d0a7d83fc1928c5010c9396 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 17:49:54 +0300 Subject: [PATCH 197/286] wip --- src/parser.ts | 188 +++++++++++++++++++++++++++++++------------------- 1 file changed, 116 insertions(+), 72 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 9211315..13d3625 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -86,56 +86,95 @@ type ParseVariableDeclarationHelper< : G : never; -type ParseTypeAnnotation>> = - T[0] extends SymbolToken<'string', TokenData> +type ParseTypeAnnotation>> = + TokenList[0] extends SymbolToken<'string', TokenData> ? [ - TypeAnnotation>, NodeData>, - Tail, + TypeAnnotation< + StringTypeAnnotation>, + NodeData + >, + Tail, ] - : T[0] extends SymbolToken<'boolean', TokenData> + : TokenList[0] extends SymbolToken< + 'boolean', + TokenData + > ? [ - TypeAnnotation>, NodeData>, - Tail, + TypeAnnotation< + BooleanTypeAnnotation>, + NodeData + >, + Tail, ] - : T[0] extends SymbolToken<'null', TokenData> + : TokenList[0] extends SymbolToken<'null', TokenData> ? [ TypeAnnotation< - NullLiteralTypeAnnotation>, - NodeData + NullLiteralTypeAnnotation>, + NodeData >, - Tail, + Tail, ] - : T[0] extends SymbolToken<'number', TokenData> + : TokenList[0] extends SymbolToken< + 'number', + TokenData + > ? [ - TypeAnnotation>, NodeData>, - Tail, + TypeAnnotation< + NumberTypeAnnotation>, + NodeData + >, + Tail, ] - : T[0] extends SymbolToken<'any', TokenData> + : TokenList[0] extends SymbolToken<'any', TokenData> ? [ - TypeAnnotation>, NodeData>, - Tail, + TypeAnnotation< + AnyTypeAnnotation>, + NodeData + >, + Tail, ] - : T[0] extends SymbolToken> + : TokenList[0] extends SymbolToken< + infer E, + TokenData + > ? [ TypeAnnotation< - GenericTypeAnnotation>, - NodeData + GenericTypeAnnotation>, + NodeData >, - Tail, + Tail, ] : null; -type ParseVariableDeclaration>> = - T[0] extends SymbolToken<'const', TokenData> - ? ParseIdentifier, true> extends infer N - ? N extends [Identifier>, infer R] +type ParseVariableDeclaration>> = + NodeList[0] extends SymbolToken<'const', TokenData> + ? ParseIdentifier, true> extends infer N + ? N extends [ + Identifier>, + infer R, + ] ? R extends Array - ? R[0] extends SymbolToken<'=', TokenData> - ? ParseVariableDeclarationHelper - : SyntaxError<"'const' declarations must be initialized.", S> + ? R[0] extends SymbolToken< + '=', + TokenData + > + ? ParseVariableDeclarationHelper< + R, + N[0], + KindLineNumber, + IdentifierLineNumber, + EqualsLineNumber + > + : SyntaxError< + "'const' declarations must be initialized.", + IdentifierLineNumber + > : never : N extends null - ? SyntaxError<'Variable declaration list cannot be empty.', L> + ? SyntaxError< + 'Variable declaration list cannot be empty.', + KindLineNumber + > : N : never : null; @@ -334,11 +373,11 @@ type ParseArrayExpression< : A : never; -type ParseExpressionStatement>> = - ParseExpression extends infer G +type ParseExpressionStatement>> = + ParseExpression extends infer G ? G extends Array - ? G[0] extends BaseNode - ? [ExpressionStatement, G[1]] + ? G[0] extends BaseNode + ? [ExpressionStatement, G[1]] : never : G : never; @@ -402,24 +441,24 @@ type ParseFunctionParamsHelper< : never; type ParseBlockStatement< - T extends Array>, + TokenList extends Array>, L extends number, F extends boolean, R extends Array> = [], N extends boolean = false, -> = T extends [] +> = TokenList extends [] ? Head extends BaseNode> ? SyntaxError<"'}' expected.", S> : SyntaxError<"'}' expected.", L> - : T[0] extends GenericToken<'}', TokenData> - ? [BlockStatement>, Tail] - : T[0] extends GenericToken<';', any> - ? ParseBlockStatement, L, F, R, false> + : TokenList[0] extends GenericToken<'}', TokenData> + ? [BlockStatement>, Tail] + : TokenList[0] extends GenericToken<';', any> + ? ParseBlockStatement, L, F, R, false> : N extends false - ? ParseBlockStatementHelper - : T[0] extends Token> + ? ParseBlockStatementHelper + : TokenList[0] extends Token> ? P extends true - ? ParseBlockStatementHelper + ? ParseBlockStatementHelper : SyntaxError<"';' expected.", L> : never; @@ -433,10 +472,12 @@ type ParseTopLevel< ? ParseTopLevel, Result, false> : NeedSemicolon extends false ? ParseTopLevelHelper - : TokenList[0] extends Token> - ? P extends true + : TokenList[0] extends Token< + TokenData + > + ? PrecedingLinebreak extends true ? ParseTopLevelHelper - : SyntaxError<"';' expected.", L> + : SyntaxError<"';' expected.", LineNumber> : never; type ParseBlockStatementHelper< @@ -451,23 +492,23 @@ type ParseBlockStatementHelper< : never; type ParseTopLevelHelper< - T extends Array>, - R extends Array>, -> = ParseStatementHelper extends infer G + TokenList extends Array>, + Result extends Array>, +> = ParseStatementHelper extends infer G ? G extends Array - ? ParseTopLevel, G[2]> + ? ParseTopLevel, G[2]> : G : never; type ParseIfStatement< - T extends Array>, - F extends boolean, -> = T[0] extends SymbolToken<'if', TokenData> - ? T[1] extends GenericToken<'(', TokenData> - ? ParseExpression> extends infer G + NodeList extends Array>, + InFunctionScope extends boolean, +> = NodeList[0] extends SymbolToken<'if', TokenData> + ? NodeList[1] extends GenericToken<'(', TokenData> + ? ParseExpression> extends infer G ? G extends Array ? G[0] extends BaseNode> - ? ParseIfStatementHelper + ? ParseIfStatementHelper : G extends Error ? G : never @@ -490,18 +531,21 @@ type ParseReturnStatementHelper< : never; type ParseReturnStatement< - T extends Array>, - F extends boolean, -> = T[0] extends SymbolToken<'return', TokenData> - ? F extends true - ? T[1] extends Token, any> - ? P extends false - ? ParseReturnStatementHelper, L> - : [ReturnStatement>, Tail] - : [ReturnStatement>, []] + NodeList extends Array>, + InFunctionScope extends boolean, +> = NodeList[0] extends SymbolToken<'return', TokenData> + ? InFunctionScope extends true + ? NodeList[1] extends Token, any> + ? PrecedingLinebreak extends false + ? ParseReturnStatementHelper, LineNumber> + : [ + ReturnStatement>, + Tail, + ] + : [ReturnStatement>, []] : SyntaxError< "A 'return' statement can only be used within a function body.", - L + LineNumber > : null; @@ -525,29 +569,29 @@ type ParseIfStatementHelper< : never; type ParseStatementHelper< - T extends Array>, - F extends boolean, -> = ParseFunctionDeclaration extends infer P + TokenList extends Array>, + InFunctionScope extends boolean, +> = ParseFunctionDeclaration extends infer P ? P extends Array ? [...P, false] : P extends Error ? P - : ParseVariableDeclaration extends infer P + : ParseVariableDeclaration extends infer P ? P extends Array ? [...P, true] : P extends Error ? P - : ParseIfStatement extends infer P + : ParseIfStatement extends infer P ? P extends Array ? [...P, false] : P extends Error ? P - : ParseReturnStatement extends infer P + : ParseReturnStatement extends infer P ? P extends Array ? [...P, true] : P extends Error ? P - : ParseExpressionStatement extends infer P + : ParseExpressionStatement extends infer P ? P extends Array ? [...P, true] : P extends Error From 9e007190e24eebc40ac674518181ee5e6d53da37 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 17:54:40 +0300 Subject: [PATCH 198/286] wip --- src/parser.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 13d3625..9ba8e5c 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -213,14 +213,14 @@ type ParseMemberExpression< : never; type ParseCallExpression< - O extends BaseNode, - T extends Array>, -> = T[0] extends GenericToken<'(', TokenData> - ? ParseCallExpressionArguments, E, ')'> extends infer G + Node extends BaseNode, + TokenList extends Array>, +> = TokenList[0] extends GenericToken<'(', TokenData> + ? ParseCallExpressionArguments, E, ')'> extends infer G ? G extends Array - ? O extends BaseNode> + ? Node extends BaseNode> ? G[2] extends Token> - ? [CallExpression>, G[1]] + ? [CallExpression>, G[1]] : never : never : G @@ -257,9 +257,9 @@ type ParseCallExpressionArgumentsHelper< : never; type CheckExpression< - O extends BaseNode, - T extends Array>, -> = ParseMemberExpression extends infer G + Node extends BaseNode, + TokenList extends Array>, +> = ParseMemberExpression extends infer G ? G extends [infer O, infer T] ? O extends BaseNode ? T extends Array> @@ -268,7 +268,7 @@ type CheckExpression< : never : G extends Error ? G - : ParseCallExpression extends infer G + : ParseCallExpression extends infer G ? G extends [infer O, infer T] ? O extends BaseNode ? T extends Array> @@ -277,7 +277,7 @@ type CheckExpression< : never : G extends Error ? G - : [O, T] + : [Node, TokenList] : never : never; From 18805b2d0a2f713ee6233676867be6cf0984a36a Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 17:55:14 +0300 Subject: [PATCH 199/286] wip --- src/test/checker.test.ts | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/test/checker.test.ts b/src/test/checker.test.ts index d332792..1c5ee55 100644 --- a/src/test/checker.test.ts +++ b/src/test/checker.test.ts @@ -21,7 +21,7 @@ hello `> >([ { - type: 'SyntaxError', + type: 'TypeError', message: "Cannot find name 'hello'.", lineNumber: 3, }, @@ -35,7 +35,7 @@ world; `> >([ { - type: 'SyntaxError', + type: 'TypeError', message: "Cannot find name 'world'.", lineNumber: 3, }, @@ -91,7 +91,7 @@ hello.world `> >([ { - type: 'SyntaxError', + type: 'TypeError', message: "Property 'world' does not exist on type '{ foo: string; }'.", lineNumber: 4, }, @@ -136,7 +136,7 @@ hello `> >([ { - type: 'SyntaxError', + type: 'TypeError', message: "Property 'hey' does not exist on type '{ bar: string; }'.", lineNumber: 11, }, @@ -152,7 +152,7 @@ hello.foo `> >([ { - type: 'SyntaxError', + type: 'TypeError', message: "Property 'foo' does not exist on type 'string'.", lineNumber: 5, }, @@ -202,7 +202,7 @@ const hello: number = "hello"; `> >([ { - type: 'SyntaxError', + type: 'TypeError', message: "Type 'string' is not assignable to type 'number'.", lineNumber: 3, }, @@ -216,7 +216,7 @@ const hello: string = 123; `> >([ { - type: 'SyntaxError', + type: 'TypeError', message: "Type 'number' is not assignable to type 'string'.", lineNumber: 3, }, @@ -231,7 +231,7 @@ const foo: number = hello; `> >([ { - type: 'SyntaxError', + type: 'TypeError', message: "Type 'string' is not assignable to type 'number'.", lineNumber: 4, }, @@ -257,7 +257,7 @@ const foo: number = hello; `> >([ { - type: 'SyntaxError', + type: 'TypeError', message: "Type '{ hey: string; }' is not assignable to type 'number'.", lineNumber: 5, }, @@ -273,7 +273,7 @@ const foo: number = hello.hey; `> >([ { - type: 'SyntaxError', + type: 'TypeError', message: "Type 'string' is not assignable to type 'number'.", lineNumber: 5, }, @@ -299,7 +299,7 @@ o["hey"]; `> >([ { - type: 'SyntaxError', + type: 'TypeError', message: "Property 'hey' does not exist on type '{}'.", lineNumber: 5, }, @@ -327,7 +327,7 @@ o `> >([ { - type: 'SyntaxError', + type: 'TypeError', message: "Property 'hey' does not exist on type '{}'.", lineNumber: 7, }, @@ -376,7 +376,7 @@ o[k]["hi"]; `> >([ { - type: 'SyntaxError', + type: 'TypeError', message: "Property 'hi' does not exist on type '{ ho: string; }'.", lineNumber: 11, }, @@ -398,7 +398,7 @@ o[k][{}]; `> >([ { - type: 'SyntaxError', + type: 'TypeError', message: "Type '{}' cannot be used as an index type.", lineNumber: 11, }, @@ -416,7 +416,7 @@ o[true]; `> >([ { - type: 'SyntaxError', + type: 'TypeError', message: "Type 'boolean' cannot be used as an index type.", lineNumber: 7, }, @@ -432,7 +432,7 @@ const b: string = a; `> >([ { - type: 'SyntaxError', + type: 'TypeError', message: "Type 'number[]' is not assignable to type 'string'.", lineNumber: 5, }, @@ -448,7 +448,7 @@ const b: string = a; `> >([ { - type: 'SyntaxError', + type: 'TypeError', message: "Type '(number | string)[]' is not assignable to type 'string'.", lineNumber: 5, }, @@ -464,7 +464,7 @@ const b: string = a; `> >([ { - type: 'SyntaxError', + type: 'TypeError', message: "Type 'number | string' is not assignable to type 'string'.", lineNumber: 5, }, @@ -480,7 +480,7 @@ const b: string = a; `> >([ { - type: 'SyntaxError', + type: 'TypeError', message: "Type 'number[][]' is not assignable to type 'string'.", lineNumber: 5, }, From 9b7919ecb02389bc54db57418f49b0f50a81572f Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 17:59:02 +0300 Subject: [PATCH 200/286] wip --- src/parser.ts | 47 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 9ba8e5c..2bfc886 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -47,20 +47,47 @@ type ExtractTokenData< : never; type ParseIdentifier< - T extends Array>, - O extends boolean, -> = T[0] extends SymbolToken> - ? O extends true - ? T[1] extends GenericToken<':', TokenData> - ? ParseTypeAnnotation> extends infer J + TokenList extends Array>, + CanBeAnnotated extends boolean, +> = TokenList[0] extends SymbolToken< + infer Name, + TokenData +> + ? CanBeAnnotated extends true + ? TokenList[1] extends GenericToken< + ':', + TokenData + > + ? ParseTypeAnnotation> extends infer J ? J extends Array - ? [Identifier>, J[1]] + ? [ + Identifier< + Name, + J[0], + NodeData + >, + J[1], + ] : J extends Error ? J - : SyntaxError<'Type expected.', G> + : SyntaxError<'Type expected.', ColonLineNumber> : never - : [Identifier>, Tail] - : [Identifier>, Tail] + : [ + Identifier< + Name, + null, + NodeData + >, + Tail, + ] + : [ + Identifier< + Name, + null, + NodeData + >, + Tail, + ] : null; type ParseVariableDeclarationHelper< From 5bbe5162ab226447708e98afd1d5c2872716664d Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 18:04:24 +0300 Subject: [PATCH 201/286] wip --- src/parser.ts | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 2bfc886..95e2ce8 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -309,10 +309,9 @@ type CheckExpression< : never; type ParseExpression< - T extends Array>, - H extends NodeData = ExtractTokenData, - G extends Array> = Tail, -> = ParseExpressionHelper extends infer P + TokenList extends Array>, + Data extends NodeData = ExtractTokenData, +> = ParseExpressionHelper> extends infer P ? P extends Array ? CheckExpression : P extends Error @@ -321,25 +320,25 @@ type ParseExpression< : never; type ParseExpressionHelper< - T extends Array>, - H extends NodeData = ExtractTokenData, - G extends Array> = Tail, -> = T[0] extends SymbolToken<'true', any> - ? [BooleanLiteral, G] - : T[0] extends SymbolToken<'false', any> - ? [BooleanLiteral, G] - : T[0] extends SymbolToken<'null', any> - ? [NullLiteral, G] - : T[0] extends NumberToken - ? [NumericLiteral, G] - : T[0] extends StringToken - ? [StringLiteral, G] - : T[0] extends SymbolToken - ? [Identifier, G] - : T[0] extends GenericToken<'[', TokenData> - ? ParseArrayExpression, E> - : T[0] extends GenericToken<'{', TokenData> - ? ParseObject, E> + TokenList extends Array>, + Data extends NodeData = ExtractTokenData, + TokenTail extends Array> = Tail, +> = TokenList[0] extends SymbolToken<'true', any> + ? [BooleanLiteral, TokenTail] + : TokenList[0] extends SymbolToken<'false', any> + ? [BooleanLiteral, TokenTail] + : TokenList[0] extends SymbolToken<'null', any> + ? [NullLiteral, TokenTail] + : TokenList[0] extends NumberToken + ? [NumericLiteral, TokenTail] + : TokenList[0] extends StringToken + ? [StringLiteral, TokenTail] + : TokenList[0] extends SymbolToken + ? [Identifier, TokenTail] + : TokenList[0] extends GenericToken<'[', TokenData> + ? ParseArrayExpression, LineNumber> + : TokenList[0] extends GenericToken<'{', TokenData> + ? ParseObject, LineNumber> : null; type ParseObject< From c26ac9e3eba75d808685eacdc31d618bdd6205b0 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 18:17:35 +0300 Subject: [PATCH 202/286] wip --- src/parser.ts | 48 ++++++++++++++++----------------- src/test/checker.test.ts | 58 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 24 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 95e2ce8..21d6447 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -342,36 +342,36 @@ type ParseExpressionHelper< : null; type ParseObject< - T extends Array>, - E extends number, - R extends Array> = [], - N extends boolean = false, -> = T[0] extends GenericToken<'}', TokenData> - ? [ObjectExpression>, Tail] - : T extends [] - ? SyntaxError<"'}' expected.", E> - : N extends true - ? T[0] extends GenericToken<',', any> - ? ParseObjectItem, E, R> - : T[0] extends Token> + TokenList extends Array>, + InitialLineNumber extends number, + Result extends Array> = [], + NeedComma extends boolean = false, +> = TokenList[0] extends GenericToken<'}', TokenData> + ? [ObjectExpression>, Tail] + : TokenList extends [] + ? SyntaxError<"'}' expected.", InitialLineNumber> + : NeedComma extends true + ? TokenList[0] extends GenericToken<',', any> + ? ParseObjectItem, InitialLineNumber, Result> + : TokenList[0] extends Token> ? SyntaxError<"',' expected.", L> : never - : ParseObjectItem; + : ParseObjectItem; type ParseObjectItem< - T extends Array>, - E extends number, - R extends Array> = [], -> = T[0] extends SymbolToken> - ? T[1] extends GenericToken<':', any> - ? ParseExpression> extends infer G + TokenList extends Array>, + InitialLineNumber extends number, + Result extends Array> = [], +> = TokenList[0] extends SymbolToken> + ? TokenList[1] extends GenericToken<':', any> + ? ParseExpression> extends infer G ? G extends Array ? G[0] extends BaseNode> ? ParseObject< G[1], - E, + InitialLineNumber, Push< - R, + Result, ObjectProperty< Identifier>, G[0], @@ -383,10 +383,10 @@ type ParseObjectItem< : never : G extends Error ? G - : SyntaxError<'Expression expected.', E> + : SyntaxError<'Expression expected.', InitialLineNumber> : never - : SyntaxError<"'}' expected.", E> - : SyntaxError<"'}' expected.", E>; + : SyntaxError<"'}' expected.", InitialLineNumber> + : SyntaxError<"'}' expected.", InitialLineNumber>; type ParseArrayExpression< T extends Array>, diff --git a/src/test/checker.test.ts b/src/test/checker.test.ts index 1c5ee55..04cf576 100644 --- a/src/test/checker.test.ts +++ b/src/test/checker.test.ts @@ -485,3 +485,61 @@ const b: string = a; lineNumber: 5, }, ]); + +expectType< + TypeCheck<` + +hello + +world + +`> +>([ + { + type: 'TypeError', + message: "Cannot find name 'hello'.", + lineNumber: 3, + }, + { + type: 'TypeError', + message: "Cannot find name 'world'.", + lineNumber: 5, + }, +]); + +expectType< + TypeCheck<` + +const a: number = hello + +const b: number = a + +`> +>([ + { + type: 'TypeError', + message: "Cannot find name 'hello'.", + lineNumber: 3, + }, +]); + +expectType< + TypeCheck<` + +const a: string = hello + +const b: number = a + +`> +>([ + { + type: 'TypeError', + message: "Cannot find name 'hello'.", + lineNumber: 3, + }, + { + type: 'TypeError', + message: "Type 'string' is not assignable to type 'number'.", + lineNumber: 5, + }, +]); From 8b6548a21063b1f8e4dca6eedff28c0b60b834c2 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 18:20:34 +0300 Subject: [PATCH 203/286] wip --- src/checker.ts | 6 +++++ src/test/checker.test.ts | 52 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/src/checker.ts b/src/checker.ts index 2002f8c..dfbdbc4 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -390,6 +390,12 @@ type InferCallExpression< Concat, StartLine > + : CalleeValue extends AnyType + ? TypeResult< + AnyType, + ArgumentsState, + Concat + > : TypeResult< AnyType, ArgumentsState, diff --git a/src/test/checker.test.ts b/src/test/checker.test.ts index 04cf576..d00d51a 100644 --- a/src/test/checker.test.ts +++ b/src/test/checker.test.ts @@ -543,3 +543,55 @@ const b: number = a lineNumber: 5, }, ]); + +expectType< + TypeCheck<` + +const a: string = hello() + +const b: number = a + +`> +>([ + { + type: 'TypeError', + message: "Cannot find name 'hello'.", + lineNumber: 3, + }, + { + type: 'TypeError', + message: "Type 'string' is not assignable to type 'number'.", + lineNumber: 5, + }, +]); + +expectType< + TypeCheck<` + +const a: string = hello(foo, bar) + +const b: number = a + +`> +>([ + { + type: 'TypeError', + message: "Cannot find name 'hello'.", + lineNumber: 3, + }, + { + type: 'TypeError', + message: "Cannot find name 'foo'.", + lineNumber: 3, + }, + { + type: 'TypeError', + message: "Cannot find name 'bar'.", + lineNumber: 3, + }, + { + type: 'TypeError', + message: "Type 'string' is not assignable to type 'number'.", + lineNumber: 5, + }, +]); From 4bd32bb2975fffa7d2acadb82dff4687e643e155 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 18:21:51 +0300 Subject: [PATCH 204/286] wip --- src/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/checker.ts b/src/checker.ts index dfbdbc4..e22482f 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -400,7 +400,7 @@ type InferCallExpression< AnyType, ArgumentsState, Unshift< - ArgumentsErrors, + Concat, TypeError< `This expression is not callable. Type '${Serialize}' has no call signatures.`, StartLine From ec6a3636ed2af0842a15b1a6ea8d4b39a36ab43e Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 18:32:10 +0300 Subject: [PATCH 205/286] wip --- src/parser.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 21d6447..1e11fd2 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -207,28 +207,28 @@ type ParseVariableDeclaration>> = : null; type ParseMemberExpression< - O extends BaseNode, - T extends Array>, -> = O extends BaseNode> - ? T[0] extends GenericToken<'.', TokenData> - ? T[1] extends SymbolToken> + Node extends BaseNode, + TokenList extends Array>, +> = Node extends BaseNode> + ? TokenList[0] extends GenericToken<'.', TokenData> + ? TokenList[1] extends SymbolToken> ? [ MemberExpression< - O, + Node, Identifier>, false, NodeData >, - TailBy, + TailBy, ] : SyntaxError<'Identifier expected.', E> - : T[0] extends GenericToken<'[', TokenData> - ? ParseExpression> extends infer G + : TokenList[0] extends GenericToken<'[', TokenData> + ? ParseExpression> extends infer G ? G extends [infer Q, infer W] ? Q extends BaseNode> ? W extends Array> ? W[0] extends GenericToken<']', TokenData> - ? [MemberExpression>, Tail] + ? [MemberExpression>, Tail] : SyntaxError<"']' expected.", S> : never : never From def66454937188f37f1f7dbf6ecc65c448eebcc7 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 18:33:22 +0300 Subject: [PATCH 206/286] wip --- src/test/checker.test.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/test/checker.test.ts b/src/test/checker.test.ts index d00d51a..530103c 100644 --- a/src/test/checker.test.ts +++ b/src/test/checker.test.ts @@ -595,3 +595,20 @@ const b: number = a lineNumber: 5, }, ]); + +expectType< + TypeCheck<` + +function foo(a: string, b: number) {} + +foo(1, 'a') + +`> +>([ + { + type: 'TypeError', + message: + "Argument of type 'number' is not assignable to parameter of type 'string'.", + lineNumber: 5, + }, +]); From 2e7da766bbcdf7c27537e46b9e176fe871e18950 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 18:45:09 +0300 Subject: [PATCH 207/286] wip --- src/parser.ts | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 1e11fd2..c2aecf2 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -209,31 +209,41 @@ type ParseVariableDeclaration>> = type ParseMemberExpression< Node extends BaseNode, TokenList extends Array>, -> = Node extends BaseNode> - ? TokenList[0] extends GenericToken<'.', TokenData> - ? TokenList[1] extends SymbolToken> +> = Node extends BaseNode> + ? TokenList[0] extends GenericToken<'.', TokenData> + ? TokenList[1] extends SymbolToken< + infer Name, + TokenData + > ? [ MemberExpression< Node, - Identifier>, + Identifier< + Name, + null, + NodeData + >, false, - NodeData + NodeData >, TailBy, ] - : SyntaxError<'Identifier expected.', E> - : TokenList[0] extends GenericToken<'[', TokenData> + : SyntaxError<'Identifier expected.', DotLineNumber> + : TokenList[0] extends GenericToken< + '[', + TokenData + > ? ParseExpression> extends infer G ? G extends [infer Q, infer W] ? Q extends BaseNode> ? W extends Array> - ? W[0] extends GenericToken<']', TokenData> + ? W[0] extends GenericToken<']', any> ? [MemberExpression>, Tail] : SyntaxError<"']' expected.", S> : never : never : G extends null - ? SyntaxError<'Expression expected.', E> + ? SyntaxError<'Expression expected.', BracketLineNumber> : G : never : null From 53ee8be8736e6a789c48fd1f9276b598500f827e Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 20:29:48 +0300 Subject: [PATCH 208/286] wip --- src/parser.ts | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index c2aecf2..ce23f70 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -478,20 +478,20 @@ type ParseFunctionParamsHelper< type ParseBlockStatement< TokenList extends Array>, - L extends number, + InitialLineNumber extends number, F extends boolean, R extends Array> = [], N extends boolean = false, > = TokenList extends [] ? Head extends BaseNode> ? SyntaxError<"'}' expected.", S> - : SyntaxError<"'}' expected.", L> + : SyntaxError<"'}' expected.", InitialLineNumber> : TokenList[0] extends GenericToken<'}', TokenData> - ? [BlockStatement>, Tail] + ? [BlockStatement>, Tail] : TokenList[0] extends GenericToken<';', any> - ? ParseBlockStatement, L, F, R, false> + ? ParseBlockStatement, InitialLineNumber, F, R, false> : N extends false - ? ParseBlockStatementHelper + ? ParseBlockStatementHelper : TokenList[0] extends Token> ? P extends true ? ParseBlockStatementHelper @@ -591,16 +591,19 @@ type ParseIfStatementHelper< F extends boolean, E extends number, > = G[1] extends Array - ? G[1][0] extends GenericToken<')', TokenData> - ? G[1][1] extends GenericToken<'{', TokenData> - ? ParseBlockStatement, H, F> extends infer B + ? G[1][0] extends GenericToken< + ')', + TokenData + > + ? G[1][1] extends GenericToken<'{', TokenData> + ? ParseBlockStatement, CurlyLineNumber, F> extends infer B ? B extends Array ? B[0] extends BaseNode> ? [IfStatement>, B[1]] : never : B : never - : SyntaxError<"'{' expected.", I> + : SyntaxError<"'{' expected.", ClosingParenLineNumber> : SyntaxError<"')' expected.", E> : never; From 3aab6750e484be329eec5182e6831840df1c1a9e Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 20:34:06 +0300 Subject: [PATCH 209/286] wip --- src/parser.ts | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index ce23f70..cab0030 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -479,22 +479,33 @@ type ParseFunctionParamsHelper< type ParseBlockStatement< TokenList extends Array>, InitialLineNumber extends number, - F extends boolean, - R extends Array> = [], - N extends boolean = false, + InFunctionScope extends boolean, + Result extends Array> = [], + NeedSemicolon extends boolean = false, > = TokenList extends [] - ? Head extends BaseNode> + ? Result[0] extends BaseNode> ? SyntaxError<"'}' expected.", S> : SyntaxError<"'}' expected.", InitialLineNumber> : TokenList[0] extends GenericToken<'}', TokenData> - ? [BlockStatement>, Tail] + ? [BlockStatement>, Tail] : TokenList[0] extends GenericToken<';', any> - ? ParseBlockStatement, InitialLineNumber, F, R, false> - : N extends false - ? ParseBlockStatementHelper + ? ParseBlockStatement< + Tail, + InitialLineNumber, + InFunctionScope, + Result, + false + > + : NeedSemicolon extends false + ? ParseBlockStatementHelper< + TokenList, + InitialLineNumber, + InFunctionScope, + Result + > : TokenList[0] extends Token> ? P extends true - ? ParseBlockStatementHelper + ? ParseBlockStatementHelper : SyntaxError<"';' expected.", L> : never; From 7df308afa23686ab3d06a12b35d203cce30d71b4 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 20:38:39 +0300 Subject: [PATCH 210/286] wip --- src/checker.ts | 2 +- src/index.ts | 10 +++++++--- src/test/checker.test.ts | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index e22482f..35c968d 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -425,7 +425,7 @@ type InferCallExpressionHelper< ? TypeResult>> : TypeResult : TypeResult< - AnyType, + ReturnType, State, Push< Errors, diff --git a/src/index.ts b/src/index.ts index d7e4d21..efc1a10 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,10 +4,14 @@ import type { Check } from './checker'; type T = Tokenize<` -function foo(a: number) {} +function foo(a: number) { + return 5 +} -foo('a', bar, bazz) +const a = foo('a', bar, bazz) + +const b: string = a; `>; type R = Parse; -type C = Check; +type C = Check[3]; diff --git a/src/test/checker.test.ts b/src/test/checker.test.ts index 530103c..0a725b3 100644 --- a/src/test/checker.test.ts +++ b/src/test/checker.test.ts @@ -612,3 +612,38 @@ foo(1, 'a') lineNumber: 5, }, ]); + +expectType< + TypeCheck<` + +function foo(a: number) { + return 5 +} + +const a = foo('a', bar, bazz) + +const b: string = a; + +`> +>([ + { + type: 'TypeError', + message: "Cannot find name 'bar'.", + lineNumber: 7, + }, + { + type: 'TypeError', + message: "Cannot find name 'bazz'.", + lineNumber: 7, + }, + { + type: 'TypeError', + message: 'Expected 1 arguments, but got 3.', + lineNumber: 7, + }, + { + type: 'TypeError', + message: "Type 'number' is not assignable to type 'string'.", + lineNumber: 9, + }, +]); From 27f93e8de56bd80e64a56c4972eb767f981bf0af Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 20:40:34 +0300 Subject: [PATCH 211/286] wip --- src/parser.ts | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index cab0030..f9ccd9a 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -483,11 +483,14 @@ type ParseBlockStatement< Result extends Array> = [], NeedSemicolon extends boolean = false, > = TokenList extends [] - ? Result[0] extends BaseNode> - ? SyntaxError<"'}' expected.", S> + ? Result[0] extends BaseNode> + ? SyntaxError<"'}' expected.", LineNumber> : SyntaxError<"'}' expected.", InitialLineNumber> - : TokenList[0] extends GenericToken<'}', TokenData> - ? [BlockStatement>, Tail] + : TokenList[0] extends GenericToken<'}', TokenData> + ? [ + BlockStatement>, + Tail, + ] : TokenList[0] extends GenericToken<';', any> ? ParseBlockStatement< Tail, @@ -503,10 +506,12 @@ type ParseBlockStatement< InFunctionScope, Result > - : TokenList[0] extends Token> - ? P extends true - ? ParseBlockStatementHelper - : SyntaxError<"';' expected.", L> + : TokenList[0] extends Token< + TokenData + > + ? PrecedingLinebreak extends true + ? ParseBlockStatementHelper + : SyntaxError<"';' expected.", LineNumber> : never; type ParseTopLevel< From 455f79138c6bd5c32f49caf30744fa9b114238ea Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 20:44:43 +0300 Subject: [PATCH 212/286] wip --- src/parser.ts | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index f9ccd9a..285ddbe 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -570,14 +570,14 @@ type ParseIfStatement< : null; type ParseReturnStatementHelper< - T extends Array>, - L extends number, -> = T[0] extends GenericToken<';', TokenData> - ? [ReturnStatement>, Tail] - : ParseExpression extends infer G + TokenList extends Array>, + LineNumber extends number, +> = TokenList[0] extends GenericToken<';', TokenData> + ? [ReturnStatement>, Tail] + : ParseExpression extends infer G ? G extends Array ? G[0] extends BaseNode> - ? [ReturnStatement>, G[1]] + ? [ReturnStatement>, G[1]] : G : never : never; @@ -604,7 +604,7 @@ type ParseReturnStatement< type ParseIfStatementHelper< G extends Array, L extends number, - F extends boolean, + InFunctionScope extends boolean, E extends number, > = G[1] extends Array ? G[1][0] extends GenericToken< @@ -612,7 +612,11 @@ type ParseIfStatementHelper< TokenData > ? G[1][1] extends GenericToken<'{', TokenData> - ? ParseBlockStatement, CurlyLineNumber, F> extends infer B + ? ParseBlockStatement< + TailBy, + CurlyLineNumber, + InFunctionScope + > extends infer B ? B extends Array ? B[0] extends BaseNode> ? [IfStatement>, B[1]] From a01dce6cc0b7f995e1f816c00250f969013c1cfc Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 20:47:56 +0300 Subject: [PATCH 213/286] wip --- src/parser.ts | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 285ddbe..8bf9b09 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -555,25 +555,31 @@ type ParseTopLevelHelper< type ParseIfStatement< NodeList extends Array>, InFunctionScope extends boolean, -> = NodeList[0] extends SymbolToken<'if', TokenData> - ? NodeList[1] extends GenericToken<'(', TokenData> +> = NodeList[0] extends SymbolToken<'if', TokenData> + ? NodeList[1] extends GenericToken<'(', TokenData> ? ParseExpression> extends infer G ? G extends Array ? G[0] extends BaseNode> - ? ParseIfStatementHelper + ? ParseIfStatementHelper : G extends Error ? G : never - : SyntaxError<'Expression expected.', H> + : SyntaxError<'Expression expected.', ParenLineNumber> : never - : SyntaxError<"'(' expected.", L> + : SyntaxError<"'(' expected.", IfLineNumber> : null; type ParseReturnStatementHelper< TokenList extends Array>, LineNumber extends number, -> = TokenList[0] extends GenericToken<';', TokenData> - ? [ReturnStatement>, Tail] +> = TokenList[0] extends GenericToken< + ';', + TokenData +> + ? [ + ReturnStatement>, + Tail, + ] : ParseExpression extends infer G ? G extends Array ? G[0] extends BaseNode> From cfce37c4fc02fe3b10dcffeedfb6f6e4d33bedf3 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 21:44:13 +0300 Subject: [PATCH 214/286] wip --- src/parser.ts | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 8bf9b09..e0155bc 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -571,19 +571,19 @@ type ParseIfStatement< type ParseReturnStatementHelper< TokenList extends Array>, - LineNumber extends number, + StartLineNumber extends number, > = TokenList[0] extends GenericToken< ';', TokenData > ? [ - ReturnStatement>, + ReturnStatement>, Tail, ] : ParseExpression extends infer G ? G extends Array - ? G[0] extends BaseNode> - ? [ReturnStatement>, G[1]] + ? G[0] extends BaseNode> + ? [ReturnStatement>, G[1]] : G : never : never; @@ -609,7 +609,7 @@ type ParseReturnStatement< type ParseIfStatementHelper< G extends Array, - L extends number, + StartLineNumber extends number, InFunctionScope extends boolean, E extends number, > = G[1] extends Array @@ -624,8 +624,15 @@ type ParseIfStatementHelper< InFunctionScope > extends infer B ? B extends Array - ? B[0] extends BaseNode> - ? [IfStatement>, B[1]] + ? B[0] extends BaseNode> + ? [ + IfStatement< + G[0], + B[0], + NodeData + >, + B[1], + ] : never : B : never From 8d1c6129dcfc595df126ccabd6492c1070bb5e97 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 23:40:45 +0300 Subject: [PATCH 215/286] wip --- src/parser.ts | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index e0155bc..08b19b6 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -446,23 +446,29 @@ type ParseFunctionDeclaration>> = : null; type ParseFunctionParams< - T extends Array>, - I extends number, - R extends Array> = [], - N extends boolean = false, -> = T[0] extends GenericToken<')', TokenData> - ? T[1] extends GenericToken<'{', TokenData> - ? [R, TailBy, K] - : SyntaxError<"'{' expected.", L> - : T extends [] - ? SyntaxError<"')' expected.", I> - : N extends true - ? T[0] extends GenericToken<',', any> - ? ParseFunctionParamsHelper, I, R> - : Head extends BaseNode> - ? SyntaxError<"',' expected.", I> + TokenList extends Array>, + InitialLineNumber extends number, + Result extends Array> = [], + NeedSemicolon extends boolean = false, +> = TokenList[0] extends GenericToken< + ')', + TokenData +> + ? TokenList[1] extends GenericToken< + '{', + TokenData + > + ? [Result, TailBy, CurlyLineNumber] + : SyntaxError<"'{' expected.", ParenLineNumber> + : TokenList extends [] + ? SyntaxError<"')' expected.", InitialLineNumber> + : NeedSemicolon extends true + ? TokenList[0] extends GenericToken<',', any> + ? ParseFunctionParamsHelper, InitialLineNumber, Result> + : Result[0] extends BaseNode> + ? SyntaxError<"',' expected.", LineNumber> : never - : ParseFunctionParamsHelper; + : ParseFunctionParamsHelper; type ParseFunctionParamsHelper< T extends Array>, From be2a78e129ac706d39c1fb068c87ff8b0cd8dd47 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 23:44:45 +0300 Subject: [PATCH 216/286] wip --- src/parser.ts | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 08b19b6..6fc9892 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -418,21 +418,40 @@ type ParseExpressionStatement>> = : G : never; -type ParseFunctionDeclaration>> = - T[0] extends SymbolToken<'function', TokenData> - ? T[1] extends SymbolToken> - ? T[2] extends GenericToken<'(', TokenData> - ? ParseFunctionParams, I> extends infer G +type ParseFunctionDeclaration>> = + TokenList[0] extends SymbolToken< + 'function', + TokenData + > + ? TokenList[1] extends SymbolToken< + infer Name, + TokenData + > + ? TokenList[2] extends GenericToken< + '(', + TokenData + > + ? ParseFunctionParams< + TailBy, + ParenLineNumber + > extends infer G ? G extends Array ? ParseBlockStatement extends infer H ? H extends Array - ? H[0] extends BaseNode> + ? H[0] extends BaseNode> ? [ FunctionDeclaration< - Identifier>, + Identifier< + Name, + null, + NodeData< + FunctionNameLineNumber, + FunctionNameLineNumber + > + >, G[0], H[0], - NodeData + NodeData >, H[1], ] @@ -441,8 +460,8 @@ type ParseFunctionDeclaration>> = : never : G : never - : SyntaxError<"'(' expected.", O> - : SyntaxError<'Identifier expected.', L> + : SyntaxError<"'(' expected.", FunctionNameLineNumber> + : SyntaxError<'Identifier expected.', FunctionLineNumber> : null; type ParseFunctionParams< From d530d42894c291ae52b0502e0cdf46a126006fb2 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 23:45:38 +0300 Subject: [PATCH 217/286] wip --- src/parser.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 6fc9892..f51edbf 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -490,15 +490,15 @@ type ParseFunctionParams< : ParseFunctionParamsHelper; type ParseFunctionParamsHelper< - T extends Array>, - I extends number, - R extends Array> = [], -> = ParseIdentifier extends infer G + TokenList extends Array>, + LineNumber extends number, + Result extends Array>, +> = ParseIdentifier extends infer G ? G extends Array - ? ParseFunctionParams, true> + ? ParseFunctionParams, true> : G extends Error ? G - : SyntaxError<'Identifier expected.', I> + : SyntaxError<'Identifier expected.', LineNumber> : never; type ParseBlockStatement< From 69e4de364b504c716bdc7f3108c9dc8e7edb56d4 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 23:47:13 +0300 Subject: [PATCH 218/286] wip --- src/parser.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index f51edbf..4ca7506 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -558,13 +558,19 @@ type ParseTopLevel< : never; type ParseBlockStatementHelper< - T extends Array>, - L extends number, - F extends boolean, - R extends Array>, -> = ParseStatementHelper extends infer G + TokenList extends Array>, + LineNumber extends number, + InFunctionScope extends boolean, + Result extends Array>, +> = ParseStatementHelper extends infer G ? G extends Array - ? ParseBlockStatement, true> + ? ParseBlockStatement< + G[1], + LineNumber, + InFunctionScope, + Push, + true + > : G : never; From de593fbe75c9d9e56c3bcd8fc261c279cab0d224 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 23:49:52 +0300 Subject: [PATCH 219/286] wip --- src/parser.ts | 48 +++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 4ca7506..08fb9ab 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -173,9 +173,12 @@ type ParseTypeAnnotation>> = ] : null; -type ParseVariableDeclaration>> = - NodeList[0] extends SymbolToken<'const', TokenData> - ? ParseIdentifier, true> extends infer N +type ParseVariableDeclaration>> = + TokenList[0] extends SymbolToken< + 'const', + TokenData + > + ? ParseIdentifier, true> extends infer N ? N extends [ Identifier>, infer R, @@ -399,18 +402,22 @@ type ParseObjectItem< : SyntaxError<"'}' expected.", InitialLineNumber>; type ParseArrayExpression< - T extends Array>, - E extends number, -> = ParseCallExpressionArguments extends infer A + TokenList extends Array>, + StartLineNumber extends number, +> = ParseCallExpressionArguments< + TokenList, + StartLineNumber, + ']' +> extends infer A ? A extends Array - ? A[2] extends Token> - ? [ArrayExpression>, A[1]] + ? A[2] extends Token> + ? [ArrayExpression>, A[1]] : never : A : never; -type ParseExpressionStatement>> = - ParseExpression extends infer G +type ParseExpressionStatement>> = + ParseExpression extends infer G ? G extends Array ? G[0] extends BaseNode ? [ExpressionStatement, G[1]] @@ -584,11 +591,14 @@ type ParseTopLevelHelper< : never; type ParseIfStatement< - NodeList extends Array>, + TokenList extends Array>, InFunctionScope extends boolean, -> = NodeList[0] extends SymbolToken<'if', TokenData> - ? NodeList[1] extends GenericToken<'(', TokenData> - ? ParseExpression> extends infer G +> = TokenList[0] extends SymbolToken<'if', TokenData> + ? TokenList[1] extends GenericToken< + '(', + TokenData + > + ? ParseExpression> extends infer G ? G extends Array ? G[0] extends BaseNode> ? ParseIfStatementHelper @@ -620,16 +630,16 @@ type ParseReturnStatementHelper< : never; type ParseReturnStatement< - NodeList extends Array>, + TokenList extends Array>, InFunctionScope extends boolean, -> = NodeList[0] extends SymbolToken<'return', TokenData> +> = TokenList[0] extends SymbolToken<'return', TokenData> ? InFunctionScope extends true - ? NodeList[1] extends Token, any> + ? TokenList[1] extends Token, any> ? PrecedingLinebreak extends false - ? ParseReturnStatementHelper, LineNumber> + ? ParseReturnStatementHelper, LineNumber> : [ ReturnStatement>, - Tail, + Tail, ] : [ReturnStatement>, []] : SyntaxError< From 826af182c4e4b3ee4a4d0efaaa9aedd0532410ec Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 23:53:27 +0300 Subject: [PATCH 220/286] wip --- src/parser.ts | 69 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 23 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 08fb9ab..0488fc4 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -255,8 +255,15 @@ type ParseMemberExpression< type ParseCallExpression< Node extends BaseNode, TokenList extends Array>, -> = TokenList[0] extends GenericToken<'(', TokenData> - ? ParseCallExpressionArguments, E, ')'> extends infer G +> = TokenList[0] extends GenericToken< + '(', + TokenData +> + ? ParseCallExpressionArguments< + Tail, + ParenLineNumber, + ')' + > extends infer G ? G extends Array ? Node extends BaseNode> ? G[2] extends Token> @@ -268,31 +275,47 @@ type ParseCallExpression< : null; type ParseCallExpressionArguments< - T extends Array>, - E extends number, - J extends string, - N extends boolean = false, - R extends Array> = [], -> = T[0] extends GenericToken - ? [R, Tail, T[0]] - : T extends [] - ? SyntaxError<`'${J}' expected.`, E> - : N extends true - ? T[0] extends GenericToken<',', any> - ? ParseCallExpressionArgumentsHelper, E, J, R> - : T[0] extends Token> - ? SyntaxError<"',' expected.", L> + TokenList extends Array>, + ParenLineNumber extends number, + ClosingString extends string, + NeedComma extends boolean = false, + Result extends Array> = [], +> = TokenList[0] extends GenericToken + ? [Result, Tail, TokenList[0]] + : TokenList extends [] + ? SyntaxError<`'${ClosingString}' expected.`, ParenLineNumber> + : NeedComma extends true + ? TokenList[0] extends GenericToken<',', any> + ? ParseCallExpressionArgumentsHelper< + Tail, + ParenLineNumber, + ClosingString, + Result + > + : TokenList[0] extends Token> + ? SyntaxError<"',' expected.", LineNumber> : never - : ParseCallExpressionArgumentsHelper; + : ParseCallExpressionArgumentsHelper< + TokenList, + ParenLineNumber, + ClosingString, + Result + >; type ParseCallExpressionArgumentsHelper< - T extends Array>, - E extends number, - J extends string, - R extends Array> = [], -> = ParseExpression extends infer G + TokenList extends Array>, + ParenLineNumber extends number, + ClosingString extends string, + Result extends Array> = [], +> = ParseExpression extends infer G ? G extends Array - ? ParseCallExpressionArguments> + ? ParseCallExpressionArguments< + G[1], + ParenLineNumber, + ClosingString, + true, + Push + > : G : never; From b0d1c87936966de616bc2771b107791de37367fa Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 15 Jul 2022 23:56:57 +0300 Subject: [PATCH 221/286] wip --- src/parser.ts | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 0488fc4..2fc30f8 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -91,25 +91,31 @@ type ParseIdentifier< : null; type ParseVariableDeclarationHelper< - R extends Array>, - N extends Identifier, - L extends number, - S extends number, - K extends number, -> = ParseExpression> extends infer G + TokenList extends Array>, + Id extends Identifier, + KindLineNumber extends number, + IdentifierLineNumber extends number, + EqualsLineNumber extends number, +> = ParseExpression> extends infer G ? G extends Array - ? G[0] extends BaseNode> + ? G[0] extends BaseNode> ? [ VariableDeclaration< - [VariableDeclarator>], + [ + VariableDeclarator< + Id, + G[0], + NodeData + >, + ], 'const', - NodeData + NodeData >, G[1], ] : never : G extends null - ? SyntaxError<'Expression expected.', K> + ? SyntaxError<'Expression expected.', EqualsLineNumber> : G : never; From 754b71ebd030950306d21a2dab2f2970aa63eb06 Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 16 Jul 2022 13:46:42 +0300 Subject: [PATCH 222/286] wip --- src/parser.ts | 2 +- src/utils/arrayUtils.ts | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 2fc30f8..a1e0a26 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -35,7 +35,7 @@ import type { Token, TokenData, } from './tokens'; -import type { Head, Push, Tail, TailBy } from './utils/arrayUtils'; +import type { Push, Tail, TailBy } from './utils/arrayUtils'; type ExtractTokenData< T extends Token, diff --git a/src/utils/arrayUtils.ts b/src/utils/arrayUtils.ts index 95fd425..aafc30e 100644 --- a/src/utils/arrayUtils.ts +++ b/src/utils/arrayUtils.ts @@ -14,10 +14,6 @@ export type Reverse< R extends Array = [], > = T extends [] ? R : Reverse, Unshift>; -export type Head> = T extends [any, ...Array] - ? T['0'] - : never; - export type Concat, T2 extends Array> = [ ...T1, ...T2, From 48509b24551cf0760ea0bce4bc12ff5f38428a1f Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 16 Jul 2022 13:59:19 +0300 Subject: [PATCH 223/286] wip --- src/parser.ts | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index a1e0a26..ee81c7d 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -37,15 +37,6 @@ import type { } from './tokens'; import type { Push, Tail, TailBy } from './utils/arrayUtils'; -type ExtractTokenData< - T extends Token, - R extends Token = T, -> = T extends Token> - ? R extends Token> - ? NodeData - : never - : never; - type ParseIdentifier< TokenList extends Array>, CanBeAnnotated extends boolean, @@ -350,21 +341,25 @@ type CheckExpression< : never : never; -type ParseExpression< - TokenList extends Array>, - Data extends NodeData = ExtractTokenData, -> = ParseExpressionHelper> extends infer P - ? P extends Array - ? CheckExpression - : P extends Error - ? P - : null +type ParseExpression>> = + ParseExpressionHelper> extends infer P + ? P extends Array + ? CheckExpression + : P extends Error + ? P + : null + : never; + +type TokenToNodeData> = InputToken extends Token< + TokenData +> + ? NodeData : never; type ParseExpressionHelper< TokenList extends Array>, - Data extends NodeData = ExtractTokenData, TokenTail extends Array> = Tail, + Data extends NodeData = TokenToNodeData, > = TokenList[0] extends SymbolToken<'true', any> ? [BooleanLiteral, TokenTail] : TokenList[0] extends SymbolToken<'false', any> From 3012d8e9c57f325e05ab2b9f225197eb0b3b9557 Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 16 Jul 2022 14:37:58 +0300 Subject: [PATCH 224/286] wip --- src/errors.ts | 30 ++++++++++++++++-------------- src/formatter.ts | 11 +++++++++++ src/index.ts | 2 +- 3 files changed, 28 insertions(+), 15 deletions(-) create mode 100644 src/formatter.ts diff --git a/src/errors.ts b/src/errors.ts index ee1d554..e44e787 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -1,17 +1,19 @@ -export type Error = { - type: T; - message: M; - lineNumber: L; +export type Error< + Type extends string, + Message extends string, + LineNumber extends number, +> = { + type: Type; + message: Message; + lineNumber: LineNumber; }; -export type SyntaxError = Error< - 'SyntaxError', - M, - L ->; +export type SyntaxError< + Message extends string, + LineNumber extends number, +> = Error<'SyntaxError', Message, LineNumber>; -export type TypeError = Error< - 'TypeError', - M, - L ->; +export type TypeError< + Message extends string, + LineNumber extends number, +> = Error<'TypeError', Message, LineNumber>; diff --git a/src/formatter.ts b/src/formatter.ts new file mode 100644 index 0000000..27f9a62 --- /dev/null +++ b/src/formatter.ts @@ -0,0 +1,11 @@ +import type { TypeError } from './errors'; +import type { Push, Tail } from './utils/arrayUtils'; + +export type Format< + Errors extends Array>, + Result extends Array = [], +> = Errors extends [] + ? Result + : Errors[0] extends TypeError + ? Format, Push> + : never; diff --git a/src/index.ts b/src/index.ts index efc1a10..0e6cd29 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,4 +14,4 @@ const b: string = a; `>; type R = Parse; -type C = Check[3]; +type C = Check; From ac7cc137f65a045c3693c3881b3b88946191243d Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 16 Jul 2022 14:48:40 +0300 Subject: [PATCH 225/286] wip --- src/serializer.ts | 116 ++++++++++++++++++++------------------- src/test/checker.test.ts | 38 +++++++++++++ src/types.ts | 28 +++++----- 3 files changed, 111 insertions(+), 71 deletions(-) diff --git a/src/serializer.ts b/src/serializer.ts index 29bb4fd..df46570 100644 --- a/src/serializer.ts +++ b/src/serializer.ts @@ -17,8 +17,8 @@ import type { } from './types'; import type { Tail } from './utils/arrayUtils'; -export type Serialize = - MapLiteralToType extends infer H +export type Serialize = + MapLiteralToType extends infer H ? H extends StringType ? 'string' : H extends BooleanType @@ -33,39 +33,39 @@ export type Serialize = ? 'any' : H extends UnknownType ? 'unknown' - : H extends ArrayType - ? SerializeArray - : H extends UnionType - ? SerializeUnion - : H extends ObjectType - ? SerializeObject - : H extends FunctionType - ? SerializeFunction + : H extends ArrayType + ? SerializeArray + : H extends UnionType + ? SerializeUnion + : H extends ObjectType + ? SerializeObject + : H extends FunctionType + ? SerializeFunction : never : never; type SerializeFunction< - P extends Array<[string, StaticType]>, - R extends StaticType, -> = SerializeFunctionParams

extends infer H + Params extends Array<[string, StaticType]>, + Return extends StaticType, +> = SerializeFunctionParams extends infer H ? H extends string - ? `(${H}) => ${Serialize}` + ? `(${H}) => ${Serialize}` : never : never; type SerializeFunctionParams< - P extends Array<[string, StaticType]>, - R extends string = '', -> = P extends [] - ? R - : P[0] extends [infer K, infer V] - ? V extends StaticType - ? K extends string + Params extends Array<[string, StaticType]>, + Result extends string = '', +> = Params extends [] + ? Result + : Params[0] extends [infer Key, infer Value] + ? Value extends StaticType + ? Key extends string ? SerializeFunctionParams< - Tail

, - `${R}${K}: ${Serialize}` extends infer U + Tail, + `${Result}${Key}: ${Serialize}` extends infer U ? U extends string - ? P['length'] extends 1 + ? Params['length'] extends 1 ? `${U}` : `${U}, ` : never @@ -75,57 +75,59 @@ type SerializeFunctionParams< : never : never; -type MapLiteralToType = T extends NumberLiteralType - ? NumberType - : T extends StringLiteralType - ? StringType - : T extends BooleanLiteralType - ? BooleanType - : T; +type MapLiteralToType = + Type extends NumberLiteralType + ? NumberType + : Type extends StringLiteralType + ? StringType + : Type extends BooleanLiteralType + ? BooleanType + : Type; -type ShouldUseParens = I extends UnionType +type ShouldUseParens = Type extends UnionType ? true - : I extends FunctionType + : Type extends FunctionType ? true : false; -type SerializeArray = Serialize extends infer H - ? H extends string - ? ShouldUseParens extends true - ? `(${H})[]` - : `${H}[]` - : never - : never; +type SerializeArray = + Serialize extends infer H + ? H extends string + ? ShouldUseParens extends true + ? `(${H})[]` + : `${H}[]` + : never + : never; type SerializeUnion< - U extends Array, - R extends string = '', -> = U extends [] - ? R - : U[0] extends StaticType - ? Serialize extends infer H + UnionTypes extends Array, + Result extends string = '', +> = UnionTypes extends [] + ? Result + : UnionTypes[0] extends StaticType + ? Serialize extends infer H ? H extends string ? SerializeUnion< - Tail, - U['length'] extends 1 ? `${R}${H}` : `${R}${H} | ` + Tail, + UnionTypes['length'] extends 1 ? `${Result}${H}` : `${Result}${H} | ` > : never : never : never; type SerializeObject< - U extends Array<[string, StaticType]>, - R extends string = '', -> = U extends [] - ? R extends '' + Properties extends Array<[string, StaticType]>, + Result extends string = '', +> = Properties extends [] + ? Result extends '' ? '{}' - : `{ ${R} }` - : U[0] extends [string, StaticType] - ? `${U[0][0]}: ${Serialize}` extends infer H + : `{ ${Result} }` + : Properties[0] extends [infer Key, infer Value] + ? `${Properties[0][0]}: ${Serialize}` extends infer H ? H extends string ? SerializeObject< - Tail, - U['length'] extends 1 ? `${R}${H};` : `${R}${H}; ` + Tail, + Properties['length'] extends 1 ? `${Result}${H};` : `${Result}${H}; ` > : never : never diff --git a/src/test/checker.test.ts b/src/test/checker.test.ts index 0a725b3..d3526a3 100644 --- a/src/test/checker.test.ts +++ b/src/test/checker.test.ts @@ -647,3 +647,41 @@ const b: string = a; lineNumber: 9, }, ]); + +expectType< + TypeCheck<` + +function foo(a: number, b: boolean) { + return 5 +} + +const b: string = foo; + +`> +>([ + { + type: 'TypeError', + message: + "Type '(a: number, b: boolean) => number' is not assignable to type 'string'.", + lineNumber: 7, + }, +]); + +expectType< + TypeCheck<` + +function foo(a: number, b: boolean) { + return 5 +} + +const b: string = { hello: true, world: foo, hey: [1, {}] }; + +`> +>([ + { + type: 'TypeError', + message: + "Type '{ hello: boolean; world: (a: number, b: boolean) => number; hey: (number | {})[]; }' is not assignable to type 'string'.", + lineNumber: 7, + }, +]); diff --git a/src/types.ts b/src/types.ts index 8246567..4cdc635 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2,27 +2,27 @@ export type StringType = { type: 'StringType'; }; -export type StringLiteralType = { +export type StringLiteralType = { type: 'StringLiteralType'; - value: V; + value: Value; }; export type NumberType = { type: 'NumberType'; }; -export type NumberLiteralType = { +export type NumberLiteralType = { type: 'NumberLiteralType'; - value: V; + value: Value; }; export type BooleanType = { type: 'BooleanType'; }; -export type BooleanLiteralType = { +export type BooleanLiteralType = { type: 'BooleanLiteralType'; - value: V; + value: Value; }; export type NullType = { @@ -42,12 +42,12 @@ export type AnyType = { }; export type FunctionType< - P extends Array<[string, StaticType]>, - R extends StaticType, + Params extends Array<[string, StaticType]>, + Return extends StaticType, > = { type: 'FunctionType'; - params: P; - return: R; + params: Params; + return: Return; }; export type ObjectType> = { @@ -55,14 +55,14 @@ export type ObjectType> = { properties: Properties; }; -export type ArrayType = { +export type ArrayType = { type: 'ArrayType'; - elements: V; + elements: ElementsType; }; -export type UnionType> = { +export type UnionType> = { type: 'UnionType'; - types: V; + types: Types; }; export type CallArgumentsType> = { From 08b39036666036dcd7c257e7a50acd7e5b273765 Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 16 Jul 2022 14:52:58 +0300 Subject: [PATCH 226/286] wip --- src/serializer.ts | 72 ++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/src/serializer.ts b/src/serializer.ts index df46570..b92c5bb 100644 --- a/src/serializer.ts +++ b/src/serializer.ts @@ -18,28 +18,28 @@ import type { import type { Tail } from './utils/arrayUtils'; export type Serialize = - MapLiteralToType extends infer H - ? H extends StringType + MapLiteralToType extends infer MappedType + ? MappedType extends StringType ? 'string' - : H extends BooleanType + : MappedType extends BooleanType ? 'boolean' - : H extends NumberType + : MappedType extends NumberType ? 'number' - : H extends NullType + : MappedType extends NullType ? 'null' - : H extends VoidType + : MappedType extends VoidType ? 'void' - : H extends AnyType + : MappedType extends AnyType ? 'any' - : H extends UnknownType + : MappedType extends UnknownType ? 'unknown' - : H extends ArrayType + : MappedType extends ArrayType ? SerializeArray - : H extends UnionType + : MappedType extends UnionType ? SerializeUnion - : H extends ObjectType + : MappedType extends ObjectType ? SerializeObject - : H extends FunctionType + : MappedType extends FunctionType ? SerializeFunction : never : never; @@ -47,9 +47,9 @@ export type Serialize = type SerializeFunction< Params extends Array<[string, StaticType]>, Return extends StaticType, -> = SerializeFunctionParams extends infer H - ? H extends string - ? `(${H}) => ${Serialize}` +> = SerializeFunctionParams extends infer SerializedParams + ? SerializedParams extends string + ? `(${SerializedParams}) => ${Serialize}` : never : never; @@ -63,11 +63,11 @@ type SerializeFunctionParams< ? Key extends string ? SerializeFunctionParams< Tail, - `${Result}${Key}: ${Serialize}` extends infer U - ? U extends string + `${Result}${Key}: ${Serialize}` extends infer SerializedSignature + ? SerializedSignature extends string ? Params['length'] extends 1 - ? `${U}` - : `${U}, ` + ? `${SerializedSignature}` + : `${SerializedSignature}, ` : never : never > @@ -91,11 +91,11 @@ type ShouldUseParens = Type extends UnionType : false; type SerializeArray = - Serialize extends infer H - ? H extends string + Serialize extends infer SerializedElements + ? SerializedElements extends string ? ShouldUseParens extends true - ? `(${H})[]` - : `${H}[]` + ? `(${SerializedElements})[]` + : `${SerializedElements}[]` : never : never; @@ -105,11 +105,13 @@ type SerializeUnion< > = UnionTypes extends [] ? Result : UnionTypes[0] extends StaticType - ? Serialize extends infer H - ? H extends string + ? Serialize extends infer SerializedType + ? SerializedType extends string ? SerializeUnion< Tail, - UnionTypes['length'] extends 1 ? `${Result}${H}` : `${Result}${H} | ` + UnionTypes['length'] extends 1 + ? `${Result}${SerializedType}` + : `${Result}${SerializedType} | ` > : never : never @@ -123,12 +125,18 @@ type SerializeObject< ? '{}' : `{ ${Result} }` : Properties[0] extends [infer Key, infer Value] - ? `${Properties[0][0]}: ${Serialize}` extends infer H - ? H extends string - ? SerializeObject< - Tail, - Properties['length'] extends 1 ? `${Result}${H};` : `${Result}${H}; ` - > + ? Value extends StaticType + ? Key extends string + ? `${Key}: ${Serialize}` extends infer SerializedProperty + ? SerializedProperty extends string + ? SerializeObject< + Tail, + Properties['length'] extends 1 + ? `${Result}${SerializedProperty};` + : `${Result}${SerializedProperty}; ` + > + : never + : never : never : never : never; From 2beb98d204b396943b121ebb5a13c05f9981921a Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 16 Jul 2022 16:23:29 +0300 Subject: [PATCH 227/286] wip --- src/parser.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index ee81c7d..084e021 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -399,20 +399,27 @@ type ParseObjectItem< TokenList extends Array>, InitialLineNumber extends number, Result extends Array> = [], -> = TokenList[0] extends SymbolToken> +> = TokenList[0] extends SymbolToken< + infer Name, + TokenData +> ? TokenList[1] extends GenericToken<':', any> ? ParseExpression> extends infer G ? G extends Array - ? G[0] extends BaseNode> + ? G[0] extends BaseNode> ? ParseObject< G[1], InitialLineNumber, Push< Result, ObjectProperty< - Identifier>, + Identifier< + Name, + null, + NodeData + >, G[0], - NodeData + NodeData > >, true From 1303ecfa508d34837725fa4127390744a7b77e6c Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 16 Jul 2022 16:25:17 +0300 Subject: [PATCH 228/286] wip --- src/errors.ts | 5 +++ src/parser.ts | 86 ++++++++++++++++++++--------------------- src/test/parser.test.ts | 80 +++++++++++++++++++------------------- 3 files changed, 88 insertions(+), 83 deletions(-) diff --git a/src/errors.ts b/src/errors.ts index e44e787..4ec300c 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -13,6 +13,11 @@ export type SyntaxError< LineNumber extends number, > = Error<'SyntaxError', Message, LineNumber>; +export type ParsingError< + Message extends string, + LineNumber extends number, +> = Error<'ParsingError', Message, LineNumber>; + export type TypeError< Message extends string, LineNumber extends number, diff --git a/src/parser.ts b/src/parser.ts index 084e021..694bb44 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -26,7 +26,7 @@ import type { NodeData, BaseNode, } from './ast'; -import type { Error, SyntaxError } from './errors'; +import type { ParsingError } from './errors'; import type { GenericToken, NumberToken, @@ -59,9 +59,9 @@ type ParseIdentifier< >, J[1], ] - : J extends Error + : J extends ParsingError ? J - : SyntaxError<'Type expected.', ColonLineNumber> + : ParsingError<'Type expected.', ColonLineNumber> : never : [ Identifier< @@ -106,7 +106,7 @@ type ParseVariableDeclarationHelper< ] : never : G extends null - ? SyntaxError<'Expression expected.', EqualsLineNumber> + ? ParsingError<'Expression expected.', EqualsLineNumber> : G : never; @@ -192,13 +192,13 @@ type ParseVariableDeclaration>> = IdentifierLineNumber, EqualsLineNumber > - : SyntaxError< + : ParsingError< "'const' declarations must be initialized.", IdentifierLineNumber > : never : N extends null - ? SyntaxError< + ? ParsingError< 'Variable declaration list cannot be empty.', KindLineNumber > @@ -228,7 +228,7 @@ type ParseMemberExpression< >, TailBy, ] - : SyntaxError<'Identifier expected.', DotLineNumber> + : ParsingError<'Identifier expected.', DotLineNumber> : TokenList[0] extends GenericToken< '[', TokenData @@ -239,11 +239,11 @@ type ParseMemberExpression< ? W extends Array> ? W[0] extends GenericToken<']', any> ? [MemberExpression>, Tail] - : SyntaxError<"']' expected.", S> + : ParsingError<"']' expected.", S> : never : never : G extends null - ? SyntaxError<'Expression expected.', BracketLineNumber> + ? ParsingError<'Expression expected.', BracketLineNumber> : G : never : null @@ -280,7 +280,7 @@ type ParseCallExpressionArguments< > = TokenList[0] extends GenericToken ? [Result, Tail, TokenList[0]] : TokenList extends [] - ? SyntaxError<`'${ClosingString}' expected.`, ParenLineNumber> + ? ParsingError<`'${ClosingString}' expected.`, ParenLineNumber> : NeedComma extends true ? TokenList[0] extends GenericToken<',', any> ? ParseCallExpressionArgumentsHelper< @@ -290,7 +290,7 @@ type ParseCallExpressionArguments< Result > : TokenList[0] extends Token> - ? SyntaxError<"',' expected.", LineNumber> + ? ParsingError<"',' expected.", LineNumber> : never : ParseCallExpressionArgumentsHelper< TokenList, @@ -326,7 +326,7 @@ type CheckExpression< ? CheckExpression : never : never - : G extends Error + : G extends ParsingError ? G : ParseCallExpression extends infer G ? G extends [infer O, infer T] @@ -335,7 +335,7 @@ type CheckExpression< ? CheckExpression : never : never - : G extends Error + : G extends ParsingError ? G : [Node, TokenList] : never @@ -345,7 +345,7 @@ type ParseExpression>> = ParseExpressionHelper> extends infer P ? P extends Array ? CheckExpression - : P extends Error + : P extends ParsingError ? P : null : never; @@ -386,12 +386,12 @@ type ParseObject< > = TokenList[0] extends GenericToken<'}', TokenData> ? [ObjectExpression>, Tail] : TokenList extends [] - ? SyntaxError<"'}' expected.", InitialLineNumber> + ? ParsingError<"'}' expected.", InitialLineNumber> : NeedComma extends true ? TokenList[0] extends GenericToken<',', any> ? ParseObjectItem, InitialLineNumber, Result> : TokenList[0] extends Token> - ? SyntaxError<"',' expected.", L> + ? ParsingError<"',' expected.", L> : never : ParseObjectItem; @@ -425,12 +425,12 @@ type ParseObjectItem< true > : never - : G extends Error + : G extends ParsingError ? G - : SyntaxError<'Expression expected.', InitialLineNumber> + : ParsingError<'Expression expected.', InitialLineNumber> : never - : SyntaxError<"'}' expected.", InitialLineNumber> - : SyntaxError<"'}' expected.", InitialLineNumber>; + : ParsingError<"'}' expected.", InitialLineNumber> + : ParsingError<"'}' expected.", InitialLineNumber>; type ParseArrayExpression< TokenList extends Array>, @@ -498,8 +498,8 @@ type ParseFunctionDeclaration>> = : never : G : never - : SyntaxError<"'(' expected.", FunctionNameLineNumber> - : SyntaxError<'Identifier expected.', FunctionLineNumber> + : ParsingError<"'(' expected.", FunctionNameLineNumber> + : ParsingError<'Identifier expected.', FunctionLineNumber> : null; type ParseFunctionParams< @@ -516,14 +516,14 @@ type ParseFunctionParams< TokenData > ? [Result, TailBy, CurlyLineNumber] - : SyntaxError<"'{' expected.", ParenLineNumber> + : ParsingError<"'{' expected.", ParenLineNumber> : TokenList extends [] - ? SyntaxError<"')' expected.", InitialLineNumber> + ? ParsingError<"')' expected.", InitialLineNumber> : NeedSemicolon extends true ? TokenList[0] extends GenericToken<',', any> ? ParseFunctionParamsHelper, InitialLineNumber, Result> : Result[0] extends BaseNode> - ? SyntaxError<"',' expected.", LineNumber> + ? ParsingError<"',' expected.", LineNumber> : never : ParseFunctionParamsHelper; @@ -534,9 +534,9 @@ type ParseFunctionParamsHelper< > = ParseIdentifier extends infer G ? G extends Array ? ParseFunctionParams, true> - : G extends Error + : G extends ParsingError ? G - : SyntaxError<'Identifier expected.', LineNumber> + : ParsingError<'Identifier expected.', LineNumber> : never; type ParseBlockStatement< @@ -547,8 +547,8 @@ type ParseBlockStatement< NeedSemicolon extends boolean = false, > = TokenList extends [] ? Result[0] extends BaseNode> - ? SyntaxError<"'}' expected.", LineNumber> - : SyntaxError<"'}' expected.", InitialLineNumber> + ? ParsingError<"'}' expected.", LineNumber> + : ParsingError<"'}' expected.", InitialLineNumber> : TokenList[0] extends GenericToken<'}', TokenData> ? [ BlockStatement>, @@ -574,7 +574,7 @@ type ParseBlockStatement< > ? PrecedingLinebreak extends true ? ParseBlockStatementHelper - : SyntaxError<"';' expected.", LineNumber> + : ParsingError<"';' expected.", LineNumber> : never; type ParseTopLevel< @@ -592,7 +592,7 @@ type ParseTopLevel< > ? PrecedingLinebreak extends true ? ParseTopLevelHelper - : SyntaxError<"';' expected.", LineNumber> + : ParsingError<"';' expected.", LineNumber> : never; type ParseBlockStatementHelper< @@ -633,12 +633,12 @@ type ParseIfStatement< ? G extends Array ? G[0] extends BaseNode> ? ParseIfStatementHelper - : G extends Error + : G extends ParsingError ? G : never - : SyntaxError<'Expression expected.', ParenLineNumber> + : ParsingError<'Expression expected.', ParenLineNumber> : never - : SyntaxError<"'(' expected.", IfLineNumber> + : ParsingError<"'(' expected.", IfLineNumber> : null; type ParseReturnStatementHelper< @@ -673,7 +673,7 @@ type ParseReturnStatement< Tail, ] : [ReturnStatement>, []] - : SyntaxError< + : ParsingError< "A 'return' statement can only be used within a function body.", LineNumber > @@ -708,8 +708,8 @@ type ParseIfStatementHelper< : never : B : never - : SyntaxError<"'{' expected.", ClosingParenLineNumber> - : SyntaxError<"')' expected.", E> + : ParsingError<"'{' expected.", ClosingParenLineNumber> + : ParsingError<"')' expected.", E> : never; type ParseStatementHelper< @@ -718,29 +718,29 @@ type ParseStatementHelper< > = ParseFunctionDeclaration extends infer P ? P extends Array ? [...P, false] - : P extends Error + : P extends ParsingError ? P : ParseVariableDeclaration extends infer P ? P extends Array ? [...P, true] - : P extends Error + : P extends ParsingError ? P : ParseIfStatement extends infer P ? P extends Array ? [...P, false] - : P extends Error + : P extends ParsingError ? P : ParseReturnStatement extends infer P ? P extends Array ? [...P, true] - : P extends Error + : P extends ParsingError ? P : ParseExpressionStatement extends infer P ? P extends Array ? [...P, true] - : P extends Error + : P extends ParsingError ? P - : SyntaxError<'Declaration or statement expected.', 1> + : ParsingError<'Declaration or statement expected.', 1> : never : never : never diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index 360680a..d00010a 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -112,13 +112,13 @@ expectType>([ ]); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "';' expected.", lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "';' expected.", lineNumber: 1, }); @@ -316,49 +316,49 @@ expectType>([ ]); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: 'Variable declaration list cannot be empty.', lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "'const' declarations must be initialized.", lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: 'Expression expected.', lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: 'Expression expected.', lineNumber: 2, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: 'Type expected.', lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: 'Identifier expected.', lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: 'Identifier expected.', lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: 'Identifier expected.', lineNumber: 2, }); @@ -506,13 +506,13 @@ expectType>([ ]); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: 'Identifier expected.', lineNumber: 2, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: 'Identifier expected.', lineNumber: 2, }); @@ -861,36 +861,36 @@ expectType>([ ]); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "')' expected.", lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "',' expected.", lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "',' expected.", lineNumber: 2, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "']' expected.", lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "',' expected.", lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "',' expected.", lineNumber: 2, }); @@ -1075,25 +1075,25 @@ expectType>([ ]); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "'}' expected.", lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "'}' expected.", lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "'}' expected.", lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "'}' expected.", lineNumber: 1, }); @@ -1711,55 +1711,55 @@ expectType>([ ]); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: 'Identifier expected.', lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "'(' expected.", lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "')' expected.", lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "'{' expected.", lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "'{' expected.", lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "'}' expected.", lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: 'Identifier expected.', lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "',' expected.", lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: 'Declaration or statement expected.', lineNumber: 1, }); @@ -2113,55 +2113,55 @@ expectType>([ ]); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "'(' expected.", lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: 'Expression expected.', lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "')' expected.", lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "'{' expected.", lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "'}' expected.", lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: 'Expression expected.', lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "A 'return' statement can only be used within a function body.", lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "A 'return' statement can only be used within a function body.", lineNumber: 1, }); expectType>({ - type: 'SyntaxError', + type: 'ParsingError', message: "A 'return' statement can only be used within a function body.", lineNumber: 1, }); From 62c66657c069c29cd7ff481d98c7d2d31b3a8a51 Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 16 Jul 2022 17:16:57 +0300 Subject: [PATCH 229/286] wip --- src/checker.ts | 56 +++++++++++++++++++++++++++++++++++++++++--------- src/index.ts | 8 ++------ 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 35c968d..03b89f6 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -243,28 +243,64 @@ type InferFunctionDeclaration< : never : never; -type MatchType = A extends AnyType +type MatchType< + TypeA extends StaticType, + TypeB extends StaticType, +> = TypeA extends AnyType ? true - : B extends AnyType + : TypeB extends AnyType ? true - : A extends B - ? B extends A + : TypeA extends TypeB + ? TypeB extends TypeA ? true : false - : A extends StringType - ? B extends StringLiteralType + : TypeA extends UnionType + ? TypeB extends UnionType + ? UnionMatchUnion + : TypeMatchUnion + : TypeB extends UnionType + ? UnionMatchType + : TypeA extends StringType + ? TypeB extends StringLiteralType ? true : false - : A extends BooleanType - ? B extends BooleanLiteralType + : TypeA extends BooleanType + ? TypeB extends BooleanLiteralType ? true : false - : A extends NumberType - ? B extends NumberLiteralType + : TypeA extends NumberType + ? TypeB extends NumberLiteralType ? true : false : false; +type UnionMatchUnion< + UnionTypesA extends Array, + UnionTypesB extends Array, +> = UnionTypesB extends [] + ? true + : TypeMatchUnion extends true + ? UnionMatchUnion> + : false; + +type TypeMatchUnion< + UnionTypes extends Array, + Type extends StaticType, +> = UnionTypes extends [] + ? false + : MatchType extends true + ? true + : TypeMatchUnion, Type>; + +type UnionMatchType< + Type extends StaticType, + UnionTypes extends Array, +> = UnionTypes extends [] + ? true + : MatchType extends true + ? UnionMatchType> + : false; + type MatchTypeArrays< ParamsType extends Array<[string, StaticType]>, ArgumentsType extends Array, diff --git a/src/index.ts b/src/index.ts index 0e6cd29..ab21df9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,13 +4,9 @@ import type { Check } from './checker'; type T = Tokenize<` -function foo(a: number) { - return 5 -} +const a = [1, 'f', false]; -const a = foo('a', bar, bazz) - -const b: string = a; +const b: number = a[0]; `>; type R = Parse; From f336322c2afb49bbcf752d229de4960ae44e1a45 Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 16 Jul 2022 22:04:21 +0300 Subject: [PATCH 230/286] wip --- src/checker.ts | 66 +++++++++++++++++++++++++++++++++++++++++--------- src/index.ts | 10 ++++++-- 2 files changed, 63 insertions(+), 13 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 03b89f6..d07b664 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -23,6 +23,7 @@ import type { TypeAnnotation, VariableDeclaration, VariableDeclarator, + IfStatement, } from './ast'; import type { TypeError } from './errors'; import type { Serialize } from './serializer'; @@ -62,13 +63,39 @@ export type Check>> = InferBlockStatement< ? Errors : never; +type InferBlockStatementHelper< + TypeList extends Array, + Result extends StaticType, +> = TypeList extends [] + ? Result + : InferBlockStatementHelper, MergeTypes>; + +type MergeTypes = MatchType< + TypeA, + TypeB +> extends true + ? TypeA + : MatchType extends true + ? TypeB + : TypeA extends UnionType + ? TypeB extends UnionType + ? UnionType<[...UnionTypesA, ...UnionTypesB]> + : UnionType<[...UnionTypesA, TypeB]> + : TypeB extends UnionType + ? UnionType<[...UnionTypesB, TypeA]> + : UnionType<[TypeA, TypeB]>; + type InferBlockStatement< NodeList extends Array>, State extends StateType, - Result extends StaticType = VoidType, + Result extends Array = [], Errors extends Array> = [], > = NodeList extends [] - ? TypeResult + ? InferBlockStatementHelper extends infer ReturnType + ? ReturnType extends StaticType + ? TypeResult + : never + : never : NodeList[0] extends ExpressionStatement ? InferExpression extends TypeResult< any, @@ -131,18 +158,35 @@ type InferBlockStatement< : never : NodeList[0] extends ReturnStatement ? InferReturnStatement extends TypeResult< - infer ExpressionValue, - infer ExpressionState, - infer ExpressionErrors + infer ReturnValue, + infer ReturnState, + infer ReturnErrors > - ? InferBlockStatement< - [], - ExpressionState, - ExpressionValue, - Concat + ? InferBlockStatementHelper extends infer ReturnType + ? ReturnType extends StaticType + ? TypeResult> + : never + : never + : never + : NodeList[0] extends IfStatement< + any, + BlockStatement, + any + > + ? InferBlockStatement extends TypeResult< + infer IfStatementValue, + any, + infer IfStatementErrors + > + ? // ? TypeResult + InferBlockStatement< + Tail, + State, + Push, + Concat > : never - : InferBlockStatement, State, VoidType, Errors>; + : InferBlockStatement, State, Result, Errors>; type InferReturnStatement< ReturnExpression extends BaseNode | null, diff --git a/src/index.ts b/src/index.ts index ab21df9..e83e519 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,9 +4,15 @@ import type { Check } from './checker'; type T = Tokenize<` -const a = [1, 'f', false]; +function foo() { + if (a) { + return 'hello'; + } -const b: number = a[0]; + return 'world'; +} + +const a: number = foo; `>; type R = Parse; From 8b5cbb485a92949f05929cfc5e6d4934c367877d Mon Sep 17 00:00:00 2001 From: ronami Date: Sat, 16 Jul 2022 23:52:20 +0300 Subject: [PATCH 231/286] wip --- src/checker.ts | 7 ++++--- src/index.ts | 1 - 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index d07b664..0603020 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -178,11 +178,12 @@ type InferBlockStatement< any, infer IfStatementErrors > - ? // ? TypeResult - InferBlockStatement< + ? InferBlockStatement< Tail, State, - Push, + IfStatementValue extends VoidType + ? Result + : Push, Concat > : never diff --git a/src/index.ts b/src/index.ts index e83e519..9aa76c0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,7 +6,6 @@ type T = Tokenize<` function foo() { if (a) { - return 'hello'; } return 'world'; From bd84815a343ea950a4ff13baa4421e910b39d074 Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 17 Jul 2022 00:19:26 +0300 Subject: [PATCH 232/286] wip --- README.md | 2 +- src/errors.ts | 36 +++++++++++++++++------------------- src/example.ts | 11 +++++++++++ src/formatter.ts | 8 ++++---- src/index.ts | 36 ++++++++++++++++++++++-------------- 5 files changed, 55 insertions(+), 38 deletions(-) create mode 100644 src/example.ts diff --git a/README.md b/README.md index 2ba1127..300468d 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ foo('not a number'); // Errors is now equal to the following type: type Expected = [ - "Line 7: Argument of type 'string' is not assignable to parameter of type 'number'." + "7: Argument of type 'string' is not assignable to parameter of type 'number'." ]; ``` diff --git a/src/errors.ts b/src/errors.ts index 4ec300c..1573463 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -1,24 +1,22 @@ -export type Error< - Type extends string, - Message extends string, - LineNumber extends number, -> = { - type: Type; +export type Error = + | SyntaxError + | ParsingError + | TypeError; + +export type SyntaxError = { + type: 'SyntaxError'; message: Message; lineNumber: LineNumber; }; -export type SyntaxError< - Message extends string, - LineNumber extends number, -> = Error<'SyntaxError', Message, LineNumber>; - -export type ParsingError< - Message extends string, - LineNumber extends number, -> = Error<'ParsingError', Message, LineNumber>; +export type ParsingError = { + type: 'ParsingError'; + message: Message; + lineNumber: LineNumber; +}; -export type TypeError< - Message extends string, - LineNumber extends number, -> = Error<'TypeError', Message, LineNumber>; +export type TypeError = { + type: 'TypeError'; + message: Message; + lineNumber: LineNumber; +}; diff --git a/src/example.ts b/src/example.ts new file mode 100644 index 0000000..5fe5884 --- /dev/null +++ b/src/example.ts @@ -0,0 +1,11 @@ +import type { TypeCheck } from '.'; + +type Errors = TypeCheck<` + +function foo(name: number) { + return name; +} + +foo('not a number'); + +`>; diff --git a/src/formatter.ts b/src/formatter.ts index 27f9a62..7642be3 100644 --- a/src/formatter.ts +++ b/src/formatter.ts @@ -1,11 +1,11 @@ -import type { TypeError } from './errors'; +import type { Error } from './errors'; import type { Push, Tail } from './utils/arrayUtils'; export type Format< - Errors extends Array>, + Errors extends Array>, Result extends Array = [], > = Errors extends [] ? Result - : Errors[0] extends TypeError - ? Format, Push> + : Errors[0] extends Error + ? Format, Push> : never; diff --git a/src/index.ts b/src/index.ts index 9aa76c0..f2bd1ce 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,18 +1,26 @@ import type { Tokenize } from './tokenizer'; import type { Parse } from './parser'; import type { Check } from './checker'; +import type { Format } from './formatter'; +import type { Error } from './errors'; +import type { Token } from './tokens'; +import type { BaseNode } from './ast'; -type T = Tokenize<` - -function foo() { - if (a) { - } - - return 'world'; -} - -const a: number = foo; - -`>; -type R = Parse; -type C = Check; +export type TypeCheck = + Tokenize extends infer TokenList + ? TokenList extends Error + ? Format<[TokenList]> + : TokenList extends Array> + ? Parse extends infer NodeList + ? NodeList extends Error + ? Format<[NodeList]> + : NodeList extends Array> + ? Check extends infer Errors + ? Errors extends Array> + ? Format + : never + : never + : never + : never + : never + : never; From 921801da737c5bf643b5f697c33cd43eb6e2029a Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 17 Jul 2022 00:23:17 +0300 Subject: [PATCH 233/286] wip --- src/tokenizer.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/tokenizer.ts b/src/tokenizer.ts index de8a2fd..985010b 100644 --- a/src/tokenizer.ts +++ b/src/tokenizer.ts @@ -113,10 +113,15 @@ export type Tokenize< ? TokenizeHelper : never; -export type TokenizeHelper< +type TokenizeHelper< TokenizeResult, - R extends Array, - L extends number, + Result extends Array, + LineNumber extends number, > = TokenizeResult extends Array - ? Tokenize, L, false> + ? Tokenize< + TokenizeResult[1], + Push, + LineNumber, + false + > : TokenizeResult; From d4fd67ea189b8e00b2ef9c4611491ada546dfcb2 Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 17 Jul 2022 00:37:27 +0300 Subject: [PATCH 234/286] wip --- src/checker.ts | 8 ++++++-- src/example.ts | 14 +++++++++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 0603020..19c7b6e 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -198,7 +198,11 @@ type InferReturnStatement< infer ExpressionState, infer ExpressionErrors > - ? TypeResult + ? TypeResult< + MapLiteralToType, + ExpressionState, + ExpressionErrors + > : never : TypeResult; @@ -763,7 +767,7 @@ type InferObjectProperties< ? InferObjectProperties< Tail, ExpressionState, - Push, + Push]>, Concat > : never diff --git a/src/example.ts b/src/example.ts index 5fe5884..e65e6f1 100644 --- a/src/example.ts +++ b/src/example.ts @@ -2,10 +2,18 @@ import type { TypeCheck } from '.'; type Errors = TypeCheck<` -function foo(name: number) { - return name; +function foo() { + if (a) { + return 'hello'; + } + + return 'world'; } -foo('not a number'); +const b = { + hello: 'hello' +}; + +const c = b[b.hello] `>; From e193a56ab4b155ecde6fc61ac87597e40cb7c0f4 Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 17 Jul 2022 00:51:46 +0300 Subject: [PATCH 235/286] wip --- src/utils/math.ts | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/utils/math.ts b/src/utils/math.ts index e4e2397..ba2c4ee 100644 --- a/src/utils/math.ts +++ b/src/utils/math.ts @@ -29,6 +29,36 @@ type SuccTable = { 27: 28; 28: 29; 29: 30; + 30: 31; + 31: 32; + 32: 33; + 33: 34; + 34: 35; + 35: 36; + 36: 37; + 37: 38; + 38: 39; + 39: 40; + 40: 41; + 41: 42; + 42: 43; + 43: 44; + 44: 45; + 45: 46; + 46: 47; + 47: 48; + 48: 49; + 49: 50; + 50: 51; + 51: 52; + 52: 53; + 53: 54; + 54: 55; + 55: 56; + 56: 57; + 57: 58; + 58: 59; + 59: 60; }; export type Succ = T extends keyof SuccTable ? SuccTable[T] : never; From 9ede34c0181751be7e31bd5c556ea59f2b7055f1 Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 17 Jul 2022 18:57:27 +0300 Subject: [PATCH 236/286] wip --- src/checker.ts | 6 ++-- src/example.ts | 29 ++++++++++-------- src/test/checker.test.ts | 65 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 14 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 19c7b6e..e71e25c 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -597,8 +597,10 @@ type MapLiteralToType = ? BooleanType : Type extends ObjectType ? ObjectType<{ - [P in keyof Properties]: Properties[P] extends StaticType - ? MapLiteralToType + [P in keyof Properties]: Properties[P] extends [infer Key, infer Value] + ? Value extends StaticType + ? [Key, MapLiteralToType] + : never : never; }> : Type; diff --git a/src/example.ts b/src/example.ts index e65e6f1..f115fe2 100644 --- a/src/example.ts +++ b/src/example.ts @@ -1,19 +1,24 @@ -import type { TypeCheck } from '.'; +// import type { TypeCheck } from '.'; +import type { Tokenize } from './tokenizer'; +import type { Parse } from './parser'; +import type { Check } from './checker'; +// import type { Format } from './formatter'; +// import type { Error } from './errors'; +// import type { Token } from './tokens'; +// import type { BaseNode } from './ast'; -type Errors = TypeCheck<` +type T = Tokenize<` -function foo() { - if (a) { - return 'hello'; - } +function bar() { + if (a) { + return 2; + } - return 'world'; + return 1; } -const b = { - hello: 'hello' -}; - -const c = b[b.hello] +const b: number = bar; `>; +type P = Parse; +type C = Check

; diff --git a/src/test/checker.test.ts b/src/test/checker.test.ts index d3526a3..05ea0cb 100644 --- a/src/test/checker.test.ts +++ b/src/test/checker.test.ts @@ -685,3 +685,68 @@ const b: string = { hello: true, world: foo, hey: [1, {}] }; lineNumber: 7, }, ]); + +expectType< + TypeCheck<` + +function bar() { + if (a) { + return 2; + } + + return 1; +} + +const b: number = bar; + +`> +>([ + { + type: 'TypeError', + message: "Type '() => number' is not assignable to type 'number'.", + lineNumber: 11, + }, +]); + +expectType< + TypeCheck<` + +function bar() { + if (a) { + return 'foo'; + } + + return 1; +} + +const b: number = bar; + +`> +>([ + { + type: 'TypeError', + message: "Type '() => string | number' is not assignable to type 'number'.", + lineNumber: 11, + }, +]); + +expectType< + TypeCheck<` + +function bar() { + return { + hello: 'world' + } +} + +const b: number = bar; + +`> +>([ + { + type: 'TypeError', + message: + "Type '() => { hello: string; }' is not assignable to type 'number'.", + lineNumber: 9, + }, +]); From 2feec0e2edde8d2eccb9fcb52d99e8ab7bc0b5cc Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 17 Jul 2022 19:38:38 +0300 Subject: [PATCH 237/286] wip --- src/test/checker.test.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/test/checker.test.ts b/src/test/checker.test.ts index 05ea0cb..6f77a73 100644 --- a/src/test/checker.test.ts +++ b/src/test/checker.test.ts @@ -750,3 +750,22 @@ const b: number = bar; lineNumber: 9, }, ]); + +expectType< + TypeCheck<` + +const a = [1, 'a']; +const b = [true, null]; +const c = [a[1], b[0]]; + +const num: number = c; + +`> +>([ + { + type: 'TypeError', + message: + "Type '(number | string | boolean | null)[]' is not assignable to type 'number'.", + lineNumber: 7, + }, +]); From 30dd872db641452ff16878c37555eb2bfa821162 Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 17 Jul 2022 20:22:07 +0300 Subject: [PATCH 238/286] wip --- src/example.ts | 20 ++++++++++---- src/test/checker.test.ts | 58 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/src/example.ts b/src/example.ts index f115fe2..2e6a8ec 100644 --- a/src/example.ts +++ b/src/example.ts @@ -10,14 +10,24 @@ import type { Check } from './checker'; type T = Tokenize<` function bar() { - if (a) { - return 2; - } + if (a) { + return { + hello: 'world' + }; + } - return 1; + if (a) { + return { + foo: '123' + }; + } + + return { + hello: '1' + }; } -const b: number = bar; +const b: string = bar().hello; `>; type P = Parse; diff --git a/src/test/checker.test.ts b/src/test/checker.test.ts index 6f77a73..af08d81 100644 --- a/src/test/checker.test.ts +++ b/src/test/checker.test.ts @@ -769,3 +769,61 @@ const num: number = c; lineNumber: 7, }, ]); + +expectType< + TypeCheck<` + +function bar() { + if (a) { + return { + hello: 'world' + }; + } + + if (a) { + return { + hello: 123 + }; + } + + return { + hello: '1' + }; +} + +const b: string = bar().hello; + +`> +>([ + { + type: 'TypeError', + message: "Type 'number | string' is not assignable to type 'string'.", + lineNumber: 21, + }, +]); + +expectType< + TypeCheck<` + +function bar() { + if (a) { + return { + hello: 'world' + }; + } + + if (a) { + return { + hello: '123' + }; + } + + return { + hello: '1' + }; +} + +const b: string = bar().hello; + +`> +>([]); From f9be26cb95fd4d7d1b89cb23f823de416972dbee Mon Sep 17 00:00:00 2001 From: ronami Date: Sun, 17 Jul 2022 23:56:50 +0300 Subject: [PATCH 239/286] wip --- src/parser.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 694bb44..6e8d14b 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -345,9 +345,7 @@ type ParseExpression>> = ParseExpressionHelper> extends infer P ? P extends Array ? CheckExpression - : P extends ParsingError - ? P - : null + : P : never; type TokenToNodeData> = InputToken extends Token< From 06ff13dd22ae324d944fdd4d87a5cf0d14c4f694 Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 18 Jul 2022 18:05:14 +0300 Subject: [PATCH 240/286] wip --- src/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/checker.ts b/src/checker.ts index e71e25c..0bc33c6 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -733,7 +733,7 @@ type InferMemberExpressionUnionHelper< Key, State, StartLine, - Errors + [] > extends TypeResult< infer ExpressionValue, infer ExpressionState, From 8ce3ae031eb5f2ae01f8e01585c8ae2b4f28b33b Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 18 Jul 2022 18:11:37 +0300 Subject: [PATCH 241/286] wip --- src/checker.ts | 15 ++++++++------- src/serializer.ts | 3 +++ src/test/checker.test.ts | 32 ++++++++++++++++++++++++++++++++ src/types.ts | 5 +++++ 4 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 0bc33c6..60b294d 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -41,6 +41,7 @@ import type { StaticType, StringLiteralType, StringType, + UndefinedType, UnionType, UnknownType, VoidType, @@ -204,7 +205,7 @@ type InferReturnStatement< ExpressionErrors > : never - : TypeResult; + : TypeResult; type MapAnnotationToType> = AnnotationValue extends StringTypeAnnotation @@ -275,7 +276,7 @@ type InferFunctionDeclaration< infer BlockStatementErrors > ? TypeResult< - NullType, + UndefinedType, MergeWithOverride< State, { @@ -383,7 +384,7 @@ type InferVariableDeclaration< ? ExpectedType extends StaticType ? MatchType extends true ? TypeResult< - NullType, + UndefinedType, MergeWithOverride< InitExpressionState, { [a in Name]: ExpectedType } @@ -391,7 +392,7 @@ type InferVariableDeclaration< InitExpressionErrors > : TypeResult< - NullType, + UndefinedType, MergeWithOverride< InitExpressionState, { [a in Name]: ExpectedType } @@ -407,7 +408,7 @@ type InferVariableDeclaration< : never : never : TypeResult< - NullType, + UndefinedType, MergeWithOverride, InitExpressionErrors > @@ -697,7 +698,7 @@ type InferMemberExpressionHelper< ? MemberExpressionValue extends StaticType ? TypeResult : TypeResult< - NullType, + UndefinedType, State, Push< Errors, @@ -744,7 +745,7 @@ type InferMemberExpressionUnionHelper< Key, ExpressionState, StartLine, - Concat, + Errors, Push > : never; diff --git a/src/serializer.ts b/src/serializer.ts index b92c5bb..2ff3348 100644 --- a/src/serializer.ts +++ b/src/serializer.ts @@ -11,6 +11,7 @@ import type { StaticType, StringLiteralType, StringType, + UndefinedType, UnionType, UnknownType, VoidType, @@ -27,6 +28,8 @@ export type Serialize = ? 'number' : MappedType extends NullType ? 'null' + : MappedType extends UndefinedType + ? 'undefined' : MappedType extends VoidType ? 'void' : MappedType extends AnyType diff --git a/src/test/checker.test.ts b/src/test/checker.test.ts index af08d81..720c2a5 100644 --- a/src/test/checker.test.ts +++ b/src/test/checker.test.ts @@ -827,3 +827,35 @@ const b: string = bar().hello; `> >([]); + +expectType< + TypeCheck<` + +function bar() { + if (a) { + return { + hello: 'world' + }; + } + + if (a) { + return { + foo: '123' + }; + } + + return { + hello: '1' + }; +} + +const b: string = bar().hello; + +`> +>([ + { + type: 'TypeError', + message: "Type 'undefined | string' is not assignable to type 'string'.", + lineNumber: 21, + }, +]); diff --git a/src/types.ts b/src/types.ts index 4cdc635..cbe30a4 100644 --- a/src/types.ts +++ b/src/types.ts @@ -29,6 +29,10 @@ export type NullType = { type: 'NullType'; }; +export type UndefinedType = { + type: 'UndefinedType'; +}; + export type UnknownType = { type: 'UnknownType'; }; @@ -86,6 +90,7 @@ export type StaticType = | VoidType | AnyType | NullType + | UndefinedType | FunctionType | ObjectType | ArrayType From b32681df6154cfeceff137aadf792b5ba2c4205c Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 18 Jul 2022 19:26:32 +0300 Subject: [PATCH 242/286] wip --- src/checker.ts | 110 ++++++++++++++++++++++++++++++++----------------- src/example.ts | 26 +++++------- 2 files changed, 83 insertions(+), 53 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 60b294d..38885fe 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -467,61 +467,97 @@ type InferCallExpression< infer ArgumentsState, infer ArgumentsErrors > - ? CalleeValue extends FunctionType - ? InferCallExpressionHelper< - ParamsType, - ArgumentsType, - ReturnType, - ArgumentsState, - Concat, - StartLine - > - : CalleeValue extends AnyType - ? TypeResult< - AnyType, - ArgumentsState, - Concat - > - : TypeResult< - AnyType, - ArgumentsState, - Unshift< - Concat, - TypeError< - `This expression is not callable. Type '${Serialize}' has no call signatures.`, - StartLine - > - > - > + ? InferCallExpressionHelper< + CalleeValue, + ArgumentsType, + ArgumentsState, + Concat, + StartLine + > : never : never; type InferCallExpressionHelper< - ParamsType extends Array<[string, StaticType]>, + CalleeValue extends StaticType, ArgumentsType extends Array, - ReturnType extends StaticType, State extends StateType, Errors extends Array>, StartLine extends number, -> = ParamsType['length'] extends ArgumentsType['length'] - ? MatchTypeArrays extends TypeError< - infer Message, - infer StartLine +> = CalleeValue extends FunctionType + ? ParamsType['length'] extends ArgumentsType['length'] + ? MatchTypeArrays extends TypeError< + infer Message, + infer StartLine + > + ? TypeResult< + ReturnType, + State, + Push> + > + : TypeResult + : TypeResult< + ReturnType, + State, + Push< + Errors, + TypeError< + `Expected ${ParamsType['length']} arguments, but got ${ArgumentsType['length']}.`, + StartLine + > + > + > + : CalleeValue extends AnyType + ? TypeResult + : CalleeValue extends UnionType + ? InferCallExpressionUnionHelper< + UnionTypes, + ArgumentsType, + State, + StartLine, + Errors > - ? TypeResult>> - : TypeResult : TypeResult< - ReturnType, + AnyType, State, - Push< + Unshift< Errors, TypeError< - `Expected ${ParamsType['length']} arguments, but got ${ArgumentsType['length']}.`, + `This expression is not callable. Type '${Serialize}' has no call signatures.`, StartLine > > >; +type InferCallExpressionUnionHelper< + UnionTypes extends Array, + ArgumentsType extends Array, + State extends StateType, + StartLine extends number, + Errors extends Array>, + Result extends Array = [], +> = UnionTypes extends [] + ? TypeResult, State, Errors> + : InferCallExpressionHelper< + UnionTypes[0], + ArgumentsType, + State, + Errors, + StartLine + > extends TypeResult< + infer ExpressionValue, + infer ExpressionState, + infer ExpressionErrors + > + ? InferCallExpressionUnionHelper< + Tail, + ArgumentsType, + ExpressionState, + StartLine, + ExpressionErrors, + Push + > + : never; + type InferExpressionsArray< NodeList extends Array>, State extends StateType, diff --git a/src/example.ts b/src/example.ts index 2e6a8ec..74ceb79 100644 --- a/src/example.ts +++ b/src/example.ts @@ -9,25 +9,19 @@ import type { Check } from './checker'; type T = Tokenize<` -function bar() { - if (a) { - return { - hello: 'world' - }; - } - - if (a) { - return { - foo: '123' - }; - } +function f1(a: number) { + return 1; +} - return { - hello: '1' - }; +function f2(a: string) { + return 'a'; } -const b: string = bar().hello; +const a = [f1, f2]; + +const fn = a[0]; + +const b: number = fn(1); `>; type P = Parse; From f4304973d8ec064945e91f6fd7f352ccb6f7aadd Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 18 Jul 2022 20:14:44 +0300 Subject: [PATCH 243/286] wip --- src/checker.ts | 35 ++++++++--------------------------- src/example.ts | 14 ++------------ src/test/checker.test.ts | 17 +++++++++++++++++ 3 files changed, 27 insertions(+), 39 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 38885fe..3c44278 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -581,6 +581,7 @@ type InferExpressionsArray< type InferArrayElements< Elements extends Array>, State extends StateType, + First extends boolean = true, Result extends StaticType = AnyType, Errors extends Array> = [], > = Elements extends [] @@ -593,38 +594,18 @@ type InferArrayElements< > ? MapLiteralToType extends infer E ? E extends StaticType - ? InferArrayElementsHelper extends infer U - ? U extends StaticType - ? InferArrayElements< - Tail, - ExpressionState, - U, - Concat - > - : never - : never + ? InferArrayElements< + Tail, + ExpressionState, + false, + First extends true ? E : MergeTypes, + Concat + > : never : never : never : never; -type InferArrayElementsHelper< - R extends StaticType, - E extends StaticType, -> = R extends AnyType - ? E - : R extends E - ? E - : R extends UnionType - ? E extends UnionType - ? UnionType> - : Includes extends true - ? R - : UnionType> - : E extends UnionType - ? UnionType> - : UnionType<[R, E]>; - type MapLiteralToType = Type extends NumberLiteralType ? NumberType diff --git a/src/example.ts b/src/example.ts index 74ceb79..ead708b 100644 --- a/src/example.ts +++ b/src/example.ts @@ -9,19 +9,9 @@ import type { Check } from './checker'; type T = Tokenize<` -function f1(a: number) { - return 1; -} +const a = [1,2,'3']; -function f2(a: string) { - return 'a'; -} - -const a = [f1, f2]; - -const fn = a[0]; - -const b: number = fn(1); +const b: string = a; `>; type P = Parse; diff --git a/src/test/checker.test.ts b/src/test/checker.test.ts index 720c2a5..bf4f90c 100644 --- a/src/test/checker.test.ts +++ b/src/test/checker.test.ts @@ -454,6 +454,23 @@ const b: string = a; }, ]); +expectType< + TypeCheck<` + +const c: any = 1; + +const a = [c, 2, '3']; + +const b: string = a; + +`> +>([ + { + type: 'TypeError', + message: "Type 'any[]' is not assignable to type 'string'.", + lineNumber: 7, + }, +]); expectType< TypeCheck<` From 3dea82e41ce8493cfcaecb1be66146f6fa2703f9 Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 18 Jul 2022 20:55:05 +0300 Subject: [PATCH 244/286] wip --- src/tokenizer.ts | 24 +++--------------------- src/utils/generalUtils.ts | 12 ++++++++++++ 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src/tokenizer.ts b/src/tokenizer.ts index 985010b..19396c2 100644 --- a/src/tokenizer.ts +++ b/src/tokenizer.ts @@ -5,7 +5,7 @@ import type { ConcatStrings, StringContains, } from './utils/stringUtils'; -import type { Numbers, Symbols } from './utils/generalUtils'; +import type { GenericTokens, Numbers, Symbols } from './utils/generalUtils'; import type { Token, NumberToken, @@ -24,26 +24,8 @@ type TokenizeInput< PrecedingLinebreak extends boolean, LineNumber extends number, Data extends TokenData = TokenData, -> = FirstChar extends ',' - ? [GenericToken<',', Data>, InputTail] - : FirstChar extends '(' - ? [GenericToken<'(', Data>, InputTail] - : FirstChar extends ')' - ? [GenericToken<')', Data>, InputTail] - : FirstChar extends '[' - ? [GenericToken<'[', Data>, InputTail] - : FirstChar extends ']' - ? [GenericToken<']', Data>, InputTail] - : FirstChar extends '{' - ? [GenericToken<'{', Data>, InputTail] - : FirstChar extends '}' - ? [GenericToken<'}', Data>, InputTail] - : FirstChar extends '.' - ? [GenericToken<'.', Data>, InputTail] - : FirstChar extends ';' - ? [GenericToken<';', Data>, InputTail] - : FirstChar extends ':' - ? [GenericToken<':', Data>, InputTail] +> = FirstChar extends GenericTokens + ? [GenericToken, InputTail] : FirstChar extends Numbers ? TokenizeNumber : FirstChar extends '"' diff --git a/src/utils/generalUtils.ts b/src/utils/generalUtils.ts index 02feaa7..c8c1283 100644 --- a/src/utils/generalUtils.ts +++ b/src/utils/generalUtils.ts @@ -2,6 +2,18 @@ export type Cast = A extends B ? A : B; export type MergeWithOverride = Omit & T2; +export type GenericTokens = + | ',' + | '(' + | ')' + | '[' + | ']' + | '{' + | '}' + | '.' + | ';' + | ':'; + export type Numbers = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'; export type Symbols = From b13b69be98a2a277331aabb41afb27f8d8106754 Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 18 Jul 2022 22:12:55 +0300 Subject: [PATCH 245/286] wip --- src/example.ts | 3 ++- src/parser.ts | 2 +- src/utils/generalUtils.ts | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/example.ts b/src/example.ts index ead708b..bea7c9b 100644 --- a/src/example.ts +++ b/src/example.ts @@ -8,8 +8,9 @@ import type { Check } from './checker'; // import type { BaseNode } from './ast'; type T = Tokenize<` +const c: any = 1 -const a = [1,2,'3']; +const a=[1,'3',c]; const b: string = a; diff --git a/src/parser.ts b/src/parser.ts index 6e8d14b..891d497 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -181,7 +181,7 @@ type ParseVariableDeclaration>> = infer R, ] ? R extends Array - ? R[0] extends SymbolToken< + ? R[0] extends GenericToken< '=', TokenData > diff --git a/src/utils/generalUtils.ts b/src/utils/generalUtils.ts index c8c1283..1b448ff 100644 --- a/src/utils/generalUtils.ts +++ b/src/utils/generalUtils.ts @@ -12,7 +12,8 @@ export type GenericTokens = | '}' | '.' | ';' - | ':'; + | ':' + | '='; export type Numbers = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'; @@ -80,7 +81,6 @@ export type Symbols = | '8' | '9' | '_' - | '$' - | '='; + | '$'; export type IsNever = [T] extends [never] ? true : false; From e19b8ae6c0700af307c25a7b273a00b7c85db60e Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 18 Jul 2022 22:35:30 +0300 Subject: [PATCH 246/286] wip --- src/checker.ts | 6 +++--- src/example.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 3c44278..2145f02 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -592,13 +592,13 @@ type InferArrayElements< infer ExpressionState, infer ExpressionErrors > - ? MapLiteralToType extends infer E - ? E extends StaticType + ? MapLiteralToType extends infer LiteralType + ? LiteralType extends StaticType ? InferArrayElements< Tail, ExpressionState, false, - First extends true ? E : MergeTypes, + First extends true ? LiteralType : MergeTypes, Concat > : never diff --git a/src/example.ts b/src/example.ts index bea7c9b..8b481e8 100644 --- a/src/example.ts +++ b/src/example.ts @@ -10,7 +10,7 @@ import type { Check } from './checker'; type T = Tokenize<` const c: any = 1 -const a=[1,'3',c]; +const a = [1,'3',c]; const b: string = a; From 8352ff689ec45b276efe1e61154a8cda07b67a03 Mon Sep 17 00:00:00 2001 From: ronami Date: Mon, 18 Jul 2022 23:30:36 +0300 Subject: [PATCH 247/286] wip --- src/parser.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 891d497..7d56873 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -629,8 +629,13 @@ type ParseIfStatement< > ? ParseExpression> extends infer G ? G extends Array - ? G[0] extends BaseNode> - ? ParseIfStatementHelper + ? G[0] extends BaseNode> + ? ParseIfStatementHelper< + G, + IfLineNumber, + InFunctionScope, + IfExpressionLineNumber + > : G extends ParsingError ? G : never @@ -681,7 +686,7 @@ type ParseIfStatementHelper< G extends Array, StartLineNumber extends number, InFunctionScope extends boolean, - E extends number, + IfExpressionLineNumber extends number, > = G[1] extends Array ? G[1][0] extends GenericToken< ')', @@ -707,7 +712,7 @@ type ParseIfStatementHelper< : B : never : ParsingError<"'{' expected.", ClosingParenLineNumber> - : ParsingError<"')' expected.", E> + : ParsingError<"')' expected.", IfExpressionLineNumber> : never; type ParseStatementHelper< From b528eef29b16e2605fad1efd0d098b3f6c8f288e Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 19 Jul 2022 19:55:19 +0300 Subject: [PATCH 248/286] wip --- src/checker.ts | 18 +++++++++++------- src/example.ts | 3 ++- src/test/checker.test.ts | 18 ++++++++++++++++++ 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 2145f02..9c9b41f 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -71,19 +71,23 @@ type InferBlockStatementHelper< ? Result : InferBlockStatementHelper, MergeTypes>; -type MergeTypes = MatchType< - TypeA, - TypeB -> extends true - ? TypeA - : MatchType extends true - ? TypeB +type MergeTypes< + TypeA extends StaticType, + TypeB extends StaticType, +> = TypeA extends AnyType + ? AnyType + : TypeB extends AnyType + ? AnyType : TypeA extends UnionType ? TypeB extends UnionType ? UnionType<[...UnionTypesA, ...UnionTypesB]> : UnionType<[...UnionTypesA, TypeB]> : TypeB extends UnionType ? UnionType<[...UnionTypesB, TypeA]> + : MatchType extends true + ? TypeA + : MatchType extends true + ? TypeB : UnionType<[TypeA, TypeB]>; type InferBlockStatement< diff --git a/src/example.ts b/src/example.ts index 8b481e8..c9ee75c 100644 --- a/src/example.ts +++ b/src/example.ts @@ -8,9 +8,10 @@ import type { Check } from './checker'; // import type { BaseNode } from './ast'; type T = Tokenize<` + const c: any = 1 -const a = [1,'3',c]; +const a = [1, c, 'a']; const b: string = a; diff --git a/src/test/checker.test.ts b/src/test/checker.test.ts index bf4f90c..2810aec 100644 --- a/src/test/checker.test.ts +++ b/src/test/checker.test.ts @@ -876,3 +876,21 @@ const b: string = bar().hello; lineNumber: 21, }, ]); + +expectType< + TypeCheck<` + +const c: any = 1 + +const a = [1, c, 'a']; + +const b: string = a; + +`> +>([ + { + type: 'TypeError', + message: "Type 'any[]' is not assignable to type 'string'.", + lineNumber: 7, + }, +]); From dc67a3c91f1566b128622bf334ebe37cdcb66221 Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 19 Jul 2022 20:12:37 +0300 Subject: [PATCH 249/286] wip --- src/checker.ts | 68 +++++++++++++++++++++++++--------------- src/example.ts | 10 +++--- src/test/checker.test.ts | 34 ++++++++++++++++++++ 3 files changed, 82 insertions(+), 30 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 9c9b41f..ddcb12d 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -228,23 +228,36 @@ type InferFunctionParams< Params extends Array>, FunctionParams extends Array<[string, StaticType]> = [], ParamsByName extends StateType = {}, + Errors extends Array> = [], > = Params extends [] - ? [FunctionParams, ParamsByName] - : Params[0] extends Identifier + ? [FunctionParams, ParamsByName, Errors] + : Params[0] extends Identifier< + infer Name, + infer Annotation, + NodeData + > ? Annotation extends TypeAnnotation ? InferFunctionParamsHelper< Params, FunctionParams, ParamsByName, MapAnnotationToType, - Name + Name, + Errors > : InferFunctionParamsHelper< Params, FunctionParams, ParamsByName, AnyType, - Name + Name, + Push< + Errors, + TypeError< + `Parameter '${Name}' implicitly has an 'any' type.`, + LineNumber + > + > > : never; @@ -254,10 +267,12 @@ type InferFunctionParamsHelper< ParamsByName extends StateType, Type extends StaticType, Name extends string, + Errors extends Array>, > = InferFunctionParams< Tail, Push, - MergeWithOverride + MergeWithOverride, + Errors >; type InferFunctionDeclaration< @@ -268,30 +283,33 @@ type InferFunctionDeclaration< > = InferFunctionParams extends [ infer FunctionParams, infer ParamsByName, + infer Errors, ] ? FunctionParams extends Array<[string, StaticType]> ? ParamsByName extends StateType - ? InferBlockStatement< - Body, - MergeWithOverride - > extends TypeResult< - infer BlockStatementReturnType, - any, - infer BlockStatementErrors - > - ? TypeResult< - UndefinedType, - MergeWithOverride< - State, - { - [a in Name]: FunctionType< - FunctionParams, - BlockStatementReturnType - >; - } - >, - BlockStatementErrors + ? Errors extends Array> + ? InferBlockStatement< + Body, + MergeWithOverride + > extends TypeResult< + infer BlockStatementReturnType, + any, + infer BlockStatementErrors > + ? TypeResult< + UndefinedType, + MergeWithOverride< + State, + { + [a in Name]: FunctionType< + FunctionParams, + BlockStatementReturnType + >; + } + >, + Concat + > + : never : never : never : never diff --git a/src/example.ts b/src/example.ts index c9ee75c..10608b4 100644 --- a/src/example.ts +++ b/src/example.ts @@ -9,12 +9,12 @@ import type { Check } from './checker'; type T = Tokenize<` -const c: any = 1 +function foo(bar, hello) { + hey() +} -const a = [1, c, 'a']; - -const b: string = a; +const a: number = foo; `>; type P = Parse; -type C = Check

; +type C = Check

[3]; diff --git a/src/test/checker.test.ts b/src/test/checker.test.ts index 2810aec..ae99335 100644 --- a/src/test/checker.test.ts +++ b/src/test/checker.test.ts @@ -894,3 +894,37 @@ const b: string = a; lineNumber: 7, }, ]); + +expectType< + TypeCheck<` + +function foo(bar, hello) { + hey() +} + +const a: number = foo; + +`> +>([ + { + type: 'TypeError', + message: "Parameter 'bar' implicitly has an 'any' type.", + lineNumber: 3, + }, + { + type: 'TypeError', + message: "Parameter 'hello' implicitly has an 'any' type.", + lineNumber: 3, + }, + { + type: 'TypeError', + message: "Cannot find name 'hey'.", + lineNumber: 4, + }, + { + type: 'TypeError', + message: + "Type '(bar: any, hello: any) => void' is not assignable to type 'number'.", + lineNumber: 7, + }, +]); From 2344ffd9f052c92b5c9cc7283ea275aabbade743 Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 19 Jul 2022 20:12:53 +0300 Subject: [PATCH 250/286] wip --- src/example.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/example.ts b/src/example.ts index 10608b4..85d96af 100644 --- a/src/example.ts +++ b/src/example.ts @@ -17,4 +17,4 @@ const a: number = foo; `>; type P = Parse; -type C = Check

[3]; +type C = Check

; From 9c25aa8b50fab7569916eda9940a527806aa95d1 Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 19 Jul 2022 21:10:37 +0300 Subject: [PATCH 251/286] wip --- src/checker.ts | 30 +++++++++++++++----------- src/example.ts | 6 ++---- src/test/checker.test.ts | 45 +++++++++++++++++++++++++++++++++++++-- src/utils/utilityTypes.ts | 2 +- 4 files changed, 64 insertions(+), 19 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index ddcb12d..7125ef1 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -174,23 +174,29 @@ type InferBlockStatement< : never : never : NodeList[0] extends IfStatement< - any, + infer Test, BlockStatement, any > - ? InferBlockStatement extends TypeResult< - infer IfStatementValue, - any, - infer IfStatementErrors + ? InferExpression extends TypeResult< + infer TestValue, + infer TestState, + infer TestErrors > - ? InferBlockStatement< - Tail, - State, - IfStatementValue extends VoidType - ? Result - : Push, - Concat + ? InferBlockStatement extends TypeResult< + infer IfStatementValue, + any, + infer IfStatementErrors > + ? InferBlockStatement< + Tail, + TestState, + IfStatementValue extends VoidType + ? Result + : Push, + [...Errors, ...TestErrors, ...IfStatementErrors] + > + : never : never : InferBlockStatement, State, Result, Errors>; diff --git a/src/example.ts b/src/example.ts index 85d96af..bdd1fd1 100644 --- a/src/example.ts +++ b/src/example.ts @@ -9,11 +9,9 @@ import type { Check } from './checker'; type T = Tokenize<` -function foo(bar, hello) { - hey() -} +if (a) { -const a: number = foo; +} `>; type P = Parse; diff --git a/src/test/checker.test.ts b/src/test/checker.test.ts index ae99335..c49b5df 100644 --- a/src/test/checker.test.ts +++ b/src/test/checker.test.ts @@ -718,6 +718,11 @@ const b: number = bar; `> >([ + { + type: 'TypeError', + message: "Cannot find name 'a'.", + lineNumber: 4, + }, { type: 'TypeError', message: "Type '() => number' is not assignable to type 'number'.", @@ -740,6 +745,11 @@ const b: number = bar; `> >([ + { + type: 'TypeError', + message: "Cannot find name 'a'.", + lineNumber: 4, + }, { type: 'TypeError', message: "Type '() => string | number' is not assignable to type 'number'.", @@ -812,6 +822,16 @@ const b: string = bar().hello; `> >([ + { + type: 'TypeError', + message: "Cannot find name 'a'.", + lineNumber: 4, + }, + { + type: 'TypeError', + message: "Cannot find name 'a'.", + lineNumber: 10, + }, { type: 'TypeError', message: "Type 'number | string' is not assignable to type 'string'.", @@ -843,7 +863,18 @@ function bar() { const b: string = bar().hello; `> ->([]); +>([ + { + type: 'TypeError', + message: "Cannot find name 'a'.", + lineNumber: 4, + }, + { + type: 'TypeError', + message: "Cannot find name 'a'.", + lineNumber: 10, + }, +]); expectType< TypeCheck<` @@ -852,7 +883,7 @@ function bar() { if (a) { return { hello: 'world' - }; + }; } if (a) { @@ -870,6 +901,16 @@ const b: string = bar().hello; `> >([ + { + type: 'TypeError', + message: "Cannot find name 'a'.", + lineNumber: 4, + }, + { + type: 'TypeError', + message: "Cannot find name 'a'.", + lineNumber: 10, + }, { type: 'TypeError', message: "Type 'undefined | string' is not assignable to type 'string'.", diff --git a/src/utils/utilityTypes.ts b/src/utils/utilityTypes.ts index 622b8d2..e78fd0d 100644 --- a/src/utils/utilityTypes.ts +++ b/src/utils/utilityTypes.ts @@ -3,7 +3,7 @@ import type { TypeError } from '../errors'; export type TypeResult< Value extends StaticType, - State extends Record, + State extends StateType, Errors extends Array> = [], > = { type: 'TypeResult'; From 8cecf25f297289a9e5fba420ae533278ed463742 Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 19 Jul 2022 21:57:37 +0300 Subject: [PATCH 252/286] wip wip --- src/checker.ts | 65 ++++++++++++++++++++++++++++++++++------------- src/example.ts | 10 +++++++- src/serializer.ts | 3 +++ src/types.ts | 5 ++++ 4 files changed, 65 insertions(+), 18 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 7125ef1..f4ae5b4 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -34,6 +34,7 @@ import type { BooleanType, CallArgumentsType, FunctionType, + NeverType, NullType, NumberLiteralType, NumberType, @@ -71,6 +72,50 @@ type InferBlockStatementHelper< ? Result : InferBlockStatementHelper, MergeTypes>; +type MergeFunctionTypes< + FunctionTypes extends Array>, + ReturnType extends FunctionType, +> = FunctionTypes extends [] + ? ReturnType + : FunctionTypes[0] extends FunctionType + ? MergeFunctionTypes< + Tail, + MergeFunctions + > + : never; + +type MergeFunctions< + Params extends Array<[string, StaticType]>, + Return extends StaticType, + Function extends FunctionType, +> = Function extends FunctionType + ? MergeFunctionParams extends infer P + ? P extends Array<[string, StaticType]> + ? FunctionType> + : never + : never + : never; + +type MergeFunctionParams< + ParamsA extends Array<[string, StaticType]>, + ParamsB extends Array<[string, StaticType]>, + Return extends Array<[string, StaticType]> = [], +> = ParamsA extends [] + ? ParamsB extends [] + ? Return + : [...Return, ...ParamsB] + : ParamsB extends [] + ? [...Return, ...ParamsA] + : MatchType extends true + ? MergeFunctionParams, Tail, Push> + : MatchType extends true + ? MergeFunctionParams, Tail, Push> + : MergeFunctionParams< + Tail, + Tail, + Push + >; + type MergeTypes< TypeA extends StaticType, TypeB extends StaticType, @@ -562,27 +607,13 @@ type InferCallExpressionUnionHelper< State extends StateType, StartLine extends number, Errors extends Array>, - Result extends Array = [], -> = UnionTypes extends [] - ? TypeResult, State, Errors> - : InferCallExpressionHelper< - UnionTypes[0], +> = UnionTypes extends Array> + ? InferCallExpressionHelper< + MergeFunctionTypes, UnionTypes[0]>, ArgumentsType, State, Errors, StartLine - > extends TypeResult< - infer ExpressionValue, - infer ExpressionState, - infer ExpressionErrors - > - ? InferCallExpressionUnionHelper< - Tail, - ArgumentsType, - ExpressionState, - StartLine, - ExpressionErrors, - Push > : never; diff --git a/src/example.ts b/src/example.ts index bdd1fd1..b8a14be 100644 --- a/src/example.ts +++ b/src/example.ts @@ -9,10 +9,18 @@ import type { Check } from './checker'; type T = Tokenize<` -if (a) { +function a (a: number) { + return 1; +} +function b (b: any) { + return '1'; } +const c = [a, b]; + +const d: number = c[0](1); + `>; type P = Parse; type C = Check

; diff --git a/src/serializer.ts b/src/serializer.ts index 2ff3348..3b0d9b1 100644 --- a/src/serializer.ts +++ b/src/serializer.ts @@ -4,6 +4,7 @@ import type { BooleanLiteralType, BooleanType, FunctionType, + NeverType, NullType, NumberLiteralType, NumberType, @@ -36,6 +37,8 @@ export type Serialize = ? 'any' : MappedType extends UnknownType ? 'unknown' + : MappedType extends NeverType + ? 'never' : MappedType extends ArrayType ? SerializeArray : MappedType extends UnionType diff --git a/src/types.ts b/src/types.ts index cbe30a4..7a42ac7 100644 --- a/src/types.ts +++ b/src/types.ts @@ -45,6 +45,10 @@ export type AnyType = { type: 'AnyType'; }; +export type NeverType = { + type: 'NeverType'; +}; + export type FunctionType< Params extends Array<[string, StaticType]>, Return extends StaticType, @@ -91,6 +95,7 @@ export type StaticType = | AnyType | NullType | UndefinedType + | NeverType | FunctionType | ObjectType | ArrayType From 7d3a10c8dc8ec9a5bfe9f782863400578d478799 Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 19 Jul 2022 22:39:09 +0300 Subject: [PATCH 253/286] wip --- src/checker.ts | 14 +++- src/example.ts | 8 +- src/test/checker.test.ts | 156 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 173 insertions(+), 5 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index f4ae5b4..5c722e4 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -583,6 +583,7 @@ type InferCallExpressionHelper< ? TypeResult : CalleeValue extends UnionType ? InferCallExpressionUnionHelper< + CalleeValue, UnionTypes, ArgumentsType, State, @@ -602,6 +603,7 @@ type InferCallExpressionHelper< >; type InferCallExpressionUnionHelper< + CalleeValue extends UnionType, UnionTypes extends Array, ArgumentsType extends Array, State extends StateType, @@ -615,7 +617,17 @@ type InferCallExpressionUnionHelper< Errors, StartLine > - : never; + : TypeResult< + AnyType, + State, + Push< + Errors, + TypeError< + `This expression is not callable. Not all constituents of type '${Serialize}' are callable.`, + StartLine + > + > + >; type InferExpressionsArray< NodeList extends Array>, diff --git a/src/example.ts b/src/example.ts index b8a14be..3c678ef 100644 --- a/src/example.ts +++ b/src/example.ts @@ -10,14 +10,14 @@ import type { Check } from './checker'; type T = Tokenize<` function a (a: number) { - return 1; + return '1'; } -function b (b: any) { - return '1'; +function b () { + return 1; } -const c = [a, b]; +const c = [a, 'b']; const d: number = c[0](1); diff --git a/src/test/checker.test.ts b/src/test/checker.test.ts index c49b5df..cc58fa5 100644 --- a/src/test/checker.test.ts +++ b/src/test/checker.test.ts @@ -969,3 +969,159 @@ const a: number = foo; lineNumber: 7, }, ]); + +expectType< + TypeCheck<` + +function a (a: number) { + return '1'; +} + +function b () { + return 1; +} + +const c = [a, 'b']; + +const d: number = c[0](1); + +`> +>([ + { + type: 'TypeError', + message: + "This expression is not callable. Not all constituents of type '(a: number) => string | string' are callable.", + lineNumber: 1, + }, +]); + +expectType< + TypeCheck<` + +function a (a: number) { + return '1'; +} + +function b () { + return 1; +} + +const c = [a, b]; + +const d: number = c[0](1); + +`> +>([ + { + type: 'TypeError', + message: "Type 'number | string' is not assignable to type 'number'.", + lineNumber: 13, + }, +]); + +expectType< + TypeCheck<` + +function a (a: number) { + return '1'; +} + +function b () { + return 1; +} + +const c = [a, b]; + +const d: number = c[0](); + +`> +>([ + { + type: 'TypeError', + message: 'Expected 1 arguments, but got 0.', + lineNumber: 1, + }, + { + type: 'TypeError', + message: "Type 'number | string' is not assignable to type 'number'.", + lineNumber: 13, + }, +]); + +expectType< + TypeCheck<` + +function a (a: number) { + return '1'; +} + +function b (b: string) { + return 1; +} + +const c = [a, b]; + +const d: number = c[0](1); + +`> +>([ + { + type: 'TypeError', + message: + "Argument of type 'number' is not assignable to parameter of type 'never'.", + lineNumber: 1, + }, + { + type: 'TypeError', + message: "Type 'number | string' is not assignable to type 'number'.", + lineNumber: 13, + }, +]); + +expectType< + TypeCheck<` + +function a (a: number) { + return '1'; +} + +function b (b: any) { + return 1; +} + +const c = [a, b]; + +const d: number = c[0](1); + +`> +>([ + { + type: 'TypeError', + message: "Type 'number | string' is not assignable to type 'number'.", + lineNumber: 13, + }, +]); + +expectType< + TypeCheck<` + +function a (a: number, c: boolean) { + return '1'; +} + +function b (b: any) { + return 1; +} + +const c = [a, b]; + +const d: number = c[0](1, false); + +`> +>([ + { + type: 'TypeError', + message: "Type 'number | string' is not assignable to type 'number'.", + lineNumber: 13, + }, +]); From 55db1bb316a43cc1b7fcec9aa5a4982e7d75b87b Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 19 Jul 2022 22:43:08 +0300 Subject: [PATCH 254/286] wip --- src/checker.ts | 9 +-------- src/test/parser.test.ts | 5 +++-- src/utils/arrayUtils.ts | 12 ------------ src/utils/generalUtils.ts | 4 ---- 4 files changed, 4 insertions(+), 26 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 5c722e4..89e5f71 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -47,14 +47,7 @@ import type { UnknownType, VoidType, } from './types'; -import type { - Concat, - Includes, - Push, - Tail, - Uniq, - Unshift, -} from './utils/arrayUtils'; +import type { Concat, Push, Tail, Unshift } from './utils/arrayUtils'; import type { MergeWithOverride } from './utils/generalUtils'; import type { StateType, TypeResult } from './utils/utilityTypes'; diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index d00010a..4509d69 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -1,10 +1,11 @@ import type { Tokenize } from '../tokenizer'; import type { Parse } from '../parser'; -import type { Cast } from '../utils/generalUtils'; import { expectType } from './utils'; type ParseAst = Tokenize extends infer G - ? Parse>> + ? G extends Array + ? Parse + : never : never; expectType>([ diff --git a/src/utils/arrayUtils.ts b/src/utils/arrayUtils.ts index aafc30e..0a99723 100644 --- a/src/utils/arrayUtils.ts +++ b/src/utils/arrayUtils.ts @@ -24,15 +24,3 @@ export type TailBy< B extends number, A extends Array = [], > = B extends A['length'] ? T : TailBy, B, Push>; - -export type Includes, E> = T extends [] - ? false - : T[0] extends E - ? true - : Includes, E>; - -export type Uniq, R extends Array = []> = T extends [] - ? R - : Includes extends true - ? Uniq, R> - : Uniq, Push>; diff --git a/src/utils/generalUtils.ts b/src/utils/generalUtils.ts index 1b448ff..ed6e66c 100644 --- a/src/utils/generalUtils.ts +++ b/src/utils/generalUtils.ts @@ -1,5 +1,3 @@ -export type Cast = A extends B ? A : B; - export type MergeWithOverride = Omit & T2; export type GenericTokens = @@ -82,5 +80,3 @@ export type Symbols = | '9' | '_' | '$'; - -export type IsNever = [T] extends [never] ? true : false; From dd93d999c1bd8a88d0558681b1404a705b0c3320 Mon Sep 17 00:00:00 2001 From: ronami Date: Tue, 19 Jul 2022 22:45:13 +0300 Subject: [PATCH 255/286] wip --- TODO.md | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/TODO.md b/TODO.md index 0ebdaf7..763f15b 100644 --- a/TODO.md +++ b/TODO.md @@ -1,21 +1,4 @@ ### TODOs -- Fully implement type checks include object/array types that require parser/tokenizer work - Re-organize tests from a long list into reasonable groups - Add comments to explain the implementation - -Errors: - -- `Expected 1 arguments, but got 0.` -- `This expression is not callable. Type 'String' has no call signatures.` -- `Argument of type 'number' is not assignable to parameter of type 'string'.` -- `Parameter 'a' implicitly has an 'any' type.` -- `Type 'string' is not assignable to type 'number'.` -- `A function whose declared type is neither 'void' nor 'any' must return a value.` -- `Property 'bar' does not exist on type '"hello"'.` -- `Unreachable code detected.` -- `Cannot find name 'bar'.` - -Bugs: - -- Don't return `void` type for empty `if` statements From 1248950b1d91c4b3958af4cb41dbe9ebf782c9f8 Mon Sep 17 00:00:00 2001 From: ronami Date: Wed, 20 Jul 2022 21:26:38 +0300 Subject: [PATCH 256/286] wip --- src/checker.ts | 79 +++++++++++++++++++++++----------------- src/test/checker.test.ts | 4 +- 2 files changed, 48 insertions(+), 35 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 89e5f71..33d8309 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -58,13 +58,6 @@ export type Check>> = InferBlockStatement< ? Errors : never; -type InferBlockStatementHelper< - TypeList extends Array, - Result extends StaticType, -> = TypeList extends [] - ? Result - : InferBlockStatementHelper, MergeTypes>; - type MergeFunctionTypes< FunctionTypes extends Array>, ReturnType extends FunctionType, @@ -84,7 +77,11 @@ type MergeFunctions< > = Function extends FunctionType ? MergeFunctionParams extends infer P ? P extends Array<[string, StaticType]> - ? FunctionType> + ? MergeTypes extends infer ReturnType + ? ReturnType extends StaticType + ? FunctionType + : never + : never : never : never : never; @@ -112,29 +109,33 @@ type MergeFunctionParams< type MergeTypes< TypeA extends StaticType, TypeB extends StaticType, -> = TypeA extends AnyType +> = TypeA extends NeverType + ? TypeB + : TypeB extends NeverType + ? TypeA + : TypeA extends AnyType ? AnyType : TypeB extends AnyType ? AnyType + : MatchType extends true + ? TypeA + : MatchType extends true + ? TypeB : TypeA extends UnionType ? TypeB extends UnionType ? UnionType<[...UnionTypesA, ...UnionTypesB]> : UnionType<[...UnionTypesA, TypeB]> : TypeB extends UnionType ? UnionType<[...UnionTypesB, TypeA]> - : MatchType extends true - ? TypeA - : MatchType extends true - ? TypeB : UnionType<[TypeA, TypeB]>; type InferBlockStatement< NodeList extends Array>, State extends StateType, - Result extends Array = [], + Result extends StaticType = NeverType, Errors extends Array> = [], > = NodeList extends [] - ? InferBlockStatementHelper extends infer ReturnType + ? MergeTypes extends infer ReturnType ? ReturnType extends StaticType ? TypeResult : never @@ -205,7 +206,7 @@ type InferBlockStatement< infer ReturnState, infer ReturnErrors > - ? InferBlockStatementHelper extends infer ReturnType + ? MergeTypes extends infer ReturnType ? ReturnType extends StaticType ? TypeResult> : never @@ -229,9 +230,13 @@ type InferBlockStatement< ? InferBlockStatement< Tail, TestState, - IfStatementValue extends VoidType - ? Result - : Push, + MergeTypes extends infer ReturnType + ? ReturnType extends StaticType + ? IfStatementValue extends VoidType + ? Result + : ReturnType + : never + : never, [...Errors, ...TestErrors, ...IfStatementErrors] > : never @@ -362,7 +367,11 @@ type InferFunctionDeclaration< type MatchType< TypeA extends StaticType, TypeB extends StaticType, -> = TypeA extends AnyType +> = TypeA extends NeverType + ? false + : TypeB extends NeverType + ? false + : TypeA extends AnyType ? true : TypeB extends AnyType ? true @@ -370,12 +379,6 @@ type MatchType< ? TypeB extends TypeA ? true : false - : TypeA extends UnionType - ? TypeB extends UnionType - ? UnionMatchUnion - : TypeMatchUnion - : TypeB extends UnionType - ? UnionMatchType : TypeA extends StringType ? TypeB extends StringLiteralType ? true @@ -388,6 +391,12 @@ type MatchType< ? TypeB extends NumberLiteralType ? true : false + : TypeA extends UnionType + ? TypeB extends UnionType + ? UnionMatchUnion + : TypeMatchUnion + : TypeB extends UnionType + ? UnionMatchType : false; type UnionMatchUnion< @@ -658,13 +667,17 @@ type InferArrayElements< > ? MapLiteralToType extends infer LiteralType ? LiteralType extends StaticType - ? InferArrayElements< - Tail, - ExpressionState, - false, - First extends true ? LiteralType : MergeTypes, - Concat - > + ? MergeTypes extends infer ReturnType + ? ReturnType extends StaticType + ? InferArrayElements< + Tail, + ExpressionState, + false, + First extends true ? LiteralType : ReturnType, + Concat + > + : never + : never : never : never : never diff --git a/src/test/checker.test.ts b/src/test/checker.test.ts index cc58fa5..aeb11c0 100644 --- a/src/test/checker.test.ts +++ b/src/test/checker.test.ts @@ -834,7 +834,7 @@ const b: string = bar().hello; }, { type: 'TypeError', - message: "Type 'number | string' is not assignable to type 'string'.", + message: "Type 'string | number' is not assignable to type 'string'.", lineNumber: 21, }, ]); @@ -913,7 +913,7 @@ const b: string = bar().hello; }, { type: 'TypeError', - message: "Type 'undefined | string' is not assignable to type 'string'.", + message: "Type 'string | undefined' is not assignable to type 'string'.", lineNumber: 21, }, ]); From 73ecd9bd55ff9a6eb4d509f290b384067a30bb2e Mon Sep 17 00:00:00 2001 From: ronami Date: Wed, 20 Jul 2022 22:42:48 +0300 Subject: [PATCH 257/286] wip --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 300468d..ccb58b1 100644 --- a/README.md +++ b/README.md @@ -39,9 +39,9 @@ Alternatively, install `hypescript` in your own project with `yarn` or `npm` ([T yarn add hypescript ``` -### Supported features and syntax +### Example showcase -Some [TypeScript](https://github.com/microsoft/TypeScript) syntax and features haven't been implemented and won't work. Here's a list of examples (with browser demo links) for some of the capabilites: +Some [TypeScript](https://github.com/microsoft/TypeScript) syntax and features haven't been implemented and won't work. Here's a list of examples (with browser demo links) for some capabilites: - [Calling a function with insufficient arguments]() - [Calling a function with wrong argument types]() @@ -52,8 +52,8 @@ Some [TypeScript](https://github.com/microsoft/TypeScript) syntax and features h ### Additional links -- [The Super Tiny Compiler](https://github.com/jamiebuilds/the-super-tiny-compiler) - [TypeScripts Type System is Turing Complete](https://github.com/microsoft/TypeScript/issues/14833) - [Typing the Technical Interview in TypeScript](https://gal.hagever.com/posts/typing-the-technical-interview-in-typescript/) - [Functions and algorithms implemented purely with TypeScript's type system](https://github.com/ronami/meta-typing) - [A SQL database implemented purely in TypeScript type annotations](https://github.com/codemix/ts-sql) +- [Collection of TypeScript type challenges with online judge](https://github.com/type-challenges/type-challenges) From 15d989ce5a9bf966a1596540ff69fba0b9b8207e Mon Sep 17 00:00:00 2001 From: ronami Date: Wed, 20 Jul 2022 23:38:15 +0300 Subject: [PATCH 258/286] wip --- src/index.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/index.ts b/src/index.ts index f2bd1ce..a5f9ba0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -15,11 +15,7 @@ export type TypeCheck = ? NodeList extends Error ? Format<[NodeList]> : NodeList extends Array> - ? Check extends infer Errors - ? Errors extends Array> - ? Format - : never - : never + ? Format> : never : never : never From f24a0b921a835bd877338fef9919ece138e1e587 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 21 Jul 2022 17:33:45 +0300 Subject: [PATCH 259/286] wip --- src/example.ts | 2 +- src/parser.ts | 65 ++++++++++++++++++++------------------- src/utils/utilityTypes.ts | 21 ++++++++++++- 3 files changed, 54 insertions(+), 34 deletions(-) diff --git a/src/example.ts b/src/example.ts index 3c678ef..e5ea40c 100644 --- a/src/example.ts +++ b/src/example.ts @@ -23,4 +23,4 @@ const d: number = c[0](1); `>; type P = Parse; -type C = Check

; +// type C = Check

; diff --git a/src/parser.ts b/src/parser.ts index 7d56873..d40d3b1 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -36,6 +36,7 @@ import type { TokenData, } from './tokens'; import type { Push, Tail, TailBy } from './utils/arrayUtils'; +import type { ParseError, ParseResult } from './utils/utilityTypes'; type ParseIdentifier< TokenList extends Array>, @@ -319,34 +320,34 @@ type ParseCallExpressionArgumentsHelper< type CheckExpression< Node extends BaseNode, TokenList extends Array>, -> = ParseMemberExpression extends infer G - ? G extends [infer O, infer T] - ? O extends BaseNode - ? T extends Array> - ? CheckExpression - : never - : never - : G extends ParsingError - ? G - : ParseCallExpression extends infer G - ? G extends [infer O, infer T] - ? O extends BaseNode - ? T extends Array> - ? CheckExpression - : never - : never - : G extends ParsingError - ? G - : [Node, TokenList] - : never - : never; +> = ParseMemberExpression extends ParseResult< + infer Node, + infer TokenList, + infer Error +> + ? Error extends ParsingError + ? ParseError + : CheckExpression + : ParseCallExpression extends ParseResult< + infer Node, + infer TokenList, + infer Error + > + ? Error extends ParsingError + ? ParseError + : CheckExpression + : ParseResult; type ParseExpression>> = - ParseExpressionHelper> extends infer P - ? P extends Array - ? CheckExpression - : P - : never; + ParseExpressionHelper> extends ParseResult< + infer Node, + infer TokenList, + infer Error + > + ? Error extends ParsingError + ? ParseError + : CheckExpression + : null; type TokenToNodeData> = InputToken extends Token< TokenData @@ -359,17 +360,17 @@ type ParseExpressionHelper< TokenTail extends Array> = Tail, Data extends NodeData = TokenToNodeData, > = TokenList[0] extends SymbolToken<'true', any> - ? [BooleanLiteral, TokenTail] + ? ParseResult, TokenTail> : TokenList[0] extends SymbolToken<'false', any> - ? [BooleanLiteral, TokenTail] + ? ParseResult, TokenTail> : TokenList[0] extends SymbolToken<'null', any> - ? [NullLiteral, TokenTail] + ? ParseResult, TokenTail> : TokenList[0] extends NumberToken - ? [NumericLiteral, TokenTail] + ? ParseResult, TokenTail> : TokenList[0] extends StringToken - ? [StringLiteral, TokenTail] + ? ParseResult, TokenTail> : TokenList[0] extends SymbolToken - ? [Identifier, TokenTail] + ? ParseResult, TokenTail> : TokenList[0] extends GenericToken<'[', TokenData> ? ParseArrayExpression, LineNumber> : TokenList[0] extends GenericToken<'{', TokenData> diff --git a/src/utils/utilityTypes.ts b/src/utils/utilityTypes.ts index e78fd0d..d8cff80 100644 --- a/src/utils/utilityTypes.ts +++ b/src/utils/utilityTypes.ts @@ -1,5 +1,7 @@ import type { StaticType } from '../types'; -import type { TypeError } from '../errors'; +import type { ParsingError, TypeError } from '../errors'; +import type { BaseNode } from '../ast'; +import type { Token } from '../tokens'; export type TypeResult< Value extends StaticType, @@ -12,4 +14,21 @@ export type TypeResult< errors: Errors; }; +export type ParseResult< + Node extends BaseNode, + TokenList extends Array>, + Error extends ParsingError | null = null, +> = { + type: 'ParseResult'; + node: Node; + tokenList: TokenList; + error: Error; +}; + +export type ParseError> = ParseResult< + any, + any, + Error +>; + export type StateType = Record; From 832afb41a4ea1c89e55371f4da6945cc0d6c1302 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 21 Jul 2022 17:40:42 +0300 Subject: [PATCH 260/286] wip --- src/parser.ts | 72 ++++++++++++++++++++++----------------- src/utils/utilityTypes.ts | 2 ++ 2 files changed, 43 insertions(+), 31 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index d40d3b1..43a2032 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -719,37 +719,47 @@ type ParseIfStatementHelper< type ParseStatementHelper< TokenList extends Array>, InFunctionScope extends boolean, -> = ParseFunctionDeclaration extends infer P - ? P extends Array - ? [...P, false] - : P extends ParsingError - ? P - : ParseVariableDeclaration extends infer P - ? P extends Array - ? [...P, true] - : P extends ParsingError - ? P - : ParseIfStatement extends infer P - ? P extends Array - ? [...P, false] - : P extends ParsingError - ? P - : ParseReturnStatement extends infer P - ? P extends Array - ? [...P, true] - : P extends ParsingError - ? P - : ParseExpressionStatement extends infer P - ? P extends Array - ? [...P, true] - : P extends ParsingError - ? P - : ParsingError<'Declaration or statement expected.', 1> - : never - : never - : never - : never - : never; +> = ParseFunctionDeclaration extends ParseResult< + infer Node, + infer TokenList, + infer Error +> + ? Error extends ParsingError + ? ParseError + : ParseResult + : ParseVariableDeclaration extends ParseResult< + infer Node, + infer TokenList, + infer Error + > + ? Error extends ParsingError + ? ParseError + : ParseResult + : ParseIfStatement extends ParseResult< + infer Node, + infer TokenList, + infer Error + > + ? Error extends ParsingError + ? ParseError + : ParseResult + : ParseReturnStatement extends ParseResult< + infer Node, + infer TokenList, + infer Error + > + ? Error extends ParsingError + ? ParseError + : ParseResult + : ParseExpressionStatement extends ParseResult< + infer Node, + infer TokenList, + infer Error + > + ? Error extends ParsingError + ? ParseError + : ParseResult + : ParseError>; export type Parse>> = ParseTopLevel; diff --git a/src/utils/utilityTypes.ts b/src/utils/utilityTypes.ts index d8cff80..859055d 100644 --- a/src/utils/utilityTypes.ts +++ b/src/utils/utilityTypes.ts @@ -18,11 +18,13 @@ export type ParseResult< Node extends BaseNode, TokenList extends Array>, Error extends ParsingError | null = null, + Data extends any = {}, > = { type: 'ParseResult'; node: Node; tokenList: TokenList; error: Error; + data: Data; }; export type ParseError> = ParseResult< From 181e7fbabf39203aa8ca51ea524d0c8f81c2a542 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 21 Jul 2022 17:44:18 +0300 Subject: [PATCH 261/286] wip --- src/parser.ts | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 43a2032..2067b18 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -599,25 +599,36 @@ type ParseBlockStatementHelper< LineNumber extends number, InFunctionScope extends boolean, Result extends Array>, -> = ParseStatementHelper extends infer G - ? G extends Array - ? ParseBlockStatement< - G[1], +> = ParseStatementHelper extends ParseResult< + infer Node, + infer TokenList, + infer Error +> + ? Error extends ParsingError + ? ParseError + : ParseBlockStatement< + TokenList, LineNumber, InFunctionScope, - Push, + Push, true > - : G : never; type ParseTopLevelHelper< TokenList extends Array>, Result extends Array>, -> = ParseStatementHelper extends infer G - ? G extends Array - ? ParseTopLevel, G[2]> - : G +> = ParseStatementHelper extends ParseResult< + infer Node, + infer TokenList, + infer Error, + infer Data +> + ? Error extends ParsingError + ? ParseError + : Data extends boolean + ? ParseTopLevel, Data> + : never : never; type ParseIfStatement< From 2f04e62ab9f0d00507d840b24565b7a5cfa14bcf Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 21 Jul 2022 17:48:09 +0300 Subject: [PATCH 262/286] wip --- src/parser.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 2067b18..c417571 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -602,17 +602,20 @@ type ParseBlockStatementHelper< > = ParseStatementHelper extends ParseResult< infer Node, infer TokenList, - infer Error + infer Error, + infer Data > ? Error extends ParsingError ? ParseError - : ParseBlockStatement< + : Data extends boolean + ? ParseBlockStatement< TokenList, LineNumber, InFunctionScope, Push, - true + Data > + : never : never; type ParseTopLevelHelper< From ec1e733145845a328d7c9bf189ea3b4a93212844 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 21 Jul 2022 17:58:49 +0300 Subject: [PATCH 263/286] wip --- src/parser.ts | 128 ++++++++++++++++++++++++++++---------------------- 1 file changed, 71 insertions(+), 57 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index c417571..51e1a66 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -642,21 +642,24 @@ type ParseIfStatement< '(', TokenData > - ? ParseExpression> extends infer G - ? G extends Array - ? G[0] extends BaseNode> - ? ParseIfStatementHelper< - G, - IfLineNumber, - InFunctionScope, - IfExpressionLineNumber - > - : G extends ParsingError - ? G - : never - : ParsingError<'Expression expected.', ParenLineNumber> - : never - : ParsingError<"'(' expected.", IfLineNumber> + ? ParseExpression> extends ParseResult< + infer Node, + infer TokenList, + infer Error + > + ? Error extends ParsingError + ? ParseError + : Node extends BaseNode> + ? ParseIfStatementHelper< + Node, + TokenList, + IfLineNumber, + InFunctionScope, + IfExpressionLineNumber + > + : never + : ParseError> + : ParseError> : null; type ParseReturnStatementHelper< @@ -666,16 +669,23 @@ type ParseReturnStatementHelper< ';', TokenData > - ? [ + ? ParseResult< ReturnStatement>, - Tail, - ] - : ParseExpression extends infer G - ? G extends Array - ? G[0] extends BaseNode> - ? [ReturnStatement>, G[1]] - : G - : never + Tail + > + : ParseExpression extends ParseResult< + infer Node, + infer TokenList, + infer Error + > + ? Error extends ParsingError + ? ParseError + : Node extends BaseNode> + ? [ + ReturnStatement>, + TokenList, + ] + : null : never; type ParseReturnStatement< @@ -686,49 +696,53 @@ type ParseReturnStatement< ? TokenList[1] extends Token, any> ? PrecedingLinebreak extends false ? ParseReturnStatementHelper, LineNumber> - : [ + : ParseResult< ReturnStatement>, - Tail, - ] - : [ReturnStatement>, []] - : ParsingError< - "A 'return' statement can only be used within a function body.", - LineNumber + Tail + > + : ParseResult>, []> + : ParseError< + ParsingError< + "A 'return' statement can only be used within a function body.", + LineNumber + > > : null; type ParseIfStatementHelper< - G extends Array, + Node extends BaseNode, + TokenList extends Array>, StartLineNumber extends number, InFunctionScope extends boolean, IfExpressionLineNumber extends number, -> = G[1] extends Array - ? G[1][0] extends GenericToken< - ')', - TokenData +> = TokenList[0] extends GenericToken< + ')', + TokenData +> + ? TokenList[1] extends GenericToken< + '{', + TokenData > - ? G[1][1] extends GenericToken<'{', TokenData> - ? ParseBlockStatement< - TailBy, - CurlyLineNumber, - InFunctionScope - > extends infer B - ? B extends Array - ? B[0] extends BaseNode> - ? [ - IfStatement< - G[0], - B[0], - NodeData - >, - B[1], - ] - : never - : B + ? ParseBlockStatement< + TailBy, + CurlyLineNumber, + InFunctionScope + > extends ParseResult + ? Error extends ParsingError + ? ParseError + : BlockNode extends BaseNode> + ? ParseResult< + IfStatement< + Node, + BlockNode, + NodeData + >, + TokenList + > : never - : ParsingError<"'{' expected.", ClosingParenLineNumber> - : ParsingError<"')' expected.", IfExpressionLineNumber> - : never; + : never + : ParseError> + : ParseError>; type ParseStatementHelper< TokenList extends Array>, From 4afe1f0b8079698faa32c35e71694e75c74eab17 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 21 Jul 2022 18:02:28 +0300 Subject: [PATCH 264/286] wip --- src/ast.ts | 2 +- src/parser.ts | 70 ++++++++++++++++++++++++++------------------------- 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index eb7fb48..1f8cd21 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -101,7 +101,7 @@ export type FunctionDeclaration< export type Identifier< Name extends string, - Annotation extends TypeAnnotation | null, + Annotation extends BaseNode | null, Data extends NodeData, > = { type: 'Identifier'; diff --git a/src/parser.ts b/src/parser.ts index 51e1a66..1a962ea 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -50,36 +50,38 @@ type ParseIdentifier< ':', TokenData > - ? ParseTypeAnnotation> extends infer J - ? J extends Array - ? [ + ? ParseTypeAnnotation> extends ParseResult< + infer Node, + infer TokenList, + infer Error + > + ? Error extends ParsingError + ? ParseError + : ParseResult< Identifier< Name, - J[0], + Node, NodeData >, - J[1], - ] - : J extends ParsingError - ? J - : ParsingError<'Type expected.', ColonLineNumber> - : never - : [ + TokenList + > + : ParseError> + : ParseResult< Identifier< Name, null, NodeData >, - Tail, - ] - : [ + Tail + > + : ParseResult< Identifier< Name, null, NodeData >, - Tail, - ] + Tail + > : null; type ParseVariableDeclarationHelper< @@ -113,62 +115,62 @@ type ParseVariableDeclarationHelper< type ParseTypeAnnotation>> = TokenList[0] extends SymbolToken<'string', TokenData> - ? [ + ? ParseResult< TypeAnnotation< StringTypeAnnotation>, NodeData >, - Tail, - ] + Tail + > : TokenList[0] extends SymbolToken< 'boolean', TokenData > - ? [ + ? ParseResult< TypeAnnotation< BooleanTypeAnnotation>, NodeData >, - Tail, - ] + Tail + > : TokenList[0] extends SymbolToken<'null', TokenData> - ? [ + ? ParseResult< TypeAnnotation< NullLiteralTypeAnnotation>, NodeData >, - Tail, - ] + Tail + > : TokenList[0] extends SymbolToken< 'number', TokenData > - ? [ + ? ParseResult< TypeAnnotation< NumberTypeAnnotation>, NodeData >, - Tail, - ] + Tail + > : TokenList[0] extends SymbolToken<'any', TokenData> - ? [ + ? ParseResult< TypeAnnotation< AnyTypeAnnotation>, NodeData >, - Tail, - ] + Tail + > : TokenList[0] extends SymbolToken< infer E, TokenData > - ? [ + ? ParseResult< TypeAnnotation< GenericTypeAnnotation>, NodeData >, - Tail, - ] + Tail + > : null; type ParseVariableDeclaration>> = From e61c62bc34884b18fecdb6c5a72003f6345f6470 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 21 Jul 2022 19:55:51 +0300 Subject: [PATCH 265/286] wip --- src/parser.ts | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 1a962ea..adc10ab 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -218,7 +218,7 @@ type ParseMemberExpression< infer Name, TokenData > - ? [ + ? ParseResult< MemberExpression< Node, Identifier< @@ -229,26 +229,29 @@ type ParseMemberExpression< false, NodeData >, - TailBy, - ] - : ParsingError<'Identifier expected.', DotLineNumber> + TailBy + > + : ParseError> : TokenList[0] extends GenericToken< '[', TokenData > - ? ParseExpression> extends infer G - ? G extends [infer Q, infer W] - ? Q extends BaseNode> - ? W extends Array> - ? W[0] extends GenericToken<']', any> - ? [MemberExpression>, Tail] - : ParsingError<"']' expected.", S> - : never - : never - : G extends null - ? ParsingError<'Expression expected.', BracketLineNumber> - : G - : never + ? ParseExpression> extends ParseResult< + infer ExpressionNode, + infer ExpressionTokenList, + infer ExpressionError + > + ? ExpressionError extends ParsingError + ? ParseError + : ExpressionNode extends BaseNode> + ? ExpressionTokenList[0] extends GenericToken<']', any> + ? ParseResult< + MemberExpression>, + Tail + > + : ParseError> + : never + : ParseError> : null : never; From f5a7a26d7d3c2b76b550f825b274f3e105b7cd44 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 21 Jul 2022 19:59:29 +0300 Subject: [PATCH 266/286] wip --- src/parser.ts | 61 ++++++++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index adc10ab..5396eb0 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -388,14 +388,17 @@ type ParseObject< Result extends Array> = [], NeedComma extends boolean = false, > = TokenList[0] extends GenericToken<'}', TokenData> - ? [ObjectExpression>, Tail] + ? ParseResult< + ObjectExpression>, + Tail + > : TokenList extends [] - ? ParsingError<"'}' expected.", InitialLineNumber> + ? ParseError> : NeedComma extends true ? TokenList[0] extends GenericToken<',', any> ? ParseObjectItem, InitialLineNumber, Result> : TokenList[0] extends Token> - ? ParsingError<"',' expected.", L> + ? ParseError> : never : ParseObjectItem; @@ -408,31 +411,33 @@ type ParseObjectItem< TokenData > ? TokenList[1] extends GenericToken<':', any> - ? ParseExpression> extends infer G - ? G extends Array - ? G[0] extends BaseNode> - ? ParseObject< - G[1], - InitialLineNumber, - Push< - Result, - ObjectProperty< - Identifier< - Name, - null, - NodeData - >, - G[0], - NodeData - > - >, - true - > - : never - : G extends ParsingError - ? G - : ParsingError<'Expression expected.', InitialLineNumber> - : never + ? ParseExpression> extends ParseResult< + infer Node, + infer TokenList, + infer Error + > + ? Error extends ParsingError + ? ParseError + : Node extends BaseNode> + ? ParseObject< + TokenList, + InitialLineNumber, + Push< + Result, + ObjectProperty< + Identifier< + Name, + null, + NodeData + >, + Node, + NodeData + > + >, + true + > + : never + : ParsingError<'Expression expected.', InitialLineNumber> : ParsingError<"'}' expected.", InitialLineNumber> : ParsingError<"'}' expected.", InitialLineNumber>; From 3ca52a2a8b40d1d2c8b7ba60692b3bf453aa8045 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 21 Jul 2022 20:06:58 +0300 Subject: [PATCH 267/286] wip --- src/ast.ts | 2 +- src/example.ts | 12 +----- src/parser.ts | 99 +++++++++++++++++++++++++------------------------- 3 files changed, 52 insertions(+), 61 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index 1f8cd21..caf94e0 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -76,7 +76,7 @@ export type VariableDeclaration< }; export type VariableDeclarator< - Id extends Identifier, + Id extends BaseNode, Init extends BaseNode, Data extends NodeData, > = { diff --git a/src/example.ts b/src/example.ts index e5ea40c..eadb2b3 100644 --- a/src/example.ts +++ b/src/example.ts @@ -9,17 +9,7 @@ import type { Check } from './checker'; type T = Tokenize<` -function a (a: number) { - return '1'; -} - -function b () { - return 1; -} - -const c = [a, 'b']; - -const d: number = c[0](1); +hello.bar; `>; type P = Parse; diff --git a/src/parser.ts b/src/parser.ts index 5396eb0..ab3f9ba 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -86,32 +86,34 @@ type ParseIdentifier< type ParseVariableDeclarationHelper< TokenList extends Array>, - Id extends Identifier, + Id extends BaseNode, KindLineNumber extends number, IdentifierLineNumber extends number, EqualsLineNumber extends number, -> = ParseExpression> extends infer G - ? G extends Array - ? G[0] extends BaseNode> - ? [ - VariableDeclaration< - [ - VariableDeclarator< - Id, - G[0], - NodeData - >, - ], - 'const', - NodeData - >, - G[1], - ] - : never - : G extends null - ? ParsingError<'Expression expected.', EqualsLineNumber> - : G - : never; +> = ParseExpression> extends ParseResult< + infer Node, + infer TokenList, + infer Error +> + ? Error extends ParsingError + ? ParseError + : Node extends BaseNode> + ? ParseResult< + VariableDeclaration< + [ + VariableDeclarator< + Id, + Node, + NodeData + >, + ], + 'const', + NodeData + >, + TokenList + > + : never + : ParseError>; type ParseTypeAnnotation>> = TokenList[0] extends SymbolToken<'string', TokenData> @@ -178,35 +180,34 @@ type ParseVariableDeclaration>> = 'const', TokenData > - ? ParseIdentifier, true> extends infer N - ? N extends [ - Identifier>, - infer R, - ] - ? R extends Array - ? R[0] extends GenericToken< - '=', - TokenData - > - ? ParseVariableDeclarationHelper< - R, - N[0], - KindLineNumber, - IdentifierLineNumber, - EqualsLineNumber - > - : ParsingError< - "'const' declarations must be initialized.", - IdentifierLineNumber - > - : never - : N extends null - ? ParsingError< + ? ParseIdentifier, true> extends ParseResult< + infer Node, + infer TokenList, + infer Error + > + ? Error extends ParsingError + ? ParseError + : TokenList[0] extends GenericToken< + '=', + TokenData + > + ? ParseVariableDeclarationHelper< + TokenList, + Node, + KindLineNumber, + Node['data']['startLineNumber'], + EqualsLineNumber + > + : ParsingError< + "'const' declarations must be initialized.", + Node['data']['startLineNumber'] + > + : ParseError< + ParsingError< 'Variable declaration list cannot be empty.', KindLineNumber > - : N - : never + > : null; type ParseMemberExpression< From dc9442656bce6e6e7b7ea27211fe7a9701b1c4c2 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 21 Jul 2022 20:09:14 +0300 Subject: [PATCH 268/286] wip --- src/parser.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index ab3f9ba..e4a803f 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -458,13 +458,15 @@ type ParseArrayExpression< : never; type ParseExpressionStatement>> = - ParseExpression extends infer G - ? G extends Array - ? G[0] extends BaseNode - ? [ExpressionStatement, G[1]] - : never - : G - : never; + ParseExpression extends ParseResult< + infer Node, + infer TokenList, + infer Error + > + ? Error extends ParsingError + ? ParseError + : ParseResult, TokenList> + : null; type ParseFunctionDeclaration>> = TokenList[0] extends SymbolToken< From 591f807f75bffe3de38d531d5447507be38a99ae Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 21 Jul 2022 20:12:41 +0300 Subject: [PATCH 269/286] wip --- src/parser.ts | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index e4a803f..4847962 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -271,7 +271,10 @@ type ParseCallExpression< ? G extends Array ? Node extends BaseNode> ? G[2] extends Token> - ? [CallExpression>, G[1]] + ? ParseResult< + CallExpression>, + G[1] + > : never : never : G @@ -452,7 +455,10 @@ type ParseArrayExpression< > extends infer A ? A extends Array ? A[2] extends Token> - ? [ArrayExpression>, A[1]] + ? ParseResult< + ArrayExpression>, + A[1] + > : never : A : never; @@ -489,7 +495,7 @@ type ParseFunctionDeclaration>> = ? ParseBlockStatement extends infer H ? H extends Array ? H[0] extends BaseNode> - ? [ + ? ParseResult< FunctionDeclaration< Identifier< Name, @@ -503,8 +509,8 @@ type ParseFunctionDeclaration>> = H[0], NodeData >, - H[1], - ] + H[1] + > : never : H : never @@ -559,13 +565,13 @@ type ParseBlockStatement< NeedSemicolon extends boolean = false, > = TokenList extends [] ? Result[0] extends BaseNode> - ? ParsingError<"'}' expected.", LineNumber> - : ParsingError<"'}' expected.", InitialLineNumber> + ? ParseError> + : ParseError> : TokenList[0] extends GenericToken<'}', TokenData> - ? [ + ? ParseResult< BlockStatement>, - Tail, - ] + Tail + > : TokenList[0] extends GenericToken<';', any> ? ParseBlockStatement< Tail, @@ -586,7 +592,7 @@ type ParseBlockStatement< > ? PrecedingLinebreak extends true ? ParseBlockStatementHelper - : ParsingError<"';' expected.", LineNumber> + : ParseError> : never; type ParseTopLevel< From eef3ed020149dcc7aec0837a6a54c630cbd24ae7 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 21 Jul 2022 20:16:37 +0300 Subject: [PATCH 270/286] wip --- src/parser.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 4847962..9545f8a 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -290,7 +290,7 @@ type ParseCallExpressionArguments< > = TokenList[0] extends GenericToken ? [Result, Tail, TokenList[0]] : TokenList extends [] - ? ParsingError<`'${ClosingString}' expected.`, ParenLineNumber> + ? ParseError> : NeedComma extends true ? TokenList[0] extends GenericToken<',', any> ? ParseCallExpressionArgumentsHelper< @@ -300,7 +300,7 @@ type ParseCallExpressionArguments< Result > : TokenList[0] extends Token> - ? ParsingError<"',' expected.", LineNumber> + ? ParseError> : never : ParseCallExpressionArgumentsHelper< TokenList, @@ -441,9 +441,9 @@ type ParseObjectItem< true > : never - : ParsingError<'Expression expected.', InitialLineNumber> - : ParsingError<"'}' expected.", InitialLineNumber> - : ParsingError<"'}' expected.", InitialLineNumber>; + : ParseError> + : ParseError> + : ParseError>; type ParseArrayExpression< TokenList extends Array>, From 4dc3a7dbed0a395da4a1614f18f5e4b9c65e3bc1 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 21 Jul 2022 20:17:57 +0300 Subject: [PATCH 271/286] wip --- src/parser.ts | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 9545f8a..23e0163 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -288,7 +288,7 @@ type ParseCallExpressionArguments< NeedComma extends boolean = false, Result extends Array> = [], > = TokenList[0] extends GenericToken - ? [Result, Tail, TokenList[0]] + ? ParseResult, null, [Result, TokenList[0]]> : TokenList extends [] ? ParseError> : NeedComma extends true @@ -314,17 +314,21 @@ type ParseCallExpressionArgumentsHelper< ParenLineNumber extends number, ClosingString extends string, Result extends Array> = [], -> = ParseExpression extends infer G - ? G extends Array - ? ParseCallExpressionArguments< - G[1], +> = ParseExpression extends ParseResult< + infer Node, + infer TokenList, + infer Error +> + ? Error extends ParsingError + ? ParseError + : ParseCallExpressionArguments< + TokenList, ParenLineNumber, ClosingString, true, - Push + Push > - : G - : never; + : null; type CheckExpression< Node extends BaseNode, From 73d43b08f698a3b6f23ad4dd750736de9f9d6498 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 21 Jul 2022 20:23:47 +0300 Subject: [PATCH 272/286] wip --- src/parser.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 23e0163..6ba6e4e 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -267,18 +267,20 @@ type ParseCallExpression< Tail, ParenLineNumber, ')' - > extends infer G - ? G extends Array + > extends ParseResult + ? Error extends ParsingError + ? ParseError + : Data extends Array ? Node extends BaseNode> - ? G[2] extends Token> + ? Data[1] extends Token> ? ParseResult< - CallExpression>, - G[1] + CallExpression>, + TokenList > : never : never - : G - : never + : never + : null : null; type ParseCallExpressionArguments< From ad6b6cf53532dbd5d8848427cb67532b5dcdbcd3 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 21 Jul 2022 20:25:59 +0300 Subject: [PATCH 273/286] wip --- src/example.ts | 2 +- src/parser.ts | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/example.ts b/src/example.ts index eadb2b3..fa84174 100644 --- a/src/example.ts +++ b/src/example.ts @@ -9,7 +9,7 @@ import type { Check } from './checker'; type T = Tokenize<` -hello.bar; +[hello.bar]; `>; type P = Parse; diff --git a/src/parser.ts b/src/parser.ts index 6ba6e4e..3b0e701 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -458,16 +458,18 @@ type ParseArrayExpression< TokenList, StartLineNumber, ']' -> extends infer A - ? A extends Array - ? A[2] extends Token> +> extends ParseResult + ? Error extends ParsingError + ? ParseError + : Data extends Array + ? Data[1] extends Token> ? ParseResult< - ArrayExpression>, - A[1] + ArrayExpression>, + TokenList > : never - : A - : never; + : never + : null; type ParseExpressionStatement>> = ParseExpression extends ParseResult< From 31aea5e71d1cb4dd1908b7d99f40bd022ab1e2d2 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 21 Jul 2022 20:28:24 +0300 Subject: [PATCH 274/286] wip --- src/parser.ts | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 3b0e701..de919e3 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -541,15 +541,15 @@ type ParseFunctionParams< '{', TokenData > - ? [Result, TailBy, CurlyLineNumber] - : ParsingError<"'{' expected.", ParenLineNumber> + ? ParseResult, null, [Result, CurlyLineNumber]> + : ParseError> : TokenList extends [] - ? ParsingError<"')' expected.", InitialLineNumber> + ? ParseError> : NeedSemicolon extends true ? TokenList[0] extends GenericToken<',', any> ? ParseFunctionParamsHelper, InitialLineNumber, Result> : Result[0] extends BaseNode> - ? ParsingError<"',' expected.", LineNumber> + ? ParseError> : never : ParseFunctionParamsHelper; @@ -557,13 +557,15 @@ type ParseFunctionParamsHelper< TokenList extends Array>, LineNumber extends number, Result extends Array>, -> = ParseIdentifier extends infer G - ? G extends Array - ? ParseFunctionParams, true> - : G extends ParsingError - ? G - : ParsingError<'Identifier expected.', LineNumber> - : never; +> = ParseIdentifier extends ParseResult< + infer Node, + infer TokenList, + infer Error +> + ? Error extends ParsingError + ? ParseError + : ParseFunctionParams, true> + : ParsingError<'Identifier expected.', LineNumber>; type ParseBlockStatement< TokenList extends Array>, From 372166e249032b89843b4e776da0d0b45f982a60 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 21 Jul 2022 20:36:35 +0300 Subject: [PATCH 275/286] wip --- src/ast.ts | 2 +- src/parser.ts | 43 ++++++++++++++++++++++--------------------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index caf94e0..329d659 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -89,7 +89,7 @@ export type VariableDeclarator< export type FunctionDeclaration< Id extends Identifier, Params extends Array>, - Body extends BlockStatement, + Body extends BaseNode, Data extends NodeData, > = { type: 'FunctionDeclaration'; diff --git a/src/parser.ts b/src/parser.ts index de919e3..886dc05 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -500,28 +500,29 @@ type ParseFunctionDeclaration>> = ParenLineNumber > extends infer G ? G extends Array - ? ParseBlockStatement extends infer H - ? H extends Array - ? H[0] extends BaseNode> - ? ParseResult< - FunctionDeclaration< - Identifier< - Name, - null, - NodeData< - FunctionNameLineNumber, - FunctionNameLineNumber - > - >, - G[0], - H[0], - NodeData + ? ParseBlockStatement extends ParseResult< + infer Node, + infer TokenList, + infer Error + > + ? Error extends ParsingError + ? ParseError + : Node extends BaseNode> + ? ParseResult< + FunctionDeclaration< + Identifier< + Name, + null, + NodeData >, - H[1] - > - : never - : H - : never + G[0], + Node, + NodeData + >, + TokenList + > + : never + : null : G : never : ParsingError<"'(' expected.", FunctionNameLineNumber> From 2e03daf9bbc2413e213e62a30dff7bdd59a971fc Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 21 Jul 2022 20:39:01 +0300 Subject: [PATCH 276/286] wip --- src/parser.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 886dc05..0702b12 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -498,9 +498,11 @@ type ParseFunctionDeclaration>> = ? ParseFunctionParams< TailBy, ParenLineNumber - > extends infer G - ? G extends Array - ? ParseBlockStatement extends ParseResult< + > extends ParseResult + ? Error extends ParsingError + ? ParseError + : Data extends Array + ? ParseBlockStatement extends ParseResult< infer Node, infer TokenList, infer Error @@ -515,15 +517,15 @@ type ParseFunctionDeclaration>> = null, NodeData >, - G[0], + Data[0], Node, NodeData >, TokenList > : never - : null - : G + : never + : null : never : ParsingError<"'(' expected.", FunctionNameLineNumber> : ParsingError<'Identifier expected.', FunctionLineNumber> From dd94b14ffcbbd7c85b801f8ed782f63894b1bdab Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 21 Jul 2022 23:17:36 +0300 Subject: [PATCH 277/286] wip --- src/example.ts | 4 +++- src/parser.ts | 29 ++++++++++++++++++++--------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/example.ts b/src/example.ts index fa84174..298a38c 100644 --- a/src/example.ts +++ b/src/example.ts @@ -9,7 +9,9 @@ import type { Check } from './checker'; type T = Tokenize<` -[hello.bar]; +function foo() { + return 1; +}; `>; type P = Parse; diff --git a/src/parser.ts b/src/parser.ts index 0702b12..0bcac9f 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -198,9 +198,11 @@ type ParseVariableDeclaration>> = Node['data']['startLineNumber'], EqualsLineNumber > - : ParsingError< - "'const' declarations must be initialized.", - Node['data']['startLineNumber'] + : ParseError< + ParsingError< + "'const' declarations must be initialized.", + Node['data']['startLineNumber'] + > > : ParseError< ParsingError< @@ -527,8 +529,8 @@ type ParseFunctionDeclaration>> = : never : null : never - : ParsingError<"'(' expected.", FunctionNameLineNumber> - : ParsingError<'Identifier expected.', FunctionLineNumber> + : ParseError> + : ParseError> : null; type ParseFunctionParams< @@ -568,7 +570,7 @@ type ParseFunctionParamsHelper< ? Error extends ParsingError ? ParseError : ParseFunctionParams, true> - : ParsingError<'Identifier expected.', LineNumber>; + : ParseError>; type ParseBlockStatement< TokenList extends Array>, @@ -613,7 +615,7 @@ type ParseTopLevel< Result extends Array> = [], NeedSemicolon extends boolean = false, > = TokenList extends [] - ? Result + ? ParseResult : TokenList[0] extends GenericToken<';', any> ? ParseTopLevel, Result, false> : NeedSemicolon extends false @@ -623,7 +625,7 @@ type ParseTopLevel< > ? PrecedingLinebreak extends true ? ParseTopLevelHelper - : ParsingError<"';' expected.", LineNumber> + : ParseError> : never; type ParseBlockStatementHelper< @@ -822,4 +824,13 @@ type ParseStatementHelper< : ParseError>; export type Parse>> = - ParseTopLevel; + ParseTopLevel extends ParseResult< + any, + infer TokenList, + infer Error, + infer Data + > + ? Error extends ParsingError + ? Error + : Data + : never; From 1ed0cb73f18380bdcdcecbb6e6e68c7dd9415bf0 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 21 Jul 2022 23:27:18 +0300 Subject: [PATCH 278/286] wip --- src/checker.ts | 2 +- src/example.ts | 2 +- src/parser.ts | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/checker.ts b/src/checker.ts index 33d8309..2f7ae52 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -445,7 +445,7 @@ type MatchTypeArrays< type InferVariableDeclaration< Name extends string, - Annotation extends TypeAnnotation | null, + Annotation extends BaseNode | null, Init extends BaseNode, State extends StateType, StartLine extends number, diff --git a/src/example.ts b/src/example.ts index 298a38c..f9de37b 100644 --- a/src/example.ts +++ b/src/example.ts @@ -15,4 +15,4 @@ function foo() { `>; type P = Parse; -// type C = Check

; +type C = Check

; diff --git a/src/parser.ts b/src/parser.ts index 0bcac9f..9bf1774 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -607,7 +607,7 @@ type ParseBlockStatement< > ? PrecedingLinebreak extends true ? ParseBlockStatementHelper - : ParseError> + : ParseError> : never; type ParseTopLevel< @@ -715,10 +715,10 @@ type ParseReturnStatementHelper< ? Error extends ParsingError ? ParseError : Node extends BaseNode> - ? [ + ? ParseResult< ReturnStatement>, - TokenList, - ] + TokenList + > : null : never; From 8a3c54abeab4b395c758b61caa7a63036138a442 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 21 Jul 2022 23:39:25 +0300 Subject: [PATCH 279/286] wip --- src/ast.ts | 50 +++++++++++++++++++-------------------- src/utils/utilityTypes.ts | 4 ++-- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index 329d659..d4a0504 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -3,14 +3,14 @@ export type NodeData = { endLineNumber: EndLine; }; -export type NullLiteral> = { +export type NullLiteral> = { type: 'NullLiteral'; data: Data; }; export type NumericLiteral< Value extends string, - Data extends NodeData, + Data extends NodeData, > = { type: 'NumericLiteral'; value: Value; @@ -19,7 +19,7 @@ export type NumericLiteral< export type BooleanLiteral< Value extends boolean, - Data extends NodeData, + Data extends NodeData, > = { type: 'BooleanLiteral'; value: Value; @@ -28,7 +28,7 @@ export type BooleanLiteral< export type StringLiteral< Value extends string, - Data extends NodeData, + Data extends NodeData, > = { type: 'StringLiteral'; value: Value; @@ -37,7 +37,7 @@ export type StringLiteral< export type ArrayExpression< Elements extends Array>, - Data extends NodeData, + Data extends NodeData, > = { type: 'ArrayExpression'; elements: Elements; @@ -46,7 +46,7 @@ export type ArrayExpression< export type ObjectExpression< Properties extends Array>, - Data extends NodeData, + Data extends NodeData, > = { type: 'ObjectExpression'; properties: Properties; @@ -56,7 +56,7 @@ export type ObjectExpression< export type ObjectProperty< Key extends Identifier, Value extends BaseNode, - Data extends NodeData, + Data extends NodeData, > = { type: 'ObjectProperty'; key: Key; @@ -67,7 +67,7 @@ export type ObjectProperty< export type VariableDeclaration< Declarations extends Array>, Kind extends 'const' | 'let', - Data extends NodeData, + Data extends NodeData, > = { type: 'VariableDeclaration'; declarations: Declarations; @@ -78,7 +78,7 @@ export type VariableDeclaration< export type VariableDeclarator< Id extends BaseNode, Init extends BaseNode, - Data extends NodeData, + Data extends NodeData, > = { type: 'VariableDeclarator'; id: Id; @@ -90,7 +90,7 @@ export type FunctionDeclaration< Id extends Identifier, Params extends Array>, Body extends BaseNode, - Data extends NodeData, + Data extends NodeData, > = { type: 'FunctionDeclaration'; id: Id; @@ -102,7 +102,7 @@ export type FunctionDeclaration< export type Identifier< Name extends string, Annotation extends BaseNode | null, - Data extends NodeData, + Data extends NodeData, > = { type: 'Identifier'; name: Name; @@ -112,7 +112,7 @@ export type Identifier< export type ExpressionStatement< Expression extends BaseNode, - Data extends NodeData, + Data extends NodeData, > = { type: 'ExpressionStatement'; expression: Expression; @@ -122,7 +122,7 @@ export type ExpressionStatement< export type CallExpression< Callee extends BaseNode, Arguments extends Array>, - Data extends NodeData, + Data extends NodeData, > = { type: 'CallExpression'; callee: Callee; @@ -134,7 +134,7 @@ export type MemberExpression< Object extends BaseNode, Property extends BaseNode, Computed extends boolean, - Data extends NodeData, + Data extends NodeData, > = { type: 'MemberExpression'; object: Object; @@ -146,7 +146,7 @@ export type MemberExpression< export type IfStatement< Test extends BaseNode, Consequent extends BaseNode, - Data extends NodeData, + Data extends NodeData, > = { type: 'IfStatement'; test: Test; @@ -157,7 +157,7 @@ export type IfStatement< export type ReturnStatement< Argument extends BaseNode | null, - Data extends NodeData, + Data extends NodeData, > = { type: 'ReturnStatement'; argument: Argument; @@ -166,7 +166,7 @@ export type ReturnStatement< export type BlockStatement< Body extends Array>, - Data extends NodeData, + Data extends NodeData, > = { type: 'BlockStatement'; body: Body; @@ -175,45 +175,45 @@ export type BlockStatement< export type TypeAnnotation< Annotation extends BaseNode, - Data extends NodeData, + Data extends NodeData, > = { type: 'TypeAnnotation'; typeAnnotation: Annotation; data: Data; }; -export type StringTypeAnnotation> = { +export type StringTypeAnnotation> = { type: 'StringTypeAnnotation'; data: Data; }; -export type NumberTypeAnnotation> = { +export type NumberTypeAnnotation> = { type: 'NumberTypeAnnotation'; data: Data; }; -export type NullLiteralTypeAnnotation> = { +export type NullLiteralTypeAnnotation> = { type: 'NullLiteralTypeAnnotation'; data: Data; }; -export type BooleanTypeAnnotation> = { +export type BooleanTypeAnnotation> = { type: 'BooleanTypeAnnotation'; data: Data; }; -export type GenericTypeAnnotation> = { +export type GenericTypeAnnotation> = { type: 'GenericTypeAnnotation'; id: I; data: Data; }; -export type AnyTypeAnnotation> = { +export type AnyTypeAnnotation> = { type: 'AnyTypeAnnotation'; data: Data; }; -export type BaseNode> = +export type BaseNode> = | NumericLiteral | BooleanLiteral | StringLiteral diff --git a/src/utils/utilityTypes.ts b/src/utils/utilityTypes.ts index 859055d..4f09fb2 100644 --- a/src/utils/utilityTypes.ts +++ b/src/utils/utilityTypes.ts @@ -1,6 +1,6 @@ import type { StaticType } from '../types'; import type { ParsingError, TypeError } from '../errors'; -import type { BaseNode } from '../ast'; +import type { BaseNode, NodeData } from '../ast'; import type { Token } from '../tokens'; export type TypeResult< @@ -15,7 +15,7 @@ export type TypeResult< }; export type ParseResult< - Node extends BaseNode, + Node extends BaseNode>, TokenList extends Array>, Error extends ParsingError | null = null, Data extends any = {}, From 7118e0a8d7bc091eaa13aff03b1ac6c0e7f41400 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 21 Jul 2022 23:51:15 +0300 Subject: [PATCH 280/286] wip --- src/parser.ts | 151 +++++++++++++++++++++++++------------------------- 1 file changed, 74 insertions(+), 77 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 9bf1774..a63b941 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -97,22 +97,20 @@ type ParseVariableDeclarationHelper< > ? Error extends ParsingError ? ParseError - : Node extends BaseNode> - ? ParseResult< + : ParseResult< VariableDeclaration< [ VariableDeclarator< Id, Node, - NodeData + NodeData >, ], 'const', - NodeData + NodeData >, TokenList > - : never : ParseError>; type ParseTypeAnnotation>> = @@ -213,53 +211,54 @@ type ParseVariableDeclaration>> = : null; type ParseMemberExpression< - Node extends BaseNode, + Node extends BaseNode>, TokenList extends Array>, -> = Node extends BaseNode> - ? TokenList[0] extends GenericToken<'.', TokenData> - ? TokenList[1] extends SymbolToken< - infer Name, - TokenData +> = TokenList[0] extends GenericToken<'.', TokenData> + ? TokenList[1] extends SymbolToken< + infer Name, + TokenData + > + ? ParseResult< + MemberExpression< + Node, + Identifier< + Name, + null, + NodeData + >, + false, + NodeData + >, + TailBy > + : ParseError> + : TokenList[0] extends GenericToken< + '[', + TokenData + > + ? ParseExpression> extends ParseResult< + infer ExpressionNode, + infer ExpressionTokenList, + infer ExpressionError + > + ? ExpressionError extends ParsingError + ? ParseError + : ExpressionTokenList[0] extends GenericToken<']', any> ? ParseResult< - MemberExpression< - Node, - Identifier< - Name, - null, - NodeData - >, - false, - NodeData - >, - TailBy + MemberExpression>, + Tail > - : ParseError> - : TokenList[0] extends GenericToken< - '[', - TokenData - > - ? ParseExpression> extends ParseResult< - infer ExpressionNode, - infer ExpressionTokenList, - infer ExpressionError - > - ? ExpressionError extends ParsingError - ? ParseError - : ExpressionNode extends BaseNode> - ? ExpressionTokenList[0] extends GenericToken<']', any> - ? ParseResult< - MemberExpression>, - Tail - > - : ParseError> - : never - : ParseError> - : null - : never; + : ParseError< + ParsingError< + "']' expected.", + ExpressionNode['data']['startLineNumber'] + > + > + : ParseError> + : null; type ParseCallExpression< - Node extends BaseNode, + Node extends BaseNode>, TokenList extends Array>, > = TokenList[0] extends GenericToken< '(', @@ -273,13 +272,15 @@ type ParseCallExpression< ? Error extends ParsingError ? ParseError : Data extends Array - ? Node extends BaseNode> - ? Data[1] extends Token> - ? ParseResult< - CallExpression>, - TokenList - > - : never + ? Data[1] extends Token> + ? ParseResult< + CallExpression< + Node, + Data[0], + NodeData + >, + TokenList + > : never : never : null @@ -430,8 +431,7 @@ type ParseObjectItem< > ? Error extends ParsingError ? ParseError - : Node extends BaseNode> - ? ParseObject< + : ParseObject< TokenList, InitialLineNumber, Push< @@ -443,12 +443,11 @@ type ParseObjectItem< NodeData >, Node, - NodeData + NodeData > >, true > - : never : ParseError> : ParseError> : ParseError>; @@ -511,8 +510,7 @@ type ParseFunctionDeclaration>> = > ? Error extends ParsingError ? ParseError - : Node extends BaseNode> - ? ParseResult< + : ParseResult< FunctionDeclaration< Identifier< Name, @@ -521,11 +519,13 @@ type ParseFunctionDeclaration>> = >, Data[0], Node, - NodeData + NodeData< + FunctionLineNumber, + Node['data']['endLineNumber'] + > >, TokenList > - : never : never : null : never @@ -536,7 +536,7 @@ type ParseFunctionDeclaration>> = type ParseFunctionParams< TokenList extends Array>, InitialLineNumber extends number, - Result extends Array> = [], + Result extends Array>> = [], NeedSemicolon extends boolean = false, > = TokenList[0] extends GenericToken< ')', @@ -553,9 +553,9 @@ type ParseFunctionParams< : NeedSemicolon extends true ? TokenList[0] extends GenericToken<',', any> ? ParseFunctionParamsHelper, InitialLineNumber, Result> - : Result[0] extends BaseNode> - ? ParseError> - : never + : ParseError< + ParsingError<"',' expected.", Result[0]['data']['endLineNumber']> + > : ParseFunctionParamsHelper; type ParseFunctionParamsHelper< @@ -683,15 +683,13 @@ type ParseIfStatement< > ? Error extends ParsingError ? ParseError - : Node extends BaseNode> - ? ParseIfStatementHelper< + : ParseIfStatementHelper< Node, TokenList, IfLineNumber, InFunctionScope, - IfExpressionLineNumber + Node['data']['endLineNumber'] > - : never : ParseError> : ParseError> : null; @@ -714,12 +712,13 @@ type ParseReturnStatementHelper< > ? Error extends ParsingError ? ParseError - : Node extends BaseNode> - ? ParseResult< - ReturnStatement>, + : ParseResult< + ReturnStatement< + Node, + NodeData + >, TokenList > - : null : never; type ParseReturnStatement< @@ -764,16 +763,14 @@ type ParseIfStatementHelper< > extends ParseResult ? Error extends ParsingError ? ParseError - : BlockNode extends BaseNode> - ? ParseResult< + : ParseResult< IfStatement< Node, BlockNode, - NodeData + NodeData >, TokenList > - : never : never : ParseError> : ParseError>; From 0478e89a40565be05f7b5c705681e0cef7a6d937 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 21 Jul 2022 23:53:02 +0300 Subject: [PATCH 281/286] wip --- src/tokens.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tokens.ts b/src/tokens.ts index fe03b29..838428d 100644 --- a/src/tokens.ts +++ b/src/tokens.ts @@ -8,7 +8,7 @@ export type TokenData< export type GenericToken< Value extends string, - Data extends TokenData, + Data extends TokenData, > = { type: 'generic'; value: Value; @@ -17,7 +17,7 @@ export type GenericToken< export type NumberToken< Value extends string, - Data extends TokenData, + Data extends TokenData, > = { type: 'number'; value: Value; @@ -26,7 +26,7 @@ export type NumberToken< export type StringToken< Value extends string, - Data extends TokenData, + Data extends TokenData, > = { type: 'string'; value: Value; @@ -35,7 +35,7 @@ export type StringToken< export type SymbolToken< Value extends string, - Data extends TokenData, + Data extends TokenData, > = { type: 'symbol'; value: Value; @@ -43,7 +43,7 @@ export type SymbolToken< }; export type Token< - Data extends TokenData, + Data extends TokenData, Value extends string = string, > = | GenericToken From a08668692eae4ba7383cb138d887b7ea92829ae4 Mon Sep 17 00:00:00 2001 From: ronami Date: Thu, 21 Jul 2022 23:57:08 +0300 Subject: [PATCH 282/286] wip --- src/parser.ts | 15 +++++++++++++-- src/test/checker.test.ts | 6 +++--- src/test/parser.test.ts | 18 +++++++++--------- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index a63b941..d7e0861 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -243,9 +243,20 @@ type ParseMemberExpression< > ? ExpressionError extends ParsingError ? ParseError - : ExpressionTokenList[0] extends GenericToken<']', any> + : ExpressionTokenList[0] extends GenericToken< + ']', + TokenData + > ? ParseResult< - MemberExpression>, + MemberExpression< + Node, + ExpressionNode, + true, + NodeData< + ExpressionNode['data']['startLineNumber'], + ClosingBracketLineNumber + > + >, Tail > : ParseError< diff --git a/src/test/checker.test.ts b/src/test/checker.test.ts index aeb11c0..8abc851 100644 --- a/src/test/checker.test.ts +++ b/src/test/checker.test.ts @@ -991,7 +991,7 @@ const d: number = c[0](1); type: 'TypeError', message: "This expression is not callable. Not all constituents of type '(a: number) => string | string' are callable.", - lineNumber: 1, + lineNumber: 13, }, ]); @@ -1039,7 +1039,7 @@ const d: number = c[0](); { type: 'TypeError', message: 'Expected 1 arguments, but got 0.', - lineNumber: 1, + lineNumber: 13, }, { type: 'TypeError', @@ -1069,7 +1069,7 @@ const d: number = c[0](1); type: 'TypeError', message: "Argument of type 'number' is not assignable to parameter of type 'never'.", - lineNumber: 1, + lineNumber: 13, }, { type: 'TypeError', diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index 4509d69..db14b78 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -2733,7 +2733,7 @@ expectType>([ }, ]); -expectType>([ +expectType>([ { type: 'ExpressionStatement', expression: { @@ -2743,8 +2743,8 @@ expectType>([ name: 'hello', typeAnnotation: null, data: { - startLineNumber: 1, - endLineNumber: 1, + startLineNumber: 3, + endLineNumber: 3, }, }, property: { @@ -2752,19 +2752,19 @@ expectType>([ name: 'world', typeAnnotation: null, data: { - startLineNumber: 1, - endLineNumber: 1, + startLineNumber: 3, + endLineNumber: 3, }, }, computed: true, data: { - startLineNumber: 1, - endLineNumber: 1, + startLineNumber: 3, + endLineNumber: 3, }, }, data: { - startLineNumber: 1, - endLineNumber: 1, + startLineNumber: 3, + endLineNumber: 3, }, }, ]); From 9761d2d4b354b7bde55eaa62392e109f7d28045b Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 22 Jul 2022 00:09:51 +0300 Subject: [PATCH 283/286] wip --- src/parser.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parser.ts b/src/parser.ts index d7e0861..aedf319 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -618,7 +618,7 @@ type ParseBlockStatement< > ? PrecedingLinebreak extends true ? ParseBlockStatementHelper - : ParseError> + : ParseError> : never; type ParseTopLevel< From ff6a9cdbdb40b605a5183ea3e0c9bf44d7f9ed64 Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 22 Jul 2022 00:10:35 +0300 Subject: [PATCH 284/286] wip --- src/test/parser.test.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index db14b78..1d10817 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -124,6 +124,12 @@ expectType>({ lineNumber: 1, }); +expectType>({ + type: 'ParsingError', + message: "';' expected.", + lineNumber: 1, +}); + expectType>([ { type: 'ExpressionStatement', From f20963b3b79acd438f075f1d6ad3311c2dc4d4ba Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 22 Jul 2022 01:11:27 +0300 Subject: [PATCH 285/286] wip --- src/parser.ts | 56 +++++++++++++++++++++------------------ src/utils/utilityTypes.ts | 5 ++++ 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index aedf319..9e573a7 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -36,7 +36,11 @@ import type { TokenData, } from './tokens'; import type { Push, Tail, TailBy } from './utils/arrayUtils'; -import type { ParseError, ParseResult } from './utils/utilityTypes'; +import type { + ParseError, + ParseErrorResult, + ParseResult, +} from './utils/utilityTypes'; type ParseIdentifier< TokenList extends Array>, @@ -65,7 +69,7 @@ type ParseIdentifier< >, TokenList > - : ParseError> + : ParseErrorResult<'Type expected.', ColonLineNumber> : ParseResult< Identifier< Name, @@ -111,7 +115,7 @@ type ParseVariableDeclarationHelper< >, TokenList > - : ParseError>; + : ParseErrorResult<'Expression expected.', EqualsLineNumber>; type ParseTypeAnnotation>> = TokenList[0] extends SymbolToken<'string', TokenData> @@ -231,7 +235,7 @@ type ParseMemberExpression< >, TailBy > - : ParseError> + : ParseErrorResult<'Identifier expected.', DotLineNumber> : TokenList[0] extends GenericToken< '[', TokenData @@ -265,7 +269,7 @@ type ParseMemberExpression< ExpressionNode['data']['startLineNumber'] > > - : ParseError> + : ParseErrorResult<'Expression expected.', BracketLineNumber> : null; type ParseCallExpression< @@ -306,7 +310,7 @@ type ParseCallExpressionArguments< > = TokenList[0] extends GenericToken ? ParseResult, null, [Result, TokenList[0]]> : TokenList extends [] - ? ParseError> + ? ParseErrorResult<`'${ClosingString}' expected.`, ParenLineNumber> : NeedComma extends true ? TokenList[0] extends GenericToken<',', any> ? ParseCallExpressionArgumentsHelper< @@ -316,7 +320,7 @@ type ParseCallExpressionArguments< Result > : TokenList[0] extends Token> - ? ParseError> + ? ParseErrorResult<"',' expected.", LineNumber> : never : ParseCallExpressionArgumentsHelper< TokenList, @@ -417,12 +421,12 @@ type ParseObject< Tail > : TokenList extends [] - ? ParseError> + ? ParseErrorResult<"'}' expected.", InitialLineNumber> : NeedComma extends true ? TokenList[0] extends GenericToken<',', any> ? ParseObjectItem, InitialLineNumber, Result> : TokenList[0] extends Token> - ? ParseError> + ? ParseErrorResult<"',' expected.", L> : never : ParseObjectItem; @@ -459,9 +463,9 @@ type ParseObjectItem< >, true > - : ParseError> - : ParseError> - : ParseError>; + : ParseErrorResult<'Expression expected.', InitialLineNumber> + : ParseErrorResult<"'}' expected.", InitialLineNumber> + : ParseErrorResult<"'}' expected.", InitialLineNumber>; type ParseArrayExpression< TokenList extends Array>, @@ -540,8 +544,8 @@ type ParseFunctionDeclaration>> = : never : null : never - : ParseError> - : ParseError> + : ParseErrorResult<"'(' expected.", FunctionNameLineNumber> + : ParseErrorResult<'Identifier expected.', FunctionLineNumber> : null; type ParseFunctionParams< @@ -558,9 +562,9 @@ type ParseFunctionParams< TokenData > ? ParseResult, null, [Result, CurlyLineNumber]> - : ParseError> + : ParseErrorResult<"'{' expected.", ParenLineNumber> : TokenList extends [] - ? ParseError> + ? ParseErrorResult<"')' expected.", InitialLineNumber> : NeedSemicolon extends true ? TokenList[0] extends GenericToken<',', any> ? ParseFunctionParamsHelper, InitialLineNumber, Result> @@ -581,7 +585,7 @@ type ParseFunctionParamsHelper< ? Error extends ParsingError ? ParseError : ParseFunctionParams, true> - : ParseError>; + : ParseErrorResult<'Identifier expected.', LineNumber>; type ParseBlockStatement< TokenList extends Array>, @@ -591,8 +595,8 @@ type ParseBlockStatement< NeedSemicolon extends boolean = false, > = TokenList extends [] ? Result[0] extends BaseNode> - ? ParseError> - : ParseError> + ? ParseErrorResult<"'}' expected.", LineNumber> + : ParseErrorResult<"'}' expected.", InitialLineNumber> : TokenList[0] extends GenericToken<'}', TokenData> ? ParseResult< BlockStatement>, @@ -618,7 +622,7 @@ type ParseBlockStatement< > ? PrecedingLinebreak extends true ? ParseBlockStatementHelper - : ParseError> + : ParseErrorResult<"';' expected.", LineNumber> : never; type ParseTopLevel< @@ -636,7 +640,7 @@ type ParseTopLevel< > ? PrecedingLinebreak extends true ? ParseTopLevelHelper - : ParseError> + : ParseErrorResult<"';' expected.", LineNumber> : never; type ParseBlockStatementHelper< @@ -701,8 +705,8 @@ type ParseIfStatement< InFunctionScope, Node['data']['endLineNumber'] > - : ParseError> - : ParseError> + : ParseErrorResult<'Expression expected.', ParenLineNumber> + : ParseErrorResult<"'(' expected.", IfLineNumber> : null; type ParseReturnStatementHelper< @@ -783,8 +787,8 @@ type ParseIfStatementHelper< TokenList > : never - : ParseError> - : ParseError>; + : ParseErrorResult<"'{' expected.", ClosingParenLineNumber> + : ParseErrorResult<"')' expected.", IfExpressionLineNumber>; type ParseStatementHelper< TokenList extends Array>, @@ -829,7 +833,7 @@ type ParseStatementHelper< ? Error extends ParsingError ? ParseError : ParseResult - : ParseError>; + : ParseErrorResult<'Declaration or statement expected.', 1>; export type Parse>> = ParseTopLevel extends ParseResult< diff --git a/src/utils/utilityTypes.ts b/src/utils/utilityTypes.ts index 4f09fb2..372032b 100644 --- a/src/utils/utilityTypes.ts +++ b/src/utils/utilityTypes.ts @@ -33,4 +33,9 @@ export type ParseError> = ParseResult< Error >; +export type ParseErrorResult< + Message extends string, + LineNumber extends number, +> = ParseError>; + export type StateType = Record; From 1ae344ef727475d9b3d1f88cea7a2063bdfd5a0b Mon Sep 17 00:00:00 2001 From: ronami Date: Fri, 22 Jul 2022 01:42:00 +0300 Subject: [PATCH 286/286] wip --- src/example.ts | 6 +- src/parser.ts | 114 ++++++++++++++++++-------------------- src/utils/utilityTypes.ts | 17 +++++- 3 files changed, 71 insertions(+), 66 deletions(-) diff --git a/src/example.ts b/src/example.ts index f9de37b..d231cab 100644 --- a/src/example.ts +++ b/src/example.ts @@ -9,10 +9,8 @@ import type { Check } from './checker'; type T = Tokenize<` -function foo() { - return 1; -}; +[111, 222] `>; type P = Parse; -type C = Check

; +// type C = Check

; diff --git a/src/parser.ts b/src/parser.ts index 9e573a7..f94a710 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -37,6 +37,7 @@ import type { } from './tokens'; import type { Push, Tail, TailBy } from './utils/arrayUtils'; import type { + ParseArrayResult, ParseError, ParseErrorResult, ParseResult, @@ -283,21 +284,20 @@ type ParseCallExpression< Tail, ParenLineNumber, ')' - > extends ParseResult + > extends ParseArrayResult ? Error extends ParsingError ? ParseError - : Data extends Array - ? Data[1] extends Token> - ? ParseResult< - CallExpression< - Node, - Data[0], - NodeData - >, - TokenList - > - : never - : never + : ParseResult< + CallExpression< + Node, + NodeList, + NodeData< + Node['data']['startLineNumber'], + TokenList[0]['data']['lineNumber'] + > + >, + Tail + > : null : null; @@ -308,7 +308,7 @@ type ParseCallExpressionArguments< NeedComma extends boolean = false, Result extends Array> = [], > = TokenList[0] extends GenericToken - ? ParseResult, null, [Result, TokenList[0]]> + ? ParseArrayResult : TokenList extends [] ? ParseErrorResult<`'${ClosingString}' expected.`, ParenLineNumber> : NeedComma extends true @@ -474,17 +474,16 @@ type ParseArrayExpression< TokenList, StartLineNumber, ']' -> extends ParseResult +> extends ParseArrayResult ? Error extends ParsingError ? ParseError - : Data extends Array - ? Data[1] extends Token> - ? ParseResult< - ArrayExpression>, - TokenList - > - : never - : never + : ParseResult< + ArrayExpression< + NodeList, + NodeData + >, + Tail + > : null; type ParseExpressionStatement>> = @@ -514,35 +513,34 @@ type ParseFunctionDeclaration>> = ? ParseFunctionParams< TailBy, ParenLineNumber - > extends ParseResult + > extends ParseArrayResult< + infer NodeList, + infer TokenList, + infer Error + > ? Error extends ParsingError ? ParseError - : Data extends Array - ? ParseBlockStatement extends ParseResult< - infer Node, - infer TokenList, - infer Error - > - ? Error extends ParsingError - ? ParseError - : ParseResult< - FunctionDeclaration< - Identifier< - Name, - null, - NodeData - >, - Data[0], - Node, - NodeData< - FunctionLineNumber, - Node['data']['endLineNumber'] - > + : ParseBlockStatement< + Tail, + TokenList[0]['data']['lineNumber'], + true + > extends ParseResult + ? Error extends ParsingError + ? ParseError + : ParseResult< + FunctionDeclaration< + Identifier< + Name, + null, + NodeData >, - TokenList - > - : never - : null + NodeList, + Node, + NodeData + >, + TokenList + > + : never : never : ParseErrorResult<"'(' expected.", FunctionNameLineNumber> : ParseErrorResult<'Identifier expected.', FunctionLineNumber> @@ -557,11 +555,8 @@ type ParseFunctionParams< ')', TokenData > - ? TokenList[1] extends GenericToken< - '{', - TokenData - > - ? ParseResult, null, [Result, CurlyLineNumber]> + ? TokenList[1] extends GenericToken<'{', any> + ? ParseArrayResult> : ParseErrorResult<"'{' expected.", ParenLineNumber> : TokenList extends [] ? ParseErrorResult<"')' expected.", InitialLineNumber> @@ -630,7 +625,7 @@ type ParseTopLevel< Result extends Array> = [], NeedSemicolon extends boolean = false, > = TokenList extends [] - ? ParseResult + ? ParseArrayResult : TokenList[0] extends GenericToken<';', any> ? ParseTopLevel, Result, false> : NeedSemicolon extends false @@ -836,13 +831,12 @@ type ParseStatementHelper< : ParseErrorResult<'Declaration or statement expected.', 1>; export type Parse>> = - ParseTopLevel extends ParseResult< - any, + ParseTopLevel extends ParseArrayResult< + infer NodeList, infer TokenList, - infer Error, - infer Data + infer Error > ? Error extends ParsingError ? Error - : Data + : NodeList : never; diff --git a/src/utils/utilityTypes.ts b/src/utils/utilityTypes.ts index 372032b..d9db8ee 100644 --- a/src/utils/utilityTypes.ts +++ b/src/utils/utilityTypes.ts @@ -1,7 +1,7 @@ import type { StaticType } from '../types'; import type { ParsingError, TypeError } from '../errors'; import type { BaseNode, NodeData } from '../ast'; -import type { Token } from '../tokens'; +import type { Token, TokenData } from '../tokens'; export type TypeResult< Value extends StaticType, @@ -18,7 +18,7 @@ export type ParseResult< Node extends BaseNode>, TokenList extends Array>, Error extends ParsingError | null = null, - Data extends any = {}, + Data extends any = null, > = { type: 'ParseResult'; node: Node; @@ -27,6 +27,19 @@ export type ParseResult< data: Data; }; +export type ParseArrayResult< + NodeList extends Array>>, + TokenList extends Array>>, + Error extends ParsingError | null = null, + Data extends any = null, +> = { + type: 'ParseResult'; + node: NodeList; + tokenList: TokenList; + error: Error; + data: Data; +}; + export type ParseError> = ParseResult< any, any,