@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
text/typescript
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,
);
}
}
}