From cf5c694be7fd2705c46770e9351adad009647d78 Mon Sep 17 00:00:00 2001 From: marihachi Date: Fri, 2 Aug 2024 21:50:56 +0900 Subject: [PATCH] apply getTokenKind, add `is(TokenKind[]): boolean` overload --- src/parser/scanner.ts | 10 +++++++--- src/parser/streams/token-stream.ts | 12 ++++++++---- src/parser/syntaxes/common.ts | 8 ++++---- src/parser/syntaxes/expressions.ts | 24 ++++++++++++------------ src/parser/syntaxes/statements.ts | 12 ++++++------ src/parser/syntaxes/toplevel.ts | 12 ++++++------ 6 files changed, 43 insertions(+), 35 deletions(-) diff --git a/src/parser/scanner.ts b/src/parser/scanner.ts index 8bb62e12..5d872e6f 100644 --- a/src/parser/scanner.ts +++ b/src/parser/scanner.ts @@ -38,8 +38,12 @@ export class Scanner implements ITokenStream { /** * カーソル位置にあるトークンの種類が指定したトークンの種類と一致するかどうかを示す値を取得します。 */ - public is(kind: TokenKind): boolean { - return this.getToken().kind === kind; + public is(kind: TokenKind | TokenKind[]): boolean { + if (Array.isArray(kind)) { + return kind.includes(this.getTokenKind()); + } else { + return this.getTokenKind() === kind; + } } /** @@ -96,7 +100,7 @@ export class Scanner implements ITokenStream { */ public expect(kind: TokenKind): void { if (!this.is(kind)) { - throw new AiScriptSyntaxError(`unexpected token: ${TokenKind[this.getToken().kind]}`, this.getPos()); + throw new AiScriptSyntaxError(`unexpected token: ${TokenKind[this.getTokenKind()]}`, this.getPos()); } } diff --git a/src/parser/streams/token-stream.ts b/src/parser/streams/token-stream.ts index b2ad23c2..75a7ac8d 100644 --- a/src/parser/streams/token-stream.ts +++ b/src/parser/streams/token-stream.ts @@ -14,7 +14,7 @@ export interface ITokenStream { /** * カーソル位置にあるトークンの種類が指定したトークンの種類と一致するかどうかを示す値を取得します。 */ - is(kind: TokenKind): boolean; + is(kind: TokenKind | TokenKind[]): boolean; /** * カーソル位置にあるトークンの種類を取得します。 @@ -79,8 +79,12 @@ export class TokenStream implements ITokenStream { /** * カーソル位置にあるトークンの種類が指定したトークンの種類と一致するかどうかを示す値を取得します。 */ - public is(kind: TokenKind): boolean { - return this.getToken().kind === kind; + public is(kind: TokenKind | TokenKind[]): boolean { + if (Array.isArray(kind)) { + return kind.includes(this.getTokenKind()); + } else { + return this.getTokenKind() === kind; + } } /** @@ -131,7 +135,7 @@ export class TokenStream implements ITokenStream { */ public expect(kind: TokenKind): void { if (!this.is(kind)) { - throw new AiScriptSyntaxError(`unexpected token: ${TokenKind[this.getToken().kind]}`, this.getPos()); + throw new AiScriptSyntaxError(`unexpected token: ${TokenKind[this.getTokenKind()]}`, this.getPos()); } } diff --git a/src/parser/syntaxes/common.ts b/src/parser/syntaxes/common.ts index e271d359..bab9e636 100644 --- a/src/parser/syntaxes/common.ts +++ b/src/parser/syntaxes/common.ts @@ -45,7 +45,7 @@ export function parseParams(s: ITokenStream): { name: string, argType?: Ast.Node items.push({ name, optional, default: defaultExpr, argType: type }); // separator - switch (s.getToken().kind) { + switch (s.getTokenKind()) { case TokenKind.NewLine: { s.next(); break; @@ -90,10 +90,10 @@ export function parseBlock(s: ITokenStream): Ast.Node[] { steps.push(parseStatement(s)); // terminator - switch (s.getToken().kind) { + switch (s.getTokenKind()) { case TokenKind.NewLine: case TokenKind.SemiColon: { - while ([TokenKind.NewLine, TokenKind.SemiColon].includes(s.getToken().kind)) { + while ([TokenKind.NewLine, TokenKind.SemiColon].includes(s.getTokenKind())) { s.next(); } break; @@ -140,7 +140,7 @@ function parseFnType(s: ITokenStream): Ast.Node { const params: Ast.Node[] = []; while (!s.is(TokenKind.CloseParen)) { if (params.length > 0) { - switch (s.getToken().kind) { + switch (s.getTokenKind()) { case TokenKind.Comma: { s.next(); break; diff --git a/src/parser/syntaxes/expressions.ts b/src/parser/syntaxes/expressions.ts index 00c71510..de7e5acc 100644 --- a/src/parser/syntaxes/expressions.ts +++ b/src/parser/syntaxes/expressions.ts @@ -53,7 +53,7 @@ const operators: OpInfo[] = [ function parsePrefix(s: ITokenStream, minBp: number): Ast.Node { const startPos = s.getPos(); - const op = s.getToken().kind; + const op = s.getTokenKind(); s.next(); // 改行のエスケープ @@ -99,7 +99,7 @@ function parsePrefix(s: ITokenStream, minBp: number): Ast.Node { function parseInfix(s: ITokenStream, left: Ast.Node, minBp: number): Ast.Node { const startPos = s.getPos(); - const op = s.getToken().kind; + const op = s.getTokenKind(); s.next(); // 改行のエスケープ @@ -174,7 +174,7 @@ function parseInfix(s: ITokenStream, left: Ast.Node, minBp: number): Ast.Node { function parsePostfix(s: ITokenStream, expr: Ast.Node): Ast.Node { const startPos = s.getPos(); - const op = s.getToken().kind; + const op = s.getTokenKind(); switch (op) { case TokenKind.OpenParen: { @@ -200,7 +200,7 @@ function parsePostfix(s: ITokenStream, expr: Ast.Node): Ast.Node { function parseAtom(s: ITokenStream, isStatic: boolean): Ast.Node { const startPos = s.getPos(); - switch (s.getToken().kind) { + switch (s.getTokenKind()) { case TokenKind.IfKeyword: { if (isStatic) break; return parseIf(s); @@ -290,7 +290,7 @@ function parseAtom(s: ITokenStream, isStatic: boolean): Ast.Node { return expr; } } - throw new AiScriptSyntaxError(`unexpected token: ${TokenKind[s.getToken().kind]}`, startPos); + throw new AiScriptSyntaxError(`unexpected token: ${TokenKind[s.getTokenKind()]}`, startPos); } /** @@ -311,7 +311,7 @@ function parseCall(s: ITokenStream, target: Ast.Node): Ast.Node { items.push(parseExpr(s, false)); // separator - switch (s.getToken().kind) { + switch (s.getTokenKind()) { case TokenKind.NewLine: { s.next(); break; @@ -433,7 +433,7 @@ function parseMatch(s: ITokenStream): Ast.Node { qs.push({ q, a }); // separator - switch (s.getToken().kind) { + switch (s.getTokenKind()) { case TokenKind.NewLine: { s.next(); break; @@ -463,7 +463,7 @@ function parseMatch(s: ITokenStream): Ast.Node { x = parseBlockOrStatement(s); // separator - switch (s.getToken().kind) { + switch (s.getTokenKind()) { case TokenKind.NewLine: { s.next(); break; @@ -579,7 +579,7 @@ function parseObject(s: ITokenStream, isStatic: boolean): Ast.Node { map.set(k, v); // separator - switch (s.getToken().kind) { + switch (s.getTokenKind()) { case TokenKind.NewLine: case TokenKind.Comma: { s.next(); @@ -623,7 +623,7 @@ function parseArray(s: ITokenStream, isStatic: boolean): Ast.Node { value.push(parseExpr(s, isStatic)); // separator - switch (s.getToken().kind) { + switch (s.getTokenKind()) { case TokenKind.NewLine: case TokenKind.Comma: { s.next(); @@ -660,7 +660,7 @@ function parsePratt(s: ITokenStream, minBp: number): Ast.Node { let left: Ast.Node; - const tokenKind = s.getToken().kind; + const tokenKind = s.getTokenKind(); const prefix = operators.find((x): x is PrefixInfo => x.opKind === 'prefix' && x.kind === tokenKind); if (prefix != null) { left = parsePrefix(s, prefix.bp); @@ -676,7 +676,7 @@ function parsePratt(s: ITokenStream, minBp: number): Ast.Node { s.next(); } - const tokenKind = s.getToken().kind; + const tokenKind = s.getTokenKind(); const postfix = operators.find((x): x is PostfixInfo => x.opKind === 'postfix' && x.kind === tokenKind); if (postfix != null) { diff --git a/src/parser/syntaxes/statements.ts b/src/parser/syntaxes/statements.ts index 186f4005..32c2ee54 100644 --- a/src/parser/syntaxes/statements.ts +++ b/src/parser/syntaxes/statements.ts @@ -16,7 +16,7 @@ import type { ITokenStream } from '../streams/token-stream.js'; export function parseStatement(s: ITokenStream): Ast.Node { const startPos = s.getPos(); - switch (s.getToken().kind) { + switch (s.getTokenKind()) { case TokenKind.VarKeyword: case TokenKind.LetKeyword: { return parseVarDef(s); @@ -69,7 +69,7 @@ export function parseStatement(s: ITokenStream): Ast.Node { } export function parseDefStatement(s: ITokenStream): Ast.Node { - switch (s.getToken().kind) { + switch (s.getTokenKind()) { case TokenKind.VarKeyword: case TokenKind.LetKeyword: { return parseVarDef(s); @@ -78,7 +78,7 @@ export function parseDefStatement(s: ITokenStream): Ast.Node { return parseFnDef(s); } default: { - throw new AiScriptSyntaxError(`unexpected token: ${TokenKind[s.getToken().kind]}`, s.getPos()); + throw new AiScriptSyntaxError(`unexpected token: ${TokenKind[s.getTokenKind()]}`, s.getPos()); } } } @@ -107,7 +107,7 @@ function parseVarDef(s: ITokenStream): Ast.Node { const startPos = s.getPos(); let mut; - switch (s.getToken().kind) { + switch (s.getTokenKind()) { case TokenKind.LetKeyword: { mut = false; break; @@ -117,7 +117,7 @@ function parseVarDef(s: ITokenStream): Ast.Node { break; } default: { - throw new AiScriptSyntaxError(`unexpected token: ${TokenKind[s.getToken().kind]}`, s.getPos()); + throw new AiScriptSyntaxError(`unexpected token: ${TokenKind[s.getTokenKind()]}`, s.getPos()); } } s.next(); @@ -463,7 +463,7 @@ function tryParseAssign(s: ITokenStream, dest: Ast.Node): Ast.Node | undefined { const startPos = s.getPos(); // Assign - switch (s.getToken().kind) { + switch (s.getTokenKind()) { case TokenKind.Eq: { s.next(); const expr = parseExpr(s, false); diff --git a/src/parser/syntaxes/toplevel.ts b/src/parser/syntaxes/toplevel.ts index b082f416..36454854 100644 --- a/src/parser/syntaxes/toplevel.ts +++ b/src/parser/syntaxes/toplevel.ts @@ -20,7 +20,7 @@ export function parseTopLevel(s: ITokenStream): Ast.Node[] { } while (!s.is(TokenKind.EOF)) { - switch (s.getToken().kind) { + switch (s.getTokenKind()) { case TokenKind.Colon2: { nodes.push(parseNamespace(s)); break; @@ -36,10 +36,10 @@ export function parseTopLevel(s: ITokenStream): Ast.Node[] { } // terminator - switch (s.getToken().kind) { + switch (s.getTokenKind()) { case TokenKind.NewLine: case TokenKind.SemiColon: { - while ([TokenKind.NewLine, TokenKind.SemiColon].includes(s.getToken().kind)) { + while ([TokenKind.NewLine, TokenKind.SemiColon].includes(s.getTokenKind())) { s.next(); } break; @@ -80,7 +80,7 @@ export function parseNamespace(s: ITokenStream): Ast.Node { } while (!s.is(TokenKind.CloseBrace)) { - switch (s.getToken().kind) { + switch (s.getTokenKind()) { case TokenKind.VarKeyword: case TokenKind.LetKeyword: case TokenKind.At: { @@ -94,10 +94,10 @@ export function parseNamespace(s: ITokenStream): Ast.Node { } // terminator - switch (s.getToken().kind) { + switch (s.getTokenKind()) { case TokenKind.NewLine: case TokenKind.SemiColon: { - while ([TokenKind.NewLine, TokenKind.SemiColon].includes(s.getToken().kind)) { + while ([TokenKind.NewLine, TokenKind.SemiColon].includes(s.getTokenKind())) { s.next(); } break;