Skip to main content

Crate astli

Crate astli 

Source
Expand description

SystemVerilog language tooling, built on one lossless syntax tree.

Each module is one of the astli-* crates, re-exported whole, so that one dependency brings the lot at versions that go together. Each has a guide of its own in its crate docs.

§A tour

Parse a file, walk the tree, report what is wrong with it, and format it:

use astli::diag::{Sources, Style, resolve_all, write};
use astli::parse::SyntaxTree;
use astli::syntax::ast::{AstNode, ModuleDecl};

let source = "module top(input logic clk);\nendmodule\nmodule sub;\n";
let tree = SyntaxTree::parse("top.sv", source.to_string());
// Or `SyntaxTree::read("top.sv")?`.

// The typed views name each construct's parts.
let names: Vec<_> = tree
    .root()
    .descendants()
    .filter_map(ModuleDecl::cast)
    .filter_map(|module| module.name())
    .map(|name| name.text().to_string())
    .collect();
assert_eq!(names, ["top"]);

// `sub` is never closed: the parser says so, and keeps its text.
assert_eq!(tree.diagnostics().len(), 1);
let mut sources = Sources::new(tree.origins());
for diagnostic in resolve_all(tree.origins(), tree.diagnostics()) {
    write(&mut std::io::stderr(), &mut sources, &diagnostic, Style::plain()).unwrap();
}
assert_eq!(tree.root().text(), source);

let formatted = astli::fmt::format(&tree, &Default::default()).unwrap();
assert!(formatted.starts_with("module top (\n  input logic clk\n);\n"));

§Which module

Bottom up, each built on the ones before it:

ModuleFor
textSpans, the file store, and where a span came from through macros and includes.
diagRendering a diagnostic, with the macro calls and includes that explain it.
syntaxSyntaxKind, the lexer, the tree types, and the typed views in syntax::ast.
preprocDirectives, macros, includes: expanding a file as a compiler would, or finding them in it as written.
parseThe grammar, and parse::SyntaxTree for one file.
fmtThe formatter.
lintLint rules over one file’s tree.
indexThe modules, packages and classes files declare and use, and which files a design needs.
semaWhat a tree means: its declarations, statements and expressions lowered to a HIR.

Most tools start at parse::SyntaxTree. One that needs a file expanded, a build’s include directories and +define+s, or several files in one store starts at preproc::Session instead, and parses against it with parse::parse().

§Scope

astli lexes, preprocesses and parses; it does not elaborate or type-check. A tree is of the file as written, with macro calls, directives and every branch of an `ifdef in it, or of what a compiler reads, with macros expanded, includes followed and one branch taken (parse::parse_expanded). A construct the grammar does not cover yet is kept as its tokens, so nothing is ever lost.

Modules§

diag
Rendering a Diagnostic for a person to read, with the macro calls and includes that explain it.
fmt
A SystemVerilog formatter, in the style of lowRISC’s Verilog style guide.
index
The top-level names SystemVerilog files declare and use, and which files a design needs.
lint
SystemVerilog lint rules over one file’s syntax tree.
parse
A SystemVerilog parser that builds a lossless syntax tree.
preproc
The SystemVerilog preprocessor: directives, macros, includes, and conditionals.
sema
Semantic analysis of SystemVerilog: what a tree means.
syntax
The vocabulary of a SystemVerilog syntax tree: its kinds, its lexer, its tree types, and typed views over them.
text
Source text, the byte spans that point into it, and where each span came from.