Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initial progress for multiple packages #123

Merged
merged 5 commits into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/concrete_ast/src/modules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::{
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Module {
pub doc_string: Option<DocString>,
pub external_modules: Vec<Ident>,
pub imports: Vec<ImportStmt>,
pub name: Ident,
pub contents: Vec<ModuleDefItem>,
Expand Down
35 changes: 18 additions & 17 deletions crates/concrete_check/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use std::{ops::Range, path::PathBuf};
use std::ops::Range;

use ariadne::{ColorGenerator, Label, Report, ReportKind};
use concrete_ir::lowering::errors::LoweringError;
use concrete_session::Session;

/// Creates a report from a lowering error.
pub fn lowering_error_to_report(
error: LoweringError,
file_paths: &[PathBuf],
session: &Session,
) -> Report<'static, (String, Range<usize>)> {
let mut colors = ColorGenerator::new();
colors.next();
Expand All @@ -17,7 +18,7 @@ pub fn lowering_error_to_report(
program_id,
} => {
let offset = span.from;
let path = file_paths[program_id].display().to_string();
let path = session.file_paths[program_id].display().to_string();
Report::build(ReportKind::Error, path.clone(), offset)
.with_code("ModuleNotFound")
.with_label(
Expand All @@ -33,7 +34,7 @@ pub fn lowering_error_to_report(
function,
program_id,
} => {
let path = file_paths[program_id].display().to_string();
let path = session.file_paths[program_id].display().to_string();
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("FunctionNotFound")
.with_label(
Expand All @@ -48,7 +49,7 @@ pub fn lowering_error_to_report(
name,
program_id,
} => {
let path = file_paths[program_id].display().to_string();
let path = session.file_paths[program_id].display().to_string();
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("StructFieldNotFound")
.with_label(
Expand All @@ -64,7 +65,7 @@ pub fn lowering_error_to_report(
symbol,
program_id,
} => {
let path = file_paths[program_id].display().to_string();
let path = session.file_paths[program_id].display().to_string();
let offset = symbol.span.from;
Report::build(ReportKind::Error, path.clone(), offset)
.with_code("ImportNotFound")
Expand All @@ -90,7 +91,7 @@ pub fn lowering_error_to_report(
type_span,
program_id,
} => {
let path = file_paths[program_id].display().to_string();
let path = session.file_paths[program_id].display().to_string();
let mut labels = vec![Label::new((path.clone(), span.into()))
.with_message(format!(
"Can't mutate {name:?} because it's behind a immutable borrow"
Expand All @@ -115,7 +116,7 @@ pub fn lowering_error_to_report(
name,
program_id,
} => {
let path = file_paths[program_id].display().to_string();
let path = session.file_paths[program_id].display().to_string();
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("UnrecognizedType")
.with_label(
Expand All @@ -131,7 +132,7 @@ pub fn lowering_error_to_report(
id,
program_id,
} => {
let path = file_paths[program_id].display().to_string();
let path = session.file_paths[program_id].display().to_string();
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("E_ID")
.with_label(
Expand All @@ -147,7 +148,7 @@ pub fn lowering_error_to_report(
message,
program_id,
} => {
let path = file_paths[program_id].display().to_string();
let path = session.file_paths[program_id].display().to_string();
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("NotYetImplemented")
.with_label(
Expand All @@ -163,7 +164,7 @@ pub fn lowering_error_to_report(
expected,
program_id,
} => {
let path = file_paths[program_id].display().to_string();
let path = session.file_paths[program_id].display().to_string();
let mut labels = vec![Label::new((path.clone(), span.into()))
.with_message(format!(
"Unexpected type '{}', expected '{}'",
Expand All @@ -190,7 +191,7 @@ pub fn lowering_error_to_report(
name,
program_id,
} => {
let path = file_paths[program_id].display().to_string();
let path = session.file_paths[program_id].display().to_string();
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("UseOfUndeclaredVariable")
.with_label(
Expand All @@ -205,7 +206,7 @@ pub fn lowering_error_to_report(
name,
program_id,
} => {
let path = file_paths[program_id].display().to_string();
let path = session.file_paths[program_id].display().to_string();
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("ExternFnWithBody")
.with_label(
Expand All @@ -216,7 +217,7 @@ pub fn lowering_error_to_report(
.finish()
}
LoweringError::InternalError(msg, program_id) => {
let path = file_paths[program_id].display().to_string();
let path = session.file_paths[program_id].display().to_string();
Report::build(ReportKind::Error, path.clone(), 0)
.with_code("InternalError")
.with_message(msg)
Expand All @@ -228,7 +229,7 @@ pub fn lowering_error_to_report(
needs,
program_id,
} => {
let path = file_paths[program_id].display().to_string();
let path = session.file_paths[program_id].display().to_string();
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("CallParamCountMismatch")
.with_label(
Expand All @@ -247,7 +248,7 @@ pub fn lowering_error_to_report(
declare_span,
program_id,
} => {
let path = file_paths[program_id].display().to_string();
let path = session.file_paths[program_id].display().to_string();
let mut report = Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("NotMutable")
.with_label(
Expand All @@ -270,7 +271,7 @@ pub fn lowering_error_to_report(
declare_span,
program_id,
} => {
let path = file_paths[program_id].display().to_string();
let path = session.file_paths[program_id].display().to_string();
let mut report = Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("CantTakeMutableBorrow")
.with_label(
Expand Down
165 changes: 87 additions & 78 deletions crates/concrete_driver/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
use anyhow::bail;
use anyhow::Context;
use anyhow::Result;
use ariadne::Source;
use clap::Args;
use clap::{Parser, Subcommand};
use concrete_ast::Program;
use concrete_ir::lowering::lower_programs;
use concrete_parser::{error::Diagnostics, ProgramSource};
use concrete_session::{
config::{DebugInfo, OptLevel},
Session,
};
use config::{Package, Profile};
use db::Database;
use git2::{IndexAddOption, Repository};
use owo_colors::OwoColorize;
use std::io::Read;
use std::os::unix::process::CommandExt;
use std::{collections::HashMap, fs::File, path::PathBuf, time::Instant};
use walkdir::WalkDir;

use crate::{
config::Config,
Expand Down Expand Up @@ -394,7 +396,6 @@ fn handle_build(
if !target_dir.exists() {
std::fs::create_dir_all(&target_dir)?;
}
let has_main = src_dir.join("main.con").exists();
let output = target_dir.join(config.package.name);
let (profile, profile_name) = if let Some(profile) = profile {
(
Expand All @@ -421,26 +422,46 @@ fn handle_build(
"dev".to_string(),
)
};
let compile_args = CompilerArgs {
input: src_dir,
output: output.clone(),
release,
optlevel: Some(profile.opt_level),
debug_info: Some(profile.debug_info),
library: !has_main,
ast,
ir,
llvm,
asm,
object,
mlir,
};

let lib_ed = src_dir.join("lib.con");
let main_ed = src_dir.join("main.con");

let start = Instant::now();
let object = compile(&compile_args)?;
if !has_main {
link_shared_lib(&[object], &output)?;
} else {
link_binary(&[object], &output)?;

for file in [main_ed, lib_ed] {
if file.exists() {
let is_lib = file.file_stem().unwrap() == "lib";

let compile_args = CompilerArgs {
input: file,
output: if is_lib {
let name = output.file_stem().unwrap().to_string_lossy().to_string();
let name = format!("lib{name}");
output
.with_file_name(name)
.with_extension(Session::get_platform_library_ext())
} else {
output.clone()
},
release,
optlevel: Some(profile.opt_level),
debug_info: Some(profile.debug_info),
library: is_lib,
ast,
ir,
llvm,
asm,
object,
mlir,
};
let object = compile(&compile_args)?;

if compile_args.library {
link_shared_lib(&[object], &compile_args.output)?;
} else {
link_binary(&[object], &compile_args.output)?;
}
}
}
let elapsed = start.elapsed();
println!(
Expand All @@ -464,54 +485,56 @@ fn handle_build(
}
}

pub fn compile(args: &CompilerArgs) -> Result<PathBuf> {
let mut files = Vec::new();
for entry in WalkDir::new(&args.input) {
let entry = entry?;
if let Some(ext) = entry.path().extension() {
if ext.eq_ignore_ascii_case("con") {
files.push(entry.path().to_path_buf());
}
}
pub fn parse_file(
modules: &mut Vec<(PathBuf, String, Program)>,
mut path: PathBuf,
db: &Database,
) -> Result<()> {
if path.is_dir() {
path = path.join("mod.ed");
}

if files.is_empty() {
panic!("files is empty");
let real_source = std::fs::read_to_string(&path)?;
let source = ProgramSource::new(db, real_source.clone(), path.display().to_string());

let mut program = match concrete_parser::parse_ast(db, source) {
Some(x) => x,
None => {
Diagnostics::dump(
db,
source,
&concrete_parser::parse_ast::accumulated::<concrete_parser::error::Diagnostics>(
db, source,
),
);
std::process::exit(1);
}
};
program.file_path = Some(path.clone());

for ident in program.modules.iter().flat_map(|x| &x.external_modules) {
let module_path = path
.parent()
.unwrap()
.join(&ident.name)
.with_extension("con");
parse_file(modules, module_path, db)?;
}

modules.push((path, real_source, program));

Ok(())
}

pub fn compile(args: &CompilerArgs) -> Result<PathBuf> {
let start_time = Instant::now();

let mut programs = Vec::new();

let db = crate::db::Database::default();

let mut sources = Vec::new();
let mut sources_str = Vec::new();

for path in files {
let source = std::fs::read_to_string(&path)?;
let source = ProgramSource::new(&db, source, args.input.display().to_string());

let mut program = match concrete_parser::parse_ast(&db, source) {
Some(x) => x,
None => {
Diagnostics::dump(
&db,
source,
&concrete_parser::parse_ast::accumulated::<concrete_parser::error::Diagnostics>(
&db, source,
),
);
std::process::exit(1);
}
};
program.file_path = Some(path);
sources.push(ariadne::Source::from(source.input(&db).clone()));
sources_str.push(source.input(&db).clone());
programs.push(program);
}
parse_file(&mut programs, args.input.clone(), &db)?;

let session = Session {
file_paths: programs.iter().map(|x| x.0.clone()).collect(),
debug_info: if let Some(debug_info) = args.debug_info {
if debug_info {
DebugInfo::Full
Expand All @@ -535,7 +558,7 @@ pub fn compile(args: &CompilerArgs) -> Result<PathBuf> {
} else {
OptLevel::None
},
sources,
sources: programs.iter().map(|x| Source::from(x.1.clone())).collect(),
library: args.library,
output_file: args.output.with_extension("o"),
output_asm: args.asm,
Expand All @@ -549,18 +572,7 @@ pub fn compile(args: &CompilerArgs) -> Result<PathBuf> {

let path_cache: Vec<_> = programs
.iter()
.zip(&sources_str)
.map(|(program, source)| {
(
program
.file_path
.clone()
.expect("path should always exist here")
.to_string_lossy()
.to_string(),
source.clone(),
)
})
.map(|x| (x.0.display().to_string(), x.1.clone()))
.collect();

if args.ast {
Expand All @@ -570,14 +582,11 @@ pub fn compile(args: &CompilerArgs) -> Result<PathBuf> {
)?;
}

let program_ir = match lower_programs(&programs) {
let modules: Vec<_> = programs.iter().map(|x| x.2.clone()).collect();
let program_ir = match lower_programs(&modules) {
Ok(ir) => ir,
Err(error) => {
let file_paths: Vec<_> = programs
.iter()
.map(|x| x.file_path.clone().unwrap())
.collect();
let report = concrete_check::lowering_error_to_report(error, &file_paths);
let report = concrete_check::lowering_error_to_report(error, &session);
report.eprint(ariadne::sources(path_cache))?;
std::process::exit(1);
}
Expand Down
Loading
Loading