Abstract Syntax Tree
The AodhML AST is a tree representation of parsed source code. Each node carries source location information for accurate error reporting.
AST Node Types
// Program root
type Program = struct {
imports: [ImportDecl],
declarations: [Decl],
loc: SourceLoc,
}
// Import declaration
type ImportDecl = struct {
path: String,
items: Option<[String]>,
alias: Option<String>,
loc: SourceLoc,
}
// Function declaration
type FunctionDecl = struct {
name: String,
generics: Option<[String]>,
params: [Param],
return_type: Option<TypeExpr>,
body: Block,
is_public: bool,
loc: SourceLoc,
}
// Type declaration
type TypeDecl = struct {
name: String,
generics: Option<[String]>,
definition: TypeDef,
is_public: bool,
loc: SourceLoc,
}
// Expression
type Expr = enum {
Literal(Literal),
Identifier(String),
Binary(BinaryExpr),
Unary(UnaryExpr),
Call(CallExpr),
MemberAccess(MemberExpr),
Index(IndexExpr),
Block(Block),
If(IfExpr),
For(ForExpr),
While(WhileExpr),
Match(MatchExpr),
Return(Option<Expr>),
ArrayLiteral([Expr]),
StructLiteral(StructLiteralExpr),
Closure(ClosureExpr),
}
Source Locations
Every AST node carries a SourceLoc for precise error reporting:
type SourceLoc = struct {
file: String,
line: u32,
column: u32,
length: u32, // Token length in bytes
}
// Example error message:
// error[E0031]: type mismatch
// --> src/main.aodh:12:15
// |
// 12 | let x: i32 = "hello"
// | ^^^^^^^ expected i32, found String
// |
// = help: try removing the type annotation or using a numeric literal
AST Visitors
The compiler uses the visitor pattern for traversing the AST:
// Rust-like pseudocode for the visitor trait
trait AstVisitor {
fn visit_program(&mut self, program: &Program);
fn visit_function(&mut self, func: &FunctionDecl);
fn visit_expr(&mut self, expr: &Expr);
fn visit_stmt(&mut self, stmt: &Stmt);
// ... etc
}