1pub mod aot;
11pub mod aot_native;
12pub mod ast;
13pub mod banner;
14pub mod builtins;
15pub mod cache;
16pub mod cli;
17pub mod compiler;
18pub mod dap;
19pub mod host;
20pub mod lexer;
21pub mod lsp;
22pub mod module;
23pub mod parser;
24pub mod regexp;
25pub mod repl;
26pub mod rust_ffi;
27pub mod stdlib;
28pub mod tiers;
29
30pub use fusevm::Value;
31
32pub fn compile(src: &str) -> Result<compiler::Program, String> {
34 let stmts = parser::parse(src)?;
35 compiler::compile(&stmts, false)
36}
37
38pub fn compile_completion(src: &str) -> Result<compiler::Program, String> {
41 let stmts = parser::parse(src)?;
42 compiler::compile_completion(&stmts, false)
43}
44
45pub fn compile_debug(src: &str) -> Result<compiler::Program, String> {
47 let stmts = parser::parse(src)?;
48 compiler::compile(&stmts, true)
49}
50
51pub fn load_merged(mut prog: compiler::Program) -> fusevm::Chunk {
55 let (func_off, try_off) = host::with_host(|h| h.program_offsets());
56 compiler::rebase_program(&mut prog, func_off, try_off);
57 let compiler::Program {
58 main,
59 functions,
60 tries,
61 } = prog;
62 let funcs: Vec<host::FuncDef> = functions.into_iter().map(|(_, f)| f).collect();
63 host::with_host(|h| h.load_program(funcs, tries));
64 main
65}
66
67pub fn run_compiled(prog: compiler::Program) -> Result<Value, String> {
69 host::run_main(load_merged(prog))
70}
71
72pub fn compile_or_load(src: &str) -> Result<compiler::Program, String> {
79 if let Some(prog) = cache::load(src) {
80 if std::env::var_os("NODE_JS_TRACE").is_some() {
81 eprintln!(
82 "node-js: cache HIT ({} ops, {} functions) — skipped lex/parse/lower",
83 prog.main.ops.len(),
84 prog.functions.len()
85 );
86 }
87 return Ok(prog);
88 }
89 let prog = compile(src)?;
90 let _ = cache::store(src, &prog);
91 if std::env::var_os("NODE_JS_TRACE").is_some() {
92 eprintln!(
93 "node-js: cache MISS — compiled + stored ({} ops, {} functions)",
94 prog.main.ops.len(),
95 prog.functions.len()
96 );
97 }
98 Ok(prog)
99}
100
101pub fn eval_str(src: &str) -> Result<Value, String> {
103 host::reset_host();
104 if let Ok(cwd) = std::env::current_dir() {
106 module::set_entry_dir(cwd);
107 }
108 run_compiled(compile_or_load(src)?)
109}
110
111pub fn eval_file(path: &str) -> Result<Value, String> {
113 let src = std::fs::read_to_string(path).map_err(|e| format!("cannot read {path}: {e}"))?;
114 host::reset_host();
115 let dir = std::path::Path::new(path)
117 .parent()
118 .filter(|p| !p.as_os_str().is_empty())
119 .map(std::path::Path::to_path_buf)
120 .or_else(|| std::env::current_dir().ok())
121 .unwrap_or_default();
122 let dir = std::fs::canonicalize(&dir).unwrap_or(dir);
123 module::set_entry_dir(dir);
124 run_compiled(compile_or_load(&src)?)
125}
126
127pub fn eval_file_debug(path: &str) -> Result<Value, String> {
129 let src = std::fs::read_to_string(path).map_err(|e| format!("cannot read {path}: {e}"))?;
130 let prog = compile_debug(&src)?;
131 host::reset_host();
132 host::set_debug_mode(true);
133 let r = run_compiled(prog);
134 host::set_debug_mode(false);
135 r
136}