[fine] Type testing with probes and reporting

I'm proud of the test harness here actually. Also fix a bug in
checking!
This commit is contained in:
John Doty 2024-01-05 17:10:15 -08:00
parent c0f40aa512
commit 618e0028d3
10 changed files with 192 additions and 78 deletions

View file

@ -51,7 +51,7 @@ impl fmt::Debug for Error {
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}:{}: {}", self.start.0, self.end.0, self.message)
write!(f, "{}:{}: {}", self.start.0, self.start.1, self.message)
}
}
@ -123,14 +123,14 @@ impl fmt::Display for Type {
pub struct Semantics<'a> {
// TODO: Do I really want my own copy here? Should we standardize on Arc
// or Rc or some other nice sharing mechanism?
syntax_tree: SyntaxTree<'a>,
lines: Lines,
syntax_tree: &'a SyntaxTree<'a>,
lines: &'a Lines,
errors: RefCell<Vec<Error>>,
types: RefCell<HashMap<TreeRef, Type>>,
}
impl<'a> Semantics<'a> {
pub fn new(tree: SyntaxTree<'a>, lines: Lines) -> Self {
pub fn new(tree: &'a SyntaxTree<'a>, lines: &'a Lines) -> Self {
let mut semantics = Semantics {
syntax_tree: tree,
lines,
@ -148,11 +148,7 @@ impl<'a> Semantics<'a> {
semantics
}
pub fn syntax(&self) -> &SyntaxTree<'a> {
&self.syntax_tree
}
pub fn errors(&self) -> Vec<Error> {
pub fn snapshot_errors(&self) -> Vec<Error> {
(*self.errors.borrow()).clone()
}
@ -181,18 +177,15 @@ impl<'a> Semantics<'a> {
where
T: ToString,
{
let start = tree.start_position(&self.syntax_tree).unwrap();
let end = tree.start_position(&self.syntax_tree).unwrap();
self.report_error_span(start, end, error)
self.report_error_span(tree.start_pos, tree.end_pos, error)
}
fn report_error_tree_ref<T>(&self, tree: TreeRef, error: T)
where
T: ToString,
{
let start = self.syntax_tree.start_position(tree).unwrap();
let end = self.syntax_tree.end_position(tree).unwrap();
self.report_error_span(start, end, error)
let tree = &self.syntax_tree[tree];
self.report_error_span(tree.start_pos, tree.end_pos, error)
}
fn gather_errors(&mut self, tree: TreeRef) {
@ -259,7 +252,7 @@ impl<'a> Semantics<'a> {
match (op.kind, argument_type) {
(TokenKind::Plus, Type::F64) => Some(Type::F64),
(TokenKind::Minus, Type::F64) => Some(Type::F64),
(TokenKind::Bang, Type::Bool) => Some(Type::F64),
(TokenKind::Bang, Type::Bool) => Some(Type::Bool),
// This is dumb and should be punished, probably.
(_, Type::Unreachable) => {