Formatting.

This commit is contained in:
2023-07-22 15:00:07 -07:00
parent f968e20a75
commit 64405d5a06
8 changed files with 70 additions and 57 deletions

View File

@@ -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\");" " assert_ne!(errors.len(), 0, \"should have seen an error\");"
)?; )?;
} else { } 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!( writeln!(
f, f,
" let syntax = syntax.expect(\"file should have parsed\");" " 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, f,
" assert_eq!(errors.len(), 0, \"file should have no validation errors\");" " assert_eq!(errors.len(), 0, \"file should have no validation errors\");"
)?; )?;
writeln!(f, " let syntax_result = syntax.eval();")?;
writeln!( writeln!(
f, f,
" let ir = syntax.type_infer().expect(\"example is typed correctly\");" " let ir = syntax.type_infer().expect(\"example is typed correctly\");"
)?; )?;
writeln!( writeln!(f, " let ir_result = ir.eval();")?;
f,
" assert_eq!(syntax_result, ir.eval(), \"syntax equivalent to IR\");"
)?;
writeln!(f, " let compiled_result = Backend::<JITModule>::eval(ir);")?; writeln!(f, " let compiled_result = Backend::<JITModule>::eval(ir);")?;
writeln!(f, " assert_eq!(syntax_result, compiled_result);")?; writeln!(f, " assert_eq!(ir_result, compiled_result);")?;
} }
writeln!(f, "}}")?; writeln!(f, "}}")?;
} }

View File

@@ -1,6 +1,6 @@
use crate::backend::{Backend, BackendError}; use crate::backend::{Backend, BackendError};
use crate::type_infer::TypeInferenceResult;
use crate::syntax::{ConstantType, Location, ParserError, Statement}; use crate::syntax::{ConstantType, Location, ParserError, Statement};
use crate::type_infer::TypeInferenceResult;
use codespan_reporting::diagnostic::Diagnostic; use codespan_reporting::diagnostic::Diagnostic;
use codespan_reporting::files::SimpleFiles; use codespan_reporting::files::SimpleFiles;
use codespan_reporting::term::{self, Config}; use codespan_reporting::term::{self, Config};

View File

@@ -108,23 +108,19 @@ impl ParserError {
ParseError::InvalidToken { location } => { ParseError::InvalidToken { location } => {
ParserError::InvalidToken(Location::new(file_idx, location..location + 1)) ParserError::InvalidToken(Location::new(file_idx, location..location + 1))
} }
ParseError::UnrecognizedEof { location, expected } => { ParseError::UnrecognizedEof { location, expected } => ParserError::UnrecognizedEOF(
ParserError::UnrecognizedEOF(Location::new(file_idx, location..location+1), expected) Location::new(file_idx, location..location + 1),
} expected,
),
ParseError::UnrecognizedToken { ParseError::UnrecognizedToken {
token: (start, token, end), token: (start, token, end),
expected, expected,
} => ParserError::UnrecognizedToken( } => {
Location::new(file_idx, start..end), ParserError::UnrecognizedToken(Location::new(file_idx, start..end), token, expected)
token, }
expected,
),
ParseError::ExtraToken { ParseError::ExtraToken {
token: (start, token, end), token: (start, token, end),
} => ParserError::ExtraToken( } => ParserError::ExtraToken(Location::new(file_idx, start..end), token),
Location::new(file_idx, start..end),
token,
),
ParseError::User { error } => match error { ParseError::User { error } => match error {
LexerError::LexFailure(offset) => { 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<usize> {
Diagnostic::error() Diagnostic::error()
.with_message(expected_str) .with_message(expected_str)
.with_labels(vec![ .with_labels(vec![loc.primary_label().with_message(unexpected_str)])
loc.primary_label().with_message(unexpected_str)
])
} }
// I think we get this when we get a token, but were expected EOF // 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<usize> {
Diagnostic::error() Diagnostic::error()
.with_message(expected_str) .with_message(expected_str)
.with_labels(vec![ .with_labels(vec![loc.primary_label().with_message(unexpected_str)])
loc.primary_label().with_message(unexpected_str)
])
} }
// simple lexer errors // simple lexer errors
@@ -289,7 +281,10 @@ fn order_of_operations() {
Location::new(testfile, 6..7), Location::new(testfile, 6..7),
"+".to_string(), "+".to_string(),
vec![ 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( Expression::Primitive(
Location::new(testfile, 10..11), Location::new(testfile, 10..11),
"*".to_string(), "*".to_string(),

View File

@@ -67,18 +67,17 @@ impl Arbitrary for Program {
defined_variables.insert(psi.name.name.clone(), psi.binding_type); defined_variables.insert(psi.name.name.clone(), psi.binding_type);
statements.push( statements.push(
expr.prop_map(move |expr| { expr.prop_map(move |expr| {
Statement::Binding( Statement::Binding(Location::manufactured(), psi.name.clone(), expr)
Location::manufactured(),
psi.name.clone(),
expr,
)
}) })
.boxed(), .boxed(),
); );
} else { } else {
let printers = defined_variables let printers = defined_variables.keys().map(|n| {
.keys() Just(Statement::Print(
.map(|n| Just(Statement::Print(Location::manufactured(), Name::manufactured(n)))); Location::manufactured(),
Name::manufactured(n),
))
});
statements.push(Union::new(printers).boxed()); statements.push(Union::new(printers).boxed());
} }
} }

View File

@@ -31,11 +31,17 @@ pub struct Name {
impl Name { impl Name {
pub fn new<S: ToString>(n: S, location: Location) -> Name { pub fn new<S: ToString>(n: S, location: Location) -> Name {
Name{ name: n.to_string(), location } Name {
name: n.to_string(),
location,
}
} }
pub fn manufactured<S: ToString>(n: S) -> Name { pub fn manufactured<S: ToString>(n: S) -> Name {
Name{ name: n.to_string(), location: Location::manufactured() } Name {
name: n.to_string(),
location: Location::manufactured(),
}
} }
pub fn intern(self) -> ArcIntern<String> { pub fn intern(self) -> ArcIntern<String> {

View File

@@ -76,10 +76,7 @@ impl Location {
/// this particular location. You'll need to extend it with actually useful /// this particular location. You'll need to extend it with actually useful
/// information, like what kind of error it is. /// information, like what kind of error it is.
pub fn error(&self) -> Diagnostic<usize> { pub fn error(&self) -> Diagnostic<usize> {
Diagnostic::error().with_labels(vec![Label::primary( Diagnostic::error().with_labels(vec![Label::primary(self.file_idx, self.location.clone())])
self.file_idx,
self.location.clone(),
)])
} }
/// Return an error diagnostic centered at this location, with the given message. /// Return an error diagnostic centered at this location, with the given message.
@@ -89,11 +86,9 @@ impl Location {
/// even more information to ut, using [`Diagnostic::with_labels`], /// even more information to ut, using [`Diagnostic::with_labels`],
/// [`Diagnostic::with_notes`], or [`Diagnostic::with_code`]. /// [`Diagnostic::with_notes`], or [`Diagnostic::with_code`].
pub fn labelled_error(&self, msg: &str) -> Diagnostic<usize> { pub fn labelled_error(&self, msg: &str) -> Diagnostic<usize> {
Diagnostic::error().with_labels(vec![Label::primary( Diagnostic::error().with_labels(vec![
self.file_idx, Label::primary(self.file_idx, self.location.clone()).with_message(msg)
self.location.clone(), ])
)
.with_message(msg)])
} }
/// Merge two locations into a single location spanning the whole range between /// Merge two locations into a single location spanning the whole range between
@@ -105,9 +100,20 @@ impl Location {
if self.file_idx != other.file_idx { if self.file_idx != other.file_idx {
None None
} else { } else {
let start = if self.location.start <= other.location.start { self.location.start } else { other.location.start }; let start = if self.location.start <= other.location.start {
let end = if self.location.end >= other.location.end { self.location.end } else { other.location.end }; self.location.start
Some(Location { file_idx: self.file_idx, location: start..end }) } 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,
})
} }
} }
} }

View File

@@ -1,8 +1,8 @@
use super::ast as ir; use super::ast as ir;
use super::ast::Type; use super::ast::Type;
use crate::eval::PrimitiveType; use crate::eval::PrimitiveType;
use crate::type_infer::solve::Constraint;
use crate::syntax::{self, ConstantType}; use crate::syntax::{self, ConstantType};
use crate::type_infer::solve::Constraint;
use internment::ArcIntern; use internment::ArcIntern;
use std::collections::HashMap; use std::collections::HashMap;
use std::str::FromStr; use std::str::FromStr;
@@ -112,7 +112,10 @@ fn convert_expression(
let newtype = ir::gentype(); let newtype = ir::gentype();
let newval = ir::Value::Unknown(base, value); 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) (newval, newtype)
} }
Some(ConstantType::U8) => ( Some(ConstantType::U8) => (

View File

@@ -373,10 +373,13 @@ pub fn solve_constraints(
// we try to advance it to a primitive // we try to advance it to a primitive
Constraint::ConstantNumericType(loc, Type::Variable(vloc, var)) => { Constraint::ConstantNumericType(loc, Type::Variable(vloc, var)) => {
match resolutions.get(&var) { match resolutions.get(&var) {
None => constraint_db None => constraint_db.push(Constraint::ConstantNumericType(
.push(Constraint::ConstantNumericType(loc, Type::Variable(vloc, var))), loc,
Type::Variable(vloc, var),
)),
Some(nt) => { Some(nt) => {
constraint_db.push(Constraint::ConstantNumericType(loc, Type::Primitive(*nt))); constraint_db
.push(Constraint::ConstantNumericType(loc, Type::Primitive(*nt)));
changed_something = true; changed_something = true;
} }
} }