🤔 Add a type inference engine, along with typed literals. #4
@@ -1,6 +1,8 @@
|
|||||||
use crate::syntax::{Expression, Location, Program, Statement};
|
use crate::{syntax::{Expression, Location, Program, Statement}, eval::PrimitiveType};
|
||||||
use codespan_reporting::diagnostic::Diagnostic;
|
use codespan_reporting::diagnostic::Diagnostic;
|
||||||
use std::collections::HashMap;
|
use std::{collections::HashMap, str::FromStr};
|
||||||
|
|
||||||
|
use super::location;
|
||||||
|
|
||||||
/// An error we found while validating the input program.
|
/// An error we found while validating the input program.
|
||||||
///
|
///
|
||||||
@@ -11,6 +13,7 @@ use std::collections::HashMap;
|
|||||||
/// and using [`codespan_reporting`] to present them to the user.
|
/// and using [`codespan_reporting`] to present them to the user.
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
UnboundVariable(Location, String),
|
UnboundVariable(Location, String),
|
||||||
|
UnknownType(Location, String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Error> for Diagnostic<usize> {
|
impl From<Error> for Diagnostic<usize> {
|
||||||
@@ -19,6 +22,10 @@ impl From<Error> for Diagnostic<usize> {
|
|||||||
Error::UnboundVariable(location, name) => location
|
Error::UnboundVariable(location, name) => location
|
||||||
.labelled_error("unbound here")
|
.labelled_error("unbound here")
|
||||||
.with_message(format!("Unbound variable '{}'", name)),
|
.with_message(format!("Unbound variable '{}'", name)),
|
||||||
|
|
||||||
|
Error::UnknownType(location, name) => location
|
||||||
|
.labelled_error("type referenced here")
|
||||||
|
.with_message(format!("Unknown type '{}'", name)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,7 +134,15 @@ impl Expression {
|
|||||||
vec![Error::UnboundVariable(loc.clone(), var.clone())],
|
vec![Error::UnboundVariable(loc.clone(), var.clone())],
|
||||||
vec![],
|
vec![],
|
||||||
),
|
),
|
||||||
Expression::Cast(_, _, expr) => expr.validate(variable_map),
|
Expression::Cast(location, t, expr) => {
|
||||||
|
let (mut errs, warns) = expr.validate(variable_map);
|
||||||
|
|
||||||
|
if PrimitiveType::from_str(t).is_err() {
|
||||||
|
errs.push(Error::UnknownType(location.clone(), t.clone()))
|
||||||
|
}
|
||||||
|
|
||||||
|
(errs, warns)
|
||||||
|
}
|
||||||
Expression::Primitive(_, _, args) => {
|
Expression::Primitive(_, _, args) => {
|
||||||
let mut errors = vec![];
|
let mut errors = vec![];
|
||||||
let mut warnings = vec![];
|
let mut warnings = vec![];
|
||||||
|
|||||||
Reference in New Issue
Block a user