diff --git a/src/ast.rs b/src/ast.rs index a35c991..3762420 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -1,6 +1,6 @@ //! The untyped Abstract Syntax Tree (AST). -use std::collections::{BTreeMap, HashMap}; +use std::collections::HashMap; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -12,7 +12,7 @@ use crate::token::{MetaInfo, SignedNumType, UnsignedNumType}; #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Program { /// The external constants that the top level const definitions depend upon. - pub const_deps: BTreeMap>, + pub const_deps: HashMap>, /// Top level const definitions. pub const_defs: HashMap, /// Top level struct type definitions. diff --git a/src/check.rs b/src/check.rs index 35ae966..48f41d3 100644 --- a/src/check.rs +++ b/src/check.rs @@ -1,7 +1,7 @@ //! Type-checker, transforming an untyped [`crate::ast::Program`] into a typed //! [`crate::ast::Program`]. -use std::collections::{BTreeMap, HashMap, HashSet}; +use std::collections::{HashMap, HashSet}; use crate::{ ast::{ @@ -354,7 +354,7 @@ impl UntypedProgram { struct_names, enum_names, }; - let mut const_deps: BTreeMap> = BTreeMap::new(); + let mut const_deps: HashMap> = HashMap::new(); let mut const_types = HashMap::with_capacity(self.const_defs.len()); let mut const_defs = HashMap::with_capacity(self.const_defs.len()); { @@ -363,7 +363,7 @@ impl UntypedProgram { value: &ConstExpr, const_def: &ConstDef, errors: &mut Vec>, - const_deps: &mut BTreeMap>, + const_deps: &mut HashMap>, ) { let ConstExpr(value, meta) = value; let meta = *meta; diff --git a/src/compile.rs b/src/compile.rs index 9f3ea7f..e314d11 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -18,7 +18,7 @@ use crate::{ }; /// An error that occurred during compilation. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum CompilerError { /// The specified function could not be compiled, as it was not found in the program. FnNotFound(String), @@ -28,6 +28,36 @@ pub enum CompilerError { MissingConstant(String, String, MetaInfo), } +impl PartialOrd for CompilerError { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for CompilerError { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + match (self, other) { + (CompilerError::FnNotFound(fn1), CompilerError::FnNotFound(fn2)) => fn1.cmp(fn2), + (CompilerError::FnNotFound(_), _) => std::cmp::Ordering::Less, + (CompilerError::InvalidLiteralType(_, _), CompilerError::FnNotFound(_)) => { + std::cmp::Ordering::Greater + } + ( + CompilerError::InvalidLiteralType(literal1, _), + CompilerError::InvalidLiteralType(literal2, _), + ) => literal1.cmp(literal2), + (CompilerError::InvalidLiteralType(_, _), CompilerError::MissingConstant(_, _, _)) => { + std::cmp::Ordering::Less + } + ( + CompilerError::MissingConstant(_, _, meta1), + CompilerError::MissingConstant(_, _, meta2), + ) => meta1.cmp(meta2), + (CompilerError::MissingConstant(_, _, _), _) => std::cmp::Ordering::Greater, + } + } +} + impl std::fmt::Display for CompilerError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { @@ -107,6 +137,7 @@ impl TypedProgram { } } if !errs.is_empty() { + errs.sort(); return Err(errs); } fn resolve_const_expr_unsigned( @@ -200,6 +231,7 @@ impl TypedProgram { } } if !errs.is_empty() { + errs.sort(); return Err(errs); } let mut input_gates = vec![]; diff --git a/src/literal.rs b/src/literal.rs index c65cdfb..88f6388 100644 --- a/src/literal.rs +++ b/src/literal.rs @@ -23,7 +23,7 @@ use crate::{ /// A subset of [`crate::ast::Expr`] that is used as input / output by an /// [`crate::eval::Evaluator`]. -#[derive(Debug, Clone, Hash, PartialEq, Eq)] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum Literal { /// Literal `true`. @@ -49,7 +49,7 @@ pub enum Literal { } /// A variant literal (either of unit type or containing fields), used by [`Literal::Enum`]. -#[derive(Debug, Clone, Hash, PartialEq, Eq)] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum VariantLiteral { /// A unit variant, containing no fields. diff --git a/src/parse.rs b/src/parse.rs index b2173aa..be23571 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -1,10 +1,6 @@ //! Parses a stream of [`crate::scan::Tokens`] into an untyped [`crate::ast::Program`]. -use std::{ - collections::{BTreeMap, HashMap}, - iter::Peekable, - vec::IntoIter, -}; +use std::{collections::HashMap, iter::Peekable, vec::IntoIter}; use crate::{ ast::{ @@ -175,7 +171,7 @@ impl Parser { } if self.errors.is_empty() { return Ok(Program { - const_deps: BTreeMap::new(), + const_deps: HashMap::new(), const_defs, struct_defs, enum_defs, diff --git a/src/token.rs b/src/token.rs index f4ceb69..cd757ef 100644 --- a/src/token.rs +++ b/src/token.rs @@ -176,7 +176,7 @@ impl std::fmt::Display for TokenEnum { } /// A suffix indicating the explicit unsigned number type of the literal. -#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum UnsignedNumType { /// Unsigned integer type used to index arrays, length depends on the host platform. @@ -217,7 +217,7 @@ impl std::fmt::Display for UnsignedNumType { } /// A suffix indicating the explicit signed number type of the literal. -#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum SignedNumType { /// 8-bit signed integer type.