Skip to content

Commit

Permalink
Impl integer errors
Browse files Browse the repository at this point in the history
  • Loading branch information
Amejonah1200 committed Sep 18, 2023
1 parent eceef1c commit 38abf6a
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 15 deletions.
24 changes: 23 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::{
project::{
display_integer_type,
readers::{read_workspace, ReadWorkspaceError, ReadWorkspaceResult},
Workspace,
Workspace, TypeRegistry,
},
resolution::{
name_resolution::resolve_workspace_outlines,
Expand Down Expand Up @@ -351,6 +351,28 @@ fn main() {
.with_label(ariadne::Label::new(
(&input_name as &str, span.into_range())
).with_message("This is not a field.").with_color(ariadne::Color::Red)),
NumberCouldntInferInto(ty, span) => {
let ty_color = ariadne::Color::Red;
let ty_str = TypeRegistry::display_primitive_type(ty).fg(ty_color);
rep.with_message(format!("Couldn't parse number to be inferred as `{ty_str}`"))
.with_label(ariadne::Label::new(
(&input_name as &str, span.into_range())
).with_message(format!("This number cannot be parsed as `{ty_str}`")).with_color(ariadne::Color::Red))
},
NumberCouldntBeDowncasted(ty, span, w) => {
let ty_color = ariadne::Color::Green;
let ty_str = TypeRegistry::display_primitive_type(ty).fg(ty_color);
let bitlength_str = format!("{}", w as u8).fg(colors.next());
rep.with_message(format!("The number parsed is of higher bitlength ({bitlength_str}) than the expected type `{ty_str}`.", ))
.with_label(ariadne::Label::new(
(&input_name as &str, span.into_range())
).with_message(format!("This is parsed as of bitlength `{bitlength_str}`, but expected `{ty_str}`")).with_color(ariadne::Color::Red))

},
NumberCouldntBeParsedToDefault(span) => rep
.with_message("Couldn't parse number")
.with_label(ariadne::Label::new((&input_name as &str, span.into_range()))
.with_message("Couldn't be parsed as number.").with_color(ariadne::Color::Red)),
}
.finish()
.print((&input_name as &str, ariadne::Source::from(file.src())))
Expand Down
1 change: 1 addition & 0 deletions src/project/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ impl TypeRegistry {
},
)
}

pub fn display_primitive_type(ty: PrimitiveType) -> &'static str {
use PrimitiveType::*;
match ty {
Expand Down
60 changes: 47 additions & 13 deletions src/resolution/type_resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ pub enum TypeResError {
),
ExpectedStructForCallChain(TypeId, SimpleSpan),
VariableExpectedForAssignment(SimpleSpan),
NumberCouldntInferInto(PrimitiveType, SimpleSpan),
NumberCouldntBeDowncasted(PrimitiveType, SimpleSpan, IntegerWidth),
NumberCouldntBeParsedToDefault(SimpleSpan),
}

#[derive(Debug)]
Expand Down Expand Up @@ -492,7 +495,7 @@ impl<'a> ResolutionEnv<'a> {
span: SimpleSpan,
) -> (TypeId, fir::Expression) {
match rslt {
Ok(lit) => self.resolve_number_literal_ok(try_to_be, lit),
Ok(lit) => self.resolve_number_literal_ok(try_to_be, lit, span),
Err(e) => (
try_to_be.unwrap_or_else(|| {
self.resolve_type(Type::Error(
Expand All @@ -510,6 +513,7 @@ impl<'a> ResolutionEnv<'a> {
&mut self,
try_to_be: Option<TypeId>,
lit: &parsers::number::NumberLiteral,
span: SimpleSpan,
) -> (TypeId, fir::Expression) {
let (ty, lit) = match lit {
parsers::number::NumberLiteral::Unsigned(n, w) => (
Expand All @@ -526,16 +530,29 @@ impl<'a> ResolutionEnv<'a> {
),
parsers::number::NumberLiteral::Inferred(int) => {
let int = int.as_ref().expect_left("TODO: floats");
let Some(try_to_be @ (PrimitiveType::Float(_) | PrimitiveType::Integer(_, _))) =
try_to_be
.and_then(|t| self.resolver.type_registery.borrow().get_as_primitive(t))
let Some((
try_to_be_ty_id,
try_to_be @ (PrimitiveType::Float(_) | PrimitiveType::Integer(_, _)),
)) = try_to_be.and_then(|t| {
self.resolver
.type_registery
.borrow()
.get_as_primitive(t)
.map(|t2| (t, t2))
})
else {
let Some((i, w)) = TryInto::<i32>::try_into(int)
.map(|i| (i as i64, LiteralWidth::_32))
.or_else(|_| TryInto::<i64>::try_into(int).map(|i| (i, LiteralWidth::_64)))
.ok()
else {
todo!("NumberLiteral::Inferred/default/error")
self.add_error(TypeResError::NumberCouldntBeParsedToDefault(span), span);
return (
self.resolve_primitive(PrimitiveType::Integer(true, IntegerWidth::_32)),
fir::Expression::Number(Err(
parsers::number::NumberLiteralError::Error,
)),
);
};
return (
self.resolve_primitive(PrimitiveType::Integer(true, w.into())),
Expand Down Expand Up @@ -568,20 +585,37 @@ impl<'a> ResolutionEnv<'a> {
}
match try_to_be {
PrimitiveType::Integer(s, w) => {
let (p_w, p_i) = if s {
let Ok((i, w)) = try_parse!(u) else {
todo!("NumberLiteral::Inferred/into uinteger/error")
let (p_i, p_w) = if s {
let Ok((i, w)) = try_parse!(i) else {
self.add_error(
TypeResError::NumberCouldntInferInto(try_to_be, span),
span,
);
return (
try_to_be_ty_id,
fir::Expression::Number(Ok(lit.to_owned().into())),
);
};
(IntegerWidth::from(w), i as i128)
(i as i128, IntegerWidth::from(w))
} else {
let Ok((i, w)) = try_parse!(i) else {
todo!("NumberLiteral::Inferred/into iinteger/error")
let Ok((i, w)) = try_parse!(u) else {
self.add_error(
TypeResError::NumberCouldntInferInto(try_to_be, span),
span,
);
return (
try_to_be_ty_id,
fir::Expression::Number(Ok(lit.to_owned().into())),
);
};
(IntegerWidth::from(w), i as i128)
(i as i128, IntegerWidth::from(w))
};
println!("{w:?} {p_w:?}");
if w < p_w {
todo!("NumberLiteral::Inferred/downcast error")
self.add_error(
TypeResError::NumberCouldntBeDowncasted(try_to_be, span, p_w),
span,
);
}
(
self.resolve_primitive(PrimitiveType::Integer(s, w.max(p_w))),
Expand Down
2 changes: 1 addition & 1 deletion tests/test-projects/001/src/main.aplang
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,5 @@ fn main() {
e = person.address.b
var a = 1
var b: u32 = 1
var c: u8 = 1
var c: u8 = 256
}

0 comments on commit 38abf6a

Please sign in to comment.