Add getpid, exec_bg, spawn_thread, sleep_secs builtins; fix fs_write arity
This commit is contained in:
@@ -2411,6 +2411,61 @@ fn dispatch_builtin(
|
|||||||
BuiltinResult::Handled
|
BuiltinResult::Handled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Process / thread builtins ─────────────────────────────────────────
|
||||||
|
|
||||||
|
"getpid" => {
|
||||||
|
stack.push(Value::Int(std::process::id() as i64));
|
||||||
|
BuiltinResult::Handled
|
||||||
|
}
|
||||||
|
|
||||||
|
"exec_bg" => {
|
||||||
|
let cmd_str = match stack.pop().unwrap_or(Value::Nil) {
|
||||||
|
Value::Str(s) => s,
|
||||||
|
_ => { stack.push(Value::Int(-1)); return BuiltinResult::Handled; }
|
||||||
|
};
|
||||||
|
let mut parts = cmd_str.split_whitespace();
|
||||||
|
let prog = match parts.next() {
|
||||||
|
Some(p) => p.to_string(),
|
||||||
|
None => { stack.push(Value::Int(-1)); return BuiltinResult::Handled; }
|
||||||
|
};
|
||||||
|
let args_vec: Vec<String> = parts.map(|s| s.to_string()).collect();
|
||||||
|
let pid = std::process::Command::new(&prog)
|
||||||
|
.args(&args_vec)
|
||||||
|
.spawn()
|
||||||
|
.map(|child| child.id() as i64)
|
||||||
|
.unwrap_or(-1);
|
||||||
|
stack.push(Value::Int(pid));
|
||||||
|
BuiltinResult::Handled
|
||||||
|
}
|
||||||
|
|
||||||
|
"spawn_thread" => {
|
||||||
|
let fn_name = match stack.pop().unwrap_or(Value::Nil) {
|
||||||
|
Value::Str(s) => s,
|
||||||
|
_ => { stack.push(Value::Nil); return BuiltinResult::Handled; }
|
||||||
|
};
|
||||||
|
let instr_arc = SERVE_INSTRUCTIONS.with(|si| si.borrow().clone());
|
||||||
|
let fn_arc = SERVE_FN_TABLE.with(|sf| sf.borrow().clone());
|
||||||
|
if let (Some(instr_arc), Some(fn_arc)) = (instr_arc, fn_arc) {
|
||||||
|
std::thread::spawn(move || {
|
||||||
|
if let Some(&entry) = fn_arc.get(&fn_name) {
|
||||||
|
run_sub_interpreter(&instr_arc, &fn_arc, entry);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
stack.push(Value::Nil);
|
||||||
|
BuiltinResult::Handled
|
||||||
|
}
|
||||||
|
|
||||||
|
"sleep_secs" => {
|
||||||
|
let n = match stack.pop().unwrap_or(Value::Nil) {
|
||||||
|
Value::Int(n) => n as u64,
|
||||||
|
_ => 1,
|
||||||
|
};
|
||||||
|
std::thread::sleep(std::time::Duration::from_secs(n));
|
||||||
|
stack.push(Value::Nil);
|
||||||
|
BuiltinResult::Handled
|
||||||
|
}
|
||||||
|
|
||||||
// ── String utility builtins ───────────────────────────────────────────
|
// ── String utility builtins ───────────────────────────────────────────
|
||||||
|
|
||||||
"str_replace" => {
|
"str_replace" => {
|
||||||
|
|||||||
@@ -192,9 +192,13 @@ impl TypeEnv {
|
|||||||
for name in &["fs_read"] {
|
for name in &["fs_read"] {
|
||||||
env.functions.insert(name.to_string(), str_fn(vec![s.clone()], s.clone()));
|
env.functions.insert(name.to_string(), str_fn(vec![s.clone()], s.clone()));
|
||||||
}
|
}
|
||||||
for name in &["fs_write","fs_append","fs_exists","fs_mkdir","fs_remove","fs_is_dir"] {
|
for name in &["fs_exists","fs_mkdir","fs_remove","fs_is_dir"] {
|
||||||
env.functions.insert(name.to_string(), str_fn(vec![u.clone()], b.clone()));
|
env.functions.insert(name.to_string(), str_fn(vec![u.clone()], b.clone()));
|
||||||
}
|
}
|
||||||
|
// fs_write and fs_append take (path, content) — two arguments
|
||||||
|
for name in &["fs_write","fs_append"] {
|
||||||
|
env.functions.insert(name.to_string(), str_fn(vec![s.clone(), s.clone()], b.clone()));
|
||||||
|
}
|
||||||
env.functions.insert("fs_list".into(), str_fn(vec![s.clone()], Type::Unknown));
|
env.functions.insert("fs_list".into(), str_fn(vec![s.clone()], Type::Unknown));
|
||||||
env.functions.insert("fs_list_recursive".into(), str_fn(vec![s.clone()], Type::Unknown));
|
env.functions.insert("fs_list_recursive".into(), str_fn(vec![s.clone()], Type::Unknown));
|
||||||
env.functions.insert("path_join".into(), str_fn(vec![s.clone(), s.clone()], s.clone()));
|
env.functions.insert("path_join".into(), str_fn(vec![s.clone(), s.clone()], s.clone()));
|
||||||
@@ -234,8 +238,12 @@ impl TypeEnv {
|
|||||||
env.functions.insert("args".into(), str_fn(vec![], Type::Unknown));
|
env.functions.insert("args".into(), str_fn(vec![], Type::Unknown));
|
||||||
env.functions.insert("exit".into(), str_fn(vec![i.clone()], Type::Void));
|
env.functions.insert("exit".into(), str_fn(vec![i.clone()], Type::Void));
|
||||||
env.functions.insert("sleep_ms".into(), str_fn(vec![i.clone()], Type::Void));
|
env.functions.insert("sleep_ms".into(), str_fn(vec![i.clone()], Type::Void));
|
||||||
|
env.functions.insert("sleep_secs".into(), str_fn(vec![i.clone()], Type::Void));
|
||||||
env.functions.insert("timestamp".into(), str_fn(vec![], s.clone()));
|
env.functions.insert("timestamp".into(), str_fn(vec![], s.clone()));
|
||||||
env.functions.insert("readline".into(), str_fn(vec![s.clone()], s.clone()));
|
env.functions.insert("readline".into(), str_fn(vec![s.clone()], s.clone()));
|
||||||
|
env.functions.insert("getpid".into(), str_fn(vec![], i.clone()));
|
||||||
|
env.functions.insert("exec_bg".into(), str_fn(vec![s.clone()], i.clone()));
|
||||||
|
env.functions.insert("spawn_thread".into(), str_fn(vec![s.clone()], Type::Void));
|
||||||
|
|
||||||
// ANSI color builtins
|
// ANSI color builtins
|
||||||
for name in &["color_cyan","color_green","color_red","color_yellow","color_bold","color_dim"] {
|
for name in &["color_cyan","color_green","color_red","color_yellow","color_bold","color_dim"] {
|
||||||
|
|||||||
Reference in New Issue
Block a user