Expand description
The arena-allocated AST and its printer.
Design: spec/06-lexer-and-parser.md. Layer rank 6, see spec/18-package-layout.md.
§Status
The tree is here: the three arenas, the side tables, the nodes for every expression,
statement and declaration this compiler intends to parse, the declarator representation that
the type system reads, and the Printer that writes any of it back out as C. What fills
the tree in is rucc-parse.
Every crate in the workspace is published, and publishing implies a promise. This one is
tier 3: its Rust API is explicitly unstable and will change without a major version bump.
Depend on the rucc binary’s behaviour, not on this.
§What shape the tree is
Flat vectors and four-byte indices, per spec/03-architecture.md section 3.3. An Ast
owns everything in one translation unit, Expr, Stmt and Decl live in three
arenas of their own, and anything that would make a node bigger than it needs to be lives in
a side table with an index in the node. Spans are in a vector parallel to each arena rather
than in the node, because almost nothing that walks the tree reads them.
use rucc_ast::{Ast, BinaryOp, Expr};
use rucc_diag::Span;
let mut ast = Ast::new();
let left = ast.expr(Expr::Bool(true), Span::new(0, 4));
let right = ast.expr(Expr::Bool(false), Span::new(8, 13));
let both = ast.expr(Expr::Binary { op: BinaryOp::LogAnd, lhs: left, rhs: right },
Span::new(0, 13));
assert_eq!(ast[left], Expr::Bool(true));
assert_eq!(ast.expr_span(both), Span::new(0, 13));
assert_eq!(ast.counts().exprs, 3);§What the tree does not do
It is not desugared and it never will be. a[i] is a subscript, a += b is a compound
assignment, a for loop is a for loop, and a switch is a statement with cases in it
rather than a table. Rewriting any of that here would make every diagnostic after this point
talk about a program nobody wrote. The rewriting happens once, at IR construction, in
spec/08-ir.md.
It is also untyped. A Expr::Name is an identifier and not a declaration, a
TypeSpec::Typedef is the name a typedef was written with and not the type behind it, and
nothing here holds a type from rucc-types. Names are resolved and types are assigned by
rucc-sema, which produces the typed tree that everything downstream reads.
The one place the tree does more than record what was written is Builtin, which holds
the type keywords as the multiset they were written in and turns them into a type with
Builtin::resolve. That is a table rather than a judgement, it is the same table in every
dialect, and it is much easier to get right with a test next to it than spread across the
parser.
Structs§
- Asm
- An
asmstatement or a file-scopeasm. - AsmOperand
- One operand of an assembly statement.
- AsmQuals
- The qualifiers on an assembly statement, as a set.
- Ast
- Every node of one translation unit.
- Attribute
- One attribute.
- Basic
- A built-in type, once the keywords have been read together.
- Builtin
- The keywords naming a built-in type, as the multiset that was written.
- Builtin
Set - The set of built-in type keywords, without the count of
long. - Counts
- How many nodes of each kind a tree holds.
- DeclRef
- The table of references to declarations.
- Decl
Specs - Everything a declaration says before its first declarator.
- Declarator
- A name and the steps that build its type outward from it.
- Enumerator
- One enumerator of an enumeration.
- ExprRef
- The table of references to expressions, which is what a call’s arguments are a run of.
- Field
- One member of a struct or a union.
- Func
Specs - The function specifiers, as a set.
- Generic
Assoc - One arm of a
_Genericselection. - Init
Declarator - One declarator of a declaration, with whatever follows it.
- Init
Item - One element of a braced initializer list.
- Param
- One parameter of a function declarator.
- Printer
- A tree being written out as C.
- Quals
- The type qualifiers, as a set.
- StmtRef
- The table of references to statements, which is what a compound statement is a run of.
- StrRef
- The table of references to string literals, which is what an
asmclobber list is a run of. - Type
Name - A type written where a type is expected rather than where a declaration is.
Enums§
- Align
Spec - An
alignasspecifier, which takes either a type or a constant expression. - Array
Size - What was written between a declarator’s brackets.
- AttrArg
- One argument of an attribute.
- Attr
Syntax - Which spelling an attribute was written in.
- Binary
Op - An operator with two operands.
- Builtin
Error - Why a built-in type keyword could not be added.
- Complexity
- Whether a built-in type is real, complex or imaginary.
- Decl
- One declaration.
- Derived
- One step in a declarator, taking a type to another type.
- Designator
- One step of a designation, or of a
__builtin_offsetofmember path. - Expr
- One expression node.
- ForInit
- The first clause of a
forstatement. - Init
- What an object is initialized with.
- Member
- One entry in a struct or union member list.
- Param
Kind - Which of the four shapes a function declarator’s parameter list has.
- Record
Kind - Which of the two record kinds.
- Scalar
- A built-in type named by keywords, with the sign folded in.
- Stmt
- One statement node.
- Storage
Class - A storage class specifier.
- Type
Spec - What type a declaration named.
- Typeof
Arg - What a
typeofwas applied to. - UnaryOp
- An operator with one operand.
Constants§
- MAX_
DECLARATOR_ DEPTH - How deeply declarators may nest before the parser gives up.
- MILESTONE
- The milestone in
spec/17-milestones.mdthat fills this crate in.
Functions§
- The whole translation unit, as text.
Type Aliases§
- AsmId
- An assembly statement, in the side table.
- AsmOperand
List - A run of assembly operands.
- Attr
ArgList - A run of attribute arguments.
- Attr
List - A run of attributes.
- CharId
- A character constant, in the constant table.
- DeclId
- A declaration in the declaration arena.
- Decl
List - A run of declarations.
- Decl
Specs Id - A set of declaration specifiers, in the side table.
- Declarator
Id - A declarator, in the side table.
- Derived
List - A run of declarator derivations.
- Designator
List - A run of designators.
- Enumerator
List - A run of enumerators.
- ExprId
- An expression in the expression arena.
- Expr
List - A run of expressions.
- FloatId
- A floating constant, in the constant table.
- Generic
List - A run of
_Genericassociations. - Init
Declarator List - A run of init-declarators.
- InitId
- An initializer, in the side table.
- Init
Item List - A run of braced initializer elements.
- IntId
- An integer constant, in the constant table.
- Member
List - A run of struct or union members.
- Param
List - A run of function parameters.
- StmtId
- A statement in the statement arena.
- Stmt
List - A run of statements.
- StrId
- A string literal, in the constant table.
- StrList
- A run of string literals.
- Symbol
List - A run of identifiers.
- Type
Name Id - A type name, in the side table.