Skip to content

Commit

Permalink
Made single-file compilation use the same machinery as workspace comp…
Browse files Browse the repository at this point in the history
…ilation. This means that when compiling a "single file", you can import other modules and a pragma section is now supported+required
  • Loading branch information
IsaacShelton committed Nov 2, 2024
1 parent 0386a1c commit 6bf8313
Show file tree
Hide file tree
Showing 52 changed files with 175 additions and 110 deletions.
2 changes: 1 addition & 1 deletion src/interpreter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ impl<'a, S: SyscallHandler> Interpreter<'a, S> {
let function = self.ir_module.functions.get(&function_ref).unwrap();

if function.is_cstyle_variadic {
todo!("c-style variadic functions are not supported in interpreter yet");
todo!("c-style variadic functions are not supported in interpreter yet - (for function {:?})", function.mangled_name);
}

assert_eq!(function.parameters.len(), args.len());
Expand Down
4 changes: 2 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ fn build_project(build_command: BuildCommand) {
};

if metadata.is_dir() {
compile_workspace(&mut compiler, filepath);
compile_workspace(&mut compiler, filepath, None);
} else {
if filepath.extension().unwrap_or_default() == "h" {
let source_files = compiler.source_files;
Expand Down Expand Up @@ -151,7 +151,7 @@ fn build_project(build_command: BuildCommand) {
}

let project_folder = filepath.parent().unwrap();
compile_single_file_only(&mut compiler, project_folder, &filename, filepath);
compile_single_file_only(&mut compiler, project_folder, filepath);
}
}

Expand Down
106 changes: 4 additions & 102 deletions src/single_file_only/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,107 +4,9 @@
---------------------------------------------------------------------------
*/

use crate::{
ast::AstWorkspace,
compiler::Compiler,
exit_unless,
inflow::IntoInflow,
interpreter_env::{run_build_system_interpreter, setup_build_system_interpreter_symbols},
lexer::Lexer,
llvm_backend::llvm_backend,
lower::lower,
parser::parse,
resolve::resolve,
text::{IntoText, IntoTextStream},
workspace::fs::Fs,
};
use indexmap::IndexMap;
use std::{ffi::OsString, fs::create_dir_all, path::Path, process::exit};
use crate::{compiler::Compiler, workspace::compile_workspace};
use std::path::Path;

pub fn compile_single_file_only(
compiler: &mut Compiler,
project_folder: &Path,
filename: &str,
filepath: &Path,
) {
let source_files = compiler.source_files;

let project_name = filepath.file_stem().map(OsString::from).unwrap_or_else(|| {
std::env::current_dir()
.ok()
.map(|dir| {
dir.file_name()
.map(OsString::from)
.unwrap_or_else(|| OsString::from("main"))
})
.unwrap_or_else(|| OsString::from("main"))
});

let bin_folder = project_folder.join("bin");
let obj_folder = project_folder.join("obj");

create_dir_all(&bin_folder).expect("failed to create bin folder");
create_dir_all(&obj_folder).expect("failed to create obj folder");

let exe_filepath = bin_folder.join(compiler.target.default_executable_name(&project_name));
let obj_filepath = obj_folder.join(compiler.target.default_object_file_name(&project_name));

let content = std::fs::read_to_string(filename)
.map_err(|err| {
eprintln!("{}", err);
exit(1);
})
.unwrap();

let key = source_files.add(filename.into(), content);
let content = source_files.get(key).content();
let text = content.chars().into_text_stream(key).into_text();

let fs = Fs::new();
let fs_node_id = fs.insert(filepath, None).expect("inserted");

let mut ast_file = exit_unless(
parse(Lexer::new(text).into_inflow(), source_files, key),
source_files,
);

if compiler.options.interpret {
setup_build_system_interpreter_symbols(&mut ast_file);
}

let files = IndexMap::from_iter(std::iter::once((fs_node_id, ast_file)));
let mut workspace = AstWorkspace::new(fs, files, compiler.source_files, None);

let resolved_ast = exit_unless(resolve(&mut workspace, &compiler.options), source_files);

let ir_module = exit_unless(
lower(&compiler.options, &resolved_ast, &compiler.target),
source_files,
);

if compiler.options.interpret {
match run_build_system_interpreter(&resolved_ast, &ir_module) {
Ok(_) => return,
Err(err) => {
eprintln!("{}", err);
exit(1);
}
}
}

exit_unless(
unsafe {
llvm_backend(
compiler,
&ir_module,
&resolved_ast,
&obj_filepath,
&exe_filepath,
&compiler.diagnostics,
)
},
source_files,
);

compiler.maybe_execute_result(&exe_filepath);
pub fn compile_single_file_only(compiler: &mut Compiler, project_folder: &Path, filepath: &Path) {
compile_workspace(compiler, project_folder, Some(filepath.to_path_buf()))
}
55 changes: 50 additions & 5 deletions src/workspace/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
---------------------------------------------------------------------------
*/

mod compile;
pub mod compile;
mod explore;
pub mod fs;
mod module_file;
Expand All @@ -22,6 +22,7 @@ use crate::{
diagnostics::{ErrorDiagnostic, WarningDiagnostic},
exit_unless,
inflow::{Inflow, IntoInflow},
interpreter_env::{run_build_system_interpreter, setup_build_system_interpreter_symbols},
lexer::Lexer,
line_column::Location,
llvm_backend::llvm_backend,
Expand All @@ -47,7 +48,7 @@ use std::{
collections::HashMap,
ffi::OsString,
fs::create_dir_all,
path::Path,
path::{Path, PathBuf},
process::exit,
sync::{
atomic::{AtomicU64, Ordering},
Expand All @@ -74,7 +75,11 @@ impl<'a, I: Inflow<Token>> CodeFile<'a, I> {
}
}

pub fn compile_workspace(compiler: &mut Compiler, project_folder: &Path) {
pub fn compile_workspace(
compiler: &mut Compiler,
project_folder: &Path,
single_file: Option<PathBuf>,
) {
let compiler = compiler;

let start_time = Instant::now();
Expand All @@ -84,11 +89,28 @@ pub fn compile_workspace(compiler: &mut Compiler, project_folder: &Path) {
let num_module_files_failed = AtomicU64::new(0);

let fs = Fs::new();
let mut guaranteed_entry = None;

let Some(ExploreResult {
module_files,
normal_files,
}) = explore(&fs, project_folder)
}) = (if let Some(single_file) = single_file {
let fs_node_id = fs.insert(&single_file, None).expect("inserted");

let file = ModuleFile {
path: single_file,
fs_node_id,
};

guaranteed_entry = Some(fs_node_id);

Some(ExploreResult {
normal_files: vec![],
module_files: vec![file],
})
} else {
explore(&fs, project_folder)
})
else {
eprintln!(
"error: Could not locate workspace folder '{}'",
Expand Down Expand Up @@ -274,7 +296,20 @@ pub fn compile_workspace(compiler: &mut Compiler, project_folder: &Path) {
};

let module_folders = HashMap::<FsNodeId, Settings>::from_iter(module_folders.into_iter());
let files = IndexMap::from_iter(ast_files.into_iter());
let mut files = IndexMap::from_iter(ast_files.into_iter());

if compiler.options.interpret {
if let Some(guaranteed_entry) = guaranteed_entry {
let ast_file = files.get_mut(&guaranteed_entry).unwrap();
setup_build_system_interpreter_symbols(ast_file);
} else {
eprintln!(
"error: experimental manual interpreter does not properly handle multiple files yet"
);
exit(1);
}
}

let workspace = AstWorkspace::new(fs, files, compiler.source_files, Some(module_folders));

let resolved_ast = exit_unless(
Expand All @@ -301,6 +336,16 @@ pub fn compile_workspace(compiler: &mut Compiler, project_folder: &Path) {
.unwrap_or_else(|| OsString::from("main"))
});

if compiler.options.interpret {
match run_build_system_interpreter(&resolved_ast, &ir_module) {
Ok(_) => return,
Err(err) => {
eprintln!("{}", err);
exit(1);
}
}
}

let bin_folder = project_folder.join("bin");
let obj_folder = project_folder.join("obj");

Expand Down
2 changes: 2 additions & 0 deletions tests/_should_fail/mismatching_yielded_types/main.adept
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

pragma => adept("3.0")

#[foreign]
func printf(format ptr<char>, ...) int

Expand Down
2 changes: 2 additions & 0 deletions tests/_should_fail/recursive_type_alias/main.adept
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

pragma => adept("3.0")

typealias Type1 = Type2
typealias Type2 = Type3
typealias Type3 = Type1
Expand Down
2 changes: 2 additions & 0 deletions tests/and_or/main.adept
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

pragma => adept("3.0")

#[foreign]
func printf(format ptr<char>, ...) int

Expand Down
2 changes: 2 additions & 0 deletions tests/annotation_groups/main.adept
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

pragma => adept("3.0")

#[foreign]
{
// NOTE: This is only macOS (also type is incorrect but it's a pointer so doesn't matter)
Expand Down
2 changes: 2 additions & 0 deletions tests/array_access/main.adept
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

pragma => adept("3.0")

#[foreign]
{
func printf(format ptr<char>, ...) int
Expand Down
2 changes: 2 additions & 0 deletions tests/bitwise_operators/main.adept
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

pragma => adept("3.0")

#[foreign]
func printf(format ptr<char>, ...) int

Expand Down
2 changes: 2 additions & 0 deletions tests/c_printf/main.adept
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

pragma => adept("3.0")

#[foreign]
func printf(format ptr<char>, ...) int

Expand Down
2 changes: 2 additions & 0 deletions tests/character_literals/main.adept
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

pragma => adept("3.0")

#[foreign]
func printf(format ptr<char>, ...) int

Expand Down
2 changes: 2 additions & 0 deletions tests/comparison_operators/main.adept
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

pragma => adept("3.0")

#[foreign]
func printf(format ptr<char>, ...) int

Expand Down
2 changes: 2 additions & 0 deletions tests/defines/main.adept
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

pragma => adept("3.0")

#[foreign]
func printf(format ptr<char>, ...) int

Expand Down
2 changes: 2 additions & 0 deletions tests/enums/main.adept
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

pragma => adept("3.0")

enum Color (Red, Green, Blue)

#[foreign]
Expand Down
2 changes: 2 additions & 0 deletions tests/float_literal/main.adept
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

pragma => adept("3.0")

#[foreign]
func printf(format ptr<char>, ...) int

Expand Down
2 changes: 2 additions & 0 deletions tests/function_parameters/main.adept
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

pragma => adept("3.0")

#[foreign]
func printf(format ptr<char>, ...) int

Expand Down
2 changes: 2 additions & 0 deletions tests/function_simple/main.adept
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

pragma => adept("3.0")

#[foreign]
func printf(format ptr<char>, ...) int

Expand Down
2 changes: 2 additions & 0 deletions tests/global_variables/main.adept
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

pragma => adept("3.0")

#[foreign]
func printf(format ptr<char>, ...) int

Expand Down
2 changes: 2 additions & 0 deletions tests/hello_world/main.adept
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

pragma => adept("3.0")

#[foreign]
func printf(format ptr<char>, ...) int

Expand Down
2 changes: 2 additions & 0 deletions tests/if/main.adept
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

pragma => adept("3.0")

#[foreign]
{
func printf(format ptr<char>, ...) int
Expand Down
2 changes: 2 additions & 0 deletions tests/if_elif_else/main.adept
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

pragma => adept("3.0")

#[foreign]
{
// NOTE: This is only macOS (also type is incorrect but it's a pointer so doesn't matter)
Expand Down
2 changes: 2 additions & 0 deletions tests/if_eval/main.adept
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

pragma => adept("3.0")

#[foreign]
func printf(format ptr<char>, ...) int

Expand Down
2 changes: 2 additions & 0 deletions tests/integer_and_float_literals_combining/main.adept
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

pragma => adept("3.0")

#[foreign]
func printf(format ptr<char>, ...) int

Expand Down
2 changes: 2 additions & 0 deletions tests/integer_hex_literals/main.adept
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

pragma => adept("3.0")

#[foreign]
func printf(format ptr<char>, ...) int

Expand Down
Loading

0 comments on commit 6bf8313

Please sign in to comment.