🤔 Add a type inference engine, along with typed literals. #4

Merged
acw merged 25 commits from acw/type-checker into develop 2023-09-19 20:40:05 -07:00
Showing only changes of commit 758766b491 - Show all commits

View File

@@ -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 std::collections::HashMap;
use std::{collections::HashMap, str::FromStr};
use super::location;
/// 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.
pub enum Error {
UnboundVariable(Location, String),
UnknownType(Location, String),
}
impl From<Error> for Diagnostic<usize> {
@@ -19,6 +22,10 @@ impl From<Error> for Diagnostic<usize> {
Error::UnboundVariable(location, name) => location
.labelled_error("unbound here")
.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![],
),
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) => {
let mut errors = vec![];
let mut warnings = vec![];