1use std::io::Read;
2use std::io::Write;
3use std::time::SystemTime;
4use std::time::UNIX_EPOCH;
5
6use rand::Rng;
7use seq_macro::seq;
8use malachite::Integer;
9use malachite::num::arithmetic::traits::Abs;
10use serde::Deserialize;
11use serde::Serialize;
12
13use crate::annotations::Annotation;
14use crate::compilation::CompiledNessaExpr;
15use crate::integer_ext::*;
16use crate::parser::Location;
17use crate::ARR_IT_OF;
18use crate::ARR_OF;
19use crate::types::*;
20use crate::object::*;
21use crate::context::NessaContext;
22
23pub type FunctionOverloadFn = fn(&Vec<Type>, &Type, Vec<Object>, &NessaContext) -> Result<Object, String>;
31pub type OptFunctionOverloadFn = Option<FunctionOverloadFn>;
32
33#[derive(Clone, Serialize, Deserialize)]
34pub struct FunctionOverload {
35 pub location: Location,
36 pub annotations: Vec<Annotation>,
37 pub templates: usize,
38 pub args: Type,
39 pub ret: Type,
40
41 #[serde(skip)]
42 pub function: OptFunctionOverloadFn
43}
44
45pub type FunctionOverloads = Vec<FunctionOverload>;
46
47const EMPTY_FUNC: FunctionOverloadFn = |_, _, _, _| Ok(Object::empty());
48
49#[derive(Clone, Serialize, Deserialize)]
50pub struct Function {
51 pub id: usize,
52 pub name: String,
53 pub overloads: FunctionOverloads
54}
55
56macro_rules! define_unary_function {
63 ($ctx: ident, $id: expr, $inner_type: expr, $return_type: expr, $unwrap_type: ident, $a: ident, $deref: ident, $result: expr) => {
64 $ctx.define_native_function_overload(
65 $id, 0,
66 &[$inner_type],
67 $return_type,
68 |_, _, v, _| {
69 let $a = v[0].$deref::<$unwrap_type>();
70 return Ok(Object::new($result));
71 }
72 ).unwrap();
73 };
74}
75
76macro_rules! define_binary_function {
77 ($ctx: ident, $id: expr, $inner_type_a: expr, $inner_type_b: expr, $return_type: expr, $unwrap_type: ident, $a: ident, $deref_a: ident, $b: ident, $deref_b: ident, $result: expr) => {
78 $ctx.define_native_function_overload(
79 $id, 0,
80 &[$inner_type_a, $inner_type_b],
81 $return_type,
82 |_, _, v, _| {
83 let $a = v[0].$deref_a::<$unwrap_type>();
84 let $b = v[1].$deref_b::<$unwrap_type>();
85
86 return Ok(Object::new($result));
87 }
88 ).unwrap();
89 };
90}
91
92macro_rules! define_unary_function_overloads {
93 ($ctx: ident, $id: expr, $inner_type: expr, $return_type: expr, $unwrap_type: ident, $a: ident, $result: expr) => {
94 define_unary_function!($ctx, $id, $inner_type, $return_type, $unwrap_type, $a, get, $result);
95 define_unary_function!($ctx, $id, Type::Ref(Box::new($inner_type)), $return_type, $unwrap_type, $a, deref, $result);
96 define_unary_function!($ctx, $id, Type::MutRef(Box::new($inner_type)), $return_type, $unwrap_type, $a, deref, $result);
97 };
98}
99
100macro_rules! define_binary_function_overloads {
101 ($ctx: ident, $id: expr, $inner_type: expr, $return_type: expr, $unwrap_type: ident, $a: ident, $b: ident, $result: expr) => {
102 define_binary_function!($ctx, $id, $inner_type, $inner_type, $return_type, $unwrap_type, $a, get, $b, get, $result);
103 define_binary_function!($ctx, $id, Type::Ref(Box::new($inner_type)), $inner_type, $return_type, $unwrap_type, $a, deref, $b, get, $result);
104 define_binary_function!($ctx, $id, Type::MutRef(Box::new($inner_type)), $inner_type, $return_type, $unwrap_type, $a, deref, $b, get, $result);
105 define_binary_function!($ctx, $id, $inner_type, Type::Ref(Box::new($inner_type)), $return_type, $unwrap_type, $a, get, $b, deref, $result);
106 define_binary_function!($ctx, $id, $inner_type, Type::MutRef(Box::new($inner_type)), $return_type, $unwrap_type, $a, get, $b, deref, $result);
107 define_binary_function!($ctx, $id, Type::Ref(Box::new($inner_type)), Type::Ref(Box::new($inner_type)), $return_type, $unwrap_type, $a, deref, $b, deref, $result);
108 define_binary_function!($ctx, $id, Type::MutRef(Box::new($inner_type)), Type::Ref(Box::new($inner_type)), $return_type, $unwrap_type, $a, deref, $b, deref, $result);
109 define_binary_function!($ctx, $id, Type::Ref(Box::new($inner_type)), Type::MutRef(Box::new($inner_type)), $return_type, $unwrap_type, $a, deref, $b, deref, $result);
110 define_binary_function!($ctx, $id, Type::MutRef(Box::new($inner_type)), Type::MutRef(Box::new($inner_type)), $return_type, $unwrap_type, $a, deref, $b, deref, $result);
111 };
112}
113
114pub const ITERATOR_FUNC_ID: usize = 10;
116pub const NEXT_FUNC_ID: usize = 11;
117pub const IS_CONSUMED_FUNC_ID: usize = 12;
118
119pub fn standard_functions(ctx: &mut NessaContext) {
120 let idx = ctx.define_function("inc".into()).unwrap();
121
122 ctx.define_native_function_overload(idx, 0, &[INT.to_mut()], Type::Empty, EMPTY_FUNC).unwrap();
123
124 let idx = ctx.define_function("print".into()).unwrap();
125
126 ctx.define_native_function_overload(idx, 0, &[INT], Type::Empty, |_, _, v, _| {
127 print!("{}", v[0].get::<Integer>());
128
129 Ok(Object::empty())
130 }).unwrap();
131
132 ctx.define_native_function_overload(idx, 0, &[FLOAT], Type::Empty, |_, _, v, _| {
133 print!("{}", v[0].get::<f64>());
134
135 Ok(Object::empty())
136 }).unwrap();
137
138 ctx.define_native_function_overload(idx, 0, &[BOOL], Type::Empty, |_, _, v, _| {
139 print!("{}", v[0].get::<bool>());
140
141 Ok(Object::empty())
142 }).unwrap();
143
144 ctx.define_native_function_overload(idx, 0, &[STR], Type::Empty, |_, _, v, _| {
145 print!("{}", v[0].get::<String>());
146
147 Ok(Object::empty())
148 }).unwrap();
149
150 ctx.define_native_function_overload(idx, 0, &[INT.to_ref().or(INT.to_mut())], Type::Empty, |_, _, v, _| {
151 print!("{}", v[0].deref::<Integer>());
152
153 Ok(Object::empty())
154 }).unwrap();
155
156 ctx.define_native_function_overload(idx, 0, &[FLOAT.to_ref().or(FLOAT.to_mut())], Type::Empty, |_, _, v, _| {
157 print!("{}", v[0].deref::<f64>());
158
159 Ok(Object::empty())
160 }).unwrap();
161
162 ctx.define_native_function_overload(idx, 0, &[BOOL.to_ref().or(BOOL.to_mut())], Type::Empty, |_, _, v, _| {
163 print!("{}", v[0].deref::<bool>());
164
165 Ok(Object::empty())
166 }).unwrap();
167
168 ctx.define_native_function_overload(idx, 0, &[STR.to_ref().or(STR.to_mut())], Type::Empty, |_, _, v, _| {
169 print!("{}", v[0].deref::<String>());
170
171 Ok(Object::empty())
172 }).unwrap();
173
174 let idx = ctx.define_function("deref".into()).unwrap();
175
176 ctx.define_native_function_overload(idx, 1, &[T_0.to_mut()], T_0, EMPTY_FUNC).unwrap();
177 ctx.define_native_function_overload(idx, 1, &[T_0.to_ref()], T_0, EMPTY_FUNC).unwrap();
178
179 let idx = ctx.define_function("ref".into()).unwrap();
180
181 ctx.define_native_function_overload(idx, 1, &[T_0], T_0.to_ref(), EMPTY_FUNC).unwrap();
182
183 let idx = ctx.define_function("mut".into()).unwrap();
184
185 ctx.define_native_function_overload(idx, 1, &[T_0], T_0.to_mut(), EMPTY_FUNC).unwrap();
186
187 let idx = ctx.define_function("demut".into()).unwrap();
188
189 ctx.define_native_function_overload(idx, 1, &[T_0.to_mut()], T_0.to_ref(), EMPTY_FUNC).unwrap();
190
191 let idx = ctx.define_function("arr".into()).unwrap();
192
193 ctx.define_native_function_overload(idx, 1, &[], ARR_OF!(T_0), |t, _, _, _| Ok(Object::arr(vec!(), t[0].clone()))).unwrap();
194
195 let idx = ctx.define_function("push".into()).unwrap();
196
197 ctx.define_native_function_overload(
198 idx,
199 1,
200 &[ARR_OF!(T_0).to_mut(), T_0],
201 Type::Empty,
202 |_, _, v, _| {
203 let array = v[0].deref::<NessaArray>();
204 array.elements.push(v[1].clone());
205
206 Ok(Object::empty())
207 }
208 ).unwrap();
209
210 let idx = ctx.define_function("reserve".into()).unwrap();
211
212 ctx.define_native_function_overload(
213 idx,
214 1,
215 &[ARR_OF!(T_0).to_mut(), INT],
216 Type::Empty,
217 |_, _, v, _| {
218 let array = v[0].deref::<NessaArray>();
219 let size = v[1].get::<Integer>();
220
221 if is_valid_index(size) && array.elements.try_reserve_exact(to_usize(size)).is_ok() {
222 Ok(Object::empty())
223
224 } else {
225 Err(format!("Unable to reserve {} elements", size))
226 }
227 }
228 ).unwrap();
229
230 let idx = ctx.define_function("capacity".into()).unwrap();
231
232 ctx.define_native_function_overload(
233 idx,
234 1,
235 &[ARR_OF!(T_0).to_ref()],
236 INT,
237 |_, _, mut v, _| Ok(Object::new(Integer::from(v.pop().unwrap().deref::<NessaArray>().elements.capacity() as u64)))
238 ).unwrap();
239
240 ctx.define_native_function_overload(
241 idx,
242 1,
243 &[ARR_OF!(T_0).to_mut()],
244 INT,
245 |_, _, mut v, _| Ok(Object::new(Integer::from(v.pop().unwrap().deref::<NessaArray>().elements.capacity() as u64)))
246 ).unwrap();
247
248 let idx = ctx.define_function("iterator".into()).unwrap();
249
250 ctx.define_native_function_overload(
251 idx,
252 1,
253 &[ARR_OF!(T_0).to_mut()],
254 ARR_IT_OF!(T_0.to_mut()),
255 |t, _, v, _| {
256 return Ok(Object::arr_it(
257 Type::MutRef(Box::new(t[0].clone())),
258 v[0].inner.borrow().dereference().clone(),
259 0
260 ));
261 }
262 ).unwrap();
263
264 ctx.define_native_function_overload(
265 idx,
266 1,
267 &[ARR_OF!(T_0).to_ref()],
268 ARR_IT_OF!(T_0.to_ref()),
269 |t, _, v, _| {
270 return Ok(Object::arr_it(
271 Type::Ref(Box::new(t[0].clone())),
272 v[0].inner.borrow().dereference().clone(),
273 0
274 ));
275 }
276 ).unwrap();
277
278 ctx.define_native_function_overload(
279 idx,
280 1,
281 &[ARR_OF!(T_0)],
282 ARR_IT_OF!(T_0.to_mut()),
283 |t, _, v, _| {
284 Ok(Object::arr_it(
285 Type::MutRef(Box::new(t[0].clone())),
286 v[0].inner.clone(),
287 0
288 ))
289 }
290 ).unwrap();
291
292 ctx.define_native_function_overload(
293 idx,
294 1,
295 &[ARR_IT_OF!(T_0.to_mut())],
296 ARR_IT_OF!(T_0.to_mut()),
297 |_, _, mut v, _| Ok(v.pop().unwrap())
298 ).unwrap();
299
300 ctx.define_native_function_overload(
301 idx,
302 1,
303 &[ARR_IT_OF!(T_0.to_ref())],
304 ARR_IT_OF!(T_0.to_ref()),
305 |_, _, mut v, _| Ok(v.pop().unwrap())
306 ).unwrap();
307
308 let idx = ctx.define_function("next".into()).unwrap();
309
310 ctx.define_native_function_overload(
311 idx,
312 1,
313 &[Type::MutRef(Box::new(ARR_IT_OF!(T_0.to_mut())))],
314 T_0.to_mut(),
315 |_, _, v, _| {
316 let iterator = v[0].deref::<NessaArrayIt>();
317 let item;
318
319 {
320 let reference = iterator.block.borrow_mut();
321 let array = &reference.mut_inner::<NessaArray>();
322 item = array.elements[iterator.pos].get_mut();
323 }
324
325 iterator.pos += 1;
326
327 Ok(item)
328 }
329 ).unwrap();
330
331 ctx.define_native_function_overload(
332 idx,
333 1,
334 &[Type::MutRef(Box::new(ARR_IT_OF!(T_0.to_ref())))],
335 T_0.to_ref(),
336 |_, _, v, _| {
337 let iterator = v[0].deref::<NessaArrayIt>();
338 let item;
339
340 {
341 let reference = iterator.block.borrow_mut();
342 let array = &reference.mut_inner::<NessaArray>();
343 item = array.elements[iterator.pos].get_ref();
344 }
345
346 iterator.pos += 1;
347
348 Ok(item)
349 }
350 ).unwrap();
351
352 let idx = ctx.define_function("is_consumed".into()).unwrap();
353
354 ctx.define_native_function_overload(
355 idx,
356 1,
357 &[ARR_IT_OF!(T_0.to_mut()).to_mut()],
358 BOOL,
359 |_, _, v, _| {
360 let iterator = v[0].deref::<NessaArrayIt>();
361
362 return Ok(Object::new(iterator.pos >= iterator.block.borrow().get_inner::<NessaArray>().elements.len()));
363 }
364 ).unwrap();
365
366 ctx.define_native_function_overload(
367 idx,
368 1,
369 &[ARR_IT_OF!(T_0.to_ref()).to_mut()],
370 BOOL,
371 |_, _, v, _| {
372 let iterator = v[0].deref::<NessaArrayIt>();
373
374 return Ok(Object::new(iterator.pos >= iterator.block.borrow().get_inner::<NessaArray>().elements.len()));
375 }
376 ).unwrap();
377
378 let idx = ctx.define_function("panic".into()).unwrap();
379
380 ctx.define_native_function_overload(
381 idx,
382 0,
383 &[STR],
384 Type::Empty,
385 |_, _, v, _| {
386 return Err(v[0].get::<String>().clone());
387 }
388 ).unwrap();
389
390 let idx = ctx.define_function("len".into()).unwrap();
391
392 ctx.define_native_function_overload(
393 idx,
394 0,
395 &[ARR_OF!(Type::Wildcard).to_ref()],
396 INT,
397 |_, _, v, _| Ok(Object::new(Integer::from(v[0].deref::<NessaArray>().elements.len() as u64)))
398 ).unwrap();
399
400 ctx.define_native_function_overload(
401 idx,
402 0,
403 &[ARR_OF!(Type::Wildcard).to_mut()],
404 INT,
405 |_, _, v, _| Ok(Object::new(Integer::from(v[0].deref::<NessaArray>().elements.len() as u64)))
406 ).unwrap();
407
408 ctx.define_native_function_overload(
409 idx,
410 0,
411 &[STR.to_ref()],
412 INT,
413 |_, _, v, _| Ok(Object::new(Integer::from(v[0].deref::<String>().len() as u64)))
414 ).unwrap();
415
416 ctx.define_native_function_overload(
417 idx,
418 0,
419 &[STR.to_mut()],
420 INT,
421 |_, _, v, _| Ok(Object::new(Integer::from(v[0].deref::<String>().len() as u64)))
422 ).unwrap();
423
424 let idx = ctx.define_function("sin".into()).unwrap();
425
426 define_unary_function_overloads!(ctx, idx, INT, FLOAT, Integer, a, to_f64(a).sin());
427 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.sin());
428
429 let idx = ctx.define_function("cos".into()).unwrap();
430
431 define_unary_function_overloads!(ctx, idx, INT, FLOAT, Integer, a, to_f64(a).cos());
432 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.cos());
433
434 let idx = ctx.define_function("tan".into()).unwrap();
435
436 define_unary_function_overloads!(ctx, idx, INT, FLOAT, Integer, a, to_f64(a).tan());
437 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.tan());
438
439 let idx = ctx.define_function("sinh".into()).unwrap();
440
441 define_unary_function_overloads!(ctx, idx, INT, FLOAT, Integer, a, to_f64(a).sinh());
442 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.sinh());
443
444 let idx = ctx.define_function("cosh".into()).unwrap();
445
446 define_unary_function_overloads!(ctx, idx, INT, FLOAT, Integer, a, to_f64(a).cosh());
447 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.cosh());
448
449 let idx = ctx.define_function("tanh".into()).unwrap();
450
451 define_unary_function_overloads!(ctx, idx, INT, FLOAT, Integer, a, to_f64(a).tanh());
452 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.tanh());
453
454 let idx = ctx.define_function("ln".into()).unwrap();
455
456 define_unary_function_overloads!(ctx, idx, INT, FLOAT, Integer, a, to_f64(a).ln());
457 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.ln());
458
459 let idx = ctx.define_function("log2".into()).unwrap();
460
461 define_unary_function_overloads!(ctx, idx, INT, FLOAT, Integer, a, to_f64(a).log2());
462 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.log2());
463
464 let idx = ctx.define_function("log10".into()).unwrap();
465
466 define_unary_function_overloads!(ctx, idx, INT, FLOAT, Integer, a, to_f64(a).log10());
467 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.log10());
468
469 let idx = ctx.define_function("exp".into()).unwrap();
470
471 define_unary_function_overloads!(ctx, idx, INT, FLOAT, Integer, a, to_f64(a).exp());
472 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.exp());
473
474 let idx = ctx.define_function("floor".into()).unwrap();
475
476 define_unary_function_overloads!(ctx, idx, FLOAT, INT, f64, a, Integer::from(a.floor() as u64));
477
478 let idx = ctx.define_function("round".into()).unwrap();
479
480 define_unary_function_overloads!(ctx, idx, FLOAT, INT, f64, a, Integer::from(a.round() as u64));
481
482 let idx = ctx.define_function("ceil".into()).unwrap();
483
484 define_unary_function_overloads!(ctx, idx, FLOAT, INT, f64, a, Integer::from(a.ceil() as u64));
485
486 let idx = ctx.define_function("fract".into()).unwrap();
487
488 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.fract());
489
490 let idx = ctx.define_function("sqrt".into()).unwrap();
491
492 define_unary_function_overloads!(ctx, idx, INT, FLOAT, Integer, a, to_f64(a).sqrt());
493 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.sqrt());
494
495 let idx = ctx.define_function("abs".into()).unwrap();
496
497 define_unary_function_overloads!(ctx, idx, INT, INT, Integer, a, a.clone().abs());
498 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.abs());
499
500 let idx = ctx.define_function("rand".into()).unwrap();
501
502 ctx.define_native_function_overload(idx, 0, &[], FLOAT, |_, _, _, _| Ok(Object::new(rand::thread_rng().gen_range(0.0..1.0)))).unwrap();
503
504 let idx = ctx.define_function("rand_int".into()).unwrap();
505
506 define_binary_function_overloads!(ctx, idx, INT, INT, Integer, a, b, randint(a.clone(), b.clone()));
507
508 let idx = ctx.define_function("as_float".into()).unwrap();
509
510 define_unary_function_overloads!(ctx, idx, INT, FLOAT, Integer, a, to_f64(a));
511
512 let idx = ctx.define_function("is".into()).unwrap();
513
514 ctx.define_native_function_overload(
515 idx,
516 1,
517 &[Type::Wildcard],
518 BOOL,
519 |t, _, v, ctx| Ok(Object::new(v[0].get_type().bindable_to(&t[0], ctx)))
520 ).unwrap();
521
522 let idx = ctx.define_function("as".into()).unwrap();
523
524 ctx.define_native_function_overload(
525 idx,
526 1,
527 &[Type::Wildcard],
528 T_0,
529 |t, _, mut v, ctx| {
530 let obj = v.pop().unwrap();
531 let obj_type = obj.get_type();
532
533 if !obj_type.bindable_to(&t[0], ctx) {
534 Err(format!("Unable to get value of type {} as {}", obj_type.get_name(ctx), t[0].get_name(ctx)))
535
536 } else {
537 Ok(obj)
538 }
539 }
540 ).unwrap();
541
542 let idx = ctx.define_function("drop".into()).unwrap();
543
544 ctx.define_native_function_overload(idx, 1, &[T_0.to_mut()], Type::Empty, |_, _, mut v, _| {
545 v.pop().unwrap().drop_contents();
546 Ok(Object::empty())
547 }).unwrap();
548
549 let idx = ctx.define_function("move".into()).unwrap();
550
551 ctx.define_native_function_overload(idx, 1, &[T_0.to_mut()], T_0, EMPTY_FUNC).unwrap();
552
553 let idx = ctx.define_function("fwd".into()).unwrap();
554
555 ctx.define_native_function_overload(idx, 1, &[Type::Wildcard], T_0, |a, _, mut v, ctx| {
556 let type_arg = a.last().unwrap();
557 let param_arg = v.last().unwrap().get_type();
558
559 match (type_arg, ¶m_arg) {
560 (Type::Ref(a), Type::Ref(b)) if a == b => Ok(v.pop().unwrap()),
561 (Type::MutRef(a), Type::MutRef(b)) if a == b => Ok(v.pop().unwrap()),
562 (Type::Ref(a), Type::MutRef(b)) if a == b => Ok(v.pop().unwrap().get_ref()),
563
564 (a, Type::MutRef(b)) if *a == **b => Ok(v.pop().unwrap().move_contents()),
565 (a, Type::Ref(b)) if *a == **b => Ok(v.pop().unwrap().deref_obj().deep_clone()),
566
567 (Type::MutRef(b), a) if *a == **b => Ok(v.pop().unwrap().get_mut_nostack()),
568 (Type::Ref(b), a) if *a == **b => Ok(v.pop().unwrap().get_ref_nostack()),
569
570 (a, b) if a == b => Ok(v.pop().unwrap().move_contents()),
571
572 _ => Err(format!(
573 "Unable to forward value of type {} as type {}",
574 param_arg.get_name(ctx),
575 type_arg.get_name(ctx)
576 ))
577 }
578 }).unwrap();
579
580 let idx = ctx.define_function("cfwd".into()).unwrap();
581
582 ctx.define_native_function_overload(idx, 1, &[Type::Wildcard], T_0, |a, _, mut v, ctx| {
583 let type_arg = a.last().unwrap();
584 let param_arg = v.last().unwrap().get_type();
585
586 match (type_arg, ¶m_arg) {
587 (Type::Ref(a), Type::Ref(b)) if a == b => Ok(v.pop().unwrap()),
588 (Type::MutRef(a), Type::MutRef(b)) if a == b => Ok(v.pop().unwrap()),
589 (Type::Ref(a), Type::MutRef(b)) if a == b => Ok(v.pop().unwrap().get_ref()),
590
591 (a, Type::MutRef(b)) if *a == **b => Ok(v.pop().unwrap().deref_obj().deep_clone()),
592 (a, Type::Ref(b)) if *a == **b => Ok(v.pop().unwrap().deref_obj().deep_clone()),
593
594 (Type::MutRef(b), a) if *a == **b => Ok(v.pop().unwrap().get_mut_nostack()),
595 (Type::Ref(b), a) if *a == **b => Ok(v.pop().unwrap().get_ref_nostack()),
596
597 (a, b) if a == b => Ok(v.pop().unwrap().deep_clone()),
598
599 _ => Err(format!(
600 "Unable to forward value of type {} as type {}",
601 param_arg.get_name(ctx),
602 type_arg.get_name(ctx)
603 ))
604 }
605 }).unwrap();
606
607 let idx = ctx.define_function("swap".into()).unwrap();
608
609 ctx.define_native_function_overload(idx, 1, &[T_0.to_mut(), T_0.to_mut()], Type::Empty, |_, _, mut v, _| {
610 let a = v.pop().unwrap();
611 let b = v.pop().unwrap();
612
613 a.swap_contents(&b);
614
615 Ok(Object::empty())
616 }).unwrap();
617
618 let idx = ctx.define_function("get_file".into()).unwrap();
619
620 ctx.define_native_function_overload(idx, 0, &[STR], FILE, |_, _, v, _| {
621 let path = v[0].get::<String>();
622 let pathbuf = std::path::Path::new(path);
623
624 Ok(Object::file(pathbuf.into()))
625 }).unwrap();
626
627 let idx = ctx.define_function("open".into()).unwrap();
628
629 ctx.define_native_function_overload(idx, 0, &[FILE.to_mut(), BOOL, BOOL, BOOL], Type::Empty, |_, _, v, _| {
630 let file = &mut *v[0].deref::<NessaFile>();
631 let read = *v[1].get::<bool>();
632 let write = *v[2].get::<bool>();
633 let append = *v[3].get::<bool>();
634
635 file.open(read, write, append)?;
636
637 Ok(Object::empty())
638 }).unwrap();
639
640 let idx = ctx.define_function("close".into()).unwrap();
641
642 ctx.define_native_function_overload(idx, 0, &[FILE.to_mut()], Type::Empty, |_, _, v, _| {
643 let file = &mut *v[0].deref::<NessaFile>();
644 file.close()?;
645
646 Ok(Object::empty())
647 }).unwrap();
648
649 let idx = ctx.define_function("exists".into()).unwrap();
650
651 ctx.define_native_function_overload(idx, 0, &[FILE.to_mut()], BOOL, |_, _, v, _| {
652 let file = &*v[0].deref::<NessaFile>();
653
654 Ok(ObjectBlock::Bool(file.exists()?).to_obj())
655 }).unwrap();
656
657 let idx = ctx.define_function("delete".into()).unwrap();
658
659 ctx.define_native_function_overload(idx, 0, &[FILE.to_mut()], BOOL, |_, _, v, _| {
660 let file = &mut *v[0].deref::<NessaFile>();
661
662 Ok(ObjectBlock::Bool(file.delete()?).to_obj())
663 }).unwrap();
664
665 let idx = ctx.define_function("read_str".into()).unwrap();
666
667 ctx.define_native_function_overload(idx, 0, &[FILE.to_mut()], STR, |_, _, v, _| {
668 let file = v[0].deref::<NessaFile>();
669 let mut buf = String::new();
670
671 if !file.is_open() {
672 return Err(format!("File at {} is closed", file.path.to_str().unwrap()));
673 }
674
675 let res = file.file.as_ref().unwrap().borrow_mut().read_to_string(&mut buf);
676
677 match res {
678 Ok(_) => Ok(ObjectBlock::Str(buf).to_obj()),
679 Err(_) => Err("Unable to read file".into())
680 }
681 }).unwrap();
682
683 let idx = ctx.define_function("read_bytes".into()).unwrap();
684
685 ctx.define_native_function_overload(idx, 0, &[FILE.to_mut()], ARR_OF!(INT), |_, _, v, _| {
686 let file = v[0].deref::<NessaFile>();
687 let mut buf = vec!();
688
689 if !file.is_open() {
690 return Err(format!("File at {} is closed", file.path.to_str().unwrap()));
691 }
692
693 let res = file.file.as_ref().unwrap().borrow_mut().read_to_end(&mut buf);
694
695 match res {
696 Ok(_) => {
697 let arr = buf.into_iter().map(|i| ObjectBlock::Int(Integer::from(i as u32)).to_obj()).collect();
698 Ok(Object::arr(arr, INT))
699 },
700 Err(_) => Err("Unable to read file".into())
701 }
702 }).unwrap();
703
704 ctx.define_native_function_overload(idx, 0, &[FILE.to_mut(), INT], ARR_OF!(INT), |_, _, v, _| {
705 let file = v[0].deref::<NessaFile>();
706 let num_bytes = v[1].get::<Integer>();
707
708 if !is_valid_index(num_bytes) || *num_bytes == *ZERO {
709 return Err(format!("Unable to read {} bytes from file", num_bytes));
710 }
711
712 if !file.is_open() {
713 return Err(format!("File at {} is closed", file.path.to_str().unwrap()));
714 }
715
716 let mut buf = vec!(0; to_usize(num_bytes));
717 let res = file.file.as_ref().unwrap().borrow_mut().read_exact(&mut buf);
718
719 match res {
720 Ok(_) => {
721 let arr = buf.into_iter().map(|i| ObjectBlock::Int(Integer::from(i as u32)).to_obj()).collect();
722 Ok(Object::arr(arr, INT))
723 },
724 Err(_) => Err("Unable to read file".into())
725 }
726 }).unwrap();
727
728 let idx = ctx.define_function("write_str".into()).unwrap();
729
730 ctx.define_native_function_overload(idx, 0, &[FILE.to_mut(), STR.to_ref()], BOOL, |_, _, v, _| {
731 let file = v[0].deref::<NessaFile>();
732 let content = &*v[1].deref::<String>();
733
734 if !file.is_open() {
735 return Err(format!("File at {} is closed", file.path.to_str().unwrap()));
736 }
737
738 let ok = file.file.as_ref().unwrap().borrow_mut().write_all(content.as_bytes()).is_ok();
739
740 Ok(ObjectBlock::Bool(ok).to_obj())
741 }).unwrap();
742
743 let idx = ctx.define_function("write_bytes".into()).unwrap();
744
745 ctx.define_native_function_overload(idx, 0, &[FILE.to_mut(), ARR_OF!(INT).to_ref()], BOOL, |_, _, v, _| {
746 let file = v[0].deref::<NessaFile>();
747 let content = &*v[1].deref::<NessaArray>();
748
749 if !file.is_open() {
750 return Err(format!("File at {} is closed", file.path.to_str().unwrap()));
751 }
752
753 let mut bytes = vec!();
754 bytes.reserve_exact(content.elements.len());
755
756 for n in &content.elements {
757 let byte = n.get::<Integer>();
758
759 if is_valid_byte(byte) {
760 bytes.push(to_u8(byte));
761
762 } else {
763 return Err(format!("{} is not a valid byte value", byte));
764 }
765 }
766
767 let ok = file.file.as_ref().unwrap().borrow_mut().write_all(&bytes).is_ok();
768
769 Ok(ObjectBlock::Bool(ok).to_obj())
770 }).unwrap();
771
772 let idx = ctx.define_function("to_string".into()).unwrap();
773
774 ctx.define_native_function_overload(idx, 0, &[INT], STR, |_, _, mut v, _| {
775 let obj = v.pop().unwrap().get::<Integer>().to_string();
776
777 Ok(ObjectBlock::Str(obj).to_obj())
778 }).unwrap();
779
780 ctx.define_native_function_overload(idx, 0, &[FLOAT], STR, |_, _, mut v, _| {
781 let obj = v.pop().unwrap().get::<f64>().to_string();
782
783 Ok(ObjectBlock::Str(obj).to_obj())
784 }).unwrap();
785
786 let idx = ctx.define_function("code_point_at".into()).unwrap();
788
789 ctx.define_native_function_overload(idx, 0, &[STR.to_ref().or(STR.to_mut()), INT], INT, |_, _, v, _| {
790 let string = &*v[0].deref::<String>();
791 let idx = v[1].get::<Integer>();
792
793 if !is_valid_index(idx) {
794 return Err(format!("{} is not a valid index", idx));
795
796 } else if string.len() <= to_usize(idx) {
797 return Err(format!("{} is higher than the length of the string ({})", idx, string.len()));
798 }
799
800 if let Some(character) = string[to_usize(idx)..].chars().next() {
801 Ok(ObjectBlock::Int(Integer::from(character as u64)).to_obj())
802
803 } else {
804 Err(format!("Invalid character start at position {}", idx))
805 }
806 }).unwrap();
807
808 let idx = ctx.define_function("code_point_to_str".into()).unwrap();
809
810 ctx.define_native_function_overload(idx, 0, &[INT], STR, |_, _, v, _| {
811 let cp = v[0].get::<Integer>();
812
813 if !is_valid_index(cp) {
814 return Err(format!("{} is not a valid code point", cp));
815 }
816
817 if let Some(character) = char::from_u32(to_u32(cp)) {
818 Ok(ObjectBlock::Str(character.to_string()).to_obj())
819
820 } else {
821 Err(format!("{} is not a valid code point", cp))
822 }
823 }).unwrap();
824
825 let idx = ctx.define_function("code_point_length".into()).unwrap();
826
827 ctx.define_native_function_overload(idx, 0, &[INT], INT, |_, _, v, _| {
828 let cp = v[0].get::<Integer>();
829
830 if !is_valid_index(cp) {
831 return Err(format!("{} is not a valid code point", cp));
832 }
833
834 if let Some(character) = char::from_u32(to_u32(cp)) {
835 Ok(ObjectBlock::Int(Integer::from(character.len_utf8() as u64)).to_obj())
836
837 } else {
838 Err(format!("{} is not a valid code point", cp))
839 }
840 }).unwrap();
841
842 let idx = ctx.define_function("utf8_array".into()).unwrap();
843
844 ctx.define_native_function_overload(idx, 0, &[STR.to_ref().or(STR.to_mut())], ARR_OF!(INT), |_, _, v, _| {
845 let string = &*v[0].deref::<String>();
846 let arr = string.bytes()
847 .map(|i| ObjectBlock::Int(Integer::from(i as u64)).to_obj())
848 .collect();
849
850 Ok(Object::arr(arr, INT))
851 }).unwrap();
852
853 let idx = ctx.define_function("utf8_to_str".into()).unwrap();
854
855 ctx.define_native_function_overload(idx, 0, &[ARR_OF!(INT).to_ref().or(ARR_OF!(INT).to_mut())], STR, |_, _, v, _| {
856 let arr = &*v[0].deref::<NessaArray>();
857 let mut bytes = vec!();
858 bytes.reserve_exact(arr.elements.len());
859
860 for i in &arr.elements {
861 let n = i.get::<Integer>();
862
863 if !is_valid_byte(n) {
864 return Err(format!("{} is not a valid byte", n));
865 }
866
867 bytes.push(to_u8(n));
868 }
869
870 if let Ok(string) = String::from_utf8(bytes) {
871 Ok(ObjectBlock::Str(string).to_obj())
872
873 } else {
874 Err("Invalid UTF-8 array".into())
875 }
876 }).unwrap();
877
878 let idx = ctx.define_function("truncate".into()).unwrap();
879
880 ctx.define_native_function_overload(idx, 0, &[INT], INT, |_, _, v, _| {
881 let cp = v[0].get::<Integer>();
882 Ok(Object::new(truncate(cp)))
883 }).unwrap();
884
885 let idx = ctx.define_function("input".into()).unwrap();
886
887 ctx.define_native_function_overload(idx, 0, &[], STR, |_, _, _, _| {
888 let mut buffer = String::new();
889
890 std::io::stdout().flush().unwrap();
891 std::io::stdin().read_line(&mut buffer).unwrap();
892
893 Ok(Object::new(buffer))
894 }).unwrap();
895
896 let idx = ctx.define_function("num_args".into()).unwrap();
897
898 ctx.define_native_function_overload(idx, 0, &[], INT, |_, _, _, ctx| {
899 Ok(Object::new(Integer::from(ctx.program_input.len() as u64)))
900 }).unwrap();
901
902 let idx = ctx.define_function("get_arg".into()).unwrap();
903
904 ctx.define_native_function_overload(idx, 0, &[INT], STR, |_, _, v, ctx| {
905 let idx = v[0].get::<Integer>();
906
907 if !is_valid_index(idx) {
908 return Err(format!("{} is not a valid index", idx));
909
910 } else if ctx.program_input.len() <= to_usize(idx) {
911 return Err(format!("{} is higher than the number of input arguments ({})", idx, ctx.program_input.len()));
912 }
913
914 Ok(Object::new(ctx.program_input[to_usize(idx)].clone()))
915 }).unwrap();
916
917 let idx = ctx.define_function("set".into()).unwrap();
918
919 ctx.define_native_function_overload(
920 idx,
921 1,
922 &[ARR_OF!(T_0).to_mut(), T_0, INT],
923 Type::Empty,
924 |_, _, v, _| {
925 let array = v[0].deref::<NessaArray>();
926 let idx = v[2].get::<Integer>();
927
928 if !is_valid_index(idx) {
929 return Err(format!("{} is not a valid index", idx));
930
931 } else if array.elements.len() <= to_usize(idx) {
932 return Err(format!("{} is higher than the length of the array ({})", idx, array.elements.len()));
933 }
934
935 array.elements[to_usize(idx)] = v[1].clone();
936
937 Ok(Object::empty())
938 }
939 ).unwrap();
940
941 let idx = ctx.define_function("insert".into()).unwrap();
942
943 ctx.define_native_function_overload(
944 idx,
945 1,
946 &[ARR_OF!(T_0).to_mut(), T_0, INT],
947 Type::Empty,
948 |_, _, v, _| {
949 let array = v[0].deref::<NessaArray>();
950 let idx = v[2].get::<Integer>();
951
952 if !is_valid_index(idx) {
953 return Err(format!("{} is not a valid index", idx));
954
955 } else if array.elements.len() <= to_usize(idx) {
956 return Err(format!("{} is higher than the length of the array ({})", idx, array.elements.len()));
957 }
958
959 array.elements.insert(to_usize(idx), v[1].clone());
960
961 Ok(Object::empty())
962 }
963 ).unwrap();
964
965 let idx = ctx.define_function("remove".into()).unwrap();
966
967 ctx.define_native_function_overload(
968 idx,
969 1,
970 &[ARR_OF!(T_0).to_mut(), INT],
971 Type::Empty,
972 |_, _, v, _| {
973 let array = v[0].deref::<NessaArray>();
974 let idx = v[1].get::<Integer>();
975
976 if !is_valid_index(idx) {
977 return Err(format!("{} is not a valid index", idx));
978
979 } else if array.elements.len() <= to_usize(idx) {
980 return Err(format!("{} is higher than the length of the array ({})", idx, array.elements.len()));
981 }
982
983 array.elements.remove(to_usize(idx));
984
985 Ok(Object::empty())
986 }
987 ).unwrap();
988
989 let idx = ctx.define_function("pop".into()).unwrap();
990
991 ctx.define_native_function_overload(
992 idx,
993 1,
994 &[ARR_OF!(T_0).to_mut()],
995 Type::Empty,
996 |_, _, v, _| {
997 let array = v[0].deref::<NessaArray>();
998 array.elements.pop();
999
1000 Ok(Object::empty())
1001 }
1002 ).unwrap();
1003
1004 let idx = ctx.define_function("time".into()).unwrap();
1005
1006 ctx.define_native_function_overload(
1007 idx,
1008 0,
1009 &[],
1010 INT,
1011 |_, _, _, _| {
1012 let time = SystemTime::now().duration_since(UNIX_EPOCH);
1013
1014 match time {
1015 Ok(d) => {
1016 let duration = d.as_nanos();
1017
1018 Ok(Object::new(Integer::from(duration)))
1019 },
1020 Err(_) => Err("Unable to get current time".into()),
1021 }
1022 }
1023 ).unwrap();
1024
1025 let idx = ctx.define_function("dec".into()).unwrap();
1026
1027 ctx.define_native_function_overload(idx, 0, &[INT.to_mut()], Type::Empty, EMPTY_FUNC).unwrap();
1028
1029 seq!(I in 0..10 {
1031 let idx = ctx.define_function(format!("get_{}", I)).unwrap();
1032
1033 seq!(J in 2..10 {
1034 let ts = Type::And((0..J).map(|i| Type::TemplateParam(i, vec!())).collect());
1035
1036 let res = ctx.define_native_function_overload(
1037 idx,
1038 J,
1039 &[ts.clone()],
1040 Type::TemplateParam(I, vec!()),
1041 EMPTY_FUNC
1042 ).unwrap();
1043
1044 ctx.cache.opcodes.functions.insert((idx, res), (CompiledNessaExpr::TupleElemMove(I), 0));
1045
1046 let res = ctx.define_native_function_overload(
1047 idx,
1048 J,
1049 &[Type::Ref(Box::new(ts.clone()))],
1050 Type::Ref(Box::new(Type::TemplateParam(I, vec!()))),
1051 EMPTY_FUNC
1052 ).unwrap();
1053
1054 ctx.cache.opcodes.functions.insert((idx, res), (CompiledNessaExpr::TupleElemRef(I), 0));
1055
1056 let res = ctx.define_native_function_overload(
1057 idx,
1058 J,
1059 &[Type::MutRef(Box::new(ts))],
1060 Type::MutRef(Box::new(Type::TemplateParam(I, vec!()))),
1061 EMPTY_FUNC
1062 ).unwrap();
1063
1064 ctx.cache.opcodes.functions.insert((idx, res), (CompiledNessaExpr::TupleElemMut(I), 0));
1065 });
1066 });
1067}
1068
1069pub fn define_macro_emit_fn(ctx: &mut NessaContext, name: String) {
1070 let idx = ctx.define_function(name).unwrap();
1071
1072 ctx.define_native_function_overload(idx, 0, &[STR], crate::types::Type::Empty, |_, _, mut args, ctx| {
1073 let obj = args.pop().unwrap();
1074 let string = obj.get::<String>();
1075
1076 *ctx.captured_output.borrow_mut() += string;
1077
1078 Ok(Object::empty())
1079 }).unwrap();
1080}