cl-ast: Hash everything

This commit is contained in:
John 2024-04-14 23:11:48 -05:00
parent d07a3e1455
commit f958bbcb79

View File

@ -18,7 +18,7 @@ pub mod ast_impl;
pub mod format; pub mod format;
/// Whether a binding ([Static] or [Let]) or reference is mutable or not /// Whether a binding ([Static] or [Let]) or reference is mutable or not
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub enum Mutability { pub enum Mutability {
#[default] #[default]
Not, Not,
@ -26,7 +26,7 @@ pub enum Mutability {
} }
/// Whether an [Item] is visible outside of the current [Module] /// Whether an [Item] is visible outside of the current [Module]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub enum Visibility { pub enum Visibility {
#[default] #[default]
Private, Private,
@ -34,26 +34,26 @@ pub enum Visibility {
} }
/// A list of [Item]s /// A list of [Item]s
#[derive(Clone, Debug, Default, PartialEq, Eq)] #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct File { pub struct File {
pub items: Vec<Item>, pub items: Vec<Item>,
} }
// Metadata decorators // Metadata decorators
#[derive(Clone, Debug, Default, PartialEq, Eq)] #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct Attrs { pub struct Attrs {
pub meta: Vec<Meta>, pub meta: Vec<Meta>,
} }
/// A metadata decorator /// A metadata decorator
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Meta { pub struct Meta {
pub name: Identifier, pub name: Identifier,
pub kind: MetaKind, pub kind: MetaKind,
} }
/// Information attached to [Meta]data /// Information attached to [Meta]data
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum MetaKind { pub enum MetaKind {
Plain, Plain,
Equals(Literal), Equals(Literal),
@ -62,7 +62,7 @@ pub enum MetaKind {
// Items // Items
/// Anything that can appear at the top level of a [File] /// Anything that can appear at the top level of a [File]
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Item { pub struct Item {
pub extents: Span, pub extents: Span,
pub attrs: Attrs, pub attrs: Attrs,
@ -71,7 +71,7 @@ pub struct Item {
} }
/// What kind of [Item] is this? /// What kind of [Item] is this?
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum ItemKind { pub enum ItemKind {
// TODO: Import declaration ("use") item // TODO: Import declaration ("use") item
// TODO: Trait declaration ("trait") item? // TODO: Trait declaration ("trait") item?
@ -94,14 +94,14 @@ pub enum ItemKind {
} }
/// An alias to another [Ty] /// An alias to another [Ty]
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Alias { pub struct Alias {
pub to: Identifier, pub to: Identifier,
pub from: Option<Box<Ty>>, pub from: Option<Box<Ty>>,
} }
/// A compile-time constant /// A compile-time constant
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Const { pub struct Const {
pub name: Identifier, pub name: Identifier,
pub ty: Box<Ty>, pub ty: Box<Ty>,
@ -109,7 +109,7 @@ pub struct Const {
} }
/// A `static` variable /// A `static` variable
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Static { pub struct Static {
pub mutable: Mutability, pub mutable: Mutability,
pub name: Identifier, pub name: Identifier,
@ -118,21 +118,21 @@ pub struct Static {
} }
/// An ordered collection of [Items](Item) /// An ordered collection of [Items](Item)
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Module { pub struct Module {
pub name: Identifier, pub name: Identifier,
pub kind: ModuleKind, pub kind: ModuleKind,
} }
/// The contents of a [Module], if they're in the same file /// The contents of a [Module], if they're in the same file
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum ModuleKind { pub enum ModuleKind {
Inline(File), Inline(File),
Outline, Outline,
} }
/// Code, and the interface to that code /// Code, and the interface to that code
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Function { pub struct Function {
pub name: Identifier, pub name: Identifier,
pub args: Vec<Param>, pub args: Vec<Param>,
@ -141,7 +141,7 @@ pub struct Function {
} }
/// A single parameter for a [Function] /// A single parameter for a [Function]
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Param { pub struct Param {
pub mutability: Mutability, pub mutability: Mutability,
pub name: Identifier, pub name: Identifier,
@ -149,14 +149,14 @@ pub struct Param {
} }
/// A user-defined product type /// A user-defined product type
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Struct { pub struct Struct {
pub name: Identifier, pub name: Identifier,
pub kind: StructKind, pub kind: StructKind,
} }
/// Either a [Struct]'s [StructMember]s or tuple [Ty]pes, if present. /// Either a [Struct]'s [StructMember]s or tuple [Ty]pes, if present.
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum StructKind { pub enum StructKind {
Empty, Empty,
Tuple(Vec<Ty>), Tuple(Vec<Ty>),
@ -164,7 +164,7 @@ pub enum StructKind {
} }
/// The [Visibility], [Identifier], and [Ty]pe of a single [Struct] member /// The [Visibility], [Identifier], and [Ty]pe of a single [Struct] member
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct StructMember { pub struct StructMember {
pub vis: Visibility, pub vis: Visibility,
pub name: Identifier, pub name: Identifier,
@ -172,14 +172,14 @@ pub struct StructMember {
} }
/// A user-defined sum type /// A user-defined sum type
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Enum { pub struct Enum {
pub name: Identifier, pub name: Identifier,
pub kind: EnumKind, pub kind: EnumKind,
} }
/// An [Enum]'s [Variant]s, if it has a variant block /// An [Enum]'s [Variant]s, if it has a variant block
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum EnumKind { pub enum EnumKind {
/// Represents an enum with no variants /// Represents an enum with no variants
NoVariants, NoVariants,
@ -187,14 +187,14 @@ pub enum EnumKind {
} }
/// A single [Enum] variant /// A single [Enum] variant
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Variant { pub struct Variant {
pub name: Identifier, pub name: Identifier,
pub kind: VariantKind, pub kind: VariantKind,
} }
/// Whether the [Variant] has a C-like constant value, a tuple, or [StructMember]s /// Whether the [Variant] has a C-like constant value, a tuple, or [StructMember]s
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum VariantKind { pub enum VariantKind {
Plain, Plain,
CLike(u128), CLike(u128),
@ -203,28 +203,28 @@ pub enum VariantKind {
} }
/// Sub-[items](Item) (associated functions, etc.) for a [Ty] /// Sub-[items](Item) (associated functions, etc.) for a [Ty]
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Impl { pub struct Impl {
pub target: ImplKind, pub target: ImplKind,
pub body: File, pub body: File,
} }
// TODO: `impl` Trait for <Target> { } // TODO: `impl` Trait for <Target> { }
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum ImplKind { pub enum ImplKind {
Type(Ty), Type(Ty),
Trait { impl_trait: Path, for_type: Box<Ty> }, Trait { impl_trait: Path, for_type: Box<Ty> },
} }
/// A type expression /// A type expression
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Ty { pub struct Ty {
pub extents: Span, pub extents: Span,
pub kind: TyKind, pub kind: TyKind,
} }
/// Information about a [Ty]pe expression /// Information about a [Ty]pe expression
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum TyKind { pub enum TyKind {
Never, Never,
Empty, Empty,
@ -236,34 +236,34 @@ pub enum TyKind {
} }
/// A tuple of [Ty]pes /// A tuple of [Ty]pes
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct TyTuple { pub struct TyTuple {
pub types: Vec<Ty>, pub types: Vec<Ty>,
} }
/// A [Ty]pe-reference expression as (number of `&`, [Path]) /// A [Ty]pe-reference expression as (number of `&`, [Path])
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct TyRef { pub struct TyRef {
pub count: u16, pub count: u16,
pub to: Path, pub to: Path,
} }
/// The args and return value for a function pointer [Ty]pe /// The args and return value for a function pointer [Ty]pe
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct TyFn { pub struct TyFn {
pub args: TyTuple, pub args: TyTuple,
pub rety: Option<Box<Ty>>, pub rety: Option<Box<Ty>>,
} }
/// A path to an [Item] in the [Module] tree /// A path to an [Item] in the [Module] tree
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Path { pub struct Path {
pub absolute: bool, pub absolute: bool,
pub parts: Vec<PathPart>, pub parts: Vec<PathPart>,
} }
/// A single component of a [Path] /// A single component of a [Path]
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum PathPart { pub enum PathPart {
SuperKw, SuperKw,
SelfKw, SelfKw,
@ -272,11 +272,11 @@ pub enum PathPart {
// TODO: Capture token? // TODO: Capture token?
/// A name /// A name
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Identifier(pub String); pub struct Identifier(pub String);
/// An abstract statement, and associated metadata /// An abstract statement, and associated metadata
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Stmt { pub struct Stmt {
pub extents: Span, pub extents: Span,
pub kind: StmtKind, pub kind: StmtKind,
@ -284,14 +284,14 @@ pub struct Stmt {
} }
/// Whether or not a [Stmt] is followed by a semicolon /// Whether or not a [Stmt] is followed by a semicolon
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum Semi { pub enum Semi {
Terminated, Terminated,
Unterminated, Unterminated,
} }
/// Whether the [Stmt] is a [Let], [Item], or [Expr] statement /// Whether the [Stmt] is a [Let], [Item], or [Expr] statement
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum StmtKind { pub enum StmtKind {
Empty, Empty,
Local(Let), Local(Let),
@ -300,7 +300,7 @@ pub enum StmtKind {
} }
/// A local variable declaration [Stmt] /// A local variable declaration [Stmt]
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Let { pub struct Let {
pub mutable: Mutability, pub mutable: Mutability,
pub name: Identifier, pub name: Identifier,
@ -309,14 +309,14 @@ pub struct Let {
} }
/// An expression, the beating heart of the language /// An expression, the beating heart of the language
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Expr { pub struct Expr {
pub extents: Span, pub extents: Span,
pub kind: ExprKind, pub kind: ExprKind,
} }
/// Any of the different [Expr]essions /// Any of the different [Expr]essions
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum ExprKind { pub enum ExprKind {
/// An [Assign]ment expression: [`Expr`] ([`AssignKind`] [`Expr`])\+ /// An [Assign]ment expression: [`Expr`] ([`AssignKind`] [`Expr`])\+
Assign(Assign), Assign(Assign),
@ -360,13 +360,13 @@ pub enum ExprKind {
} }
/// An [Assign]ment expression: [`Expr`] ([`AssignKind`] [`Expr`])\+ /// An [Assign]ment expression: [`Expr`] ([`AssignKind`] [`Expr`])\+
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Assign { pub struct Assign {
pub kind: AssignKind, pub kind: AssignKind,
pub parts: Box<(ExprKind, ExprKind)>, pub parts: Box<(ExprKind, ExprKind)>,
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum AssignKind { pub enum AssignKind {
/// Standard Assignment with no read-back /// Standard Assignment with no read-back
Plain, Plain,
@ -383,14 +383,14 @@ pub enum AssignKind {
} }
/// A [Binary] expression: [`Expr`] ([`BinaryKind`] [`Expr`])\+ /// A [Binary] expression: [`Expr`] ([`BinaryKind`] [`Expr`])\+
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Binary { pub struct Binary {
pub kind: BinaryKind, pub kind: BinaryKind,
pub parts: Box<(ExprKind, ExprKind)>, pub parts: Box<(ExprKind, ExprKind)>,
} }
/// A [Binary] operator /// A [Binary] operator
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum BinaryKind { pub enum BinaryKind {
Lt, Lt,
LtEq, LtEq,
@ -418,14 +418,14 @@ pub enum BinaryKind {
} }
/// A [Unary] expression: [`UnaryKind`]\* [`Expr`] /// A [Unary] expression: [`UnaryKind`]\* [`Expr`]
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Unary { pub struct Unary {
pub kind: UnaryKind, pub kind: UnaryKind,
pub tail: Box<ExprKind>, pub tail: Box<ExprKind>,
} }
/// A [Unary] operator /// A [Unary] operator
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum UnaryKind { pub enum UnaryKind {
Deref, Deref,
Neg, Neg,
@ -436,14 +436,14 @@ pub enum UnaryKind {
Tilde, Tilde,
} }
/// A repeated [Index] expression: a[10, 20, 30][40, 50, 60] /// A repeated [Index] expression: a[10, 20, 30][40, 50, 60]
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Index { pub struct Index {
pub head: Box<ExprKind>, pub head: Box<ExprKind>,
pub indices: Vec<Expr>, pub indices: Vec<Expr>,
} }
/// A [Literal]: 0x42, 1e123, 2.4, "Hello" /// A [Literal]: 0x42, 1e123, 2.4, "Hello"
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum Literal { pub enum Literal {
Bool(bool), Bool(bool),
Char(char), Char(char),
@ -452,21 +452,21 @@ pub enum Literal {
} }
/// An [Array] literal: `[` [`Expr`] (`,` [`Expr`])\* `]` /// An [Array] literal: `[` [`Expr`] (`,` [`Expr`])\* `]`
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Array { pub struct Array {
pub values: Vec<Expr>, pub values: Vec<Expr>,
} }
/// An Array literal constructed with [repeat syntax](ArrayRep) /// An Array literal constructed with [repeat syntax](ArrayRep)
/// `[` [Expr] `;` [Literal] `]` /// `[` [Expr] `;` [Literal] `]`
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ArrayRep { pub struct ArrayRep {
pub value: Box<ExprKind>, pub value: Box<ExprKind>,
pub repeat: Box<ExprKind>, pub repeat: Box<ExprKind>,
} }
/// An address-of expression: `&` `mut`? [`Expr`] /// An address-of expression: `&` `mut`? [`Expr`]
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct AddrOf { pub struct AddrOf {
pub count: usize, pub count: usize,
pub mutable: Mutability, pub mutable: Mutability,
@ -474,25 +474,25 @@ pub struct AddrOf {
} }
/// A [Block] expression: `{` [`Stmt`]\* [`Expr`]? `}` /// A [Block] expression: `{` [`Stmt`]\* [`Expr`]? `}`
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Block { pub struct Block {
pub stmts: Vec<Stmt>, pub stmts: Vec<Stmt>,
} }
/// A [Grouping](Group) expression `(` [`Expr`] `)` /// A [Grouping](Group) expression `(` [`Expr`] `)`
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Group { pub struct Group {
pub expr: Box<ExprKind>, pub expr: Box<ExprKind>,
} }
/// A [Tuple] expression: `(` [`Expr`] (`,` [`Expr`])+ `)` /// A [Tuple] expression: `(` [`Expr`] (`,` [`Expr`])+ `)`
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Tuple { pub struct Tuple {
pub exprs: Vec<Expr>, pub exprs: Vec<Expr>,
} }
/// A [While] expression: `while` [`Expr`] [`Block`] [`Else`]? /// A [While] expression: `while` [`Expr`] [`Block`] [`Else`]?
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct While { pub struct While {
pub cond: Box<Expr>, pub cond: Box<Expr>,
pub pass: Box<Block>, pub pass: Box<Block>,
@ -500,7 +500,7 @@ pub struct While {
} }
/// An [If] expression: `if` [`Expr`] [`Block`] [`Else`]? /// An [If] expression: `if` [`Expr`] [`Block`] [`Else`]?
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct If { pub struct If {
pub cond: Box<Expr>, pub cond: Box<Expr>,
pub pass: Box<Block>, pub pass: Box<Block>,
@ -508,7 +508,7 @@ pub struct If {
} }
/// A [For] expression: `for` Pattern `in` [`Expr`] [`Block`] [`Else`]? /// A [For] expression: `for` Pattern `in` [`Expr`] [`Block`] [`Else`]?
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct For { pub struct For {
pub bind: Identifier, // TODO: Patterns? pub bind: Identifier, // TODO: Patterns?
pub cond: Box<Expr>, pub cond: Box<Expr>,
@ -517,23 +517,23 @@ pub struct For {
} }
/// The (optional) `else` clause of a [While], [If], or [For] expression /// The (optional) `else` clause of a [While], [If], or [For] expression
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Else { pub struct Else {
pub body: Option<Box<Expr>>, pub body: Option<Box<Expr>>,
} }
/// A [Break] expression: `break` [`Expr`]? /// A [Break] expression: `break` [`Expr`]?
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Break { pub struct Break {
pub body: Option<Box<Expr>>, pub body: Option<Box<Expr>>,
} }
/// A [Return] expression `return` [`Expr`]? /// A [Return] expression `return` [`Expr`]?
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Return { pub struct Return {
pub body: Option<Box<Expr>>, pub body: Option<Box<Expr>>,
} }
/// A continue expression: `continue` /// A continue expression: `continue`
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub struct Continue; pub struct Continue;