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