diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/core/common.ts | 20 | ||||
| -rw-r--r-- | src/lib/core/eval.ts | 7 | ||||
| -rw-r--r-- | src/lib/core/lexer.ts | 33 | ||||
| -rw-r--r-- | src/lib/core/parser.ts | 87 | ||||
| -rw-r--r-- | src/lib/core/repl.ts | 3 |
5 files changed, 80 insertions, 70 deletions
diff --git a/src/lib/core/common.ts b/src/lib/core/common.ts index 1283000..a17eff4 100644 --- a/src/lib/core/common.ts +++ b/src/lib/core/common.ts @@ -4,14 +4,22 @@ export enum TokenType { SPACE = " ", SEMICOLON = ";", COMMA = ",", - UNIQUE_SYMBOL = "UNIQUE_SYMBOL", + NAME = "NAME", +} + +export enum TokenSubType { + NA = "NA", + LITERAL = "LITERAL", + REFERENCE = "REFERENCE", } export type Token< Type extends TokenType = TokenType, + Subtype extends TokenSubType = TokenSubType, Name extends string = string > = { type: Type; + subType: Subtype; name: Name; }; @@ -23,23 +31,25 @@ export type LexerCtx = { export enum NodeType { ROOT = "ROOT", - LITERAL = "LITERAL", - CALL = "CALL", + INT = "INT", + EXT = "EXT", PARSER_ERROR = "PARSER_ERROR", } export type ASTNode< Type extends NodeType = NodeType, Name extends string = string, - Children extends ASTNode[] = ASTNode<NodeType, string, any>[] + Value extends any = any, + Children extends ASTNode[] = ASTNode<NodeType, string, any, any>[] > = { type: Type; name: Name; + value: Value; children: Children; }; export type ParserCtx = { remainingTokens: readonly Token[]; - lastName: string | null; + lastToken: Token | null; stack: readonly ASTNode[]; }; diff --git a/src/lib/core/eval.ts b/src/lib/core/eval.ts new file mode 100644 index 0000000..779bfd9 --- /dev/null +++ b/src/lib/core/eval.ts @@ -0,0 +1,7 @@ +import { ASTNode } from "./common"; +import { Lex } from "./lexer"; +import { Parse } from "./parser"; + +export type Evaluate<Node extends ASTNode> = "Not implemented"; + +const test_result = null as unknown as Evaluate<Parse<Lex<"print(a)">>>; diff --git a/src/lib/core/lexer.ts b/src/lib/core/lexer.ts index 3315fb2..e9756bd 100644 --- a/src/lib/core/lexer.ts +++ b/src/lib/core/lexer.ts @@ -1,4 +1,4 @@ -import { LexerCtx, Token, TokenType } from "./common"; +import { LexerCtx, Token, TokenSubType, TokenType } from "./common"; export type BreakingToken = | TokenType.OPEN_PAREN @@ -16,7 +16,7 @@ export type IsWhitespace<T> = T extends `${TokenType.SPACE}` : false; export type ProcessNameCollection< - Cur extends LexerCtx, + Ctx extends LexerCtx, Tail extends string, _Token extends Token | null > = { @@ -24,16 +24,29 @@ export type ProcessNameCollection< nameCollection: ""; tokens: _Token extends null ? [ - ...Cur["tokens"], - ...(Cur["nameCollection"] extends "" + ...Ctx["tokens"], + ...(Ctx["nameCollection"] extends "" ? [] - : [Token<TokenType.UNIQUE_SYMBOL, Cur["nameCollection"]>]) + : [ + Token< + TokenType.NAME, + TokenSubType.REFERENCE, + Ctx["nameCollection"] + > + ]) ] : [ - ...Cur["tokens"], - ...(Cur["nameCollection"] extends "" + ...Ctx["tokens"], + ...(Ctx["nameCollection"] extends "" ? [_Token] - : [Token<TokenType.UNIQUE_SYMBOL, Cur["nameCollection"]>, _Token]) + : [ + Token< + TokenType.NAME, + TokenSubType.REFERENCE, + Ctx["nameCollection"] + >, + _Token + ]) ]; }; @@ -53,9 +66,7 @@ export type _Lex<Ctx extends LexerCtx> = nameCollection: `${Ctx["nameCollection"]}${Head}`; tokens: Ctx["tokens"]; }> - : // : Ctx["next"] extends `${infer Head}` - // ? _Lex<{ next: Head; tokens: Ctx["tokens"] }> - Ctx["tokens"]; + : Ctx["tokens"]; export type Lex<Raw extends string> = _Lex<{ next: `${Raw};`; diff --git a/src/lib/core/parser.ts b/src/lib/core/parser.ts index fbbbdc2..0f095fe 100644 --- a/src/lib/core/parser.ts +++ b/src/lib/core/parser.ts @@ -1,5 +1,12 @@ -import { ASTNode, NodeType, ParserCtx, Token, TokenType } from "./common"; -import { IsWhitespace, Lex } from "./lexer"; +import { + ASTNode, + NodeType, + ParserCtx, + Token, + TokenSubType, + TokenType, +} from "./common"; +import { Lex } from "./lexer"; /* start @@ -46,10 +53,16 @@ finally: */ -export type Error<T extends string> = ASTNode<NodeType.PARSER_ERROR, T, []>; +export type Error<T extends string> = ASTNode< + NodeType.PARSER_ERROR, + "Error", + T, + [] +>; export type PushChild<Node extends ASTNode, Child extends ASTNode> = { type: Node["type"]; + value: Node["value"]; name: Node["name"]; children: [...Node["children"], Child]; }; @@ -94,22 +107,27 @@ export type StackWithoutLast<Stack extends ParserCtx["stack"]> = Stack extends [ ? [] : never; +export type ResolveNodeFromToken<_Token extends Token> = + _Token["subType"] extends TokenSubType.LITERAL + ? ASTNode<NodeType.INT, "UNNAMED", _Token["name"], []> + : ASTNode<NodeType.EXT, _Token["name"], null, []>; + export type _Parse<Ctx extends ParserCtx> = Ctx["remainingTokens"] extends [ infer Head extends Token, ...infer Tail extends readonly Token[] ] - ? Ctx["lastName"] extends string - ? Head["type"] extends TokenType.UNIQUE_SYMBOL + ? Ctx["lastToken"] extends Token + ? Head["type"] extends TokenType.NAME ? // we already have a lastName // mutate last element of stack to push lastName as child // lastName = nextToken // goto start _Parse<{ - lastName: Head["name"]; + lastToken: Head; remainingTokens: Tail; stack: PushChildToLastElementOfStack< Ctx["stack"], - ASTNode<NodeType.LITERAL, Ctx["lastName"], []> + ResolveNodeFromToken<Ctx["lastToken"]> >; }> : //nextToken is openParen or close paren @@ -120,7 +138,7 @@ export type _Parse<Ctx extends ParserCtx> = Ctx["remainingTokens"] extends [ // [stack[last - 1].children.push(stack.pop) // goto start _Parse<{ - lastName: null; + lastToken: null; remainingTokens: Tail; // first push the last name onto the children of the top // then push the top onto the children of the next @@ -130,7 +148,7 @@ export type _Parse<Ctx extends ParserCtx> = Ctx["remainingTokens"] extends [ Ctx["stack"], PushChild< GetLastOnStack<Ctx["stack"]>, - ASTNode<NodeType.LITERAL, Ctx["lastName"], []> + ResolveNodeFromToken<Ctx["lastToken"]> > > >; @@ -139,23 +157,23 @@ export type _Parse<Ctx extends ParserCtx> = Ctx["remainingTokens"] extends [ ? // push lastName onto stack // goto start _Parse<{ - lastName: null; + lastToken: null; remainingTokens: Tail; - stack: [...Ctx["stack"], ASTNode<NodeType.CALL, Ctx["lastName"], []>]; + stack: [...Ctx["stack"], ResolveNodeFromToken<Ctx["lastToken"]>]; }> : Ctx & Error<`Was not expecting ${Head["type"]}`> : // expect nextToken to be a name or close paren - Head["type"] extends TokenType.UNIQUE_SYMBOL + Head["type"] extends TokenType.NAME ? // lastName = nextToken // goto start _Parse<{ - lastName: Head["name"]; + lastToken: Head; remainingTokens: Tail; stack: Ctx["stack"]; }> : Head["type"] extends TokenType.CLOSE_PAREN ? _Parse<{ - lastName: null; + lastToken: null; remainingTokens: Tail; // push the top onto the children of the next // then remove the top @@ -168,45 +186,12 @@ export type _Parse<Ctx extends ParserCtx> = Ctx["remainingTokens"] extends [ }> : Ctx & Error<`Expected nextToken to be a name or close paren at ${Head["type"]}`> - : Ctx["stack"]; - -// v1 -// ? Ctx["isCollecting"] extends true -// ? Head["type"] extends TokenType.CLOSE_PAREN -// ? "return" -// : Head["type"] extends TokenType.UNIQUE_SYMBOL -// ? _Parse<{ -// remainingTokens: Tail; -// isCollecting: true; -// name: Ctx["name"]; -// // fuck, how to do this without advancing seek pointer?? -// ret: [...Ctx["ret"], ASTNode; -// }> -// : Error<"Expected another name, or `)`"> -// : Head["type"] extends TokenType.OPEN_PAREN -// ? _Parse<{ -// remainingTokens: Tail; -// isCollecting: true; -// name: Ctx["name"]; -// ret: Ctx["ret"]; -// }> -// : Error<"Expected open paren"> -// : Ctx["ret"]; - -//v2 -// ? Ctx["previousName"] extends null -// ? Head["type"] extends TokenType.UNIQUE_SYMBOL -// ? _Parse<{ remainingTokens: Tail; previousName: Head; node: Ctx["node"] }> -// : ASTNode<NodeType.PARSER_ERROR, "Expected name", []> -// : IsWhitespace<`${Head["type"]}`> extends true -// ? ASTNode<NodeType.PARSER_ERROR, "1", []> -// : ASTNode<NodeType.PARSER_ERROR, "2", []> -// : Ctx["node"]; + : Ctx["stack"][0]; export type Parse<Raw extends readonly Token[]> = _Parse<{ - lastName: null; + lastToken: null; remainingTokens: Raw; - stack: [ASTNode<NodeType.ROOT, "ROOT", []>]; + stack: [ASTNode<NodeType.ROOT, "ROOT", null, []>]; }>; -const a = "a" as any as Parse<Lex<"test(a)">>; +const test_result = null as unknown as Parse<Lex<"test(a)">>; diff --git a/src/lib/core/repl.ts b/src/lib/core/repl.ts deleted file mode 100644 index 5235a64..0000000 --- a/src/lib/core/repl.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { ASTNode } from "./common"; - -export type Evaluate<Node extends ASTNode> = "Not implemented"; |
