UNPKG

@flowscripter/mpeg-sdl-parser

Version:

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

183 lines (157 loc) 5.32 kB
import { AstPath, type Doc, doc } from "prettier"; import { getDocWithTrivia } from "./print_utils"; import type { PartialArrayDimension } from "../ast/node/PartialArrayDimension"; import { ArrayDimensionKind } from "../ast/node/enum/array_dimension_kind"; import type { ArrayDefinition } from "../ast/node/ArrayDefinition"; import type { AbstractArrayDimension } from "../ast/node/AbstractArrayDimension"; import type { AbstractNode } from "../ast/node/AbstractNode"; import type { ComputedArrayDefinition } from "../ast/node/ComputedArrayDefinition"; import type { ExplicitArrayDimension } from "../ast/node/ExplicitArrayDimension"; import type { ImplicitArrayDimension } from "../ast/node/ImplicitArrayDimension"; const { join } = doc.builders; export function printAbstractArrayDimension( path: AstPath<AbstractArrayDimension>, print: (path: AstPath<AbstractNode>) => Doc, ): Doc { const { arrayDimensionKind } = path.node; switch (arrayDimensionKind) { case ArrayDimensionKind.EXPLICIT: { const explicitArrayDimensionNode = path.node as ExplicitArrayDimension; return [ getDocWithTrivia(explicitArrayDimensionNode.openBracketPunctuator), (path as AstPath<ExplicitArrayDimension>).call(print, "size"), getDocWithTrivia( explicitArrayDimensionNode.closeBracketPunctuator, ), ]; } case ArrayDimensionKind.PARTIAL: { const partialArrayDimensionNode = path.node as PartialArrayDimension; return [ getDocWithTrivia(partialArrayDimensionNode.openBracketPunctuator), getDocWithTrivia( partialArrayDimensionNode.innerOpenBracketPunctuator, ), (path as AstPath<PartialArrayDimension>).call(print, "index"), getDocWithTrivia( partialArrayDimensionNode.innerCloseBracketPunctuator, ), getDocWithTrivia(partialArrayDimensionNode.closeBracketPunctuator), ]; } case ArrayDimensionKind.IMPLICIT: { const node = path.node as ImplicitArrayDimension; const elements = []; elements.push(getDocWithTrivia(node.openBracketPunctuator)); elements.push("["); if (node.rangeStart !== undefined) { elements.push( path.call( print, "rangeStart" as keyof ImplicitArrayDimension["rangeStart"], ), ); } if (node.rangeEnd !== undefined) { elements.push(getDocWithTrivia(node.rangeOperator!)); elements.push( path.call( print, "rangeEnd" as keyof ImplicitArrayDimension["rangeEnd"], ), ); } elements.push(getDocWithTrivia(node.closeBracketPunctuator)); return elements; } default: { const exhaustiveCheck: never = arrayDimensionKind; throw new Error( "Unreachable code reached, arrayDimensionKind == " + exhaustiveCheck, ); } } } export function printArrayDefinition( path: AstPath<ArrayDefinition>, print: (path: AstPath<AbstractNode>) => Doc, ): Doc { const arrayDefinition = path.node; const elements = []; if (arrayDefinition.isReserved) { elements.push(getDocWithTrivia(arrayDefinition.reservedKeyword!)); } if (arrayDefinition.isLegacy) { elements.push(getDocWithTrivia(arrayDefinition.legacyKeyword!)); } if (arrayDefinition.alignedModifier !== undefined) { elements.push( path.call( print, "alignedModifier" as keyof ArrayDefinition["alignedModifier"], ), ); } if (arrayDefinition.elementaryType !== undefined) { const subElements = [ path.call( print, "elementaryType" as keyof ArrayDefinition["elementaryType"], ), path.call( print, "lengthAttribute" as keyof ArrayDefinition["lengthAttribute"], ), ]; elements.push(subElements); } else { elements.push( path.call( print, "classIdentifier" as keyof ArrayDefinition["classIdentifier"], ), ); } const identifierClause = [ path.call(print, "identifier"), ]; if (arrayDefinition.implicitArrayDimension !== undefined) { identifierClause.push( path.call( print, "implicitArrayDimension" as keyof ArrayDefinition[ "implicitArrayDimension" ], ), ); } if (arrayDefinition.dimensions !== undefined) { identifierClause.push( path.map( print, "dimensions" as keyof ArrayDefinition["dimensions"], ), ); } identifierClause.push( getDocWithTrivia(arrayDefinition.semicolonPunctuator), ); elements.push(identifierClause); return join(" ", elements); } export function printComputedArrayDefinition( path: AstPath<ComputedArrayDefinition>, print: (path: AstPath<AbstractNode>) => Doc, ): Doc { const computedArrayDefinition = path.node; const elements = []; elements.push(getDocWithTrivia(computedArrayDefinition.computedKeyword)); elements.push(path.call(print, "elementaryType")); const identifierClause = [path.call(print, "identifier")]; identifierClause.push(path.map(print, "dimensions")); identifierClause.push( getDocWithTrivia(computedArrayDefinition.semicolonPunctuator), ); elements.push(identifierClause); return join(" ", elements); }