// Typed narrowers for AST nodes to avoid `(node as any)` in consumers. import type { ASTCtx, LuaExpression, LuaLValue, LuaStatement } from "./ast.ts"; // Extract by `type` discriminant type NarrowByType< U, K extends U extends { type: infer T } ? T : never, > = Extract; // Expressions export const asStringExpr = (e: LuaExpression) => e as NarrowByType; export const asNumberExpr = (e: LuaExpression) => e as NarrowByType; export const asBooleanExpr = (e: LuaExpression) => e as NarrowByType; export const asNilExpr = (e: LuaExpression) => e as NarrowByType; export const asUnary = (e: LuaExpression) => e as NarrowByType; export const asBinary = (e: LuaExpression) => e as NarrowByType; export const asVariable = (e: LuaExpression) => e as NarrowByType; export const asFunctionCall = (e: LuaExpression) => e as NarrowByType; export const asTableAccess = (e: LuaExpression) => e as NarrowByType; export const asPropertyAccess = (e: LuaExpression) => e as NarrowByType; export const asParenthesized = (e: LuaExpression) => e as NarrowByType; export const asTableConstructor = (e: LuaExpression) => e as NarrowByType; export const asFunctionDef = (e: LuaExpression) => e as NarrowByType; export const asQueryExpr = (e: LuaExpression) => e as NarrowByType; // L-values export const asLValueVariable = (l: LuaLValue) => l as Extract; export const asLValueTableAccess = (l: LuaLValue) => l as Extract; export const asLValuePropertyAccess = (l: LuaLValue) => l as Extract; // Statements export const asAssignment = (s: LuaStatement) => s as NarrowByType; export const asLocal = (s: LuaStatement) => s as NarrowByType; export const asBlock = (s: LuaStatement) => s as NarrowByType; export const asIf = (s: LuaStatement) => s as NarrowByType; export const asWhile = (s: LuaStatement) => s as NarrowByType; export const asRepeat = (s: LuaStatement) => s as NarrowByType; export const asBreak = (s: LuaStatement) => s as NarrowByType; export const asFunctionStmt = (s: LuaStatement) => s as NarrowByType; export const asLocalFunction = (s: LuaStatement) => s as NarrowByType; export const asFunctionCallStmt = (s: LuaStatement) => s as NarrowByType; export const asReturn = (s: LuaStatement) => s as NarrowByType; export const asFor = (s: LuaStatement) => s as NarrowByType; export const asForIn = (s: LuaStatement) => s as NarrowByType; export const asLabel = (s: LuaStatement) => s as NarrowByType; export const asGoto = (s: LuaStatement) => s as NarrowByType; export const asSemicolon = (s: LuaStatement) => s as NarrowByType; // Pull ctx with a single shape export const ctxOf = (node: { ctx: ASTCtx }): ASTCtx => node.ctx;