From 4d064042e8a6ebf874fecbc23f13073f39fa1ebe Mon Sep 17 00:00:00 2001 From: Nathan Reiner Date: Thu, 30 Jul 2026 07:46:37 +0200 Subject: first version of js parser --- src/z/js/parser/ast.zig | 674 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 src/z/js/parser/ast.zig (limited to 'src/z/js/parser/ast.zig') diff --git a/src/z/js/parser/ast.zig b/src/z/js/parser/ast.zig new file mode 100644 index 0000000..1fb8797 --- /dev/null +++ b/src/z/js/parser/ast.zig @@ -0,0 +1,674 @@ +pub const Loc = struct { + start: usize, + end: usize, +}; + +pub const Node = union(enum) { + program: Program, + + stmt: Stmt, + expr: Expr, + pat: Pat, + + decl: Decl, + literal: Lit, + property: Prop, + template: Template, + spread: Spread, + decorator: Decorator, + + import_specifier: ImportSpecifier, + export_specifier: ExportSpecifier, + import_attr: ImportAttribute, + catch_clause: CatchClause, + switch_case: SwitchCase, +}; + +pub const Program = struct { + body: []const Node, + loc: Loc, +}; + +pub const StmtType = union(enum) { + block: BlockStmt, + empty: void, + debugger: void, + expr: ExprStmt, + @"if": IfStmt, + @"while": WhileStmt, + do_while: DoWhileStmt, + @"for": ForStmt, + for_in: ForInStmt, + for_of: ForOfStmt, + @"continue": ContinueStmt, + @"break": BreakStmt, + @"return": ReturnStmt, + @"switch": SwitchStmt, + throw: ThrowStmt, + @"try": TryStmt, + labelled: LabelledStmt, + with: WithStmt, + variable: VarStmt, + using: UsingStmt, + import: ImportDecl, + @"export": ExportDecl, +}; + +pub const Stmt = struct { + loc: Loc, + data: StmtType, +}; + +pub const ExprType = union(enum) { + identifier: []const u8, + this: void, + super: void, + null: void, + bool: bool, + number: f64, + string: []const u8, + regex: Regex, + array: ArrayExpr, + object: ObjectExpr, + func: FnExpr, + arrow: ArrowFn, + class: ClassExpr, + template: TemplateLit, + tagged_template: TaggedTemplate, + member: MemberExpr, + computed_member: ComputedMember, + call: CallExpr, + new: NewExpr, + chain: ChainExpr, + unary: UnaryExpr, + binary: BinaryExpr, + update: UpdateExpr, + conditional: IfExpr, + assign: AssignExpr, + sequence: SeqExpr, + spread: SpreadElem, + yield: YieldExpr, + await: AwaitExpr, + meta_prop: MetaProp, + parenthesized: *const Expr, + private_ident: []const u8, +}; + +pub const Expr = struct { + loc: Loc, + data: ExprType, +}; + +pub const PatType = union(enum) { + ident: []const u8, + object: ObjectPat, + array: ArrayPat, + assign: AssignPat, + rest: RestPat, +}; + +pub const Pat = struct { + loc: Loc, + data: PatType, +}; + +pub const DeclType = union(enum) { + @"fn": FnDecl, + class: ClassDecl, + @"var": VarDecl, + lexical: LexicalDecl, + using: UsingDecl, + import: ImportDecl, + @"export": ExportDecl, + export_default: ExportDefault, +}; + +pub const Decl = struct { + loc: Loc, + data: DeclType, +}; + +pub const LitType = union(enum) { + null: void, + bool: bool, + number: f64, + string: []const u8, + regex: Regex, + bigint: []const u8, +}; + +pub const Lit = struct { + loc: Loc, + data: LitType, +}; + +pub const Regex = struct { + pattern: []const u8, + flags: []const u8, +}; + +pub const PropType = union(enum) { + init: PropInit, + get: PropGet, + set: PropSet, + shorthand: []const u8, + spread: SpreadElem, + method: FnExpr, +}; + +pub const Prop = struct { + loc: Loc, + key: PropKey, + data: PropType, +}; + +pub const PropKey = union(enum) { + ident: []const u8, + string: []const u8, + number: f64, + computed: *const Expr, + private: []const u8, +}; + +pub const PropInit = struct { + key: PropKey, + value: *const Expr, +}; + +pub const PropGet = struct { + key: PropKey, + body: BlockStmt, +}; + +pub const PropSet = struct { + key: PropKey, + param: Pat, + body: BlockStmt, +}; + +pub const SpreadElem = struct { + loc: Loc, + arg: *const Expr, +}; + +pub const BlockStmt = struct { + loc: Loc, + body: []const Stmt, +}; + +pub const ExprStmt = struct { + loc: Loc, + expr: *const Expr, +}; + +pub const IfStmt = struct { + loc: Loc, + condition: *const Expr, + consequent: *const Stmt, + alternate: ?*const Stmt, +}; + +pub const WhileStmt = struct { + loc: Loc, + condition: *const Expr, + body: *const Stmt, +}; + +pub const DoWhileStmt = struct { + loc: Loc, + body: *const Stmt, + condition: *const Expr, +}; + +pub const ForStmt = struct { + loc: Loc, + init: ?union(enum) { + expr: *const Expr, + decl: *const Decl, + }, + condition: ?*const Expr, + update: ?*const Expr, + body: *const Stmt, +}; + +pub const ForInStmt = struct { + loc: Loc, + left: union(enum) { + expr: *const Expr, + decl: *const Decl, + }, + right: *const Expr, + body: *const Stmt, +}; + +pub const ForOfStmt = struct { + loc: Loc, + await_token: bool, + left: union(enum) { + expr: *const Expr, + decl: *const Decl, + }, + right: *const Expr, + body: *const Stmt, +}; + +pub const ContinueStmt = struct { + loc: Loc, + label: ?[]const u8, +}; + +pub const BreakStmt = struct { + loc: Loc, + label: ?[]const u8, +}; + +pub const ReturnStmt = struct { + loc: Loc, + arg: ?*const Expr, +}; + +pub const SwitchStmt = struct { + loc: Loc, + discriminant: *const Expr, + cases: []const SwitchCase, +}; + +pub const SwitchCase = struct { + loc: Loc, + condition: ?*const Expr, + consequent: []const Stmt, +}; + +pub const ThrowStmt = struct { + loc: Loc, + arg: *const Expr, +}; + +pub const TryStmt = struct { + loc: Loc, + block: BlockStmt, + handler: ?CatchClause, + finalizer: ?BlockStmt, +}; + +pub const CatchClause = struct { + loc: Loc, + param: ?Pat, + body: BlockStmt, +}; + +pub const LabelledStmt = struct { + loc: Loc, + label: []const u8, + body: *const Stmt, +}; + +pub const WithStmt = struct { + loc: Loc, + obj: *const Expr, + body: *const Stmt, +}; + +pub const VarStmt = struct { + loc: Loc, + kind: VarKind, + decls: []const VarDeclarator, +}; + +pub const UsingStmt = struct { + loc: Loc, + decls: []const VarDeclarator, +}; + +pub const VarKind = enum { + @"var", + let, + @"const", +}; + +pub const VarDecl = struct { + loc: Loc, + kind: VarKind, + decls: []const VarDeclarator, +}; + +pub const LexicalDecl = struct { + loc: Loc, + kind: VarKind, + decls: []const VarDeclarator, +}; + +pub const UsingDecl = struct { + loc: Loc, + is_await: bool, + decls: []const VarDeclarator, +}; + +pub const VarDeclarator = struct { + loc: Loc, + id: Pat, + init: ?*const Expr, +}; + +pub const ObjectPat = struct { + loc: Loc, + props: []const PatProp, + rest: ?*const Pat, +}; + +pub const PatProp = union(enum) { + key_value: struct { + key: PropKey, + value: *const Pat, + }, + shorthand: []const u8, + rest: *const Pat, +}; + +pub const ArrayPat = struct { + loc: Loc, + elems: []const ?Pat, + rest: ?*const Pat, +}; + +pub const AssignPat = struct { + loc: Loc, + left: *const Pat, + right: *const Expr, +}; + +pub const RestPat = struct { + loc: Loc, + arg: *const Pat, +}; + +pub const FnType = union(enum) { + normal: void, + generator: void, + async: void, + async_generator: void, +}; + +pub const FnDecl = struct { + loc: Loc, + fn_type: FnType, + id: ?[]const u8, + params: []const Pat, + body: BlockStmt, +}; + +pub const FnExpr = struct { + loc: Loc, + fn_type: FnType, + id: ?[]const u8, + params: []const Pat, + body: BlockStmt, +}; + +pub const ArrowFn = struct { + loc: Loc, + async_token: bool, + params: []const Pat, + body: union(enum) { + block: BlockStmt, + expr: *const Expr, + }, +}; + +pub const ClassDecl = struct { + loc: Loc, + id: ?[]const u8, + super_class: ?*const Expr, + body: []const ClassElem, +}; + +pub const ClassExpr = struct { + loc: Loc, + id: ?[]const u8, + super_class: ?*const Expr, + body: []const ClassElem, +}; + +pub const ClassElem = union(enum) { + method: FnExpr, + get: PropGet, + set: PropSet, + field: FieldDef, + static_block: BlockStmt, + static_method: FnExpr, + static_get: PropGet, + static_set: PropSet, + static_field: FieldDef, +}; + +pub const FieldDef = struct { + loc: Loc, + key: PropKey, + value: ?*const Expr, +}; + +pub const ImportDecl = struct { + loc: Loc, + specifiers: []const ImportSpecifier, + source: []const u8, + attributes: []const ImportAttribute, +}; + +pub const ImportSpecifier = union(enum) { + default: []const u8, + namespace: []const u8, + named: struct { imported: []const u8, local: []const u8 }, +}; + +pub const ImportAttribute = struct { + key: []const u8, + value: []const u8, +}; + +pub const ExportDecl = struct { + loc: Loc, + declaration: ?*const Decl, + specifiers: ?[]const ExportSpecifier, + source: ?[]const u8, +}; + +pub const ExportSpecifier = struct { + loc: Loc, + exported: []const u8, + local: []const u8, +}; + +pub const ExportDefault = struct { + loc: Loc, + declaration: *const Decl, +}; + +pub const ArrayExpr = struct { + loc: Loc, + elems: []const ?Expr, +}; + +pub const ObjectExpr = struct { + loc: Loc, + props: []const Prop, +}; + +pub const MemberExpr = struct { + loc: Loc, + obj: *const Expr, + prop: union(enum) { + ident: []const u8, + private: []const u8, + }, +}; + +pub const ComputedMember = struct { + loc: Loc, + obj: *const Expr, + expr: *const Expr, +}; + +pub const CallExpr = struct { + loc: Loc, + callee: *const Expr, + args: []const Expr, + optional: bool, +}; + +pub const NewExpr = struct { + loc: Loc, + callee: *const Expr, + args: []const Expr, +}; + +pub const ChainExpr = struct { + loc: Loc, + expr: *const Expr, +}; + +pub const UnaryOp = enum { + @"-", + @"+", + @"!", + @"~", + typeof, + void, + delete, +}; + +pub const UnaryExpr = struct { + loc: Loc, + op: UnaryOp, + arg: *const Expr, + prefix: bool, +}; + +pub const BinaryOp = enum { + @"==", + @"!=", + @"===", + @"!==", + @"<", + @"<=", + @">", + @">=", + @"<<", + @">>", + @">>>", + @"+", + @"-", + @"*", + @"/", + @"%", + @"**", + @"|", + @"^", + @"&", + in, + instanceof, + @"||", + @"&&", + @"??", +}; + +pub const BinaryExpr = struct { + loc: Loc, + op: BinaryOp, + left: *const Expr, + right: *const Expr, +}; + +pub const UpdateOp = enum { + @"++", + @"--", +}; + +pub const UpdateExpr = struct { + loc: Loc, + op: UpdateOp, + arg: *const Expr, + prefix: bool, +}; + +pub const IfExpr = struct { + loc: Loc, + condition: *const Expr, + consequent: *const Expr, + alternate: *const Expr, +}; + +pub const AssignOp = enum { + @"=", + @"+=", + @"-=", + @"*=", + @"/=", + @"%=", + @"**=", + @"<<=", + @">>=", + @">>>=", + @"|=", + @"^=", + @"&=", + @"||=", + @"&&=", + @"??=", +}; + +pub const AssignExpr = struct { + loc: Loc, + op: AssignOp, + left: *const Expr, + right: *const Expr, +}; + +pub const SeqExpr = struct { + loc: Loc, + exprs: []const Expr, +}; + +pub const SpreadElem = struct { + loc: Loc, + arg: *const Expr, +}; + +pub const YieldExpr = struct { + loc: Loc, + arg: ?*const Expr, + delegate: bool, +}; + +pub const AwaitExpr = struct { + loc: Loc, + arg: *const Expr, +}; + +pub const MetaProp = struct { + loc: Loc, + meta: []const u8, + prop: []const u8, +}; + +pub const TemplateLit = struct { + loc: Loc, + quasis: []const TemplateElem, + exprs: []const Expr, +}; + +pub const TemplateElem = struct { + loc: Loc, + value: []const u8, + tail: bool, +}; + +pub const TaggedTemplate = struct { + loc: Loc, + tag: *const Expr, + quasi: TemplateLit, +}; + +pub const Decorator = struct { + loc: Loc, + expr: *const Expr, +}; -- cgit v1.2.3-70-g09d2