From 64405d5a0687f4d05a374f6da9396bf8e152aa80 Mon Sep 17 00:00:00 2001 From: Adam Wick Date: Sat, 22 Jul 2023 15:00:07 -0700 Subject: [PATCH] Formatting. --- build.rs | 13 +++++++------ src/repl.rs | 2 +- src/syntax.rs | 37 ++++++++++++++++--------------------- src/syntax/arbitrary.rs | 15 +++++++-------- src/syntax/ast.rs | 12 +++++++++--- src/syntax/location.rs | 32 +++++++++++++++++++------------- src/type_infer/convert.rs | 7 +++++-- src/type_infer/solve.rs | 9 ++++++--- 8 files changed, 70 insertions(+), 57 deletions(-) diff --git a/build.rs b/build.rs index 89f3bf9..2f4266e 100644 --- a/build.rs +++ b/build.rs @@ -58,6 +58,11 @@ fn generate_tests(f: &mut File, path_so_far: PathBuf) -> std::io::Result<()> { " assert_ne!(errors.len(), 0, \"should have seen an error\");" )?; } else { + // NOTE: Since the advent of defaulting rules and type checking, we + // can't guarantee that syntax.eval() will return the same result as + // ir.eval() or backend::eval(). We must do type checking to force + // constants into the right types, first. So this now checks only that + // the result of ir.eval() and backend::eval() are the same. writeln!( f, " let syntax = syntax.expect(\"file should have parsed\");" @@ -67,17 +72,13 @@ fn generate_tests(f: &mut File, path_so_far: PathBuf) -> std::io::Result<()> { f, " assert_eq!(errors.len(), 0, \"file should have no validation errors\");" )?; - writeln!(f, " let syntax_result = syntax.eval();")?; writeln!( f, " let ir = syntax.type_infer().expect(\"example is typed correctly\");" )?; - writeln!( - f, - " assert_eq!(syntax_result, ir.eval(), \"syntax equivalent to IR\");" - )?; + writeln!(f, " let ir_result = ir.eval();")?; writeln!(f, " let compiled_result = Backend::::eval(ir);")?; - writeln!(f, " assert_eq!(syntax_result, compiled_result);")?; + writeln!(f, " assert_eq!(ir_result, compiled_result);")?; } writeln!(f, "}}")?; } diff --git a/src/repl.rs b/src/repl.rs index 197e246..fcf6b62 100644 --- a/src/repl.rs +++ b/src/repl.rs @@ -1,6 +1,6 @@ use crate::backend::{Backend, BackendError}; -use crate::type_infer::TypeInferenceResult; use crate::syntax::{ConstantType, Location, ParserError, Statement}; +use crate::type_infer::TypeInferenceResult; use codespan_reporting::diagnostic::Diagnostic; use codespan_reporting::files::SimpleFiles; use codespan_reporting::term::{self, Config}; diff --git a/src/syntax.rs b/src/syntax.rs index 2fe4d13..258831c 100644 --- a/src/syntax.rs +++ b/src/syntax.rs @@ -106,28 +106,24 @@ impl ParserError { fn convert(file_idx: usize, err: ParseError) -> Self { match err { ParseError::InvalidToken { location } => { - ParserError::InvalidToken(Location::new(file_idx, location..location+1)) - } - ParseError::UnrecognizedEof { location, expected } => { - ParserError::UnrecognizedEOF(Location::new(file_idx, location..location+1), expected) + ParserError::InvalidToken(Location::new(file_idx, location..location + 1)) } + ParseError::UnrecognizedEof { location, expected } => ParserError::UnrecognizedEOF( + Location::new(file_idx, location..location + 1), + expected, + ), ParseError::UnrecognizedToken { token: (start, token, end), expected, - } => ParserError::UnrecognizedToken( - Location::new(file_idx, start..end), - token, - expected, - ), + } => { + ParserError::UnrecognizedToken(Location::new(file_idx, start..end), token, expected) + } ParseError::ExtraToken { token: (start, token, end), - } => ParserError::ExtraToken( - Location::new(file_idx, start..end), - token, - ), + } => ParserError::ExtraToken(Location::new(file_idx, start..end), token), ParseError::User { error } => match error { LexerError::LexFailure(offset) => { - ParserError::LexFailure(Location::new(file_idx, offset..offset+1)) + ParserError::LexFailure(Location::new(file_idx, offset..offset + 1)) } }, } @@ -185,9 +181,7 @@ impl<'a> From<&'a ParserError> for Diagnostic { Diagnostic::error() .with_message(expected_str) - .with_labels(vec![ - loc.primary_label().with_message(unexpected_str) - ]) + .with_labels(vec![loc.primary_label().with_message(unexpected_str)]) } // I think we get this when we get a token, but were expected EOF @@ -198,9 +192,7 @@ impl<'a> From<&'a ParserError> for Diagnostic { Diagnostic::error() .with_message(expected_str) - .with_labels(vec![ - loc.primary_label().with_message(unexpected_str) - ]) + .with_labels(vec![loc.primary_label().with_message(unexpected_str)]) } // simple lexer errors @@ -289,7 +281,10 @@ fn order_of_operations() { Location::new(testfile, 6..7), "+".to_string(), vec![ - Expression::Value(Location::new(testfile, 4..5), Value::Number(None, None, 1),), + Expression::Value( + Location::new(testfile, 4..5), + Value::Number(None, None, 1), + ), Expression::Primitive( Location::new(testfile, 10..11), "*".to_string(), diff --git a/src/syntax/arbitrary.rs b/src/syntax/arbitrary.rs index b78ca54..2feded7 100644 --- a/src/syntax/arbitrary.rs +++ b/src/syntax/arbitrary.rs @@ -67,18 +67,17 @@ impl Arbitrary for Program { defined_variables.insert(psi.name.name.clone(), psi.binding_type); statements.push( expr.prop_map(move |expr| { - Statement::Binding( - Location::manufactured(), - psi.name.clone(), - expr, - ) + Statement::Binding(Location::manufactured(), psi.name.clone(), expr) }) .boxed(), ); } else { - let printers = defined_variables - .keys() - .map(|n| Just(Statement::Print(Location::manufactured(), Name::manufactured(n)))); + let printers = defined_variables.keys().map(|n| { + Just(Statement::Print( + Location::manufactured(), + Name::manufactured(n), + )) + }); statements.push(Union::new(printers).boxed()); } } diff --git a/src/syntax/ast.rs b/src/syntax/ast.rs index 64e8b22..6700a9f 100644 --- a/src/syntax/ast.rs +++ b/src/syntax/ast.rs @@ -20,7 +20,7 @@ pub struct Program { } /// A Name. -/// +/// /// This is basically a string, but annotated with the place the string /// is in the source file. #[derive(Clone, Debug)] @@ -31,11 +31,17 @@ pub struct Name { impl Name { pub fn new(n: S, location: Location) -> Name { - Name{ name: n.to_string(), location } + Name { + name: n.to_string(), + location, + } } pub fn manufactured(n: S) -> Name { - Name{ name: n.to_string(), location: Location::manufactured() } + Name { + name: n.to_string(), + location: Location::manufactured(), + } } pub fn intern(self) -> ArcIntern { diff --git a/src/syntax/location.rs b/src/syntax/location.rs index a4c100c..5acd070 100644 --- a/src/syntax/location.rs +++ b/src/syntax/location.rs @@ -76,10 +76,7 @@ impl Location { /// this particular location. You'll need to extend it with actually useful /// information, like what kind of error it is. pub fn error(&self) -> Diagnostic { - Diagnostic::error().with_labels(vec![Label::primary( - self.file_idx, - self.location.clone(), - )]) + Diagnostic::error().with_labels(vec![Label::primary(self.file_idx, self.location.clone())]) } /// Return an error diagnostic centered at this location, with the given message. @@ -89,25 +86,34 @@ impl Location { /// even more information to ut, using [`Diagnostic::with_labels`], /// [`Diagnostic::with_notes`], or [`Diagnostic::with_code`]. pub fn labelled_error(&self, msg: &str) -> Diagnostic { - Diagnostic::error().with_labels(vec![Label::primary( - self.file_idx, - self.location.clone(), - ) - .with_message(msg)]) + Diagnostic::error().with_labels(vec![ + Label::primary(self.file_idx, self.location.clone()).with_message(msg) + ]) } /// Merge two locations into a single location spanning the whole range between /// them. - /// + /// /// This function returns None if the locations are from different files; this /// can happen if one of the locations is manufactured, for example. pub fn merge(&self, other: &Self) -> Option { if self.file_idx != other.file_idx { None } else { - let start = if self.location.start <= other.location.start { self.location.start } else { other.location.start }; - let end = if self.location.end >= other.location.end { self.location.end } else { other.location.end }; - Some(Location { file_idx: self.file_idx, location: start..end }) + let start = if self.location.start <= other.location.start { + self.location.start + } else { + other.location.start + }; + let end = if self.location.end >= other.location.end { + self.location.end + } else { + other.location.end + }; + Some(Location { + file_idx: self.file_idx, + location: start..end, + }) } } } diff --git a/src/type_infer/convert.rs b/src/type_infer/convert.rs index 1b1d3af..78f01f7 100644 --- a/src/type_infer/convert.rs +++ b/src/type_infer/convert.rs @@ -1,8 +1,8 @@ use super::ast as ir; use super::ast::Type; use crate::eval::PrimitiveType; -use crate::type_infer::solve::Constraint; use crate::syntax::{self, ConstantType}; +use crate::type_infer::solve::Constraint; use internment::ArcIntern; use std::collections::HashMap; use std::str::FromStr; @@ -112,7 +112,10 @@ fn convert_expression( let newtype = ir::gentype(); let newval = ir::Value::Unknown(base, value); - constraint_db.push(Constraint::ConstantNumericType(loc.clone(), newtype.clone())); + constraint_db.push(Constraint::ConstantNumericType( + loc.clone(), + newtype.clone(), + )); (newval, newtype) } Some(ConstantType::U8) => ( diff --git a/src/type_infer/solve.rs b/src/type_infer/solve.rs index afecfb3..b22053b 100644 --- a/src/type_infer/solve.rs +++ b/src/type_infer/solve.rs @@ -373,10 +373,13 @@ pub fn solve_constraints( // we try to advance it to a primitive Constraint::ConstantNumericType(loc, Type::Variable(vloc, var)) => { match resolutions.get(&var) { - None => constraint_db - .push(Constraint::ConstantNumericType(loc, Type::Variable(vloc, var))), + None => constraint_db.push(Constraint::ConstantNumericType( + loc, + Type::Variable(vloc, var), + )), Some(nt) => { - constraint_db.push(Constraint::ConstantNumericType(loc, Type::Primitive(*nt))); + constraint_db + .push(Constraint::ConstantNumericType(loc, Type::Primitive(*nt))); changed_something = true; } }