UNPKG

@flowscripter/mpeg-sdl-parser

Version:

ISO/IEC 14496-34 Syntactic Description Language (MPEG SDL) parser implemented in TypeScript

135 lines (127 loc) 5.34 kB
import { AstPath, type Doc, doc } from "prettier"; import { getDocWithTrivia } from "./print_utils"; import { printClassDeclaration, printClassDefinition } from "./print_class"; import { printMapDeclaration, printMapDefinition } from "./print_map"; import { printArrayDefinition, printComputedArrayDefinition, } from "./print_array"; import { printStringDefinition } from "./print_string"; import { printComputedElementaryTypeDefinition, printElementaryTypeDefinition, } from "./print_elementary_type"; import { printDoStatement } from "./print_do"; import { printForStatement } from "./print_for"; import { printWhileStatement } from "./print_while"; import { printIfStatement } from "./print_if"; import { printSwitchStatement } from "./print_switch"; import type { AbstractNode } from "../ast/node/AbstractNode"; import type { AbstractStatement } from "../ast/node/AbstractStatement"; import type { ArrayDefinition } from "../ast/node/ArrayDefinition"; import type { ClassDefinition } from "../ast/node/ClassDefinition"; import type { CompoundStatement } from "../ast/node/CompoundStatement"; import type { ComputedArrayDefinition } from "../ast/node/ComputedArrayDefinition"; import type { ComputedElementaryTypeDefinition } from "../ast/node/ComputedElementaryTypeDefinition"; import type { ElementaryTypeDefinition } from "../ast/node/ElementaryTypeDefinition"; import { StatementKind } from "../ast/node/enum/statement_kind"; import type { MapDeclaration } from "../ast/node/MapDeclaration"; import type { MapDefinition } from "../ast/node/MapDefinition"; import type { StringDefinition } from "../ast/node/StringDefinition"; import type { ExpressionStatement } from "../ast/node/ExpressionStatement"; import type { SwitchStatement } from "../ast/node/SwitchStatement"; import type { IfStatement } from "../ast/node/IfStatement"; import type { WhileStatement } from "../ast/node/WhileStatement"; import type { ForStatement } from "../ast/node/ForStatement"; import type { DoStatement } from "../ast/node/DoStatement"; import type { ClassDeclaration } from "../ast/node/ClassDeclaration"; const { hardline, indent, join } = doc.builders; function printCompoundStatement( path: AstPath<CompoundStatement>, print: (path: AstPath<AbstractNode>) => Doc, ): Doc { const node = path.node; const elements: Doc = [ getDocWithTrivia(node.openBracePunctuator), ]; if (node.statements.length > 0) { elements.push( indent([ hardline, join(hardline, path.map(print, "statements")), ]), ); } elements.push(hardline); elements.push(getDocWithTrivia(node.closeBracePunctuator)); return elements; } function printExpressionStatement( path: AstPath<ExpressionStatement>, print: (_path: AstPath<AbstractNode>) => Doc, ): Doc { const node = path.node; return [ path.call(print, "expression"), getDocWithTrivia(node.semicolonPunctuator), ]; } export function printStatement( path: AstPath<AbstractStatement>, print: (_path: AstPath<AbstractNode>) => Doc, ): Doc { const abstractStatement = path.node; const statementKind = abstractStatement.statementKind; switch (statementKind) { case StatementKind.ARRAY_DEFINITION: return printArrayDefinition(path as AstPath<ArrayDefinition>, print); case StatementKind.COMPUTED_ARRAY_DEFINITION: return printComputedArrayDefinition( path as AstPath<ComputedArrayDefinition>, print, ); case StatementKind.COMPUTED_ELEMENTARY_TYPE_DEFINITION: return printComputedElementaryTypeDefinition( path as AstPath<ComputedElementaryTypeDefinition>, print, ); case StatementKind.CLASS_DECLARATION: return printClassDeclaration(path as AstPath<ClassDeclaration>, print); case StatementKind.CLASS_DEFINITION: return printClassDefinition(path as AstPath<ClassDefinition>, print); case StatementKind.COMPOUND: return printCompoundStatement(path as AstPath<CompoundStatement>, print); case StatementKind.DO: return printDoStatement(path as AstPath<DoStatement>, print); case StatementKind.ELEMENTARY_TYPE_DEFINITION: return printElementaryTypeDefinition( path as AstPath<ElementaryTypeDefinition>, print, ); case StatementKind.EXPRESSION: return printExpressionStatement( path as AstPath<ExpressionStatement>, print, ); case StatementKind.FOR: return printForStatement(path as AstPath<ForStatement>, print); case StatementKind.IF: return printIfStatement(path as AstPath<IfStatement>, print); case StatementKind.MAP_DECLARATION: return printMapDeclaration(path as AstPath<MapDeclaration>, print); case StatementKind.MAP_DEFINITION: return printMapDefinition(path as AstPath<MapDefinition>, print); case StatementKind.STRING_DEFINITION: return printStringDefinition(path as AstPath<StringDefinition>, print); case StatementKind.SWITCH: return printSwitchStatement(path as AstPath<SwitchStatement>, print); case StatementKind.WHILE: return printWhileStatement(path as AstPath<WhileStatement>, print); default: { const exhaustiveCheck: never = statementKind; throw new Error( "Unreachable code reached, statementKind == " + exhaustiveCheck, ); } } }