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

refactor to put program_code_data at global #107

Merged
merged 1 commit into from
Oct 19, 2021
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
49 changes: 20 additions & 29 deletions src/bin/cr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,28 +87,32 @@ fn main() -> Result<(), String> {
snapshot.files.insert(k.to_owned(), v.to_owned());
}

let mut program_code = program::extract_program_data(&snapshot)?;
// now global states
{
let mut prgm = { program::PROGRAM_CODE_DATA.write().unwrap() };
*prgm = program::extract_program_data(&snapshot)?;
}

let check_warnings: &RefCell<Vec<String>> = &RefCell::new(vec![]);

// make sure builtin classes are touched
runner::preprocess::preprocess_ns_def(
calcit_runner::primes::CORE_NS,
calcit_runner::primes::BUILTIN_CLASSES_ENTRY,
&program_code,
calcit_runner::primes::BUILTIN_CLASSES_ENTRY,
None,
check_warnings,
)
.map_err(|e| e.msg)?;

let task = if settings.emit_js {
run_codegen(init_fn, reload_fn, &program_code, &settings.emit_path, false)
run_codegen(init_fn, reload_fn, &settings.emit_path, false)
} else if settings.emit_ir {
run_codegen(init_fn, reload_fn, &program_code, &settings.emit_path, true)
run_codegen(init_fn, reload_fn, &settings.emit_path, true)
} else {
let started_time = Instant::now();

let v = calcit_runner::run_program(init_fn, im::vector![], &program_code).map_err(|e| {
let v = calcit_runner::run_program(init_fn, im::vector![]).map_err(|e| {
for w in e.warnings {
println!("{}", w);
}
Expand Down Expand Up @@ -173,21 +177,17 @@ fn main() -> Result<(), String> {
println!("failed re-compiling, got empty inc file");
continue;
}
recall_program(&mut program_code, &content, init_fn, reload_fn, &settings)?;
recall_program(&content, init_fn, reload_fn, &settings)?;
}
}
} else {
Ok(())
}
}

fn recall_program(
program_code: &mut program::ProgramCodeData,
content: &str,
init_fn: &str,
reload_fn: &str,
settings: &ProgramSettings,
) -> Result<(), String> {
// overwrite previous state

fn recall_program(content: &str, init_fn: &str, reload_fn: &str, settings: &ProgramSettings) -> Result<(), String> {
println!("\n-------- file change --------\n");
call_stack::clear_stack();

Expand All @@ -201,21 +201,21 @@ fn recall_program(

// println!("\ndata: {}", &data);
// println!("\nchanges: {:?}", changes);
let new_code = program::apply_code_changes(program_code, &changes)?;
program::apply_code_changes(&changes)?;
// println!("\nprogram code: {:?}", new_code);

// clear data in evaled states
program::clear_all_program_evaled_defs(init_fn, reload_fn, settings.reload_libs)?;
builtins::meta::force_reset_gensym_index()?;

let task = if settings.emit_js {
run_codegen(init_fn, reload_fn, &new_code, &settings.emit_path, false)
run_codegen(init_fn, reload_fn, &settings.emit_path, false)
} else if settings.emit_ir {
run_codegen(init_fn, reload_fn, &new_code, &settings.emit_path, true)
run_codegen(init_fn, reload_fn, &settings.emit_path, true)
} else {
// run from `reload_fn` after reload
let started_time = Instant::now();
let v = calcit_runner::run_program(reload_fn, im::vector![], &new_code).map_err(|e| {
let v = calcit_runner::run_program(reload_fn, im::vector![]).map_err(|e| {
for w in e.warnings {
println!("{}", w);
}
Expand All @@ -233,19 +233,10 @@ fn recall_program(
}
}

// overwrite previous state
*program_code = new_code;

Ok(())
}

fn run_codegen(
init_fn: &str,
reload_fn: &str,
program_code: &program::ProgramCodeData,
emit_path: &str,
ir_mode: bool,
) -> Result<(), String> {
fn run_codegen(init_fn: &str, reload_fn: &str, emit_path: &str, ir_mode: bool) -> Result<(), String> {
let started_time = Instant::now();

let (init_ns, init_def) = util::string::extract_ns_def(init_fn)?;
Expand All @@ -267,7 +258,7 @@ fn run_codegen(
let check_warnings: &RefCell<Vec<String>> = &RefCell::new(vec![]);

// preprocess to init
match runner::preprocess::preprocess_ns_def(&init_ns, &init_def, program_code, &init_def, None, check_warnings) {
match runner::preprocess::preprocess_ns_def(&init_ns, &init_def, &init_def, None, check_warnings) {
Ok(_) => (),
Err(failure) => {
println!("\nfailed preprocessing, {}", failure);
Expand All @@ -285,7 +276,7 @@ fn run_codegen(
}

// preprocess to reload
match runner::preprocess::preprocess_ns_def(&reload_ns, &reload_def, program_code, &init_def, None, check_warnings) {
match runner::preprocess::preprocess_ns_def(&reload_ns, &reload_def, &init_def, None, check_warnings) {
Ok(_) => (),
Err(failure) => {
println!("\nfailed preprocessing, {}", failure);
Expand Down
67 changes: 66 additions & 1 deletion src/bin/injection/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::runner;
use cirru_edn::Edn;
use std::thread;

use calcit_runner::{
builtins,
Expand All @@ -13,11 +15,12 @@ pub fn inject_platform_apis() {
builtins::register_import_proc("&call-dylib-edn", call_dylib_edn);
builtins::register_import_proc("echo", echo);
builtins::register_import_proc("println", echo);
builtins::register_import_proc("&callback-dylib-edn", callback_dylib_edn);
}

// &call-dylib-edn
pub fn call_dylib_edn(xs: &CalcitItems) -> Result<Calcit, CalcitErr> {
if xs.is_empty() {
if xs.len() < 2 {
return Err(CalcitErr::use_string(format!(
"&call-dylib-edn expected >2 arguments, got {}",
CrListWrap(xs.to_owned())
Expand Down Expand Up @@ -63,3 +66,65 @@ pub fn echo(xs: &CalcitItems) -> Result<Calcit, CalcitErr> {
println!("{}", s);
Ok(Calcit::Nil)
}

// &call-dylib-edn

pub fn callback_dylib_edn(xs: &CalcitItems) -> Result<Calcit, CalcitErr> {
if xs.len() < 3 {
return Err(CalcitErr::use_string(format!(
"&callback-dylib-edn expected >3 arguments, got {}",
CrListWrap(xs.to_owned())
)));
}

let lib_name = if let Calcit::Str(s) = &xs[0] {
s.to_owned()
} else {
return Err(CalcitErr::use_string(format!("&call-dylib-edn expected a lib_name, got {}", xs[0])));
};

let method: String = if let Calcit::Str(s) = &xs[1] {
s.to_owned()
} else {
return Err(CalcitErr::use_string(format!(
"&call-dylib-edn expected a method name, got {}",
xs[1]
)));
};
let mut ys: Vec<Edn> = vec![];
let callback = xs[xs.len() - 1].clone();
for (idx, v) in xs.iter().enumerate() {
if idx > 1 && idx < xs.len() - 1 {
ys.push(calcit_to_edn(v).map_err(CalcitErr::use_string)?);
}
}
if let Calcit::Fn(..) = callback {
} else {
return Err(CalcitErr::use_string(format!(
"expected last argument to be callback fn, got: {}",
callback
)));
}

let result = unsafe {
let lib = libloading::Library::new(&lib_name).expect("dylib not found");
let func: libloading::Symbol<EdnFfi> = lib.get(method.as_bytes()).expect("dy function not found");
let ret = func(ys.to_owned()).map_err(CalcitErr::use_string)?;
edn_to_calcit(&ret)
};

if let Calcit::Fn(_, def_ns, _, def_scope, args, body) = callback {
let handle = thread::spawn(move || {
let r = runner::run_fn(&im::vector![result], &def_scope, &args, &body, &def_ns);
println!("callback {:?}", r);
});

handle.join().unwrap();
Ok(Calcit::Nil)
} else {
return Err(CalcitErr::use_string(format!(
"expected last argument to be callback fn, got: {}",
callback
)));
}
}
44 changes: 19 additions & 25 deletions src/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ use std::collections::HashMap;
use std::sync::RwLock;

use crate::primes::{Calcit, CalcitErr, CalcitItems, CalcitScope, CalcitSyntax};
use crate::program::ProgramCodeData;

pub type FnType = fn(xs: &CalcitItems) -> Result<Calcit, CalcitErr>;
pub type SyntaxType = fn(expr: &CalcitItems, scope: &CalcitScope, file_ns: &str) -> Result<Calcit, CalcitErr>;

lazy_static! {
static ref IMPORTED_PROCS: RwLock<HashMap<String, FnType>> = RwLock::new(HashMap::new());
Expand Down Expand Up @@ -365,32 +365,26 @@ pub fn register_import_proc(name: &str, f: FnType) {
(*ps).insert(name.to_owned(), f);
}

pub fn handle_syntax(
name: &CalcitSyntax,
nodes: &CalcitItems,
scope: &CalcitScope,
file_ns: &str,
program: &ProgramCodeData,
) -> Result<Calcit, CalcitErr> {
pub fn handle_syntax(name: &CalcitSyntax, nodes: &CalcitItems, scope: &CalcitScope, file_ns: &str) -> Result<Calcit, CalcitErr> {
match name {
CalcitSyntax::Defn => syntax::defn(nodes, scope, file_ns, program),
CalcitSyntax::Eval => syntax::eval(nodes, scope, file_ns, program),
CalcitSyntax::Defmacro => syntax::defmacro(nodes, scope, file_ns, program),
CalcitSyntax::Quote => syntax::quote(nodes, scope, file_ns, program),
CalcitSyntax::Quasiquote => syntax::quasiquote(nodes, scope, file_ns, program),
CalcitSyntax::If => syntax::syntax_if(nodes, scope, file_ns, program),
CalcitSyntax::CoreLet => syntax::syntax_let(nodes, scope, file_ns, program),
CalcitSyntax::Foldl => lists::foldl(nodes, scope, file_ns, program),
CalcitSyntax::FoldlShortcut => lists::foldl_shortcut(nodes, scope, file_ns, program),
CalcitSyntax::FoldrShortcut => lists::foldr_shortcut(nodes, scope, file_ns, program),
CalcitSyntax::Macroexpand => syntax::macroexpand(nodes, scope, file_ns, program),
CalcitSyntax::Macroexpand1 => syntax::macroexpand_1(nodes, scope, file_ns, program),
CalcitSyntax::MacroexpandAll => syntax::macroexpand_all(nodes, scope, file_ns, program),
CalcitSyntax::Try => syntax::call_try(nodes, scope, file_ns, program),
CalcitSyntax::Sort => lists::sort(nodes, scope, file_ns, program),
CalcitSyntax::Defn => syntax::defn(nodes, scope, file_ns),
CalcitSyntax::Eval => syntax::eval(nodes, scope, file_ns),
CalcitSyntax::Defmacro => syntax::defmacro(nodes, scope, file_ns),
CalcitSyntax::Quote => syntax::quote(nodes, scope, file_ns),
CalcitSyntax::Quasiquote => syntax::quasiquote(nodes, scope, file_ns),
CalcitSyntax::If => syntax::syntax_if(nodes, scope, file_ns),
CalcitSyntax::CoreLet => syntax::syntax_let(nodes, scope, file_ns),
CalcitSyntax::Foldl => lists::foldl(nodes, scope, file_ns),
CalcitSyntax::FoldlShortcut => lists::foldl_shortcut(nodes, scope, file_ns),
CalcitSyntax::FoldrShortcut => lists::foldr_shortcut(nodes, scope, file_ns),
CalcitSyntax::Macroexpand => syntax::macroexpand(nodes, scope, file_ns),
CalcitSyntax::Macroexpand1 => syntax::macroexpand_1(nodes, scope, file_ns),
CalcitSyntax::MacroexpandAll => syntax::macroexpand_all(nodes, scope, file_ns),
CalcitSyntax::Try => syntax::call_try(nodes, scope, file_ns),
CalcitSyntax::Sort => lists::sort(nodes, scope, file_ns),
// "define reference" although it uses a confusing name "atom"
CalcitSyntax::Defatom => refs::defatom(nodes, scope, file_ns, program),
CalcitSyntax::Reset => refs::reset_bang(nodes, scope, file_ns, program),
CalcitSyntax::Defatom => refs::defatom(nodes, scope, file_ns),
CalcitSyntax::Reset => refs::reset_bang(nodes, scope, file_ns),
// different behavoirs, in Rust interpreter it's nil, in js codegen it's nothing
CalcitSyntax::HintFn => meta::no_op(),
}
Expand Down
Loading