UNPKG

@flowscripter/mpeg-sdl-parser

Version:

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

150 lines (132 loc) 4.21 kB
import { AstPath, type Doc, doc } from "prettier"; import { getDocWithTrivia } from "./print_utils"; import type { AbstractExpression } from "../ast/node/AbstractExpression"; import type { AbstractNode } from "../ast/node/AbstractNode"; import type { ArrayElementAccess } from "../ast/node/ArrayElementAccess"; import type { ClassMemberAccess } from "../ast/node/ClassMemberAccess"; import { ExpressionKind } from "../ast/node/enum/expression_kind"; import type { LengthofExpression } from "../ast/node/LengthofExpression"; import type { BinaryExpression } from "../ast/node/BinaryExpression"; import type { UnaryExpression } from "../ast/node/UnaryExpression"; const { join } = doc.builders; export function printClassMemberAccess( path: AstPath<ClassMemberAccess>, print: (path: AstPath<AbstractNode>) => Doc, ): Doc { const node = path.node; return [ getDocWithTrivia(node.classMemberAccessOperator), path.call(print, "memberIdentifier"), ]; } export function printArrayElementAccess( path: AstPath<ArrayElementAccess>, print: (path: AstPath<AbstractNode>) => Doc, ): Doc { const arrayElementAccess = path.node; return [ getDocWithTrivia(arrayElementAccess.openBracketPunctuator), path.call(print, "index"), getDocWithTrivia(arrayElementAccess.closeBracketPunctuator), ]; } function printUnaryExpression( path: AstPath<UnaryExpression>, print: (path: AstPath<AbstractNode>) => Doc, ): Doc { const unaryExpression = path.node; const elements = []; if (unaryExpression.unaryOperator !== undefined) { elements.push( getDocWithTrivia(unaryExpression.unaryOperator), ); } if (unaryExpression.openParenthesisPunctuator !== undefined) { elements.push( getDocWithTrivia(unaryExpression.openParenthesisPunctuator), ); } elements.push([ path.call( print, "operand" as keyof UnaryExpression["operand"], ), ]); if (unaryExpression.arrayElementAccess !== undefined) { elements.push( path.call( print, "arrayElementAccess" as keyof UnaryExpression["arrayElementAccess"], ), ); } if (unaryExpression.classMemberAccess !== undefined) { elements.push( path.call( print, "classMemberAccess" as keyof UnaryExpression["classMemberAccess"], ), ); } if (unaryExpression.closeParenthesisPunctuator !== undefined) { elements.push( getDocWithTrivia(unaryExpression.closeParenthesisPunctuator), ); } if (unaryExpression.postfixOperator !== undefined) { elements.push( getDocWithTrivia(unaryExpression.postfixOperator), ); } return elements; } function printBinaryExpression( path: AstPath<BinaryExpression>, print: (path: AstPath<AbstractNode>) => Doc, ): Doc { const node = path.node; return join(" ", [ path.call(print, "leftOperand"), getDocWithTrivia(node.binaryOperator), path.call(print, "rightOperand"), ]); } function printLengthOfExpression( path: AstPath<LengthofExpression>, print: (path: AstPath<AbstractNode>) => Doc, ): Doc { const lengthOfExpression = path.node; const elements = []; elements.push(getDocWithTrivia(lengthOfExpression.lengthOfKeyword)); elements.push( getDocWithTrivia(lengthOfExpression.openParenthesisPunctuator), ); elements.push(path.call(print, "operand")); elements.push( getDocWithTrivia(lengthOfExpression.closeParenthesisPunctuator), ); return elements; } export function printAbstractExpression( path: AstPath<AbstractExpression>, print: (path: AstPath<AbstractNode>) => Doc, ): Doc { const { expressionKind } = path.node; switch (expressionKind) { case ExpressionKind.BINARY: return printBinaryExpression(path as AstPath<BinaryExpression>, print); case ExpressionKind.LENGTHOF: return printLengthOfExpression( path as AstPath<LengthofExpression>, print, ); case ExpressionKind.UNARY: return printUnaryExpression(path as AstPath<UnaryExpression>, print); default: { const exhaustiveCheck: never = expressionKind; throw new Error( "Unreachable code reached, expressionKind == " + exhaustiveCheck, ); } } }