Formatting.
This commit is contained in:
13
build.rs
13
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\");"
|
" 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, "}}")?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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};
|
||||||
|
|||||||
@@ -106,28 +106,24 @@ impl ParserError {
|
|||||||
fn convert(file_idx: usize, err: ParseError<usize, Token, LexerError>) -> Self {
|
fn convert(file_idx: usize, err: ParseError<usize, Token, LexerError>) -> Self {
|
||||||
match err {
|
match err {
|
||||||
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 } => {
|
|
||||||
ParserError::UnrecognizedEOF(Location::new(file_idx, location..location+1), expected)
|
|
||||||
}
|
}
|
||||||
|
ParseError::UnrecognizedEof { location, expected } => ParserError::UnrecognizedEOF(
|
||||||
|
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(),
|
||||||
|
|||||||
@@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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> {
|
||||||
|
|||||||
@@ -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,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) => (
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user