Nearly complete Zig AST
This commit is contained in:
@@ -1,50 +1,497 @@
|
||||
// Abstract Syntax Tree (AST) definitions for Zig, closely following the grammar in zig-grammar.peg
|
||||
package zig
|
||||
|
||||
// https://github.com/ziglang/zig-spec/blob/master/grammar/grammar.peg
|
||||
|
||||
// Root is the top-level node of a Zig source file.
|
||||
type Root struct {
|
||||
ContainerDocComment string // //! Doc Comment
|
||||
ContainerDocComment DocComment // //! Doc Comment (optional)
|
||||
ContainerMembers []*ContainerMember
|
||||
}
|
||||
|
||||
type ContainerMember struct {
|
||||
// FIXME
|
||||
Decls []Decl
|
||||
DocComment DocComment // /// Doc Comment (optional)
|
||||
Comptime bool // 'comptime' field (optional)
|
||||
Field *ContainerField
|
||||
Decl Decl // Can be nil if this is a field
|
||||
}
|
||||
|
||||
type Decl interface{}
|
||||
// ContainerField represents a field in a struct/enum/union container.
|
||||
type ContainerField struct {
|
||||
Name string // May be empty for anonymous fields
|
||||
Type TypeExpr
|
||||
ByteAlign *Expr // Optional
|
||||
Value Expr // Optional initializer
|
||||
}
|
||||
|
||||
// Decl is any top-level declaration (function, variable, usingnamespace, etc).
|
||||
type Decl interface {
|
||||
isDecl()
|
||||
}
|
||||
|
||||
// FnDecl represents a function declaration.
|
||||
type FnDecl struct {
|
||||
Name string
|
||||
Params []*ParamDecl
|
||||
CallConv string
|
||||
ReturnType TypeExpr
|
||||
Body *Block // nil means semicolon
|
||||
Export bool
|
||||
Extern bool
|
||||
ExternName string // Optional string for extern
|
||||
Inline bool
|
||||
NoInline bool
|
||||
ThreadLocal bool
|
||||
Name string // May be empty (anonymous)
|
||||
Params []*ParamDecl
|
||||
ByteAlign *Expr
|
||||
AddrSpace *Expr
|
||||
LinkSection *Expr
|
||||
CallConv *Expr
|
||||
ReturnType TypeExpr
|
||||
Body *Block // nil means semicolon
|
||||
}
|
||||
|
||||
func (*FnDecl) isDecl() {}
|
||||
|
||||
// GlobalVarDecl represents a global variable declaration.
|
||||
type GlobalVarDecl struct {
|
||||
Export bool
|
||||
Extern bool
|
||||
ExternName string // Optional string for extern
|
||||
ThreadLocal bool
|
||||
Const bool
|
||||
Name string
|
||||
Type TypeExpr // Optional
|
||||
ByteAlign *Expr
|
||||
AddrSpace *Expr
|
||||
LinkSection *Expr
|
||||
Value Expr // Optional initializer
|
||||
}
|
||||
|
||||
func (*GlobalVarDecl) isDecl() {}
|
||||
|
||||
// UsingNamespaceDecl represents a 'usingnamespace' declaration.
|
||||
type UsingNamespaceDecl struct {
|
||||
Expr Expr
|
||||
}
|
||||
|
||||
func (*UsingNamespaceDecl) isDecl() {}
|
||||
|
||||
// ComptimeDecl represents a 'comptime' block at the container level.
|
||||
type ComptimeDecl struct {
|
||||
Block *Block
|
||||
}
|
||||
|
||||
func (*ComptimeDecl) isDecl() {}
|
||||
|
||||
// TestDecl represents a 'test' declaration.
|
||||
type TestDecl struct {
|
||||
Name string // Optional
|
||||
Block *Block
|
||||
}
|
||||
|
||||
func (*TestDecl) isDecl() {}
|
||||
|
||||
// ParamDecl represents a function parameter.
|
||||
type ParamDecl struct {
|
||||
DocComment string // ??? It's what it says
|
||||
Name string // Can be empty
|
||||
Type TypeExpr // anytype when empty
|
||||
DocComment DocComment // /// Doc Comment (optional)
|
||||
NoAlias bool
|
||||
Comptime bool
|
||||
Name string // May be empty
|
||||
Type TypeExpr // 'anytype' if empty
|
||||
}
|
||||
|
||||
// Block represents a block of statements.
|
||||
type Block struct {
|
||||
Label string
|
||||
Label string // Optional
|
||||
Stmts []Stmt
|
||||
}
|
||||
|
||||
type Stmt interface{}
|
||||
// Stmt is any statement.
|
||||
type Stmt interface {
|
||||
isStmt()
|
||||
}
|
||||
|
||||
type ReturnStmt struct{}
|
||||
// ReturnStmt represents a 'return' statement.
|
||||
type ReturnStmt struct {
|
||||
Value Expr // Optional
|
||||
}
|
||||
|
||||
func (*ReturnStmt) isStmt() {}
|
||||
|
||||
// IfStmt represents an if statement (with optional else branch and payload).
|
||||
type IfStmt struct {
|
||||
Cond Expr // Condition expression
|
||||
Then Stmt // Then branch
|
||||
Else Stmt // Optional else branch
|
||||
Payload *Payload // Optional payload (for |x|, |*x|, |*x, y|, etc.)
|
||||
}
|
||||
|
||||
func (*IfStmt) isStmt() {}
|
||||
|
||||
// IfExpr represents an if expression (with optional else branch and payload).
|
||||
type IfExpr struct {
|
||||
Cond Expr // Condition expression
|
||||
Then Expr // Then branch
|
||||
Else Expr // Optional else branch
|
||||
Payload *Payload // Optional payload (for |x|, |*x|, |*x, y|, etc.)
|
||||
}
|
||||
|
||||
// DeferStmt represents a 'defer' or 'errdefer' statement.
|
||||
type DeferStmt struct {
|
||||
ErrDefer bool // True for 'errdefer', false for 'defer'
|
||||
Payload *Payload // Optional payload (for |x|, |*x|, etc.)
|
||||
Stmt Stmt // Statement to defer
|
||||
}
|
||||
|
||||
func (*DeferStmt) isStmt() {}
|
||||
|
||||
// SuspendStmt represents a 'suspend' or 'nosuspend' statement.
|
||||
type SuspendStmt struct {
|
||||
NoSuspend bool
|
||||
Stmt Stmt
|
||||
}
|
||||
|
||||
func (*SuspendStmt) isStmt() {}
|
||||
|
||||
// BlockStmt allows a block to be used as a statement.
|
||||
type BlockStmt struct {
|
||||
Block *Block
|
||||
}
|
||||
|
||||
func (*BlockStmt) isStmt() {}
|
||||
|
||||
// BreakStmt represents a 'break' statement.
|
||||
type BreakStmt struct {
|
||||
Label string // Optional
|
||||
Value Expr // Optional
|
||||
}
|
||||
|
||||
func (*BreakStmt) isStmt() {}
|
||||
|
||||
// ContinueStmt represents a 'continue' statement.
|
||||
type ContinueStmt struct {
|
||||
Label string // Optional
|
||||
}
|
||||
|
||||
func (*ContinueStmt) isStmt() {}
|
||||
|
||||
// LoopStmt represents a for/while loop statement.
|
||||
type LoopStmt struct {
|
||||
Inline bool // True if 'inline' is present
|
||||
Kind string // "for" or "while"
|
||||
Prefix LoopPrefix // ForPrefix or WhilePrefix
|
||||
Body Stmt // Loop body
|
||||
Else Stmt // Optional else branch
|
||||
Payload *Payload // Optional payload (for |x|, |*x|, |*x, y|, etc.)
|
||||
}
|
||||
|
||||
func (*LoopStmt) isStmt() {}
|
||||
|
||||
// LoopPrefix is the prefix of a for/while loop.
|
||||
type LoopPrefix interface{}
|
||||
|
||||
// ForPrefix represents the prefix of a for loop.
|
||||
type ForPrefix struct {
|
||||
Args []ForArg // For loop arguments
|
||||
Payload *Payload // Payload (|*x, y|, etc.)
|
||||
}
|
||||
|
||||
// ForArg represents an argument in a for loop.
|
||||
type ForArg struct {
|
||||
Expr Expr // Argument expression
|
||||
From Expr // Optional (for .. or ..<)
|
||||
}
|
||||
|
||||
// WhilePrefix represents the prefix of a while loop.
|
||||
type WhilePrefix struct {
|
||||
Cond Expr // Condition expression
|
||||
Payload *Payload // Optional payload (for |x|, |*x|, etc.)
|
||||
Continue Expr // Optional (while continue expression)
|
||||
}
|
||||
|
||||
// SwitchStmt represents a switch statement.
|
||||
type SwitchStmt struct {
|
||||
Cond Expr
|
||||
Prongs []*SwitchProng
|
||||
}
|
||||
|
||||
func (*SwitchStmt) isStmt() {}
|
||||
|
||||
// SwitchExpr represents a switch expression.
|
||||
type SwitchExpr struct {
|
||||
Cond Expr
|
||||
Prongs []*SwitchProng
|
||||
}
|
||||
|
||||
// SwitchProng represents a prong in a switch.
|
||||
type SwitchProng struct {
|
||||
Inline bool // True if 'inline' is present
|
||||
Cases []*SwitchCase // List of cases for this prong
|
||||
Payload *Payload // Optional payload (for |*x, y|, etc.)
|
||||
Expr Expr // Result expression for this prong
|
||||
}
|
||||
|
||||
// SwitchCase represents a case in a switch.
|
||||
type SwitchCase struct {
|
||||
Expr Expr
|
||||
To Expr // Optional (for ..)
|
||||
IsElse bool
|
||||
}
|
||||
|
||||
// AsmExpr represents an inline assembly expression.
|
||||
type AsmExpr struct {
|
||||
Volatile bool
|
||||
Template Expr
|
||||
Outputs []*AsmOutputItem
|
||||
Inputs []*AsmInputItem
|
||||
Clobbers []string
|
||||
}
|
||||
|
||||
// AsmOutputItem represents an output operand in asm.
|
||||
type AsmOutputItem struct {
|
||||
Name string
|
||||
Constraint string
|
||||
Type TypeExpr
|
||||
}
|
||||
|
||||
// AsmInputItem represents an input operand in asm.
|
||||
type AsmInputItem struct {
|
||||
Name string
|
||||
Constraint string
|
||||
Expr Expr
|
||||
}
|
||||
|
||||
// ContainerDecl represents a struct, enum, union, or opaque declaration.
|
||||
type ContainerDecl struct {
|
||||
Extern bool
|
||||
Packed bool
|
||||
Kind string // "struct", "enum", "union", "opaque"
|
||||
TagType TypeExpr // Optional (for enum/union)
|
||||
Fields []*ContainerMember
|
||||
DocComment DocComment
|
||||
}
|
||||
|
||||
// ErrorSetDecl represents an error set declaration.
|
||||
type ErrorSetDecl struct {
|
||||
Names []string
|
||||
}
|
||||
|
||||
// InitListExpr represents an initializer list.
|
||||
// Exactly one of Fields, Values, or Empty must be set (non-nil/non-empty or true).
|
||||
type InitListExpr struct {
|
||||
Fields []*FieldInit // Field initializers (for {.foo = 1, .bar = 2}), mutually exclusive with Values/Empty
|
||||
Values []Expr // Positional initializers (for {1, 2, 3}), mutually exclusive with Fields/Empty
|
||||
Empty bool // True if '{}', mutually exclusive with Fields/Values
|
||||
}
|
||||
|
||||
// FieldInit represents a field initializer in an init list.
|
||||
type FieldInit struct {
|
||||
Name string
|
||||
Value Expr
|
||||
}
|
||||
|
||||
// Identifier represents an identifier expression (variable, field, etc).
|
||||
type Identifier struct {
|
||||
Name string // The identifier name
|
||||
}
|
||||
|
||||
// Literal represents a literal value (int, float, string, char).
|
||||
type Literal struct {
|
||||
Kind string // "int", "float", "string", "char"
|
||||
Value string // The literal value as a string
|
||||
}
|
||||
|
||||
// BinaryExpr represents a binary operation (e.g. +, -, *, /, etc).
|
||||
type BinaryExpr struct {
|
||||
Op string // Operator, e.g. "+", "-", "*", etc.
|
||||
Left Expr // Left operand
|
||||
Right Expr // Right operand
|
||||
}
|
||||
|
||||
// UnaryExpr represents a unary operation (e.g. !, -, ~, etc).
|
||||
type UnaryExpr struct {
|
||||
Op string // Operator, e.g. "-", "!", "~"
|
||||
Expr Expr // Operand
|
||||
}
|
||||
|
||||
// GroupedExpr represents a parenthesized expression.
|
||||
type GroupedExpr struct {
|
||||
Expr Expr // The grouped expression
|
||||
}
|
||||
|
||||
// CallExpr represents a function call.
|
||||
type CallExpr struct {
|
||||
Fun Expr // Function being called
|
||||
Args []Expr // Arguments to the function
|
||||
}
|
||||
|
||||
// FieldAccessExpr represents a field/member access as a suffix operation (e.g. foo.bar).
|
||||
type FieldAccessExpr struct {
|
||||
Receiver Expr // The object being accessed
|
||||
Field string // The field name
|
||||
}
|
||||
|
||||
// IndexExpr represents an indexing operation as a suffix (e.g. arr[0]).
|
||||
type IndexExpr struct {
|
||||
Receiver Expr // The object being indexed
|
||||
Index Expr // The index expression
|
||||
}
|
||||
|
||||
// ResumeExpr represents a 'resume' expression.
|
||||
type ResumeExpr struct {
|
||||
Expr Expr // The expression to resume
|
||||
}
|
||||
|
||||
// ComptimeExpr represents a 'comptime' expression.
|
||||
type ComptimeExpr struct {
|
||||
Expr Expr // The expression to evaluate at comptime
|
||||
}
|
||||
|
||||
// NosuspendExpr represents a 'nosuspend' expression.
|
||||
type NosuspendExpr struct {
|
||||
Expr Expr // The expression to evaluate with nosuspend
|
||||
}
|
||||
|
||||
// ContinueExpr represents a 'continue' expression.
|
||||
type ContinueExpr struct {
|
||||
Label string // Optional label
|
||||
}
|
||||
|
||||
// Expr is any expression.
|
||||
type Expr interface{}
|
||||
|
||||
// This will need to become a real type expr someday
|
||||
type TypeExpr string
|
||||
// TypeExpr is any type expression.
|
||||
type TypeExpr interface{}
|
||||
|
||||
func (t TypeExpr) String() string {
|
||||
if string(t) == "" {
|
||||
return "anytype"
|
||||
}
|
||||
return string(t)
|
||||
// DocComment represents a doc comment (/// or //! lines).
|
||||
// Newlines in the string automatically add more comments in the output.
|
||||
type DocComment string
|
||||
|
||||
// Payload represents a control flow payload (|x|, |*x|, |*x, y|, etc).
|
||||
// Each entry in Names corresponds to a variable name; the same index in Pointers is true if that name is a pointer (|*x|).
|
||||
type Payload struct {
|
||||
Names []string // Names in the payload, in order
|
||||
Pointers []bool // True if the corresponding name is a pointer (|*x|, |*x, y|, |*x, *y|, etc.)
|
||||
}
|
||||
|
||||
// LabeledBlock represents a labeled block or loop (label: {...}).
|
||||
type LabeledBlock struct {
|
||||
Label string // The label name
|
||||
Block *Block // The labeled block
|
||||
}
|
||||
|
||||
// LabeledTypeExpr represents a labeled type block (label: type).
|
||||
type LabeledTypeExpr struct {
|
||||
Label string // The label name
|
||||
Type TypeExpr // The labeled type
|
||||
}
|
||||
|
||||
// IfTypeExpr represents an if expression at the type level.
|
||||
type IfTypeExpr struct {
|
||||
Cond Expr
|
||||
Then TypeExpr
|
||||
Else TypeExpr // Optional
|
||||
Payload *Payload // Optional
|
||||
}
|
||||
|
||||
// ForTypeExpr represents a for expression at the type level.
|
||||
type ForTypeExpr struct {
|
||||
Prefix *ForPrefix
|
||||
Body TypeExpr
|
||||
Else TypeExpr // Optional
|
||||
Payload *Payload // Optional
|
||||
}
|
||||
|
||||
// WhileTypeExpr represents a while expression at the type level.
|
||||
type WhileTypeExpr struct {
|
||||
Prefix *WhilePrefix
|
||||
Body TypeExpr
|
||||
Else TypeExpr // Optional
|
||||
Payload *Payload // Optional
|
||||
}
|
||||
|
||||
// DotAsteriskExpr represents a .*
|
||||
type DotAsteriskExpr struct {
|
||||
Receiver Expr // The expression being dereferenced
|
||||
}
|
||||
|
||||
// DotQuestionExpr represents a .?
|
||||
type DotQuestionExpr struct {
|
||||
Receiver Expr // The expression being checked for optional
|
||||
}
|
||||
|
||||
// AsyncExpr represents an 'async' expression.
|
||||
type AsyncExpr struct {
|
||||
Expr Expr // The expression to be awaited asynchronously
|
||||
}
|
||||
|
||||
// TryExpr represents a 'try' expression.
|
||||
type TryExpr struct {
|
||||
Expr Expr // The expression to try
|
||||
}
|
||||
|
||||
// AwaitExpr represents an 'await' expression.
|
||||
type AwaitExpr struct {
|
||||
Expr Expr // The expression to await
|
||||
}
|
||||
|
||||
// UnreachableExpr represents the 'unreachable' keyword.
|
||||
type UnreachableExpr struct{}
|
||||
|
||||
// EmptyInitListExpr represents an empty initializer list '{}'.
|
||||
type EmptyInitListExpr struct{}
|
||||
|
||||
// PositionalInitListExpr represents a positional initializer list '{expr, ...}'.
|
||||
type PositionalInitListExpr struct {
|
||||
Values []Expr // Expressions in order
|
||||
}
|
||||
|
||||
// FieldInitListExpr represents a field initializer list '{.field = expr, ...}'.
|
||||
type FieldInitListExpr struct {
|
||||
Fields []*FieldInit // Field initializers
|
||||
}
|
||||
|
||||
// SwitchProngPayload represents a switch prong payload (|*x, y|).
|
||||
type SwitchProngPayload struct {
|
||||
Pointer bool
|
||||
Names []string
|
||||
}
|
||||
|
||||
// SwitchProngCase represents a single case in a switch prong.
|
||||
type SwitchProngCase struct {
|
||||
Expr Expr // The case expression
|
||||
To Expr // Optional, for ranges
|
||||
}
|
||||
|
||||
// SwitchProngFull represents a full switch prong with cases and payload.
|
||||
type SwitchProngFull struct {
|
||||
Inline bool
|
||||
Cases []*SwitchProngCase // One or more cases
|
||||
Payload *SwitchProngPayload // Optional
|
||||
Expr Expr // The result expression
|
||||
}
|
||||
|
||||
// SwitchElseProng represents an 'else' prong in a switch.
|
||||
type SwitchElseProng struct {
|
||||
Expr Expr // The result expression
|
||||
}
|
||||
|
||||
// VarPattern represents a variable pattern for destructuring or multiple variable declarations.
|
||||
type VarPattern struct {
|
||||
Names []string // Variable names (single or multiple for destructuring)
|
||||
}
|
||||
|
||||
// VarDeclStmt represents a variable or const declaration at statement level, supporting destructuring and multi-var declarations.
|
||||
type VarDeclStmt struct {
|
||||
Const bool
|
||||
Pattern VarPattern // Destructuring or multiple variable names
|
||||
Type TypeExpr // Optional
|
||||
Value Expr // Optional initializer
|
||||
ByteAlign Expr // Optional
|
||||
AddrSpace Expr // Optional
|
||||
LinkSection Expr // Optional
|
||||
}
|
||||
|
||||
func (*VarDeclStmt) isStmt() {}
|
||||
|
||||
// DotCallExpr represents a method call expression where a method is called on a receiver.
|
||||
// For example, in the expression `foo.bar()`, `foo` is the Receiver and `bar()` is the Call.
|
||||
type DotCallExpr struct {
|
||||
Receiver Expr // The expression being called (e.g. foo)
|
||||
Call *CallExpr
|
||||
}
|
||||
|
Reference in New Issue
Block a user