Skip to content

Commit

Permalink
Merge pull request #123 from lambdaclass/multiple_packages
Browse files Browse the repository at this point in the history
initial progress for multiple packages
  • Loading branch information
juanbono authored May 10, 2024
2 parents 56a8221 + b19ba57 commit 055c734
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 98 deletions.
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

0 comments on commit 055c734

Please sign in to comment.