Skip to content

Commit

Permalink
feat: code checking in lowering
Browse files Browse the repository at this point in the history
  • Loading branch information
edg-l committed Feb 24, 2024
1 parent 3992a57 commit 14bd8af
Show file tree
Hide file tree
Showing 10 changed files with 368 additions and 96 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions lib/edlang_check/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ repository = "https://github.com/edg-l/edlang"
[dependencies]
ariadne = { version = "0.4.0", features = ["auto-color"] }
edlang_ast = { version = "0.0.1-alpha.8", path = "../edlang_ast" }
edlang_lowering = { version = "0.0.1-alpha.8", path = "../edlang_lowering" }
edlang_session = { version = "0.0.1-alpha.8", path = "../edlang_session" }
tracing = { workspace = true }
108 changes: 108 additions & 0 deletions lib/edlang_check/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1 +1,109 @@
use std::ops::Range;

use ariadne::{ColorGenerator, Label, Report, ReportKind};
use edlang_lowering::errors::LoweringError;
use edlang_session::Session;

/// Creates a report from a lowering error.
pub fn lowering_error_to_report(
error: LoweringError,
session: &Session,
) -> Report<(String, Range<usize>)> {
let path = session.file_path.display().to_string();
let mut colors = ColorGenerator::new();
colors.next();
match error {
LoweringError::ModuleNotFound { span, module } => {
let offset = span.lo;
Report::build(ReportKind::Error, path.clone(), offset)
.with_code("E1")
.with_label(
Label::new((path, span.into()))
.with_message(format!("Module {module:?} not found."))
.with_color(colors.next()),
)
.with_message("Unresolved import.")
.finish()
}
LoweringError::FunctionNotFound { span, function } => {
Report::build(ReportKind::Error, path.clone(), span.lo)
.with_code("EFNNOTFOUND")
.with_label(
Label::new((path, span.into()))
.with_message(format!("Function {function:?} not found."))
.with_color(colors.next()),
)
.finish()
},
LoweringError::ImportNotFound { import_span, module_span, symbol } => {
let offset = symbol.span.lo;
Report::build(ReportKind::Error, path.clone(), offset)
.with_code("E2")
.with_label(
Label::new((path.clone(), module_span.into()))
.with_message("In module this module."),
)
.with_label(
Label::new((path.clone(), import_span.into()))
.with_message("In this import statement"),
)
.with_label(
Label::new((path, symbol.span.into()))
.with_message(format!("Failed to find symbol {:?}", symbol.name))
.with_color(colors.next()),
)
.with_message("Unresolved import.")
.finish()
},
LoweringError::BorrowNotMutable { span, name, type_span } => {
let mut labels = vec![
Label::new((path.clone(), span.into()))
.with_message(format!("Can't mutate {name:?} because it's behind a immutable borrow"))
.with_color(colors.next())
];

if let Some(type_span) = type_span {
labels.push(Label::new((path.clone(), type_span.into()))
.with_message(format!("Variable {name:?} has this type"))
.with_color(colors.next()));
}

Report::build(ReportKind::Error, path.clone(), span.lo)
.with_code("EREFMUT")
.with_labels(labels)
.finish()
},
LoweringError::UnrecognizedType { span, name } => {
Report::build(ReportKind::Error, path.clone(), span.lo)
.with_code("E3")
.with_label(
Label::new((path, span.into()))
.with_message(format!("Failed to find type {:?}", name))
.with_color(colors.next()),
)
.with_message(format!("Unresolved type {:?}.", name))
.finish()
},
LoweringError::IdNotFound { span, id } => {
Report::build(ReportKind::Error, path.clone(), span.lo)
.with_code("E_ID")
.with_label(
Label::new((path, span.into()))
.with_message("Failed to definition id")
.with_color(colors.next()),
)
.with_message(format!("Failed to find definition id {id:?}, this is most likely a compiler bug or a unimplemented lowering"))
.finish()
},
LoweringError::NotYetImplemented { span, message } => {
Report::build(ReportKind::Error, path.clone(), span.lo)
.with_code("TODO")
.with_label(
Label::new((path, span.into()))
.with_message(message)
.with_color(colors.next()),
)
.finish()
},
}
}
10 changes: 9 additions & 1 deletion lib/edlang_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,15 @@ pub fn main() -> Result<(), Box<dyn Error>> {
return Ok(());
}

let program_ir = lower_modules(&[module.clone()]);
let program_ir = match lower_modules(&[module.clone()]) {
Ok(ir) => ir,
Err(error) => {
let report = edlang_check::lowering_error_to_report(error, &session);
let path = session.file_path.display().to_string();
report.eprint((path, session.source.clone()))?;
std::process::exit(1);
}
};

if args.ir {
println!("{:#?}", program_ir);
Expand Down
2 changes: 1 addition & 1 deletion lib/edlang_driver/tests/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ pub fn compile_program(
output_asm: false,
};

let program_ir = lower_modules(&[module]);
let program_ir = lower_modules(&[module])?;

let object_path = edlang_codegen_llvm::compile(&session, &program_ir)?;

Expand Down
1 change: 1 addition & 0 deletions lib/edlang_lowering/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ repository = "https://github.com/edg-l/edlang"
edlang_ast = { version = "0.0.1-alpha.8", path = "../edlang_ast" }
edlang_ir = { version = "0.0.1-alpha.8", path = "../edlang_ir" }
tracing.workspace = true
thiserror = "1.0.57"
30 changes: 30 additions & 0 deletions lib/edlang_lowering/src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use edlang_ast::{Ident, Span};
use thiserror::Error;

use crate::DefId;

#[derive(Debug, Error, Clone)]
pub enum LoweringError {
#[error("module {module:?} not found")]
ModuleNotFound { span: Span, module: String },
#[error("function {function:?} not found")]
FunctionNotFound { span: Span, function: String },
#[error("symbol {:?} not found", symbol.name)]
ImportNotFound {
module_span: Span,
import_span: Span,
symbol: Ident,
},
#[error("trying to mutate a non-mutable reference")]
BorrowNotMutable {
span: Span,
type_span: Option<Span>,
name: String,
},
#[error("unrecognized type {name}")]
UnrecognizedType { span: Span, name: String },
#[error("id not found")]
IdNotFound { span: Span, id: DefId },
#[error("feature not yet implemented: {message}")]
NotYetImplemented { span: Span, message: &'static str },
}
Loading

0 comments on commit 14bd8af

Please sign in to comment.