Skip to content

Commit

Permalink
add undeclared variable check
Browse files Browse the repository at this point in the history
  • Loading branch information
edg-l committed Mar 4, 2024
1 parent 33843e2 commit 9c0396e
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 20 deletions.
24 changes: 17 additions & 7 deletions crates/concrete_check/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub fn lowering_error_to_report(
LoweringError::ModuleNotFound { span, module } => {
let offset = span.from;
Report::build(ReportKind::Error, path.clone(), offset)
.with_code("E1")
.with_code("ModuleNotFound")
.with_label(
Label::new((path, span.into()))
.with_message(format!("Module {module:?} not found."))
Expand All @@ -27,7 +27,7 @@ pub fn lowering_error_to_report(
}
LoweringError::FunctionNotFound { span, function } => {
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("EFNNOTFOUND")
.with_code("FunctionNotFound")
.with_label(
Label::new((path, span.into()))
.with_message(format!("Function {function:?} not found."))
Expand All @@ -38,7 +38,7 @@ pub fn lowering_error_to_report(
LoweringError::ImportNotFound { import_span, module_span, symbol } => {
let offset = symbol.span.from;
Report::build(ReportKind::Error, path.clone(), offset)
.with_code("E2")
.with_code("ImportNotFound")
.with_label(
Label::new((path.clone(), module_span.into()))
.with_message("In module this module."),
Expand Down Expand Up @@ -69,13 +69,13 @@ pub fn lowering_error_to_report(
}

Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("EREFMUT")
.with_code("BorrowNotMutable")
.with_labels(labels)
.finish()
},
LoweringError::UnrecognizedType { span, name } => {
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("E3")
.with_code("UnrecognizedType")
.with_label(
Label::new((path, span.into()))
.with_message(format!("Failed to find type {:?}", name))
Expand All @@ -97,7 +97,7 @@ pub fn lowering_error_to_report(
},
LoweringError::NotYetImplemented { span, message } => {
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("TODO")
.with_code("NotYetImplemented")
.with_label(
Label::new((path, span.into()))
.with_message(message)
Expand All @@ -121,10 +121,20 @@ pub fn lowering_error_to_report(
}

Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("E3")
.with_code("UnexpectedType")
.with_labels(labels)
.with_message(format!("expected type {}.", expected.kind))
.finish()
},
LoweringError::UseOfUndeclaredVariable { span, name } => {
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("UseOfUndeclaredVariable")
.with_label(
Label::new((path, span.into()))
.with_message(format!("Use of undeclared variable {:?}", name))
.with_color(colors.next()),
)
.finish()
},
}
}
18 changes: 18 additions & 0 deletions crates/concrete_driver/tests/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,21 @@ pub fn check_invalid_program(source: &str, name: &str) -> LoweringError {

lower_program(&program).expect_err("expected error")
}

#[test]
fn undeclared_var() {
let (source, name) = (
include_str!("invalid_programs/undeclared_var.con"),
"undeclared_var",
);
let error = check_invalid_program(source, name);

assert!(
matches!(
&error,
LoweringError::UseOfUndeclaredVariable { name, .. } if name == "b"
),
"{:#?}",
error
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
mod Simple {
fn main() -> i32 {
b = 2;
return 0;
}
}
31 changes: 18 additions & 13 deletions crates/concrete_ir/src/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ fn lower_let(builder: &mut FnBodyBuilder, info: &LetStmt) -> Result<(), Lowering
}

fn lower_assign(builder: &mut FnBodyBuilder, info: &AssignStmt) -> Result<(), LoweringError> {
let (mut place, mut ty, _path_span) = lower_path(builder, &info.target);
let (mut place, mut ty, _path_span) = lower_path(builder, &info.target)?;

for _ in 0..info.derefs {
match &ty.kind {
Expand Down Expand Up @@ -681,7 +681,7 @@ fn lower_expression(
) -> Result<(Rvalue, TyKind, Span), LoweringError> {
Ok(match info {
Expression::Value(info, span) => {
let value = lower_value_expr(builder, info, type_hint);
let value = lower_value_expr(builder, info, type_hint)?;
(value.0, value.1, *span)
}
Expression::FnCall(info) => lower_fn_call(builder, info)?,
Expand Down Expand Up @@ -1008,8 +1008,8 @@ fn lower_value_expr(
builder: &mut FnBodyBuilder,
info: &ValueExpr,
type_hint: Option<TyKind>,
) -> (Rvalue, TyKind) {
match info {
) -> Result<(Rvalue, TyKind), LoweringError> {
Ok(match info {
ValueExpr::ConstBool(value) => (
Rvalue::Use(Operand::Const(ConstData {
ty: TyKind::Bool,
Expand Down Expand Up @@ -1115,17 +1115,22 @@ fn lower_value_expr(
}
ValueExpr::ConstStr(_) => todo!(),
ValueExpr::Path(info) => {
let (place, place_ty, _span) = lower_path(builder, info);
let (place, place_ty, _span) = lower_path(builder, info)?;
(Rvalue::Use(Operand::Place(place.clone())), place_ty.kind)
}
}
})
}

pub fn lower_path(builder: &mut FnBodyBuilder, info: &PathOp) -> (Place, Ty, Span) {
let local = *builder
.name_to_local
.get(&info.first.name)
.expect("local not found");
pub fn lower_path(
builder: &mut FnBodyBuilder,
info: &PathOp,
) -> Result<(Place, Ty, Span), LoweringError> {
let local = *builder.name_to_local.get(&info.first.name).ok_or(
LoweringError::UseOfUndeclaredVariable {
span: info.span,
name: info.first.name.clone(),
},
)?;

let ty = builder.body.locals[local].ty.clone();
let ty_span = ty.span;
Expand All @@ -1152,14 +1157,14 @@ pub fn lower_path(builder: &mut FnBodyBuilder, info: &PathOp) -> (Place, Ty, Spa
}
}

(
Ok((
Place { local, projection },
Ty {
span: ty_span,
kind: ty,
},
info.span,
)
))
}

pub fn lower_type(ctx: &BuildCtx, spec: &TypeSpec, module_id: DefId) -> Result<Ty, LoweringError> {
Expand Down
2 changes: 2 additions & 0 deletions crates/concrete_ir/src/lowering/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ pub enum LoweringError {
import_span: Span,
symbol: Ident,
},
#[error("use of underclared variable {name:?}")]
UseOfUndeclaredVariable { span: Span, name: String },
#[error("trying to mutate a non-mutable reference")]
BorrowNotMutable {
span: Span,
Expand Down

0 comments on commit 9c0396e

Please sign in to comment.