Skip to content

Commit

Permalink
Get basic function imports working
Browse files Browse the repository at this point in the history
  • Loading branch information
dfellis committed Nov 6, 2024
1 parent a9b80c5 commit 90b4b26
Show file tree
Hide file tree
Showing 11 changed files with 385 additions and 170 deletions.
63 changes: 35 additions & 28 deletions alan/src/compile/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,9 @@ macro_rules! test {
return Err(format!("Unable to write {} to disk. {:?}", filename, e).into());
}
};
{
let mut program = crate::program::Program::get_program().lock().unwrap();
program.env.insert("ALAN_TARGET".to_string(), "test".to_string());
}
let mut program = crate::program::Program::get_program();
program.env.insert("ALAN_TARGET".to_string(), "test".to_string());
crate::program::Program::return_program(program);
match crate::compile::build(filename.to_string()) {
Ok(_) => { /* Do nothing */ }
Err(e) => {
Expand Down Expand Up @@ -64,10 +63,9 @@ macro_rules! test_full {
return Err(format!("Unable to write {} to disk. {:?}", filename, e).into());
}
};
{
let mut program = crate::program::Program::get_program().lock().unwrap();
program.env.insert("ALAN_TARGET".to_string(), "test".to_string());
}
let mut program = crate::program::Program::get_program();
program.env.insert("ALAN_TARGET".to_string(), "test".to_string());
crate::program::Program::return_program(program);
match crate::compile::build(filename.to_string()) {
Ok(_) => { /* Do nothing */ }
Err(e) => {
Expand All @@ -90,10 +88,9 @@ macro_rules! test_full {
Err(e) => Err(format!("Could not remove the test binary {:?}", e)),
}?;
crate::program::Program::set_target_lang_js();
{
let mut program = crate::program::Program::get_program().lock().unwrap();
program.env.insert("ALAN_TARGET".to_string(), "test".to_string());
}
let mut program = crate::program::Program::get_program();
program.env.insert("ALAN_TARGET".to_string(), "test".to_string());
crate::program::Program::return_program(program);
match crate::compile::web(filename.to_string()) {
Ok(_) => { /* Do nothing */ }
Err(e) => {
Expand Down Expand Up @@ -132,10 +129,9 @@ macro_rules! test_full {
return Err(format!("Unable to write {} to disk. {:?}", $filename, e).into());
}
})+
{
let mut program = crate::program::Program::get_program().lock().unwrap();
program.env.insert("ALAN_TARGET".to_string(), "test".to_string());
}
let mut program = crate::program::Program::get_program();
program.env.insert("ALAN_TARGET".to_string(), "test".to_string());
crate::program::Program::return_program(program);
match crate::compile::build(format!("{}.ln", $entryfile)) {
Ok(_) => { /* Do nothing */ }
Err(e) => {
Expand All @@ -158,10 +154,9 @@ macro_rules! test_full {
Err(e) => Err(format!("Could not remove the test binary {:?}", e)),
}?;
crate::program::Program::set_target_lang_js();
{
let mut program = crate::program::Program::get_program().lock().unwrap();
program.env.insert("ALAN_TARGET".to_string(), "test".to_string());
}
let mut program = crate::program::Program::get_program();
program.env.insert("ALAN_TARGET".to_string(), "test".to_string());
crate::program::Program::return_program(program);
match crate::compile::web(format!("{}.ln", $entryfile)) {
Ok(_) => { /* Do nothing */ }
Err(e) => {
Expand Down Expand Up @@ -203,10 +198,9 @@ macro_rules! test_gpgpu {
return Err(format!("Unable to write {} to disk. {:?}", filename, e).into());
}
};
{
let mut program = crate::program::Program::get_program().lock().unwrap();
program.env.insert("ALAN_TARGET".to_string(), "test".to_string());
}
let mut program = crate::program::Program::get_program();
program.env.insert("ALAN_TARGET".to_string(), "test".to_string());
crate::program::Program::return_program(program);
match crate::compile::build(filename.to_string()) {
Ok(_) => { /* Do nothing */ }
Err(e) => {
Expand Down Expand Up @@ -331,10 +325,9 @@ macro_rules! test_ignore {
return Err(format!("Unable to write {} to disk. {:?}", filename, e).into());
}
};
{
let mut program = crate::program::Program::get_program().lock().unwrap();
program.env.insert("ALAN_TARGET".to_string(), "test".to_string());
}
let mut program = crate::program::Program::get_program();
program.env.insert("ALAN_TARGET".to_string(), "test".to_string());
crate::program::Program::return_program(program);
match crate::compile::build(filename.to_string()) {
Ok(_) => { /* Do nothing */ }
Err(e) => {
Expand Down Expand Up @@ -2595,6 +2588,20 @@ test_full!(basic_type_import "foo" =>
stdout "Bar\n";
);

test_full!(basic_fn_import "foo" =>
"bar.ln" => r#"
export fn bar = "Bar";
"#,
"foo.ln" => r#"
fn bar <-- "./bar.ln";
export fn main {
bar().print;
}
"#;
stdout "Bar\n";
);

// Maybe, Result, and Either

test_full!(maybe_exists => r#"
Expand Down
55 changes: 25 additions & 30 deletions alan/src/compile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,12 +379,11 @@ edition = "2021"
pub fn compile(source_file: String) -> Result<(), Box<dyn std::error::Error>> {
let start_time = Instant::now();
Program::set_target_lang_rs();
{
let mut program = Program::get_program().lock().unwrap();
program
.env
.insert("ALAN_TARGET".to_string(), "release".to_string());
}
let mut program = Program::get_program();
program
.env
.insert("ALAN_TARGET".to_string(), "release".to_string());
Program::return_program(program);
build(source_file)?;
println!("Done! Took {:.2}sec", start_time.elapsed().as_secs_f32());
Ok(())
Expand All @@ -394,12 +393,11 @@ pub fn compile(source_file: String) -> Result<(), Box<dyn std::error::Error>> {
/// test mode, then immediately invokes it, and deletes the binary when done.
pub fn test(source_file: String) -> Result<(), Box<dyn std::error::Error>> {
Program::set_target_lang_rs();
{
let mut program = Program::get_program().lock().unwrap();
program
.env
.insert("ALAN_TARGET".to_string(), "test".to_string());
}
let mut program = Program::get_program();
program
.env
.insert("ALAN_TARGET".to_string(), "test".to_string());
Program::return_program(program);
let binary = build(source_file)?;
let mut run = Command::new(format!("./{}", binary))
.current_dir(current_dir()?)
Expand Down Expand Up @@ -695,12 +693,11 @@ pub fn web(source_file: String) -> Result<String, Box<dyn std::error::Error>> {
pub fn bundle(source_file: String) -> Result<(), Box<dyn std::error::Error>> {
let start_time = Instant::now();
Program::set_target_lang_js();
{
let mut program = Program::get_program().lock().unwrap();
program
.env
.insert("ALAN_TARGET".to_string(), "release".to_string());
}
let mut program = Program::get_program();
program
.env
.insert("ALAN_TARGET".to_string(), "release".to_string());
Program::return_program(program);
web(source_file)?;
println!("Done! Took {:.2}sec", start_time.elapsed().as_secs_f32());
Ok(())
Expand All @@ -710,12 +707,11 @@ pub fn bundle(source_file: String) -> Result<(), Box<dyn std::error::Error>> {
/// file.
pub fn to_rs(source_file: String) -> Result<(), Box<dyn std::error::Error>> {
Program::set_target_lang_rs();
{
let mut program = Program::get_program().lock().unwrap();
program
.env
.insert("ALAN_TARGET".to_string(), "release".to_string());
}
let mut program = Program::get_program();
program
.env
.insert("ALAN_TARGET".to_string(), "release".to_string());
Program::return_program(program);
// Generate the rust code to compile
let (rs_str, deps) = lntors(source_file.clone())?;
// Shove it into a temp file for rustc
Expand Down Expand Up @@ -753,12 +749,11 @@ pub fn to_rs(source_file: String) -> Result<(), Box<dyn std::error::Error>> {
/// file.
pub fn to_js(source_file: String) -> Result<(), Box<dyn std::error::Error>> {
Program::set_target_lang_js();
{
let mut program = Program::get_program().lock().unwrap();
program
.env
.insert("ALAN_TARGET".to_string(), "release".to_string());
}
let mut program = Program::get_program();
program
.env
.insert("ALAN_TARGET".to_string(), "release".to_string());
Program::return_program(program);
// Generate the rust code to compile
let (js_str, deps) = lntojs(source_file.clone())?;
// Shove it into a temp file for rustc
Expand Down
24 changes: 22 additions & 2 deletions alan/src/lntojs/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use ordered_hash_map::OrderedHashMap;

use crate::lntojs::typen;
use crate::parse::{booln, integer, real};
use crate::program::{ArgKind, CType, FnKind, Function, Microstatement, Scope};
use crate::program::{ArgKind, CType, FnKind, Function, Microstatement, Program, Scope};

pub fn from_microstatement(
microstatement: &Microstatement,
Expand Down Expand Up @@ -160,7 +160,27 @@ pub fn from_microstatement(
},
CType::Function(..) => {
let f = scope.resolve_function_by_type(representation, typen);
match f {
let f = match f {
None => {
// If the current scope isn't the original scope for the parent function, maybe the
// function we're looking for is in the original scope
if parent_fn.origin_scope_path != scope.path {
let program = Program::get_program();
let out = match program.scope_by_file(&parent_fn.origin_scope_path) {
Ok(original_scope) => original_scope
.resolve_function_by_type(representation, typen)
.cloned(),
Err(_) => None,
};
Program::return_program(program);
out
} else {
None
}
}
f => f.cloned(), // TODO: Can I avoid this?
};
match &f {
None => {
let args = parent_fn.args();
for (name, _, typen) in args {
Expand Down
22 changes: 12 additions & 10 deletions alan/src/lntojs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub fn lntojs(
) -> Result<(String, OrderedHashMap<String, String>), Box<dyn std::error::Error>> {
Program::set_target_lang_js();
Program::load(entry_file.clone())?;
let program = Program::get_program().lock().unwrap();
let program = Program::get_program();
let scope = program.scope_by_file(&entry_file)?;
// Without support for building shared libs yet, assume there is an `export fn main` in the
// entry file or fail otherwise
Expand Down Expand Up @@ -46,6 +46,16 @@ pub fn lntojs(
OrderedHashMap::new(),
OrderedHashMap::new(),
)?;
let main_call = if let CType::Type(n, _) = func[0].rettype() {
if &n == "ExitCode" {
"main().then(process.exit);"
} else {
"main();"
}
} else {
"main();"
};
Program::return_program(program);
Ok((
format!(
"{}\n{}\n{}",
Expand All @@ -54,15 +64,7 @@ pub fn lntojs(
.collect::<Vec<String>>()
.join("\n"),
fns.into_values().collect::<Vec<String>>().join("\n"),
if let CType::Type(n, _) = func[0].rettype() {
if &n == "ExitCode" {
"main().then(process.exit);"
} else {
"main();"
}
} else {
"main();"
}
main_call,
),
deps,
))
Expand Down
24 changes: 22 additions & 2 deletions alan/src/lntors/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use ordered_hash_map::OrderedHashMap;

use crate::lntors::typen;
use crate::program::{ArgKind, CType, FnKind, Function, Microstatement, Scope};
use crate::program::{ArgKind, CType, FnKind, Function, Microstatement, Program, Scope};

pub fn from_microstatement(
microstatement: &Microstatement,
Expand Down Expand Up @@ -158,7 +158,27 @@ pub fn from_microstatement(
CType::Function(..) => {
// We need to make sure this function we're referencing exists
let f = scope.resolve_function_by_type(representation, typen);
match f {
let f = match f {
None => {
// If the current scope isn't the original scope for the parent function, maybe the
// function we're looking for is in the original scope
if parent_fn.origin_scope_path != scope.path {
let program = Program::get_program();
let out = match program.scope_by_file(&parent_fn.origin_scope_path) {
Ok(original_scope) => original_scope
.resolve_function_by_type(representation, typen)
.cloned(),
Err(_) => None,
};
Program::return_program(program);
out
} else {
None
}
}
f => f.cloned(), // TODO: Can I avoid this?
};
match &f {
None => {
let args = parent_fn.args();
for (name, _, typen) in args {
Expand Down
3 changes: 2 additions & 1 deletion alan/src/lntors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub fn lntors(
) -> Result<(String, OrderedHashMap<String, String>), Box<dyn std::error::Error>> {
Program::set_target_lang_rs();
Program::load(entry_file.clone())?;
let program = Program::get_program().lock().unwrap();
let program = Program::get_program();
let scope = program.scope_by_file(&entry_file)?;
// Without support for building shared libs yet, assume there is an `export fn main` in the
// entry file or fail otherwise
Expand Down Expand Up @@ -46,5 +46,6 @@ pub fn lntors(
OrderedHashMap::new(),
OrderedHashMap::new(),
)?;
Program::return_program(program);
Ok((fns.into_values().collect::<Vec<String>>().join("\n"), deps))
}
Loading

0 comments on commit 90b4b26

Please sign in to comment.