Skip to content

Commit

Permalink
Impl If expression
Browse files Browse the repository at this point in the history
  • Loading branch information
Amejonah1200 committed Sep 6, 2023
1 parent f07536a commit a1fd411
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 25 deletions.
45 changes: 24 additions & 21 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,26 +163,29 @@ fn main() {
}
rep
}
TypesAreNotMatching(a, b) => rep
.with_message("Types are not matching")
.with_label({
let color = colors.next();
ariadne::Label::new((&input_name as &str, a.1.into_range()))
.with_color(color)
.with_message(format!(
"this is of type: {}",
workspace.display_type(&rodeo, a.0).fg(color)
))
})
.with_label({
let color = colors.next();
ariadne::Label::new((&input_name as &str, b.1.into_range()))
.with_color(color)
.with_message(format!(
"this is of type: {}",
workspace.display_type(&rodeo, b.0).fg(color)
))
}),
TypesAreNotMatching(context, a, b) => {
use resolution::type_resolution::TypesAreNotMatchingContext::*;
let ty_a_color = colors.next();
let ty_a_str = workspace.display_type(&rodeo, a.0).fg(ty_a_color);
let ty_b_color = colors.next();
let ty_b_str = workspace.display_type(&rodeo, b.0).fg(ty_b_color);
rep
.with_message(match context {
If => format!("Ifs arms des not have matching types, both must be of type `{ty_a_str}`, but second arm is `{ty_b_str}`"),
Assignment => format!("Assignments right-hand's type does not match left-hand's type. Expected `{ty_a_str}`, got `{ty_b_str}`."),
FuncRet => format!("Return's expression's type does not match functions return type: function returns `{ty_a_str}` but the return's expression is of type `{ty_b_str}`."),
})
.with_label(
ariadne::Label::new((&input_name as &str, a.1.into_range()))
.with_color(ty_a_color)
.with_message(format!("this is of type: {ty_a_str}"))
)
.with_label(
ariadne::Label::new((&input_name as &str, b.1.into_range()))
.with_color(ty_b_color)
.with_message(format!("this is of type: {ty_b_str}"))
)
},
FieldNotFound(
Spanned((dep, struct_id), base_span),
Spanned(name, name_span),
Expand Down Expand Up @@ -306,7 +309,7 @@ fn main() {
.with_message(format!("this condition is of type `{ty_str}`"))
)
},
BinaryHandsNotPrimitive(group, Spanned(op, op_span), error, Spanned(lhs_ty, lhs_span), Spanned(rhs_ty, rhs_span)) => {
BinaryHandsNotPrimitive(group, Spanned(op, op_span), _error, Spanned(lhs_ty, lhs_span), Spanned(rhs_ty, rhs_span)) => {
let lhs_color = colors.next();
let rhs_color = colors.next();
let op_color = colors.next();
Expand Down
50 changes: 48 additions & 2 deletions src/resolution/type_resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pub enum TypeResError {
FunctionNotFound(Spanned<Spur>, Vec<Spanned<TypeId>>),
VariableNotFound(Spanned<Spur>, Option<TypeId>),
FieldNotFound(Spanned<(DependencyId, StructId)>, Spanned<Spur>),
TypesAreNotMatching(Spanned<TypeId>, Spanned<TypeId>),
TypesAreNotMatching(TypesAreNotMatchingContext, Spanned<TypeId>, Spanned<TypeId>),
SignNotMatching(
Spanned<(bool, IntegerWidth)>,
OperationGroup,
Expand All @@ -98,6 +98,14 @@ pub enum TypeResError {
Spanned<TypeId>,
),
}

#[derive(Debug)]
pub enum TypesAreNotMatchingContext {
If,
Assignment,
FuncRet,
}

#[derive(Debug)]
pub enum FunctionReturnProblem {
ExpectedEmptyReturn,
Expand Down Expand Up @@ -208,7 +216,43 @@ impl<'a> ResolutionEnv<'a> {
self.resolve_primitive(PrimitiveType::Boolean),
fir::Expression::Bool(*b),
),
e => todo!("Expression::{}", Into::<&'static str>::into(e)),
ast::expressions::Expression::If {
condition,
then,
other,
} => {
let Spanned(cond, cond_span) = condition.as_ref();
let bool_ty = self.resolve_primitive(PrimitiveType::Boolean);
let cond = self.resolve_expression(Some(bool_ty), cond, *cond_span);
if cond.info != bool_ty {
self.add_error(
TypeResError::ConditionNotBool(cond.as_spanned_cloned_info()),
span,
);
}
let Spanned(then, then_span) = then.as_ref();
let then = Box::new(self.resolve_expression(try_to_be, then, *then_span));
let Spanned(other, other_span) = other.as_ref();
let other = Box::new(self.resolve_expression(Some(then.info), other, *other_span));
if then.info != other.info {
self.add_error(
TypeResError::TypesAreNotMatching(
TypesAreNotMatchingContext::If,
then.as_spanned_cloned_info(),
other.as_spanned_cloned_info(),
),
span,
);
}
(
then.info,
fir::Expression::If {
condition: cond.into(),
then,
other,
},
)
}
};
Infoed {
inner: expr,
Expand Down Expand Up @@ -837,6 +881,7 @@ impl<'a> ResolutionEnv<'a> {
if ty != expr_ty {
self.add_error(
TypeResError::TypesAreNotMatching(
TypesAreNotMatchingContext::Assignment,
Spanned(ty, *var_span),
Spanned(expr_ty, *expr_span),
),
Expand Down Expand Up @@ -1026,6 +1071,7 @@ impl<'a> ResolutionEnv<'a> {
if a != b.0 {
self.add_error(
TypeResError::TypesAreNotMatching(
TypesAreNotMatchingContext::FuncRet,
self.func_info
.decl
.ast
Expand Down
4 changes: 2 additions & 2 deletions tests/test-projects/001/src/main.aplang
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ fn main() {
var test = new_newborn(r"a") + new_newborn(r"b")
var test = new_newborn(r"a") + 1u16
var test = 1u16 + new_newborn(r"b")
var d1 = !1u16
var a = c + (d = e) - 2u16 / 2u16
var d = if (1u16) 1u16 else 1u8
var a = c + (d = r"") - 2u16 / 2u16
println(r"Hello World!")
val person = Person(r"Amejonah", 42u8)
test_person(person)
Expand Down

0 comments on commit a1fd411

Please sign in to comment.