ast/lib.rs
1//! # Abstract Syntax Tree
2//!
3//! The AST is a syntactical representation of a program.
4//! It is the output of the `parser`.
5//!
6//! This AST doesn't have any semantic information.
7//! For example, it doesn't know the different types of binary operations
8//! (arithmetic, logical, etc.). It just sees `<OPERAND> <OPERATOR> <OPERAND>`.
9//!
10//! We try to presserve all the syntactic information of the program
11//! (semicolons, parenthesis, etc.), and we don't make up things that aren't there.
12//!
13//! For example, see [`ItemKind::Function`]. Its return type is an [Option],
14//! beacuse this program is syntactically correct:
15//! ```text
16//! fn foo() { }
17//! ```
18//! but this one is also correct:
19//! ```text
20//! fn foo() -> int { ... }
21//! ```
22//!
23//! So the AST doesn't infer anything. It's job is to represent the input program as
24//! faithfully as possible. That's why the return type is optional, beacuse it can
25//! be ommited.
26//!
27//! Later, we'll lower this AST to a HIR Tree, which will desugar some things, like
28//! return types. It'll also remove parenthesis, since their only job is to explicit
29//! the precedence of operations, and they become useless after building the AST.
30
31pub mod expr;
32pub mod stmt;
33
34use std::fmt::Debug;
35
36pub use expr::Expression;
37use span::{Span, Spanned};
38pub use stmt::Statement;
39pub mod item;
40pub use item::*;
41pub mod types;
42pub mod visitor;
43pub use interner::Symbol;
44pub use visitor::Visitor;
45
46#[derive(Debug)]
47pub struct Block<T> {
48 pub open_brace: Span,
49 pub val: Box<[T]>,
50 pub close_brace: Span,
51}
52
53#[derive(Debug)]
54pub struct Parenthesized<T> {
55 pub open_paren: Span,
56 pub val: T,
57 pub close_paren: Span,
58}
59
60#[derive(Debug, Clone, PartialEq)]
61pub struct Path {
62 pub segments: Box<[Spanned<Symbol>]>,
63 pub span: Span,
64}
65
66impl<T> Parenthesized<T> {
67 pub fn span(&self) -> Span { self.open_paren.join(&self.close_paren) }
68}