Skip to content

Commit

Permalink
Merge branch 'main' into syntax-union-enum
Browse files Browse the repository at this point in the history
  • Loading branch information
JulianGCalderon committed Apr 22, 2024
2 parents f9585b8 + 802b249 commit 6aefbe3
Show file tree
Hide file tree
Showing 16 changed files with 443 additions and 189 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ target/
.vscode/
lcov.info

build_artifacts/
build/

*.so
*.a
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ export LLVM_SYS_170_PREFIX=/usr/lib/llvm-17
export TABLEGEN_170_PREFIX=/usr/lib/llvm-17
```

If you installed llvm with brew, source the `env-macos.sh` script to set up the needed env vars:
```sh
source scripts/env-macos.sh
```

## Table of Contents

- [Design](#design)
Expand Down
7 changes: 4 additions & 3 deletions crates/concrete_ast/src/statements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,11 @@ pub struct Binding {

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ForStmt {
pub name: Ident,
pub from: Expression,
pub to: Expression,
pub init: Option<LetStmt>,
pub condition: Option<Expression>,
pub post: Option<AssignStmt>,
pub contents: Vec<Statement>,
pub span: Span,
}

#[derive(Clone, Debug, Eq, PartialEq)]
Expand Down
284 changes: 175 additions & 109 deletions crates/concrete_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use config::{Package, Profile};
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;

Expand Down Expand Up @@ -55,6 +56,19 @@ enum Commands {
#[arg(short, long, default_value_t = false)]
release: bool,

/// Override the profile to use.
#[arg(short, long)]
profile: Option<String>,
},
/// Run a concrete file
Run {
#[arg(required = false)]
path: Option<PathBuf>,

/// Build for release with all optimizations.
#[arg(short, long, default_value_t = false)]
release: bool,

/// Override the profile to use.
#[arg(short, long)]
profile: Option<String>,
Expand Down Expand Up @@ -125,7 +139,7 @@ pub fn main() -> Result<()> {
} => {
let name = name.unwrap_or_else(|| {
path.file_name()
.context("Failed to get project name")
.context("failed to get project name")
.unwrap()
.to_string_lossy()
.to_string()
Expand Down Expand Up @@ -234,126 +248,178 @@ mod {} {{
}
}
Commands::Build { release, profile } => {
let mut current_dir = std::env::current_dir()?;
let mut config_path = None;

// Go up to 3 parent folders to find Concrete.toml
for _ in 0..3 {
if !current_dir.join("Concrete.toml").exists() {
current_dir = if let Some(parent) = current_dir.parent() {
parent.to_path_buf()
} else {
bail!("Couldn't find Concrete.toml");
build_command(profile, release)?;
}
Commands::Run {
path,
release,
profile,
} => {
let output = match path {
Some(input) => {
let input_stem = input
.file_stem()
.context("could not get file stem")?
.to_str()
.context("could not convert file stem to string")?;

let build_dir = std::env::current_dir()?.join("build");
if !build_dir.exists() {
std::fs::create_dir_all(&build_dir)?;
}
let output = build_dir.join(input_stem);

let compile_args = CompilerArgs {
input: input.clone(),
output: output.clone(),
release,
optlevel: None,
debug_info: None,
library: false,
ast: false,
ir: false,
llvm: true,
asm: false,
object: true,
mlir: true,
};
} else {
config_path = Some(current_dir.join("Concrete.toml"));
break;
}
}

let config_path = match config_path {
Some(x) => x,
None => bail!("Couldn't find Concrete.toml"),
println!(
" {} {} ({})",
"Compiling".green().bold(),
input_stem,
input.display()
);

let start = Instant::now();
let object = compile(&compile_args)?;
link_binary(&[object], &output)?;
let elapsed = start.elapsed();

println!(
" {} {} in {elapsed:?}",
"Finished".green().bold(),
if release { "release" } else { "dev" },
);

output
}
None => build_command(profile, release)?,
};

let base_dir = config_path
.parent()
.context("couldn't get config parent dir")?;
let mut config = File::open(&config_path).context("Failed to open Concrete.toml")?;
let mut buf = String::new();
config.read_to_string(&mut buf)?;

let config: Config = toml::from_str(&buf).context("failed to parse Concrete.toml")?;

println!(
" {} {} v{} ({})",
"Compiling".green().bold(),
config.package.name,
config.package.version,
base_dir.display()
);
println!(" {} {}", "Running".green().bold(), &output.display());

let src_dir = base_dir.join("src");
let target_dir = base_dir.join("build");
Err(std::process::Command::new(output).exec())?;
}
}

if !target_dir.exists() {
std::fs::create_dir_all(&target_dir)?;
}
Ok(())
}

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 {
(
config
.profile
.get(&profile)
.context("Couldn't get requested profile")?,
profile,
)
} else if release {
(
config
.profile
.get("release")
.context("Couldn't get profile: release")?,
"release".to_string(),
)
fn build_command(profile: Option<String>, release: bool) -> Result<PathBuf> {
let mut current_dir = std::env::current_dir()?;
let mut config_path = None;
for _ in 0..3 {
if !current_dir.join("Concrete.toml").exists() {
current_dir = if let Some(parent) = current_dir.parent() {
parent.to_path_buf()
} else {
(
config
.profile
.get("dev")
.context("Couldn't get profile: dev")?,
"dev".to_string(),
)
bail!("couldn't find Concrete.toml");
};

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: false,
ir: false,
llvm: true,
asm: false,
object: true,
mlir: true,
};

let start = Instant::now();
let object = compile(&compile_args)?;

if !has_main {
link_shared_lib(&[object], &output)?;
} else {
link_binary(&[object], &output)?;
}

let elapsed = start.elapsed();

println!(
" {} {} [{}{}] in {elapsed:?}",
"Finished".green().bold(),
profile_name,
if profile.opt_level > 0 {
"optimized"
} else {
"unoptimized"
},
if profile.debug_info {
" + debuginfo"
} else {
""
}
);
} else {
config_path = Some(current_dir.join("Concrete.toml"));
break;
}
}
let config_path = match config_path {
Some(x) => x,
None => bail!("couldn't find Concrete.toml"),
};
let base_dir = config_path
.parent()
.context("couldn't get config parent dir")?;
let mut config = File::open(&config_path).context("failed to open Concrete.toml")?;
let mut buf = String::new();
config.read_to_string(&mut buf)?;
let config: Config = toml::from_str(&buf).context("failed to parse Concrete.toml")?;
println!(
" {} {} v{} ({})",
"Compiling".green().bold(),
config.package.name,
config.package.version,
base_dir.display()
);
let src_dir = base_dir.join("src");
let target_dir = base_dir.join("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 {
(
config
.profile
.get(&profile)
.context("couldn't get requested profile")?,
profile,
)
} else if release {
(
config
.profile
.get("release")
.context("couldn't get profile: release")?,
"release".to_string(),
)
} else {
(
config
.profile
.get("dev")
.context("couldn't get profile: dev")?,
"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: false,
ir: false,
llvm: true,
asm: false,
object: true,
mlir: true,
};
let start = Instant::now();
let object = compile(&compile_args)?;
if !has_main {
link_shared_lib(&[object], &output)?;
} else {
link_binary(&[object], &output)?;
}
let elapsed = start.elapsed();
println!(
" {} {} [{}{}] in {elapsed:?}",
"Finished".green().bold(),
profile_name,
if profile.opt_level > 0 {
"optimized"
} else {
"unoptimized"
},
if profile.debug_info {
" + debuginfo"
} else {
""
}
);

Ok(())
Ok(output)
}

pub fn compile(args: &CompilerArgs) -> Result<PathBuf> {
Expand Down
2 changes: 2 additions & 0 deletions crates/concrete_driver/tests/examples.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ mod common;
#[test_case(include_str!("../../../examples/structs.con"), "structs", false, 8 ; "structs.con")]
#[test_case(include_str!("../../../examples/casts.con"), "casts", false, 2 ; "casts.con")]
#[test_case(include_str!("../../../examples/malloc.con"), "malloc", false, 5 ; "malloc.con")]
#[test_case(include_str!("../../../examples/while_if_false.con"), "while_if_false", false, 7 ; "while_if_false.con")]
#[test_case(include_str!("../../../examples/if_if_false.con"), "if_if_false", false, 7 ; "if_if_false.con")]
fn example_tests(source: &str, name: &str, is_library: bool, status_code: i32) {
assert_eq!(
status_code,
Expand Down
Loading

0 comments on commit 6aefbe3

Please sign in to comment.