1use std::io::{self, Write};
18use std::sync::{Arc, Mutex};
19
20use mumu::{
21 parser::interpreter::Interpreter,
22 parser::types::{
23 FunctionValue, IteratorHandle, IteratorKind, PluginIterator, Value,
24 },
25};
26
27fn to_printable(v: &Value) -> String {
30 match v {
31 Value::SingleString(s) => s.clone(),
32 Value::Int(i) => i.to_string(),
33 Value::Long(l) => l.to_string(),
34 Value::Float(f) => f.to_string(),
35 Value::Bool(b) => b.to_string(),
36 _ => format!("{:?}", v),
38 }
39}
40
41fn escape_str(s: &str) -> String {
42 let mut out = String::with_capacity(s.len() + 8);
43 for ch in s.chars() {
44 match ch {
45 '\\' => out.push_str("\\\\"),
46 '"' => out.push_str("\\\""),
47 '\n' => out.push_str("\\n"),
48 '\r' => out.push_str("\\r"),
49 '\t' => out.push_str("\\t"),
50 other => out.push(other),
51 }
52 }
53 out
54}
55
56fn deep_to_string(v: &Value) -> String {
62 deep_to_string_inner(v, 0)
63}
64
65fn deep_to_string_inner(v: &Value, depth: usize) -> String {
66 if depth > 64 {
67 return "<depth-limit>".to_string();
68 }
69 match v {
70 Value::SingleString(s) => format!("\"{}\"", escape_str(s)),
71 Value::Int(i) => i.to_string(),
72 Value::Long(l) => l.to_string(),
73 Value::Float(f) => {
74 if f.fract() == 0.0 { format!("{:.1}", f) } else { f.to_string() }
76 }
77 Value::Bool(b) => b.to_string(),
78 Value::Undefined => "undefined".to_string(),
79 Value::Placeholder => "_".to_string(),
80
81 Value::IntArray(xs) => {
82 let inner = xs.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(", ");
83 format!("[{}]", inner)
84 }
85 Value::FloatArray(xs) => {
86 let inner = xs.iter()
87 .map(|f| if f.fract()==0.0 { format!("{:.1}", f) } else { f.to_string() })
88 .collect::<Vec<_>>().join(", ");
89 format!("[{}]", inner)
90 }
91 Value::BoolArray(xs) => {
92 let inner = xs.iter().map(|b| b.to_string()).collect::<Vec<_>>().join(", ");
93 format!("[{}]", inner)
94 }
95 Value::StrArray(xs) => {
96 let inner = xs.iter().map(|s| format!("\"{}\"", escape_str(s))).collect::<Vec<_>>().join(", ");
97 format!("[{}]", inner)
98 }
99 Value::Int2DArray(rows) => {
100 let inner = rows.iter()
101 .map(|r| format!("[{}]", r.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(", ")))
102 .collect::<Vec<_>>().join(", ");
103 format!("[{}]", inner)
104 }
105 Value::Float2DArray(rows) => {
106 let fmt = |f: &f64| if f.fract()==0.0 { format!("{:.1}", f) } else { f.to_string() };
107 let inner = rows.iter()
108 .map(|r| format!("[{}]", r.iter().map(fmt).collect::<Vec<_>>().join(", ")))
109 .collect::<Vec<_>>().join(", ");
110 format!("[{}]", inner)
111 }
112 Value::MixedArray(items) => {
113 let inner = items.iter()
114 .map(|x| deep_to_string_inner(x, depth+1))
115 .collect::<Vec<_>>().join(", ");
116 format!("[{}]", inner)
117 }
118 Value::KeyedArray(map) => {
119 let parts = map.iter()
120 .map(|(k, v)| format!("{}: {}", k, deep_to_string_inner(v, depth+1)))
121 .collect::<Vec<_>>().join(", ");
122 format!("[{}]", parts)
123 }
124
125 Value::Function(_) => "[Function]".to_string(),
126 Value::Stream(sh) => format!("<Stream id={}, label={}>", sh.stream_id, sh.label),
127 Value::Iterator(_) => "[Iterator]".to_string(),
128 Value::Tensor(_) => "[Tensor]".to_string(),
129 Value::Ref(cell) => {
130 let guard = cell.lock().unwrap();
131 deep_to_string_inner(&*guard, depth+1)
132 }
133 Value::Regex(rx) => format!("Regex(/{}{}/)", rx.pattern, rx.flags),
134 }
135}
136
137fn print_no_nl(interp: &mut Interpreter, s: &str) {
138 print!("{}", s);
139 let _ = io::stdout().flush();
140 interp.push_print(s);
141}
142
143fn print_with_nl(interp: &mut Interpreter, s: &str) {
144 println!("{}", s);
145 interp.push_print(&(s.to_string() + "\n"));
146}
147
148fn drain_iterator_blocking(
151 interp: &mut Interpreter,
152 it: &IteratorHandle,
153 printer: &dyn Fn(&mut Interpreter, &str),
154) -> Result<(), String> {
155 match &it.kind {
156 IteratorKind::Core(state_arc) => {
157 let mut guard = state_arc
158 .lock()
159 .map_err(|_| "std: drain => iterator lock error".to_string())?;
160 while !guard.done && guard.current < guard.end {
161 let item = guard.current;
162 guard.current += 1;
163 if guard.current >= guard.end {
164 guard.done = true;
165 }
166 drop(guard);
167 printer(interp, &item.to_string());
168 guard = state_arc
169 .lock()
170 .map_err(|_| "std: drain => iterator lock error".to_string())?;
171 }
172 Ok(())
173 }
174 IteratorKind::Plugin(plugin_arc) => {
175 let mut plugin =
176 plugin_arc.lock().map_err(|_| "std: drain => plugin iterator lock error".to_string())?;
177 loop {
178 match plugin.next_value() {
179 Ok(item) => {
180 let s = to_printable(&item);
181 printer(interp, &s);
182 }
183 Err(e) if e == "NO_MORE_DATA" => break,
184 Err(e) => return Err(e),
185 }
186 }
187 Ok(())
188 }
189 }
190}
191
192fn std_input_bridge(_interp: &mut Interpreter, args: Vec<Value>) -> Result<Value, String> {
195 if args.len() > 1 {
196 return Err(format!(
197 "std:input => expected 0 or 1 arg (prompt), got {}",
198 args.len()
199 ));
200 }
201
202 if let Some(Value::SingleString(prompt)) = args.get(0) {
203 print!("{}", prompt);
204 let _ = io::stdout().flush();
205 }
206
207 let mut buf = String::new();
208 match io::stdin().read_line(&mut buf) {
209 Ok(0) => Ok(Value::SingleString(String::new())), Ok(_) => {
211 if buf.ends_with('\n') {
212 buf.pop();
213 if buf.ends_with('\r') {
214 buf.pop();
215 }
216 }
217 Ok(Value::SingleString(buf))
218 }
219 Err(e) => Err(format!("std:input => {}", e)),
220 }
221}
222
223#[derive(Default)]
225struct StdinLines;
226
227impl PluginIterator for StdinLines {
228 fn next_value(&mut self) -> Result<Value, String> {
229 let mut buf = String::new();
230 let n = io::stdin()
231 .read_line(&mut buf)
232 .map_err(|e| format!("std:input_iter => {}", e))?;
233 if n == 0 {
234 return Err("NO_MORE_DATA".into());
235 }
236 if buf.ends_with('\n') {
237 buf.pop();
238 if buf.ends_with('\r') {
239 buf.pop();
240 }
241 }
242 Ok(Value::SingleString(buf))
243 }
244}
245
246fn std_input_iter_bridge(_interp: &mut Interpreter, args: Vec<Value>) -> Result<Value, String> {
247 if !args.is_empty() {
248 return Err(format!(
249 "std:input_iter => expected 0 args, got {}",
250 args.len()
251 ));
252 }
253
254 let handle = IteratorHandle {
255 kind: IteratorKind::Plugin(Arc::new(Mutex::new(StdinLines::default()))),
256 };
257
258 Ok(Value::Iterator(handle))
259}
260
261fn std_put_bridge(interp: &mut Interpreter, mut args: Vec<Value>) -> Result<Value, String> {
262 if args.len() != 1 {
263 return Err(format!(
264 "std:put => expected exactly 1 argument, got {}",
265 args.len()
266 ));
267 }
268 let val = args.remove(0);
269
270 match &val {
271 Value::Iterator(handle) => {
272 drain_iterator_blocking(interp, handle, &print_no_nl)?;
273 Ok(val)
274 }
275 other => {
276 let s = to_printable(other);
277 print_no_nl(interp, &s);
278 Ok(val)
279 }
280 }
281}
282
283fn std_log_bridge(interp: &mut Interpreter, mut args: Vec<Value>) -> Result<Value, String> {
284 if args.len() != 1 {
285 return Err(format!(
286 "std:log => expected exactly 1 argument, got {}",
287 args.len()
288 ));
289 }
290 let val = args.remove(0);
291
292 match &val {
293 Value::Iterator(handle) => {
294 drain_iterator_blocking(interp, handle, &print_with_nl)?;
295 Ok(val)
296 }
297 other => {
298 let s = to_printable(other);
299 print_with_nl(interp, &s);
300 Ok(val)
301 }
302 }
303}
304
305fn std_deep_bridge(interp: &mut Interpreter, mut args: Vec<Value>) -> Result<Value, String> {
307 if args.len() != 1 {
308 return Err(format!(
309 "std:deep => expected exactly 1 argument, got {}",
310 args.len()
311 ));
312 }
313 let val = args.remove(0);
314 let s = deep_to_string(&val);
315 println!("{}", s);
316 interp.push_print(&(s + "\n"));
317 Ok(val)
318}
319
320#[export_name = "Cargo_lock"]
323pub unsafe extern "C" fn cargo_lock(
324 interp_ptr: *mut std::ffi::c_void,
325 _extra: *const std::ffi::c_void,
326) -> i32 {
327 if interp_ptr.is_null() {
328 return 1;
329 }
330 let interp = &mut *(interp_ptr as *mut Interpreter);
331
332 let f_input = Arc::new(Mutex::new(std_input_bridge));
334 let f_iter = Arc::new(Mutex::new(std_input_iter_bridge));
335 let f_put = Arc::new(Mutex::new(std_put_bridge));
336 let f_log = Arc::new(Mutex::new(std_log_bridge));
337 let f_deep = Arc::new(Mutex::new(std_deep_bridge));
338
339 interp.register_dynamic_function("std:input", f_input);
340 interp.register_dynamic_function("std:input_iter", f_iter);
341 interp.register_dynamic_function("std:put", f_put);
342 interp.register_dynamic_function("std:log", f_log);
343 interp.register_dynamic_function("std:deep", f_deep);
344
345 interp.set_variable(
347 "std:input",
348 Value::Function(Box::new(FunctionValue::Named("std:input".into()))),
349 );
350 interp.set_variable(
351 "std:input_iter",
352 Value::Function(Box::new(FunctionValue::Named("std:input_iter".into()))),
353 );
354 interp.set_variable(
355 "std:put",
356 Value::Function(Box::new(FunctionValue::Named("std:put".into()))),
357 );
358 interp.set_variable(
359 "std:log",
360 Value::Function(Box::new(FunctionValue::Named("std:log".into()))),
361 );
362 interp.set_variable(
363 "std:deep",
364 Value::Function(Box::new(FunctionValue::Named("std:deep".into()))),
365 );
366
367 0
368}