1use crate::{
2 IdGenerator, aiken_fn,
3 ast::{
4 Annotation, ArgName, CallArg, DataType, DataTypeKey, Function, FunctionAccessKey,
5 ModuleKind, OnTestFailure, RecordConstructor, RecordConstructorArg, Span, TypedArg,
6 TypedDataType, TypedFunction, UnOp, well_known,
7 },
8 expr::TypedExpr,
9 tipo::{
10 Type, TypeConstructor, TypeInfo, ValueConstructor, ValueConstructorVariant,
11 fields::FieldMap,
12 },
13};
14use std::{collections::BTreeSet, sync::LazyLock};
15
16use indexmap::IndexMap;
17use std::{collections::HashMap, rc::Rc};
18use strum::IntoEnumIterator;
19
20use uplc::{
21 builder::{CONSTR_FIELDS_EXPOSER, CONSTR_INDEX_EXPOSER},
22 builtins::DefaultFunction,
23};
24
25pub const PRELUDE: &str = "aiken";
26pub const BUILTIN: &str = "aiken/builtin";
27
28pub static INTERNAL_FUNCTIONS: LazyLock<BTreeSet<&'static str>> = LazyLock::new(|| {
29 let mut set = BTreeSet::new();
30 set.insert("diagnostic");
31 set.insert("do_from_int");
32 set.insert("encode_base16");
33 set.insert("enumerate");
34 set.insert("from_int");
35 set
36});
37
38pub fn prelude(id_gen: &IdGenerator) -> TypeInfo {
41 let mut prelude = TypeInfo {
42 name: PRELUDE.to_string(),
43 package: "".to_string(),
44 kind: ModuleKind::Lib,
45 types: HashMap::new(),
46 types_constructors: HashMap::new(),
47 values: HashMap::new(),
48 accessors: HashMap::new(),
49 annotations: HashMap::new(),
50 };
51
52 prelude.types.insert(
54 well_known::DATA.to_string(),
55 TypeConstructor::primitive(Type::data()),
56 );
57
58 prelude.types.insert(
60 well_known::INT.to_string(),
61 TypeConstructor::primitive(Type::int()),
62 );
63
64 prelude.types.insert(
66 well_known::BYTE_ARRAY.to_string(),
67 TypeConstructor::primitive(Type::byte_array()),
68 );
69
70 prelude.types.insert(
72 well_known::BOOL.to_string(),
73 TypeConstructor::primitive(Type::bool()),
74 );
75 prelude.types_constructors.insert(
76 well_known::BOOL.to_string(),
77 ValueConstructor::known_enum(
78 &mut prelude.values,
79 Type::bool(),
80 well_known::BOOL_CONSTRUCTORS,
81 ),
82 );
83
84 prelude.types.insert(
86 well_known::G1_ELEMENT.to_string(),
87 TypeConstructor::primitive(Type::g1_element()),
88 );
89
90 prelude.types.insert(
92 well_known::G2_ELEMENT.to_string(),
93 TypeConstructor::primitive(Type::g2_element()),
94 );
95
96 prelude.types.insert(
98 well_known::MILLER_LOOP_RESULT.to_string(),
99 TypeConstructor::primitive(Type::miller_loop_result()),
100 );
101
102 prelude.types.insert(
104 well_known::ORDERING.to_string(),
105 TypeConstructor::primitive(Type::ordering()),
106 );
107 prelude.types_constructors.insert(
108 well_known::ORDERING.to_string(),
109 ValueConstructor::known_enum(
110 &mut prelude.values,
111 Type::ordering(),
112 well_known::ORDERING_CONSTRUCTORS,
113 ),
114 );
115
116 prelude.types.insert(
118 well_known::STRING.to_string(),
119 TypeConstructor::primitive(Type::string()),
120 );
121
122 prelude.types.insert(
124 well_known::VOID.to_string(),
125 TypeConstructor::primitive(Type::void()),
126 );
127 prelude.types_constructors.insert(
128 well_known::VOID.to_string(),
129 ValueConstructor::known_enum(
130 &mut prelude.values,
131 Type::void(),
132 well_known::VOID_CONSTRUCTORS,
133 ),
134 );
135
136 prelude.types.insert(
138 well_known::LIST.to_string(),
139 TypeConstructor::primitive(Type::list(Type::generic_var(id_gen.next()))),
140 );
141
142 let pair_left = Type::generic_var(id_gen.next());
144 let pair_right = Type::generic_var(id_gen.next());
145 prelude.types.insert(
146 well_known::PAIR.to_string(),
147 TypeConstructor::primitive(Type::pair(pair_left.clone(), pair_right.clone())),
148 );
149 prelude.types_constructors.insert(
150 well_known::PAIR.to_string(),
151 ValueConstructor::known_adt(
152 &mut prelude.values,
153 &[(
154 well_known::PAIR,
155 Type::function(
156 vec![pair_left.clone(), pair_right.clone()],
157 Type::pair(pair_left, pair_right),
158 ),
159 )],
160 ),
161 );
162
163 prelude.types.insert(
165 well_known::PAIRS.to_string(),
166 TypeConstructor::primitive(Type::map(
167 Type::generic_var(id_gen.next()),
168 Type::generic_var(id_gen.next()),
169 )),
170 );
171
172 let option_value = Type::generic_var(id_gen.next());
174 prelude.types.insert(
175 well_known::OPTION.to_string(),
176 TypeConstructor::primitive(Type::option(option_value.clone())),
177 );
178 let some_type = Type::function(
179 vec![option_value.clone()],
180 Type::option(option_value.clone()),
181 );
182 let none_type = Type::option(option_value);
183 prelude.types_constructors.insert(
184 well_known::OPTION.to_string(),
185 ValueConstructor::known_adt(
186 &mut prelude.values,
187 &[
188 (well_known::OPTION_CONSTRUCTORS[0], some_type),
189 (well_known::OPTION_CONSTRUCTORS[1], none_type),
190 ],
191 ),
192 );
193
194 prelude.types.insert(
196 well_known::NEVER.to_string(),
197 TypeConstructor::primitive(Type::never()),
198 );
199 prelude.types_constructors.insert(
200 well_known::NEVER.to_string(),
201 ValueConstructor::known_adt(
202 &mut prelude.values,
203 &[(well_known::NEVER_CONSTRUCTORS[1], Type::never())],
204 ),
205 );
206
207 prelude.types.insert(
209 well_known::SCRIPT_CONTEXT.to_string(),
210 TypeConstructor::primitive(Type::script_context()),
211 );
212 prelude.types_constructors.insert(
213 well_known::SCRIPT_CONTEXT.to_string(),
214 vec![
215 well_known::SCRIPT_CONTEXT_TRANSACTION.to_string(),
216 well_known::SCRIPT_CONTEXT_REDEEMER.to_string(),
217 well_known::SCRIPT_CONTEXT_PURPOSE.to_string(),
218 ],
219 );
220
221 prelude.types.insert(
223 well_known::SCRIPT_PURPOSE.to_string(),
224 TypeConstructor::primitive(Type::script_purpose()),
225 );
226
227 prelude.types_constructors.insert(
228 well_known::SCRIPT_PURPOSE.to_string(),
229 ValueConstructor::known_adt(
230 &mut prelude.values,
231 &[
232 (
233 well_known::SCRIPT_PURPOSE_MINT,
234 Type::function(vec![Type::data()], Type::script_purpose()),
235 ),
236 (
237 well_known::SCRIPT_PURPOSE_SPEND,
238 Type::function(
239 vec![Type::data(), Type::option(Type::data())],
240 Type::script_purpose(),
241 ),
242 ),
243 (
244 well_known::SCRIPT_PURPOSE_WITHDRAW,
245 Type::function(vec![Type::data()], Type::script_purpose()),
246 ),
247 (
248 well_known::SCRIPT_PURPOSE_PUBLISH,
249 Type::function(vec![Type::int(), Type::data()], Type::script_purpose()),
250 ),
251 (
252 well_known::SCRIPT_PURPOSE_VOTE,
253 Type::function(vec![Type::data()], Type::script_purpose()),
254 ),
255 (
256 well_known::SCRIPT_PURPOSE_PROPOSE,
257 Type::function(vec![Type::int(), Type::data()], Type::script_purpose()),
258 ),
259 ],
260 ),
261 );
262
263 prelude.values.insert(
265 "not".to_string(),
266 ValueConstructor::public(
267 Type::function(vec![Type::bool()], Type::bool()),
268 ValueConstructorVariant::ModuleFn {
269 name: "not".to_string(),
270 field_map: None,
271 module: "".to_string(),
272 arity: 1,
273 location: Span::empty(),
274 builtin: None,
275 },
276 ),
277 );
278
279 let identity_var = Type::generic_var(id_gen.next());
281 prelude.values.insert(
282 "identity".to_string(),
283 ValueConstructor::public(
284 Type::function(vec![identity_var.clone()], identity_var),
285 ValueConstructorVariant::ModuleFn {
286 name: "identity".to_string(),
287 field_map: None,
288 module: "".to_string(),
289 arity: 1,
290 location: Span::empty(),
291 builtin: None,
292 },
293 ),
294 );
295
296 prelude.values.insert(
298 "as_data".to_string(),
299 ValueConstructor::public(
300 Type::function(vec![Type::data()], Type::data()),
301 ValueConstructorVariant::ModuleFn {
302 name: "as_data".to_string(),
303 field_map: None,
304 module: "".to_string(),
305 arity: 1,
306 location: Span::empty(),
307 builtin: None,
308 },
309 ),
310 );
311
312 let enumerate_a = Type::generic_var(id_gen.next());
314 let enumerate_b = Type::generic_var(id_gen.next());
315 prelude.values.insert(
316 "enumerate".to_string(),
317 ValueConstructor::public(
318 Type::function(
319 vec![
320 Type::list(enumerate_a.clone()),
321 enumerate_b.clone(),
322 Type::function(
323 vec![enumerate_a.clone(), enumerate_b.clone()],
324 enumerate_b.clone(),
325 ),
326 Type::function(
327 vec![enumerate_a.clone(), enumerate_b.clone()],
328 enumerate_b.clone(),
329 ),
330 ],
331 enumerate_b,
332 ),
333 ValueConstructorVariant::ModuleFn {
334 name: "enumerate".to_string(),
335 field_map: None,
336 module: "".to_string(),
337 arity: 4,
338 location: Span::empty(),
339 builtin: None,
340 },
341 ),
342 );
343
344 prelude.values.insert(
346 "encode_base16".to_string(),
347 ValueConstructor::public(
348 Type::function(
349 vec![Type::byte_array(), Type::int(), Type::byte_array()],
350 Type::byte_array(),
351 ),
352 ValueConstructorVariant::ModuleFn {
353 name: "encode_base16".to_string(),
354 field_map: None,
355 module: "".to_string(),
356 arity: 3,
357 location: Span::empty(),
358 builtin: None,
359 },
360 ),
361 );
362
363 prelude.values.insert(
365 "from_int".to_string(),
366 ValueConstructor::public(
367 Type::function(vec![Type::int(), Type::byte_array()], Type::byte_array()),
368 ValueConstructorVariant::ModuleFn {
369 name: "from_int".to_string(),
370 field_map: None,
371 module: "".to_string(),
372 arity: 2,
373 location: Span::empty(),
374 builtin: None,
375 },
376 ),
377 );
378
379 prelude.values.insert(
381 "do_from_int".to_string(),
382 ValueConstructor::public(
383 Type::function(vec![Type::int(), Type::byte_array()], Type::byte_array()),
384 ValueConstructorVariant::ModuleFn {
385 name: "do_from_int".to_string(),
386 field_map: None,
387 module: "".to_string(),
388 arity: 2,
389 location: Span::empty(),
390 builtin: None,
391 },
392 ),
393 );
394
395 prelude.values.insert(
397 "diagnostic".to_string(),
398 ValueConstructor::public(
399 Type::function(vec![Type::data(), Type::byte_array()], Type::byte_array()),
400 ValueConstructorVariant::ModuleFn {
401 name: "diagnostic".to_string(),
402 field_map: None,
403 module: "".to_string(),
404 arity: 2,
405 location: Span::empty(),
406 builtin: None,
407 },
408 ),
409 );
410
411 let always_a_var = Type::generic_var(id_gen.next());
413 let always_b_var = Type::generic_var(id_gen.next());
414 prelude.values.insert(
415 "always".to_string(),
416 ValueConstructor::public(
417 Type::function(vec![always_a_var.clone(), always_b_var], always_a_var),
418 ValueConstructorVariant::ModuleFn {
419 name: "always".to_string(),
420 field_map: None,
421 module: "".to_string(),
422 arity: 2,
423 location: Span::empty(),
424 builtin: None,
425 },
426 ),
427 );
428
429 let tautology_var = Type::generic_var(id_gen.next());
431 prelude.values.insert(
432 "tautology".to_string(),
433 ValueConstructor::public(
434 Type::function(vec![tautology_var], Type::void()),
435 ValueConstructorVariant::ModuleFn {
436 name: "tautology".to_string(),
437 field_map: None,
438 module: "".to_string(),
439 arity: 1,
440 location: Span::empty(),
441 builtin: None,
442 },
443 ),
444 );
445
446 let flip_a_var = Type::generic_var(id_gen.next());
448 let flip_b_var = Type::generic_var(id_gen.next());
449 let flip_c_var = Type::generic_var(id_gen.next());
450
451 let input_type = Type::function(
452 vec![flip_a_var.clone(), flip_b_var.clone()],
453 flip_c_var.clone(),
454 );
455
456 let return_type = Type::function(vec![flip_b_var, flip_a_var], flip_c_var);
457
458 prelude.values.insert(
459 "flip".to_string(),
460 ValueConstructor::public(
461 Type::function(vec![input_type], return_type),
462 ValueConstructorVariant::ModuleFn {
463 name: "flip".to_string(),
464 field_map: None,
465 module: "".to_string(),
466 arity: 1,
467 location: Span::empty(),
468 builtin: None,
469 },
470 ),
471 );
472
473 prelude.types.insert(
480 well_known::PRNG.to_string(),
481 TypeConstructor::primitive(Type::prng()),
482 );
483
484 prelude.types_constructors.insert(
485 well_known::PRNG.to_string(),
486 vec!["Seeded".to_string(), "Replayed".to_string()],
487 );
488
489 let mut seeded_fields = HashMap::new();
490 seeded_fields.insert("seed".to_string(), (0, Span::empty()));
491 seeded_fields.insert("choices".to_string(), (1, Span::empty()));
492 prelude.values.insert(
493 "Seeded".to_string(),
494 ValueConstructor::public(
495 Type::function(vec![Type::byte_array(), Type::byte_array()], Type::prng()),
496 ValueConstructorVariant::Record {
497 module: "".into(),
498 name: "Seeded".to_string(),
499 field_map: Some(FieldMap {
500 arity: 2,
501 fields: seeded_fields,
502 is_function: false,
503 }),
504 arity: 2,
505 location: Span::empty(),
506 constructors_count: 2,
507 },
508 ),
509 );
510
511 let mut replayed_fields = HashMap::new();
512 replayed_fields.insert("cursor".to_string(), (0, Span::empty()));
513 replayed_fields.insert("choices".to_string(), (1, Span::empty()));
514 prelude.values.insert(
515 "Replayed".to_string(),
516 ValueConstructor::public(
517 Type::function(vec![Type::int(), Type::byte_array()], Type::prng()),
518 ValueConstructorVariant::Record {
519 module: "".into(),
520 name: "Replayed".to_string(),
521 field_map: Some(FieldMap {
522 arity: 2,
523 fields: replayed_fields,
524 is_function: false,
525 }),
526 arity: 2,
527 location: Span::empty(),
528 constructors_count: 2,
529 },
530 ),
531 );
532
533 let fuzzer_generic = Type::generic_var(id_gen.next());
538 prelude.types.insert(
539 well_known::FUZZER.to_string(),
540 TypeConstructor {
541 location: Span::empty(),
542 parameters: vec![fuzzer_generic.clone()],
543 tipo: Type::fuzzer(fuzzer_generic),
544 module: "".to_string(),
545 public: true,
546 },
547 );
548
549 let sampler_generic = Type::generic_var(id_gen.next());
554 prelude.types.insert(
555 well_known::SAMPLER.to_string(),
556 TypeConstructor {
557 location: Span::empty(),
558 parameters: vec![sampler_generic.clone()],
559 tipo: Type::sampler(sampler_generic),
560 module: "".to_string(),
561 public: true,
562 },
563 );
564
565 prelude
566}
567
568pub fn plutus(id_gen: &IdGenerator) -> TypeInfo {
569 let mut plutus = TypeInfo {
570 name: BUILTIN.to_string(),
571 package: "".to_string(),
572 kind: ModuleKind::Lib,
573 types: HashMap::new(),
574 types_constructors: HashMap::new(),
575 values: HashMap::new(),
576 accessors: HashMap::new(),
577 annotations: HashMap::new(),
578 };
579
580 for builtin in DefaultFunction::iter() {
581 let value = from_default_function(builtin, id_gen);
582 plutus.values.insert(builtin.aiken_name(), value);
583 }
584
585 let index_tipo = Type::function(vec![Type::data()], Type::int());
586 plutus.values.insert(
587 "unconstr_index".to_string(),
588 ValueConstructor::public(
589 index_tipo,
590 ValueConstructorVariant::ModuleFn {
591 name: "unconstr_index".to_string(),
592 field_map: None,
593 module: BUILTIN.to_string(),
594 arity: 1,
595 location: Span::empty(),
596 builtin: None,
597 },
598 ),
599 );
600
601 let fields_tipo = Type::function(vec![Type::data()], Type::list(Type::data()));
602 plutus.values.insert(
603 "unconstr_fields".to_string(),
604 ValueConstructor::public(
605 fields_tipo,
606 ValueConstructorVariant::ModuleFn {
607 name: "unconstr_fields".to_string(),
608 field_map: None,
609 module: BUILTIN.to_string(),
610 arity: 1,
611 location: Span::empty(),
612 builtin: None,
613 },
614 ),
615 );
616
617 plutus
618}
619
620pub fn from_default_function(builtin: DefaultFunction, id_gen: &IdGenerator) -> ValueConstructor {
621 let (tipo, arity) = match builtin {
622 DefaultFunction::AddInteger
623 | DefaultFunction::SubtractInteger
624 | DefaultFunction::MultiplyInteger
625 | DefaultFunction::DivideInteger
626 | DefaultFunction::QuotientInteger
627 | DefaultFunction::RemainderInteger
628 | DefaultFunction::ModInteger => {
629 let tipo = Type::function(vec![Type::int(), Type::int()], Type::int());
630 (tipo, 2)
631 }
632
633 DefaultFunction::EqualsInteger
634 | DefaultFunction::LessThanInteger
635 | DefaultFunction::LessThanEqualsInteger => {
636 let tipo = Type::function(vec![Type::int(), Type::int()], Type::bool());
637
638 (tipo, 2)
639 }
640 DefaultFunction::AppendByteString => {
641 let tipo = Type::function(
642 vec![Type::byte_array(), Type::byte_array()],
643 Type::byte_array(),
644 );
645
646 (tipo, 2)
647 }
648 DefaultFunction::ConsByteString => {
649 let tipo = Type::function(vec![Type::int(), Type::byte_array()], Type::byte_array());
650
651 (tipo, 2)
652 }
653 DefaultFunction::SliceByteString => {
654 let tipo = Type::function(
655 vec![Type::int(), Type::int(), Type::byte_array()],
656 Type::byte_array(),
657 );
658
659 (tipo, 3)
660 }
661 DefaultFunction::LengthOfByteString => {
662 let tipo = Type::function(vec![Type::byte_array()], Type::int());
663
664 (tipo, 1)
665 }
666 DefaultFunction::IndexByteString => {
667 let tipo = Type::function(vec![Type::byte_array(), Type::int()], Type::int());
668
669 (tipo, 2)
670 }
671 DefaultFunction::EqualsByteString
672 | DefaultFunction::LessThanByteString
673 | DefaultFunction::LessThanEqualsByteString => {
674 let tipo = Type::function(vec![Type::byte_array(), Type::byte_array()], Type::bool());
675
676 (tipo, 2)
677 }
678 DefaultFunction::Sha2_256
679 | DefaultFunction::Sha3_256
680 | DefaultFunction::Blake2b_224
681 | DefaultFunction::Blake2b_256
682 | DefaultFunction::Keccak_256 => {
683 let tipo = Type::function(vec![Type::byte_array()], Type::byte_array());
684
685 (tipo, 1)
686 }
687
688 DefaultFunction::VerifyEd25519Signature => {
689 let tipo = Type::function(
690 vec![Type::byte_array(), Type::byte_array(), Type::byte_array()],
691 Type::bool(),
692 );
693
694 (tipo, 3)
695 }
696
697 DefaultFunction::VerifyEcdsaSecp256k1Signature => {
698 let tipo = Type::function(
699 vec![Type::byte_array(), Type::byte_array(), Type::byte_array()],
700 Type::bool(),
701 );
702
703 (tipo, 3)
704 }
705 DefaultFunction::VerifySchnorrSecp256k1Signature => {
706 let tipo = Type::function(
707 vec![Type::byte_array(), Type::byte_array(), Type::byte_array()],
708 Type::bool(),
709 );
710
711 (tipo, 3)
712 }
713
714 DefaultFunction::AppendString => {
715 let tipo = Type::function(vec![Type::string(), Type::string()], Type::string());
716
717 (tipo, 2)
718 }
719 DefaultFunction::EqualsString => {
720 let tipo = Type::function(vec![Type::string(), Type::string()], Type::bool());
721
722 (tipo, 2)
723 }
724 DefaultFunction::EncodeUtf8 => {
725 let tipo = Type::function(vec![Type::string()], Type::byte_array());
726
727 (tipo, 1)
728 }
729 DefaultFunction::DecodeUtf8 => {
730 let tipo = Type::function(vec![Type::byte_array()], Type::string());
731
732 (tipo, 1)
733 }
734 DefaultFunction::IfThenElse => {
735 let ret = Type::generic_var(id_gen.next());
736
737 let tipo = Type::function(vec![Type::bool(), ret.clone(), ret.clone()], ret);
738
739 (tipo, 3)
740 }
741 DefaultFunction::HeadList => {
742 let ret = Type::generic_var(id_gen.next());
743
744 let tipo = Type::function(vec![Type::list(ret.clone())], ret);
745
746 (tipo, 1)
747 }
748 DefaultFunction::TailList => {
749 let ret = Type::list(Type::generic_var(id_gen.next()));
750
751 let tipo = Type::function(vec![ret.clone()], ret);
752
753 (tipo, 1)
754 }
755 DefaultFunction::NullList => {
756 let ret = Type::list(Type::generic_var(id_gen.next()));
757
758 let tipo = Type::function(vec![ret], Type::bool());
759
760 (tipo, 1)
761 }
762 DefaultFunction::ConstrData => {
763 let tipo = Type::function(vec![Type::int(), Type::list(Type::data())], Type::data());
764
765 (tipo, 2)
766 }
767 DefaultFunction::MapData => {
768 let tipo = Type::function(
769 vec![Type::list(Type::pair(Type::data(), Type::data()))],
770 Type::data(),
771 );
772
773 (tipo, 1)
774 }
775 DefaultFunction::ListData => {
776 let tipo = Type::function(vec![Type::list(Type::data())], Type::data());
777
778 (tipo, 1)
779 }
780 DefaultFunction::IData => {
781 let tipo = Type::function(vec![Type::int()], Type::data());
782
783 (tipo, 1)
784 }
785 DefaultFunction::BData => {
786 let tipo = Type::function(vec![Type::byte_array()], Type::data());
787
788 (tipo, 1)
789 }
790 DefaultFunction::UnConstrData => {
791 let tipo = Type::function(
792 vec![Type::data()],
793 Type::pair(Type::int(), Type::list(Type::data())),
794 );
795
796 (tipo, 1)
797 }
798 DefaultFunction::UnMapData => {
799 let tipo = Type::function(
800 vec![Type::data()],
801 Type::list(Type::pair(Type::data(), Type::data())),
802 );
803
804 (tipo, 1)
805 }
806 DefaultFunction::UnListData => {
807 let tipo = Type::function(vec![Type::data()], Type::list(Type::data()));
808
809 (tipo, 1)
810 }
811 DefaultFunction::UnIData => {
812 let tipo = Type::function(vec![Type::data()], Type::int());
813
814 (tipo, 1)
815 }
816 DefaultFunction::UnBData => {
817 let tipo = Type::function(vec![Type::data()], Type::byte_array());
818
819 (tipo, 1)
820 }
821 DefaultFunction::EqualsData => {
822 let tipo = Type::function(vec![Type::data(), Type::data()], Type::bool());
823
824 (tipo, 2)
825 }
826 DefaultFunction::SerialiseData => {
827 let tipo = Type::function(vec![Type::data()], Type::byte_array());
828
829 (tipo, 1)
830 }
831 DefaultFunction::ChooseData => {
832 let a = Type::generic_var(id_gen.next());
833 let tipo = Type::function(
834 vec![
835 Type::data(),
836 a.clone(),
837 a.clone(),
838 a.clone(),
839 a.clone(),
840 a.clone(),
841 ],
842 a,
843 );
844 (tipo, 6)
845 }
846 DefaultFunction::MkPairData => {
847 let tipo = Type::function(
848 vec![Type::data(), Type::data()],
849 Type::pair(Type::data(), Type::data()),
850 );
851 (tipo, 2)
852 }
853 DefaultFunction::MkNilData => {
854 let tipo = Type::function(vec![], Type::list(Type::data()));
855 (tipo, 0)
856 }
857 DefaultFunction::MkNilPairData => {
858 let tipo = Type::function(vec![], Type::list(Type::pair(Type::data(), Type::data())));
859 (tipo, 0)
860 }
861 DefaultFunction::ChooseUnit => {
862 let a = Type::generic_var(id_gen.next());
863 let tipo = Type::function(vec![Type::data(), a.clone()], a);
864 (tipo, 2)
865 }
866 DefaultFunction::Trace => {
867 let a = Type::generic_var(id_gen.next());
868 let tipo = Type::function(vec![Type::string(), a.clone()], a);
869 (tipo, 2)
870 }
871 DefaultFunction::FstPair => {
872 let a = Type::generic_var(id_gen.next());
873 let b = Type::generic_var(id_gen.next());
874 let tipo = Type::function(vec![Type::pair(a.clone(), b)], a);
875 (tipo, 1)
876 }
877 DefaultFunction::SndPair => {
878 let a = Type::generic_var(id_gen.next());
879 let b = Type::generic_var(id_gen.next());
880 let tipo = Type::function(vec![Type::pair(a, b.clone())], b);
881 (tipo, 1)
882 }
883 DefaultFunction::ChooseList => {
884 let a = Type::generic_var(id_gen.next());
885 let b = Type::generic_var(id_gen.next());
886 let tipo = Type::function(vec![Type::list(a), b.clone(), b.clone()], b);
887 (tipo, 3)
888 }
889 DefaultFunction::MkCons => {
890 let a = Type::generic_var(id_gen.next());
891 let tipo = Type::function(vec![a.clone(), Type::list(a.clone())], Type::list(a));
892 (tipo, 2)
893 }
894 DefaultFunction::Bls12_381_G1_Add => {
895 let tipo = Type::function(
896 vec![Type::g1_element(), Type::g1_element()],
897 Type::g1_element(),
898 );
899
900 (tipo, 2)
901 }
902 DefaultFunction::Bls12_381_G1_Equal => {
903 let tipo = Type::function(vec![Type::g1_element(), Type::g1_element()], Type::bool());
904
905 (tipo, 2)
906 }
907 DefaultFunction::Bls12_381_G1_Neg => {
908 let tipo = Type::function(vec![Type::g1_element()], Type::g1_element());
909
910 (tipo, 1)
911 }
912 DefaultFunction::Bls12_381_G1_ScalarMul => {
913 let tipo = Type::function(vec![Type::int(), Type::g1_element()], Type::g1_element());
914
915 (tipo, 2)
916 }
917 DefaultFunction::Bls12_381_G1_Compress => {
918 let tipo = Type::function(vec![Type::g1_element()], Type::byte_array());
919
920 (tipo, 1)
921 }
922 DefaultFunction::Bls12_381_G1_Uncompress => {
923 let tipo = Type::function(vec![Type::byte_array()], Type::g1_element());
924
925 (tipo, 1)
926 }
927 DefaultFunction::Bls12_381_G1_HashToGroup => {
928 let tipo = Type::function(
929 vec![Type::byte_array(), Type::byte_array()],
930 Type::g1_element(),
931 );
932
933 (tipo, 2)
934 }
935
936 DefaultFunction::Bls12_381_G2_Add => {
937 let tipo = Type::function(
938 vec![Type::g2_element(), Type::g2_element()],
939 Type::g2_element(),
940 );
941
942 (tipo, 2)
943 }
944 DefaultFunction::Bls12_381_G2_Equal => {
945 let tipo = Type::function(vec![Type::g2_element(), Type::g2_element()], Type::bool());
946
947 (tipo, 2)
948 }
949 DefaultFunction::Bls12_381_G2_Neg => {
950 let tipo = Type::function(vec![Type::g2_element()], Type::g2_element());
951
952 (tipo, 1)
953 }
954 DefaultFunction::Bls12_381_G2_ScalarMul => {
955 let tipo = Type::function(vec![Type::int(), Type::g2_element()], Type::g2_element());
956
957 (tipo, 2)
958 }
959 DefaultFunction::Bls12_381_G2_Compress => {
960 let tipo = Type::function(vec![Type::g2_element()], Type::byte_array());
961
962 (tipo, 1)
963 }
964 DefaultFunction::Bls12_381_G2_Uncompress => {
965 let tipo = Type::function(vec![Type::byte_array()], Type::g2_element());
966
967 (tipo, 1)
968 }
969 DefaultFunction::Bls12_381_G2_HashToGroup => {
970 let tipo = Type::function(
971 vec![Type::byte_array(), Type::byte_array()],
972 Type::g2_element(),
973 );
974
975 (tipo, 2)
976 }
977 DefaultFunction::Bls12_381_MillerLoop => {
978 let tipo = Type::function(
979 vec![Type::g1_element(), Type::g2_element()],
980 Type::miller_loop_result(),
981 );
982
983 (tipo, 2)
984 }
985 DefaultFunction::Bls12_381_MulMlResult => {
986 let tipo = Type::function(
987 vec![Type::miller_loop_result(), Type::miller_loop_result()],
988 Type::miller_loop_result(),
989 );
990
991 (tipo, 2)
992 }
993 DefaultFunction::Bls12_381_FinalVerify => {
994 let tipo = Type::function(
995 vec![Type::miller_loop_result(), Type::miller_loop_result()],
996 Type::bool(),
997 );
998
999 (tipo, 2)
1000 }
1001 DefaultFunction::IntegerToByteString => {
1002 let tipo = Type::function(
1003 vec![Type::bool(), Type::int(), Type::int()],
1004 Type::byte_array(),
1005 );
1006
1007 (tipo, 3)
1008 }
1009 DefaultFunction::ByteStringToInteger => {
1010 let tipo = Type::function(vec![Type::bool(), Type::byte_array()], Type::int());
1011
1012 (tipo, 2)
1013 }
1014 DefaultFunction::AndByteString => {
1015 let tipo = Type::function(
1016 vec![Type::bool(), Type::byte_array(), Type::byte_array()],
1017 Type::byte_array(),
1018 );
1019
1020 (tipo, 3)
1021 }
1022 DefaultFunction::OrByteString => {
1023 let tipo = Type::function(
1024 vec![Type::bool(), Type::byte_array(), Type::byte_array()],
1025 Type::byte_array(),
1026 );
1027
1028 (tipo, 3)
1029 }
1030 DefaultFunction::XorByteString => {
1031 let tipo = Type::function(
1032 vec![Type::bool(), Type::byte_array(), Type::byte_array()],
1033 Type::byte_array(),
1034 );
1035
1036 (tipo, 3)
1037 }
1038 DefaultFunction::ComplementByteString => {
1039 let tipo = Type::function(vec![Type::byte_array()], Type::byte_array());
1040
1041 (tipo, 1)
1042 }
1043 DefaultFunction::ReadBit => {
1044 let tipo = Type::function(vec![Type::byte_array(), Type::int()], Type::bool());
1045
1046 (tipo, 2)
1047 }
1048 DefaultFunction::WriteBits => {
1049 let tipo = Type::function(
1050 vec![Type::byte_array(), Type::list(Type::int()), Type::bool()],
1051 Type::byte_array(),
1052 );
1053
1054 (tipo, 3)
1055 }
1056 DefaultFunction::ReplicateByte => {
1057 let tipo = Type::function(vec![Type::int(), Type::int()], Type::byte_array());
1058
1059 (tipo, 2)
1060 }
1061 DefaultFunction::ShiftByteString => {
1062 let tipo = Type::function(vec![Type::byte_array(), Type::int()], Type::byte_array());
1063
1064 (tipo, 2)
1065 }
1066 DefaultFunction::RotateByteString => {
1067 let tipo = Type::function(vec![Type::byte_array(), Type::int()], Type::byte_array());
1068
1069 (tipo, 2)
1070 }
1071 DefaultFunction::CountSetBits => {
1072 let tipo = Type::function(vec![Type::byte_array()], Type::int());
1073
1074 (tipo, 1)
1075 }
1076 DefaultFunction::FindFirstSetBit => {
1077 let tipo = Type::function(vec![Type::byte_array()], Type::int());
1078
1079 (tipo, 1)
1080 }
1081 DefaultFunction::Ripemd_160 => {
1082 let tipo = Type::function(vec![Type::byte_array()], Type::byte_array());
1083
1084 (tipo, 1)
1085 } };
1091
1092 ValueConstructor::public(
1093 tipo,
1094 ValueConstructorVariant::ModuleFn {
1095 name: builtin.aiken_name(),
1096 field_map: None,
1097 module: "".to_string(),
1098 arity,
1099 location: Span::empty(),
1100 builtin: Some(builtin),
1101 },
1102 )
1103}
1104
1105pub fn prelude_functions(
1106 id_gen: &IdGenerator,
1107 module_types: &HashMap<String, TypeInfo>,
1108) -> IndexMap<FunctionAccessKey, TypedFunction> {
1109 let mut functions = IndexMap::new();
1110
1111 let unconstr_index_body = TypedExpr::Call {
1112 location: Span::empty(),
1113 tipo: Type::int(),
1114 fun: TypedExpr::local_var(
1115 CONSTR_INDEX_EXPOSER,
1116 Type::function(vec![Type::data()], Type::int()),
1117 Span::empty(),
1118 )
1119 .into(),
1120 args: vec![CallArg {
1121 label: None,
1122 location: Span::empty(),
1123 value: TypedExpr::Var {
1124 location: Span::empty(),
1125 constructor: ValueConstructor {
1126 public: true,
1127 tipo: Type::data(),
1128 variant: ValueConstructorVariant::LocalVariable {
1129 location: Span::empty(),
1130 },
1131 },
1132 name: "constr".to_string(),
1133 },
1134 }],
1135 };
1136
1137 let unconstr_index_func = Function {
1138 arguments: vec![TypedArg {
1139 arg_name: ArgName::Named {
1140 name: "constr".to_string(),
1141 label: "constr".to_string(),
1142 location: Span::empty(),
1143 },
1144 is_validator_param: false,
1145 doc: None,
1146 location: Span::empty(),
1147 annotation: None,
1148 tipo: Type::data(),
1149 }],
1150 on_test_failure: OnTestFailure::FailImmediately,
1151 doc: Some(
1152 indoc::indoc! {
1153 r#"
1154 /// Access the index of a constr typed as Data. Fails if the Data object is not a constr.
1155 "#
1156 }.to_string()
1157 ),
1158 location: Span::empty(),
1159 name: "unconstr_index".to_string(),
1160 public: true,
1161 return_annotation: None,
1162 return_type: Type::int(),
1163 end_position: 0,
1164 body: unconstr_index_body,
1165 };
1166
1167 functions.insert(
1168 FunctionAccessKey {
1169 module_name: BUILTIN.to_string(),
1170 function_name: "unconstr_index".to_string(),
1171 },
1172 unconstr_index_func,
1173 );
1174
1175 let unconstr_fields_body = TypedExpr::Call {
1176 location: Span::empty(),
1177 tipo: Type::list(Type::data()),
1178 fun: TypedExpr::local_var(
1179 CONSTR_FIELDS_EXPOSER,
1180 Type::function(vec![Type::data()], Type::list(Type::data())),
1181 Span::empty(),
1182 )
1183 .into(),
1184 args: vec![CallArg {
1185 label: None,
1186 location: Span::empty(),
1187 value: TypedExpr::Var {
1188 location: Span::empty(),
1189 constructor: ValueConstructor {
1190 public: true,
1191 tipo: Type::data(),
1192 variant: ValueConstructorVariant::LocalVariable {
1193 location: Span::empty(),
1194 },
1195 },
1196 name: "constr".to_string(),
1197 },
1198 }],
1199 };
1200
1201 let unconstr_fields_func = Function {
1202 arguments: vec![TypedArg {
1203 arg_name: ArgName::Named {
1204 name: "constr".to_string(),
1205 label: "constr".to_string(),
1206 location: Span::empty(),
1207 },
1208 is_validator_param: false,
1209 doc: None,
1210 location: Span::empty(),
1211 annotation: None,
1212 tipo: Type::data(),
1213 }],
1214 on_test_failure: OnTestFailure::FailImmediately,
1215 doc: Some(
1216 indoc::indoc! {
1217 r#"
1218 /// Access the fields of a constr typed as Data. Fails if the Data object is not a constr.
1219 "#
1220 }.to_string()
1221 ),
1222 location: Span::empty(),
1223 name: "unconstr_fields".to_string(),
1224 public: true,
1225 return_annotation: None,
1226 return_type: Type::list(Type::data()),
1227 end_position: 0,
1228 body: unconstr_fields_body,
1229 };
1230
1231 functions.insert(
1232 FunctionAccessKey {
1233 module_name: BUILTIN.to_string(),
1234 function_name: "unconstr_fields".to_string(),
1235 },
1236 unconstr_fields_func,
1237 );
1238
1239 functions.insert(
1240 FunctionAccessKey {
1241 module_name: "".to_string(),
1242 function_name: "as_data".to_string(),
1243 },
1244 Function {
1245 arguments: vec![TypedArg {
1246 arg_name: ArgName::Named {
1247 name: "data".to_string(),
1248 label: "data".to_string(),
1249 location: Span::empty(),
1250 },
1251 is_validator_param: false,
1252 location: Span::empty(),
1253 annotation: None,
1254 doc: None,
1255 tipo: Type::data(),
1256 }],
1257 on_test_failure: OnTestFailure::FailImmediately,
1258 body: TypedExpr::Var {
1259 location: Span::empty(),
1260 constructor: ValueConstructor {
1261 public: true,
1262 tipo: Type::data(),
1263 variant: ValueConstructorVariant::LocalVariable {
1264 location: Span::empty(),
1265 },
1266 },
1267 name: "data".to_string(),
1268 },
1269 doc: Some(
1270 indoc::indoc! {
1271 r#"
1272 A function for explicitly upcasting any serialisable type into `Data`.
1273 "#
1274 }
1275 .to_string(),
1276 ),
1277 location: Span::empty(),
1278 name: "as_data".to_string(),
1279 public: true,
1280 return_annotation: None,
1281 return_type: Type::data(),
1282 end_position: 0,
1283 },
1284 );
1285
1286 functions.insert(
1291 FunctionAccessKey {
1292 module_name: "".to_string(),
1293 function_name: "not".to_string(),
1294 },
1295 Function {
1296 arguments: vec![TypedArg {
1297 arg_name: ArgName::Named {
1298 name: "self".to_string(),
1299 label: "self".to_string(),
1300 location: Span::empty(),
1301 },
1302 is_validator_param: false,
1303 doc: None,
1304 location: Span::empty(),
1305 annotation: None,
1306 tipo: Type::bool(),
1307 }],
1308 on_test_failure: OnTestFailure::FailImmediately,
1309 doc: Some(
1310 indoc::indoc! {
1311 r#"
1312 /// Like `!`, but as a function. Handy for chaining using the pipe operator `|>` or to pass as a function.
1313 "#
1314 }.to_string()
1315 ),
1316 location: Span::empty(),
1317 name: "not".to_string(),
1318 public: true,
1319 return_annotation: None,
1320 return_type: Type::bool(),
1321 end_position: 0,
1322 body: TypedExpr::UnOp {
1323 location: Span::empty(),
1324 tipo: Type::bool(),
1325 op: UnOp::Not,
1326 value: Box::new(TypedExpr::Var {
1327 location: Span::empty(),
1328 constructor: ValueConstructor {
1329 public: true,
1330 tipo: Type::bool(),
1331 variant: ValueConstructorVariant::LocalVariable {
1332 location: Span::empty(),
1333 },
1334 },
1335 name: "self".to_string(),
1336 }),
1337 },
1338 },
1339 );
1340
1341 let a_var = Type::generic_var(id_gen.next());
1346
1347 functions.insert(
1348 FunctionAccessKey {
1349 module_name: "".to_string(),
1350 function_name: "identity".to_string(),
1351 },
1352 Function {
1353 arguments: vec![TypedArg {
1354 arg_name: ArgName::Named {
1355 name: "a".to_string(),
1356 label: "a".to_string(),
1357 location: Span::empty(),
1358 },
1359 is_validator_param: false,
1360 location: Span::empty(),
1361 annotation: None,
1362 doc: None,
1363 tipo: a_var.clone(),
1364 }],
1365 on_test_failure: OnTestFailure::FailImmediately,
1366 body: TypedExpr::Var {
1367 location: Span::empty(),
1368 constructor: ValueConstructor {
1369 public: true,
1370 tipo: a_var.clone(),
1371 variant: ValueConstructorVariant::LocalVariable {
1372 location: Span::empty(),
1373 },
1374 },
1375 name: "a".to_string(),
1376 },
1377 doc: Some(
1378 indoc::indoc! {
1379 r#"
1380 A function that returns its argument. Handy as a default behavior sometimes.
1381 "#
1382 }
1383 .to_string(),
1384 ),
1385 location: Span::empty(),
1386 name: "identity".to_string(),
1387 public: true,
1388 return_annotation: None,
1389 return_type: a_var,
1390 end_position: 0,
1391 },
1392 );
1393
1394 let a_var = Type::generic_var(id_gen.next());
1399 let b_var = Type::generic_var(id_gen.next());
1400
1401 functions.insert(
1402 FunctionAccessKey {
1403 module_name: "".to_string(),
1404 function_name: "always".to_string(),
1405 },
1406 Function {
1407 on_test_failure: OnTestFailure::FailImmediately,
1408 arguments: vec![
1409 TypedArg {
1410 arg_name: ArgName::Named {
1411 name: "a".to_string(),
1412 label: "a".to_string(),
1413 location: Span::empty(),
1414 },
1415 is_validator_param: false,
1416 location: Span::empty(),
1417 annotation: None,
1418 doc: None,
1419 tipo: a_var.clone(),
1420 },
1421 TypedArg {
1422 arg_name: ArgName::Discarded {
1423 name: "_b".to_string(),
1424 label: "_b".to_string(),
1425 location: Span::empty(),
1426 },
1427 is_validator_param: false,
1428 location: Span::empty(),
1429 annotation: None,
1430 doc: None,
1431 tipo: b_var,
1432 },
1433 ],
1434 body: TypedExpr::Var {
1435 location: Span::empty(),
1436 constructor: ValueConstructor {
1437 public: true,
1438 tipo: a_var.clone(),
1439 variant: ValueConstructorVariant::LocalVariable {
1440 location: Span::empty(),
1441 },
1442 },
1443 name: "a".to_string(),
1444 },
1445 doc: Some(
1446 indoc::indoc! {
1447 r#"
1448 A function that always return its first argument. Handy in folds and maps.
1449
1450 ```aiken
1451 let always_14 = always(14, _)
1452 always_14(42) == 14
1453 always_14(1337) == 14
1454 always_14(0) == 14
1455 ```
1456 "#
1457 }
1458 .to_string(),
1459 ),
1460 location: Span::empty(),
1461 name: "always".to_string(),
1462 public: true,
1463 return_annotation: None,
1464 return_type: a_var,
1465 end_position: 0,
1466 },
1467 );
1468
1469 functions.insert(
1475 FunctionAccessKey {
1476 module_name: "".to_string(),
1477 function_name: "tautology".to_string(),
1478 },
1479 aiken_fn!(
1480 &module_types,
1481 &id_gen,
1482 r#"
1483 pub fn tautology(a: a) -> Bool {
1484 a == a
1485 }
1486 "#
1487 ),
1488 );
1489
1490 functions.insert(
1496 FunctionAccessKey {
1497 module_name: "".to_string(),
1498 function_name: "tautology".to_string(),
1499 },
1500 aiken_fn!(
1501 &module_types,
1502 &id_gen,
1503 r#"
1504 pub fn tautology(a: a) -> Bool {
1505 a == a
1506 }
1507 "#
1508 ),
1509 );
1510
1511 let a_var = Type::generic_var(id_gen.next());
1516 let b_var = Type::generic_var(id_gen.next());
1517 let c_var = Type::generic_var(id_gen.next());
1518
1519 let input_type = Type::function(vec![a_var.clone(), b_var.clone()], c_var.clone());
1520 let return_type = Type::function(vec![b_var.clone(), a_var.clone()], c_var.clone());
1521
1522 functions.insert(
1523 FunctionAccessKey {
1524 module_name: "".to_string(),
1525 function_name: "flip".to_string(),
1526 },
1527 Function {
1528 on_test_failure: OnTestFailure::FailImmediately,
1529 arguments: vec![TypedArg {
1530 arg_name: ArgName::Named {
1531 name: "f".to_string(),
1532 label: "f".to_string(),
1533 location: Span::empty(),
1534 },
1535 is_validator_param: false,
1536 location: Span::empty(),
1537 annotation: None,
1538 doc: None,
1539 tipo: input_type.clone(),
1540 }],
1541 body: TypedExpr::Fn {
1542 location: Span::empty(),
1543 tipo: return_type.clone(),
1544 is_capture: false,
1545 args: vec![
1546 TypedArg {
1547 arg_name: ArgName::Named {
1548 name: "b".to_string(),
1549 label: "b".to_string(),
1550 location: Span::empty(),
1551 },
1552 is_validator_param: false,
1553 location: Span::empty(),
1554 annotation: None,
1555 doc: None,
1556 tipo: b_var.clone(),
1557 },
1558 TypedArg {
1559 arg_name: ArgName::Named {
1560 name: "a".to_string(),
1561 label: "a".to_string(),
1562 location: Span::empty(),
1563 },
1564 is_validator_param: false,
1565 location: Span::empty(),
1566 annotation: None,
1567 doc: None,
1568 tipo: a_var.clone(),
1569 },
1570 ],
1571 body: Box::new(TypedExpr::Call {
1572 location: Span::empty(),
1573 tipo: c_var,
1574 fun: Box::new(TypedExpr::Var {
1575 location: Span::empty(),
1576 constructor: ValueConstructor {
1577 public: true,
1578 tipo: input_type,
1579 variant: ValueConstructorVariant::LocalVariable {
1580 location: Span::empty(),
1581 },
1582 },
1583 name: "f".to_string(),
1584 }),
1585 args: vec![
1586 CallArg {
1587 label: None,
1588 location: Span::empty(),
1589 value: TypedExpr::Var {
1590 location: Span::empty(),
1591 constructor: ValueConstructor {
1592 public: true,
1593 tipo: a_var,
1594 variant: ValueConstructorVariant::LocalVariable {
1595 location: Span::empty(),
1596 },
1597 },
1598 name: "a".to_string(),
1599 },
1600 },
1601 CallArg {
1602 label: None,
1603 location: Span::empty(),
1604 value: TypedExpr::Var {
1605 location: Span::empty(),
1606 constructor: ValueConstructor {
1607 public: true,
1608 tipo: b_var,
1609 variant: ValueConstructorVariant::LocalVariable {
1610 location: Span::empty(),
1611 },
1612 },
1613 name: "b".to_string(),
1614 },
1615 },
1616 ],
1617 }),
1618 return_annotation: None,
1619 },
1620 doc: Some(
1621 indoc::indoc! {
1622 r#"
1623 A function that flips the arguments of a function.
1624
1625 ```aiken
1626 pub fn titleize(left: String, right: String) {}
1627
1628 titleize("Hello", "World") // "Hello, World!"
1629
1630 flip(titleize)("Hello", "World") // "World, Hello!"
1631 ```
1632 "#
1633 }
1634 .to_string(),
1635 ),
1636 location: Span::empty(),
1637 name: "flip".to_string(),
1638 public: true,
1639 return_annotation: None,
1640 return_type,
1641 end_position: 0,
1642 },
1643 );
1644
1645 functions.insert(
1646 FunctionAccessKey {
1647 module_name: "".to_string(),
1648 function_name: "enumerate".to_string(),
1649 },
1650 aiken_fn!(
1651 &module_types,
1652 &id_gen,
1653 r#"
1654 fn enumerate(
1655 self: List<a>,
1656 zero: b,
1657 with: fn(a, b) -> b,
1658 last: fn(a, b) -> b,
1659 ) -> b {
1660 when self is {
1661 [] -> zero
1662 [x] -> last(x, zero)
1663 [x, ..xs] -> with(x, enumerate(xs, zero, with, last))
1664 }
1665 }
1666 "#
1667 ),
1668 );
1669
1670 functions.insert(
1671 FunctionAccessKey {
1672 module_name: "".to_string(),
1673 function_name: "encode_base16".to_string(),
1674 },
1675 aiken_fn!(
1676 &module_types,
1677 &id_gen,
1678 r#"
1679 use aiken/builtin
1680
1681 fn encode_base16(bytes: ByteArray, ix: Int, builder: ByteArray) -> ByteArray {
1682 if ix < 0 {
1683 builder
1684 } else {
1685 let byte = builtin.index_bytearray(bytes, ix)
1686 let msb = byte / 16
1687 let lsb = byte % 16
1688 let builder =
1689 builtin.cons_bytearray(
1690 msb + if msb < 10 {
1691 48
1692 } else {
1693 55
1694 },
1695 builtin.cons_bytearray(
1696 lsb + if lsb < 10 {
1697 48
1698 } else {
1699 55
1700 },
1701 builder,
1702 ),
1703 )
1704 encode_base16(bytes, ix - 1, builder)
1705 }
1706 }
1707 "#
1708 ),
1709 );
1710
1711 functions.insert(
1712 FunctionAccessKey {
1713 module_name: "".to_string(),
1714 function_name: "do_from_int".to_string(),
1715 },
1716 aiken_fn!(
1717 &module_types,
1718 &id_gen,
1719 r#"
1720 use aiken/builtin
1721
1722 fn do_from_int(i: Int, digits: ByteArray) -> ByteArray {
1723 if i <= 0 {
1724 digits
1725 } else {
1726 do_from_int(
1727 builtin.quotient_integer(i, 10),
1728 builtin.cons_bytearray(builtin.remainder_integer(i, 10) + 48, digits),
1729 )
1730 }
1731 }
1732 "#
1733 ),
1734 );
1735
1736 functions.insert(
1737 FunctionAccessKey {
1738 module_name: "".to_string(),
1739 function_name: "from_int".to_string(),
1740 },
1741 aiken_fn!(
1742 &module_types,
1743 &id_gen,
1744 r#"
1745 use aiken/builtin
1746
1747 /// Encode an integer into UTF-8.
1748 fn from_int(i: Int, digits: ByteArray) -> ByteArray {
1749 if i == 0 {
1750 builtin.append_bytearray(#"30", digits)
1751 } else if i < 0 {
1752 builtin.append_bytearray(#"2d", from_int(-i, digits))
1753 } else {
1754 do_from_int(
1755 builtin.quotient_integer(i, 10),
1756 builtin.cons_bytearray(builtin.remainder_integer(i, 10) + 48, digits),
1757 )
1758 }
1759 }
1760 "#
1761 ),
1762 );
1763
1764 functions.insert(
1765 FunctionAccessKey {
1766 module_name: "".to_string(),
1767 function_name: "diagnostic".to_string(),
1768 },
1769 aiken_fn!(
1770 &module_types,
1771 &id_gen,
1772 r#"
1773 use aiken/builtin
1774
1775 fn diagnostic(self: Data, builder: ByteArray) -> ByteArray {
1776 builtin.choose_data(
1777 self,
1778 {
1779 let Pair(constr, fields) = builtin.un_constr_data(self)
1780
1781 let builder =
1782 when fields is {
1783 [] -> builtin.append_bytearray(#"5b5d29", builder)
1784 _ -> {
1785 let bytes =
1786 enumerate(
1787 fields,
1788 builtin.append_bytearray(#"5d29", builder),
1789 fn(e: Data, st: ByteArray) {
1790 diagnostic(e, builtin.append_bytearray(#"2c20", st))
1791 },
1792 fn(e: Data, st: ByteArray) { diagnostic(e, st) },
1793 )
1794 builtin.append_bytearray(#"5b5f20", bytes)
1795 }
1796 }
1797
1798 let constr_tag =
1799 if constr < 7 {
1800 121 + constr
1801 } else if constr < 128 {
1802 1280 + constr - 7
1803 } else {
1804 fail @"What are you doing? No I mean, seriously."
1805 }
1806
1807 builder
1808 |> builtin.append_bytearray(#"28", _)
1809 |> from_int(constr_tag, _)
1810 },
1811 {
1812 let elems = builtin.un_map_data(self)
1813 when elems is {
1814 [] -> builtin.append_bytearray(#"7b7d", builder)
1815 _ -> {
1816 let bytes =
1817 enumerate(
1818 elems,
1819 builtin.append_bytearray(#"207d", builder),
1820 fn(e: Pair<Data, Data>, st: ByteArray) {
1821 let value = diagnostic(e.2nd, builtin.append_bytearray(#"2c20", st))
1822 diagnostic(e.1st, builtin.append_bytearray(#"3a20", value))
1823 },
1824 fn(e: Pair<Data, Data>, st: ByteArray) {
1825 let value = diagnostic(e.2nd, st)
1826 diagnostic(e.1st, builtin.append_bytearray(#"3a20", value))
1827 },
1828 )
1829 builtin.append_bytearray(#"7b5f20", bytes)
1830 }
1831 }
1832 },
1833 {
1834 let elems = builtin.un_list_data(self)
1835 when elems is {
1836 [] -> builtin.append_bytearray(#"5b5d", builder)
1837 _ -> {
1838 let bytes =
1839 enumerate(
1840 elems,
1841 builtin.append_bytearray(#"5d", builder),
1842 fn(e: Data, st: ByteArray) {
1843 diagnostic(e, builtin.append_bytearray(#"2c20", st))
1844 },
1845 fn(e: Data, st: ByteArray) { diagnostic(e, st) },
1846 )
1847 builtin.append_bytearray(#"5b5f20", bytes)
1848 }
1849 }
1850 },
1851 self
1852 |> builtin.un_i_data
1853 |> from_int(builder),
1854 {
1855 let bytes = builtin.un_b_data(self)
1856 bytes
1857 |> encode_base16(
1858 builtin.length_of_bytearray(bytes) - 1,
1859 builtin.append_bytearray(#"27", builder),
1860 )
1861 |> builtin.append_bytearray(#"6827", _)
1862 },
1863 )
1864 }
1865 "#
1866 ),
1867 );
1868
1869 functions
1870}
1871
1872pub fn prelude_data_types(id_gen: &IdGenerator) -> IndexMap<DataTypeKey, TypedDataType> {
1873 let mut data_types = IndexMap::new();
1874
1875 let data_data_type = TypedDataType::data();
1877 data_types.insert(
1878 DataTypeKey {
1879 module_name: "".to_string(),
1880 defined_type: well_known::DATA.to_string(),
1881 },
1882 data_data_type,
1883 );
1884
1885 let void_data_type = TypedDataType::void();
1887 data_types.insert(
1888 DataTypeKey {
1889 module_name: "".to_string(),
1890 defined_type: well_known::VOID.to_string(),
1891 },
1892 void_data_type,
1893 );
1894
1895 let ordering_data_type = TypedDataType::ordering();
1897 data_types.insert(
1898 DataTypeKey {
1899 module_name: "".to_string(),
1900 defined_type: well_known::ORDERING.to_string(),
1901 },
1902 ordering_data_type,
1903 );
1904
1905 let bool_data_type = TypedDataType::bool();
1907 data_types.insert(
1908 DataTypeKey {
1909 module_name: "".to_string(),
1910 defined_type: well_known::BOOL.to_string(),
1911 },
1912 bool_data_type,
1913 );
1914
1915 let option_data_type = TypedDataType::option(Type::generic_var(id_gen.next()));
1917 data_types.insert(
1918 DataTypeKey {
1919 module_name: "".to_string(),
1920 defined_type: well_known::OPTION.to_string(),
1921 },
1922 option_data_type,
1923 );
1924
1925 let pair_data_type = TypedDataType::pair(
1927 Type::generic_var(id_gen.next()),
1928 Type::generic_var(id_gen.next()),
1929 );
1930 data_types.insert(
1931 DataTypeKey {
1932 module_name: "".to_string(),
1933 defined_type: well_known::PAIR.to_string(),
1934 },
1935 pair_data_type,
1936 );
1937
1938 data_types.insert(
1940 DataTypeKey {
1941 module_name: "".to_string(),
1942 defined_type: well_known::NEVER.to_string(),
1943 },
1944 TypedDataType::never(),
1945 );
1946
1947 let prng_data_type = TypedDataType::prng();
1949 data_types.insert(
1950 DataTypeKey {
1951 module_name: "".to_string(),
1952 defined_type: well_known::PRNG.to_string(),
1953 },
1954 prng_data_type,
1955 );
1956
1957 let script_purpose_data_type = TypedDataType::script_purpose();
1959 data_types.insert(
1960 DataTypeKey {
1961 module_name: "".to_string(),
1962 defined_type: well_known::SCRIPT_PURPOSE.to_string(),
1963 },
1964 script_purpose_data_type,
1965 );
1966
1967 let script_context_data_type = TypedDataType::script_context();
1969 data_types.insert(
1970 DataTypeKey {
1971 module_name: "".to_string(),
1972 defined_type: well_known::SCRIPT_CONTEXT.to_string(),
1973 },
1974 script_context_data_type,
1975 );
1976
1977 data_types
1978}
1979
1980impl TypedDataType {
1987 pub fn data() -> Self {
1988 DataType::known_enum(well_known::DATA, &[])
1989 }
1990
1991 pub fn void() -> Self {
1992 DataType::known_enum(well_known::VOID, well_known::VOID_CONSTRUCTORS)
1993 }
1994
1995 pub fn bool() -> Self {
1996 DataType::known_enum(well_known::BOOL, well_known::BOOL_CONSTRUCTORS)
1997 }
1998
1999 pub fn script_purpose() -> Self {
2000 DataType::known_enum(
2001 well_known::SCRIPT_PURPOSE,
2002 well_known::SCRIPT_PURPOSE_CONSTRUCTORS,
2003 )
2004 }
2005
2006 pub fn script_context() -> Self {
2007 DataType::known_enum(
2008 well_known::SCRIPT_CONTEXT,
2009 well_known::SCRIPT_CONTEXT_CONSTRUCTORS,
2010 )
2011 }
2012
2013 pub fn prng() -> Self {
2014 let bytearray_arg = |label: &str| RecordConstructorArg {
2015 label: Some(label.to_string()),
2016 doc: None,
2017 annotation: Annotation::bytearray(Span::empty()),
2018 location: Span::empty(),
2019 tipo: Type::byte_array(),
2020 };
2021
2022 let int_arg = |label: &str| RecordConstructorArg {
2023 label: Some(label.to_string()),
2024 doc: None,
2025 annotation: Annotation::int(Span::empty()),
2026 location: Span::empty(),
2027 tipo: Type::int(),
2028 };
2029
2030 DataType::known_data_type(
2031 well_known::PRNG,
2032 &[
2033 RecordConstructor::known_record(
2034 well_known::PRNG_CONSTRUCTORS[0],
2035 &[bytearray_arg("seed"), bytearray_arg("choices")],
2036 ),
2037 RecordConstructor::known_record(
2038 well_known::PRNG_CONSTRUCTORS[1],
2039 &[int_arg("cursor"), bytearray_arg("choices")],
2040 ),
2041 ],
2042 )
2043 }
2044
2045 pub fn ordering() -> Self {
2046 DataType::known_enum(well_known::ORDERING, well_known::ORDERING_CONSTRUCTORS)
2047 }
2048
2049 pub fn option(tipo: Rc<Type>) -> Self {
2050 DataType {
2051 decorators: vec![],
2052 constructors: vec![
2053 RecordConstructor {
2054 decorators: vec![],
2055 location: Span::empty(),
2056 name: well_known::OPTION_CONSTRUCTORS[0].to_string(),
2057 arguments: vec![RecordConstructorArg {
2058 label: None,
2059 annotation: Annotation::Var {
2060 location: Span::empty(),
2061 name: "a".to_string(),
2062 },
2063 location: Span::empty(),
2064 tipo: tipo.clone(),
2065 doc: None,
2066 }],
2067 doc: None,
2068 sugar: false,
2069 },
2070 RecordConstructor {
2071 decorators: vec![],
2072 location: Span::empty(),
2073 name: well_known::OPTION_CONSTRUCTORS[1].to_string(),
2074 arguments: vec![],
2075 doc: None,
2076 sugar: false,
2077 },
2078 ],
2079 doc: None,
2080 location: Span::empty(),
2081 name: well_known::OPTION.to_string(),
2082 opaque: false,
2083 parameters: vec!["a".to_string()],
2084 public: true,
2085 typed_parameters: vec![tipo],
2086 }
2087 }
2088
2089 pub fn pair(left: Rc<Type>, right: Rc<Type>) -> Self {
2090 DataType {
2091 decorators: vec![],
2092 constructors: vec![RecordConstructor {
2093 decorators: vec![],
2094 location: Span::empty(),
2095 name: well_known::PAIR.to_string(),
2096 arguments: vec![
2097 RecordConstructorArg {
2098 label: None,
2099 annotation: Annotation::Var {
2100 location: Span::empty(),
2101 name: "left".to_string(),
2102 },
2103 location: Span::empty(),
2104 tipo: left.clone(),
2105 doc: None,
2106 },
2107 RecordConstructorArg {
2108 label: None,
2109 annotation: Annotation::Var {
2110 location: Span::empty(),
2111 name: "right".to_string(),
2112 },
2113 location: Span::empty(),
2114 tipo: right.clone(),
2115 doc: None,
2116 },
2117 ],
2118 doc: None,
2119 sugar: false,
2120 }],
2121 doc: None,
2122 location: Span::empty(),
2123 name: well_known::PAIR.to_string(),
2124 opaque: false,
2125 parameters: vec!["left".to_string(), "right".to_string()],
2126 public: true,
2127 typed_parameters: vec![left, right],
2128 }
2129 }
2130
2131 pub fn never() -> Self {
2132 DataType::known_enum(well_known::NEVER, well_known::NEVER_CONSTRUCTORS)
2133 }
2134}