Skip to main content

Crate rucc_ast

Crate rucc_ast 

Source
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 asm statement or a file-scope asm.
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.
BuiltinSet
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.
DeclSpecs
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.
FuncSpecs
The function specifiers, as a set.
GenericAssoc
One arm of a _Generic selection.
InitDeclarator
One declarator of a declaration, with whatever follows it.
InitItem
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 asm clobber list is a run of.
TypeName
A type written where a type is expected rather than where a declaration is.

Enums§

AlignSpec
An alignas specifier, which takes either a type or a constant expression.
ArraySize
What was written between a declarator’s brackets.
AttrArg
One argument of an attribute.
AttrSyntax
Which spelling an attribute was written in.
BinaryOp
An operator with two operands.
BuiltinError
Why a built-in type keyword could not be added.
Complexity
Whether a built-in type is real, complex or imaginary.
Decl
One declaration.
Deduction
Which of the two spellings asked for a deduced type.
Derived
One step in a declarator, taking a type to another type.
Designator
One step of a designation, or of a __builtin_offsetof member path.
Expr
One expression node.
ForInit
The first clause of a for statement.
Init
What an object is initialized with.
Member
One entry in a struct or union member list.
ParamKind
Which of the four shapes a function declarator’s parameter list has.
RecordKind
Which of the two record kinds.
Scalar
A built-in type named by keywords, with the sign folded in.
Stmt
One statement node.
StorageClass
A storage class specifier.
TypeSpec
What type a declaration named.
TypeofArg
What a typeof was 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.md that fills this crate in.

Functions§

print
The whole translation unit, as text.

Type Aliases§

AsmId
An assembly statement, in the side table.
AsmOperandList
A run of assembly operands.
AttrArgList
A run of attribute arguments.
AttrList
A run of attributes.
CharId
A character constant, in the constant table.
DeclId
A declaration in the declaration arena.
DeclList
A run of declarations.
DeclSpecsId
A set of declaration specifiers, in the side table.
DeclaratorId
A declarator, in the side table.
DerivedList
A run of declarator derivations.
DesignatorList
A run of designators.
EnumeratorList
A run of enumerators.
ExprId
An expression in the expression arena.
ExprList
A run of expressions.
FloatId
A floating constant, in the constant table.
GenericList
A run of _Generic associations.
InitDeclaratorList
A run of init-declarators.
InitId
An initializer, in the side table.
InitItemList
A run of braced initializer elements.
IntId
An integer constant, in the constant table.
MemberList
A run of struct or union members.
ParamList
A run of function parameters.
StmtId
A statement in the statement arena.
StmtList
A run of statements.
StrId
A string literal, in the constant table.
StrList
A run of string literals.
SymbolList
A run of identifiers.
TypeNameId
A type name, in the side table.