Skip to main content

geam_core/plan/module/expression/
function.rs

1mod bit_array;
2mod bool;
3mod custom;
4mod external;
5mod float;
6mod generic;
7mod int;
8mod list;
9mod nil;
10mod returning_function;
11mod string;
12mod tuple;
13mod typed;
14mod utf_codepoint;
15
16use crate::plan::{
17    BitArrayFunctionReference, BoolFunctionReference, ConstantFunctionInstantiation,
18    CustomFieldAccess, CustomFunctionReference, ExternalFunctionReference, FloatFunctionReference,
19    FunctionFunctionReference, FunctionReference, FunctionShape, FunctionType,
20    IntFunctionReference, ListFunctionReference, NilFunctionReference, StringFunctionReference,
21    TupleFunctionReference, UtfCodepointFunctionReference, ValueShape,
22};
23
24pub use self::{
25    bit_array::BitArrayFunctionExpr, bool::BoolFunctionExpr, custom::CustomFunctionExpr,
26    external::ExternalFunctionExpr, float::FloatFunctionExpr, int::IntFunctionExpr,
27    list::ListFunctionExpr, nil::NilFunctionExpr, returning_function::FunctionFunctionExpr,
28    string::StringFunctionExpr, tuple::TupleFunctionExpr, utf_codepoint::UtfCodepointFunctionExpr,
29};
30pub(crate) use self::{
31    bit_array::BitArrayFunctionExprKind,
32    bool::BoolFunctionExprKind,
33    custom::CustomFunctionExprKind,
34    external::ExternalFunctionExprKind,
35    float::FloatFunctionExprKind,
36    generic::{GenericFunctionExpr, GenericFunctionExprKind},
37    int::IntFunctionExprKind,
38    list::ListFunctionExprKind,
39    nil::NilFunctionExprKind,
40    returning_function::FunctionFunctionExprKind,
41    string::StringFunctionExprKind,
42    tuple::TupleFunctionExprKind,
43    typed::TypedFunctionExpr,
44    utf_codepoint::UtfCodepointFunctionExprKind,
45};
46
47#[derive(Debug, Clone, PartialEq)]
48pub struct FunctionExpr {
49    shape: crate::plan::FunctionShape,
50    kind: FunctionExprKind,
51}
52
53#[derive(Debug, Clone, PartialEq)]
54pub(crate) enum FunctionExprKind {
55    Generic(GenericFunctionExpr),
56    Int(IntFunctionExpr),
57    String(StringFunctionExpr),
58    BitArray(BitArrayFunctionExpr),
59    UtfCodepoint(UtfCodepointFunctionExpr),
60    Custom(CustomFunctionExpr),
61    External(ExternalFunctionExpr),
62    Float(FloatFunctionExpr),
63    Bool(BoolFunctionExpr),
64    Nil(NilFunctionExpr),
65    Tuple(TupleFunctionExpr),
66    List(ListFunctionExpr),
67    Function(FunctionFunctionExpr),
68}
69
70#[derive(Debug, Clone, PartialEq)]
71pub(crate) enum TypedFunctionExprKind {
72    Generic(TypedFunctionExpr<GenericFunctionExpr>),
73    Int(TypedFunctionExpr<IntFunctionExpr>),
74    String(TypedFunctionExpr<StringFunctionExpr>),
75    BitArray(TypedFunctionExpr<BitArrayFunctionExpr>),
76    UtfCodepoint(TypedFunctionExpr<UtfCodepointFunctionExpr>),
77    Custom(TypedFunctionExpr<CustomFunctionExpr>),
78    External(TypedFunctionExpr<ExternalFunctionExpr>),
79    Float(TypedFunctionExpr<FloatFunctionExpr>),
80    Bool(TypedFunctionExpr<BoolFunctionExpr>),
81    Nil(TypedFunctionExpr<NilFunctionExpr>),
82    Tuple(TypedFunctionExpr<TupleFunctionExpr>),
83    List(TypedFunctionExpr<ListFunctionExpr>),
84    Function(TypedFunctionExpr<FunctionFunctionExpr>),
85}
86
87impl FunctionExpr {
88    pub(in crate::plan::module) fn constant(value: ConstantFunctionInstantiation) -> Self {
89        match value {
90            ConstantFunctionInstantiation::Generic(value) => {
91                let shape = value.shape().clone();
92                let type_ = crate::plan::GenericFunctionType::new(
93                    shape.argument_shapes().to_vec(),
94                    *value.return_(),
95                );
96                Self::generic_with_shape(GenericFunctionExpr::constant(value, type_), shape)
97            }
98            ConstantFunctionInstantiation::Int(value) => {
99                let shape = value.shape().clone();
100                Self::int_with_shape(IntFunctionExpr::constant(value, shape.type_()), shape)
101            }
102            ConstantFunctionInstantiation::String(value) => {
103                let shape = value.shape().clone();
104                Self::string_with_shape(StringFunctionExpr::constant(value, shape.type_()), shape)
105            }
106            ConstantFunctionInstantiation::BitArray(value) => {
107                let shape = value.shape().clone();
108                Self::bit_array_with_shape(
109                    BitArrayFunctionExpr::constant(value, shape.type_()),
110                    shape,
111                )
112            }
113            ConstantFunctionInstantiation::UtfCodepoint(value) => {
114                let shape = value.shape().clone();
115                Self::utf_codepoint_with_shape(
116                    UtfCodepointFunctionExpr::constant(value, shape.type_()),
117                    shape,
118                )
119            }
120            ConstantFunctionInstantiation::Custom(value) => {
121                let shape = value.shape().clone();
122                let type_ = crate::plan::CustomFunctionType::from_shapes(
123                    shape.argument_shapes().to_vec(),
124                    value.return_().clone(),
125                );
126                Self::with_typed_shape(
127                    FunctionExprKind::Custom(CustomFunctionExpr::constant(value, type_)),
128                    shape,
129                )
130            }
131            ConstantFunctionInstantiation::External(value) => {
132                let shape = value.shape().clone();
133                let type_ = crate::plan::ExternalFunctionType::from_shapes(
134                    shape.argument_shapes().to_vec(),
135                    value.return_().clone(),
136                );
137                Self::with_typed_shape(
138                    FunctionExprKind::External(ExternalFunctionExpr::constant(value, type_)),
139                    shape,
140                )
141            }
142            ConstantFunctionInstantiation::Float(value) => {
143                let shape = value.shape().clone();
144                Self::float_with_shape(FloatFunctionExpr::constant(value, shape.type_()), shape)
145            }
146            ConstantFunctionInstantiation::Bool(value) => {
147                let shape = value.shape().clone();
148                Self::bool_with_shape(BoolFunctionExpr::constant(value, shape.type_()), shape)
149            }
150            ConstantFunctionInstantiation::Nil(value) => {
151                let shape = value.shape().clone();
152                Self::nil_with_shape(NilFunctionExpr::constant(value, shape.type_()), shape)
153            }
154            ConstantFunctionInstantiation::Tuple(value) => {
155                let shape = value.shape().clone();
156                Self::tuple_with_shape(TupleFunctionExpr::constant(value, shape.type_()), shape)
157            }
158            ConstantFunctionInstantiation::List(value) => {
159                let shape = value.shape().clone();
160                let type_ = shape.type_();
161                let item_type = value.return_().value_type();
162                Self::list_with_shape(ListFunctionExpr::constant(value, type_, item_type), shape)
163            }
164            ConstantFunctionInstantiation::Function(value) => {
165                let shape = value.shape().clone();
166                let type_ = crate::plan::FunctionFunctionType::from_shapes(
167                    shape.argument_shapes().to_vec(),
168                    value.return_().as_ref().clone(),
169                );
170                Self::function_with_shape(FunctionFunctionExpr::constant(value, type_), shape)
171            }
172        }
173    }
174
175    pub(crate) fn custom_field_shape(access: CustomFieldAccess, shape: FunctionShape) -> Self {
176        let type_ = shape.type_();
177        match shape.return_shape().clone() {
178            ValueShape::Parameter(parameter) => {
179                let type_ = crate::plan::GenericFunctionType::new(
180                    shape.argument_shapes().to_vec(),
181                    parameter,
182                );
183                Self::generic(GenericFunctionExpr::custom_field(access, type_))
184            }
185            ValueShape::Int => {
186                Self::int_with_shape(IntFunctionExpr::custom_field(access, type_), shape)
187            }
188            ValueShape::String => {
189                Self::string_with_shape(StringFunctionExpr::custom_field(access, type_), shape)
190            }
191            ValueShape::BitArray => {
192                Self::bit_array_with_shape(BitArrayFunctionExpr::custom_field(access, type_), shape)
193            }
194            ValueShape::UtfCodepoint => Self::utf_codepoint_with_shape(
195                UtfCodepointFunctionExpr::custom_field(access, type_),
196                shape,
197            ),
198            ValueShape::Custom(return_shape) => Self::custom(CustomFunctionExpr::custom_field(
199                access,
200                crate::plan::CustomFunctionType::from_shapes(
201                    shape.argument_shapes().to_vec(),
202                    return_shape,
203                ),
204            )),
205            ValueShape::External(return_shape) => {
206                Self::external(ExternalFunctionExpr::custom_field(
207                    access,
208                    crate::plan::ExternalFunctionType::from_shapes(
209                        shape.argument_shapes().to_vec(),
210                        return_shape,
211                    ),
212                ))
213            }
214            ValueShape::Float => {
215                Self::float_with_shape(FloatFunctionExpr::custom_field(access, type_), shape)
216            }
217            ValueShape::Bool => {
218                Self::bool_with_shape(BoolFunctionExpr::custom_field(access, type_), shape)
219            }
220            ValueShape::Nil => {
221                Self::nil_with_shape(NilFunctionExpr::custom_field(access, type_), shape)
222            }
223            ValueShape::Tuple(_) => {
224                Self::tuple_with_shape(TupleFunctionExpr::custom_field(access, type_), shape)
225            }
226            ValueShape::List(item_shape) => Self::list_with_shape(
227                ListFunctionExpr::custom_field(access, type_, item_shape.value_type()),
228                shape,
229            ),
230            ValueShape::Function(return_shape) => Self::function_with_shape(
231                FunctionFunctionExpr::custom_field(
232                    access,
233                    crate::plan::FunctionFunctionType::from_shapes(
234                        shape.argument_shapes().to_vec(),
235                        *return_shape,
236                    ),
237                ),
238                shape,
239            ),
240        }
241    }
242
243    pub(crate) fn tuple_index_shape(
244        tuple: super::TupleExpr,
245        index: usize,
246        shape: FunctionShape,
247    ) -> Self {
248        let type_ = shape.type_();
249        match shape.return_shape().clone() {
250            ValueShape::Parameter(parameter) => Self::generic_with_shape(
251                GenericFunctionExpr::tuple_index(
252                    tuple,
253                    index,
254                    crate::plan::GenericFunctionType::new(
255                        shape.argument_shapes().to_vec(),
256                        parameter,
257                    ),
258                ),
259                shape,
260            ),
261            ValueShape::Int => {
262                Self::int_with_shape(IntFunctionExpr::tuple_index(tuple, index, type_), shape)
263            }
264            ValueShape::String => {
265                Self::string_with_shape(StringFunctionExpr::tuple_index(tuple, index, type_), shape)
266            }
267            ValueShape::BitArray => Self::bit_array_with_shape(
268                BitArrayFunctionExpr::tuple_index(tuple, index, type_),
269                shape,
270            ),
271            ValueShape::UtfCodepoint => Self::utf_codepoint_with_shape(
272                UtfCodepointFunctionExpr::tuple_index(tuple, index, type_),
273                shape,
274            ),
275            ValueShape::Custom(return_shape) => Self::custom(CustomFunctionExpr::tuple_index(
276                tuple,
277                index,
278                crate::plan::CustomFunctionType::from_shapes(
279                    shape.argument_shapes().to_vec(),
280                    return_shape,
281                ),
282            )),
283            ValueShape::External(return_shape) => {
284                Self::external(ExternalFunctionExpr::tuple_index(
285                    tuple,
286                    index,
287                    crate::plan::ExternalFunctionType::from_shapes(
288                        shape.argument_shapes().to_vec(),
289                        return_shape,
290                    ),
291                ))
292            }
293            ValueShape::Float => {
294                Self::float_with_shape(FloatFunctionExpr::tuple_index(tuple, index, type_), shape)
295            }
296            ValueShape::Bool => {
297                Self::bool_with_shape(BoolFunctionExpr::tuple_index(tuple, index, type_), shape)
298            }
299            ValueShape::Nil => {
300                Self::nil_with_shape(NilFunctionExpr::tuple_index(tuple, index, type_), shape)
301            }
302            ValueShape::Tuple(_) => {
303                Self::tuple_with_shape(TupleFunctionExpr::tuple_index(tuple, index, type_), shape)
304            }
305            ValueShape::List(item_shape) => Self::list_with_shape(
306                ListFunctionExpr::tuple_index(tuple, index, type_, item_shape.value_type()),
307                shape,
308            ),
309            ValueShape::Function(return_shape) => Self::function_with_shape(
310                FunctionFunctionExpr::tuple_index(
311                    tuple,
312                    index,
313                    crate::plan::FunctionFunctionType::from_shapes(
314                        shape.argument_shapes().to_vec(),
315                        *return_shape,
316                    ),
317                ),
318                shape,
319            ),
320        }
321    }
322
323    pub(crate) fn reference(reference: FunctionReference) -> Self {
324        let instantiation = reference.into_instantiation();
325        let shape = instantiation.shape().clone();
326        match shape.return_shape().clone() {
327            ValueShape::Parameter(parameter) => {
328                let type_ = crate::plan::GenericFunctionType::new(
329                    shape.argument_shapes().to_vec(),
330                    parameter,
331                );
332                Self::generic_with_shape(
333                    GenericFunctionExpr::reference(
334                        crate::plan::GenericFunctionReference::new(instantiation),
335                        type_,
336                    ),
337                    shape,
338                )
339            }
340            ValueShape::Int => Self::int_with_shape(
341                IntFunctionExpr::reference(IntFunctionReference::new(instantiation)),
342                shape,
343            ),
344            ValueShape::Float => Self::float_with_shape(
345                FloatFunctionExpr::reference(FloatFunctionReference::new(instantiation)),
346                shape,
347            ),
348            ValueShape::String => Self::string_with_shape(
349                StringFunctionExpr::reference(StringFunctionReference::new(instantiation)),
350                shape,
351            ),
352            ValueShape::BitArray => Self::bit_array_with_shape(
353                BitArrayFunctionExpr::reference(BitArrayFunctionReference::new(instantiation)),
354                shape,
355            ),
356            ValueShape::UtfCodepoint => Self::utf_codepoint_with_shape(
357                UtfCodepointFunctionExpr::reference(UtfCodepointFunctionReference::new(
358                    instantiation,
359                )),
360                shape,
361            ),
362            ValueShape::Custom(return_shape) => Self::with_typed_shape(
363                FunctionExprKind::Custom(CustomFunctionExpr::reference(
364                    CustomFunctionReference::new(instantiation),
365                    return_shape,
366                )),
367                shape,
368            ),
369            ValueShape::External(return_shape) => Self::with_typed_shape(
370                FunctionExprKind::External(ExternalFunctionExpr::reference(
371                    ExternalFunctionReference::new(instantiation),
372                    return_shape,
373                )),
374                shape,
375            ),
376            ValueShape::Bool => Self::bool_with_shape(
377                BoolFunctionExpr::reference(BoolFunctionReference::new(instantiation)),
378                shape,
379            ),
380            ValueShape::Nil => Self::nil_with_shape(
381                NilFunctionExpr::reference(NilFunctionReference::new(instantiation)),
382                shape,
383            ),
384            ValueShape::Tuple(_) => Self::tuple_with_shape(
385                TupleFunctionExpr::reference(TupleFunctionReference::new(instantiation)),
386                shape,
387            ),
388            ValueShape::List(item_shape) => Self::list_with_shape(
389                ListFunctionExpr::reference(
390                    ListFunctionReference::new(instantiation),
391                    item_shape.value_type(),
392                ),
393                shape,
394            ),
395            ValueShape::Function(return_shape) => Self::function_with_shape(
396                FunctionFunctionExpr::reference(
397                    FunctionFunctionReference::new(instantiation),
398                    return_shape.type_(),
399                ),
400                shape,
401            ),
402        }
403    }
404
405    pub(crate) fn call_at(
406        function: crate::plan::FunctionInstantiation,
407        args: Vec<crate::plan::CallArg>,
408        shape: FunctionShape,
409        site: crate::plan::HostCallSite,
410    ) -> Self {
411        let type_ = shape.type_();
412        match shape.return_shape().clone() {
413            ValueShape::Parameter(parameter) => Self::generic(GenericFunctionExpr::call_at(
414                function,
415                args,
416                crate::plan::GenericFunctionType::new(shape.argument_shapes().to_vec(), parameter),
417                site,
418            )),
419            ValueShape::Int => {
420                Self::int_with_shape(IntFunctionExpr::call_at(function, args, type_, site), shape)
421            }
422            ValueShape::String => Self::string_with_shape(
423                StringFunctionExpr::call_at(function, args, type_, site),
424                shape,
425            ),
426            ValueShape::BitArray => Self::bit_array_with_shape(
427                BitArrayFunctionExpr::call_at(function, args, type_, site),
428                shape,
429            ),
430            ValueShape::UtfCodepoint => Self::utf_codepoint_with_shape(
431                UtfCodepointFunctionExpr::call_at(function, args, type_, site),
432                shape,
433            ),
434            ValueShape::Custom(return_) => Self::custom(CustomFunctionExpr::call_at(
435                function,
436                args,
437                crate::plan::CustomFunctionType::from_shapes(
438                    shape.argument_shapes().to_vec(),
439                    return_,
440                ),
441                site,
442            )),
443            ValueShape::External(return_) => Self::external(ExternalFunctionExpr::call_at(
444                function,
445                args,
446                crate::plan::ExternalFunctionType::from_shapes(
447                    shape.argument_shapes().to_vec(),
448                    return_,
449                ),
450                site,
451            )),
452            ValueShape::Float => Self::float_with_shape(
453                FloatFunctionExpr::call_at(function, args, type_, site),
454                shape,
455            ),
456            ValueShape::Bool => Self::bool_with_shape(
457                BoolFunctionExpr::call_at(function, args, type_, site),
458                shape,
459            ),
460            ValueShape::Nil => {
461                Self::nil_with_shape(NilFunctionExpr::call_at(function, args, type_, site), shape)
462            }
463            ValueShape::Tuple(_) => Self::tuple_with_shape(
464                TupleFunctionExpr::call_at(function, args, type_, site),
465                shape,
466            ),
467            ValueShape::List(item) => Self::list_with_shape(
468                ListFunctionExpr::call_at(function, args, type_, item.value_type(), site),
469                shape,
470            ),
471            ValueShape::Function(return_) => Self::function_with_shape(
472                FunctionFunctionExpr::call_at(
473                    function,
474                    args,
475                    crate::plan::FunctionFunctionType::from_shapes(
476                        shape.argument_shapes().to_vec(),
477                        *return_,
478                    ),
479                    site,
480                ),
481                shape,
482            ),
483        }
484    }
485
486    pub(crate) fn int(expression: IntFunctionExpr) -> Self {
487        Self::new(FunctionExprKind::Int(expression))
488    }
489
490    pub(crate) fn generic(expression: GenericFunctionExpr) -> Self {
491        Self::new(FunctionExprKind::Generic(expression))
492    }
493
494    pub(crate) fn generic_with_shape(
495        expression: GenericFunctionExpr,
496        shape: crate::plan::FunctionShape,
497    ) -> Self {
498        Self::with_typed_shape(FunctionExprKind::Generic(expression), shape)
499    }
500
501    pub(crate) fn int_with_shape(
502        expression: IntFunctionExpr,
503        shape: crate::plan::FunctionShape,
504    ) -> Self {
505        Self::with_typed_shape(FunctionExprKind::Int(expression), shape)
506    }
507
508    pub(crate) fn string(expression: StringFunctionExpr) -> Self {
509        Self::new(FunctionExprKind::String(expression))
510    }
511
512    pub(crate) fn string_with_shape(
513        expression: StringFunctionExpr,
514        shape: crate::plan::FunctionShape,
515    ) -> Self {
516        Self::with_typed_shape(FunctionExprKind::String(expression), shape)
517    }
518
519    pub(crate) fn bit_array(expression: BitArrayFunctionExpr) -> Self {
520        Self::new(FunctionExprKind::BitArray(expression))
521    }
522
523    pub(crate) fn bit_array_with_shape(
524        expression: BitArrayFunctionExpr,
525        shape: crate::plan::FunctionShape,
526    ) -> Self {
527        Self::with_typed_shape(FunctionExprKind::BitArray(expression), shape)
528    }
529
530    pub(crate) fn utf_codepoint(expression: UtfCodepointFunctionExpr) -> Self {
531        Self::new(FunctionExprKind::UtfCodepoint(expression))
532    }
533
534    pub(crate) fn utf_codepoint_with_shape(
535        expression: UtfCodepointFunctionExpr,
536        shape: crate::plan::FunctionShape,
537    ) -> Self {
538        Self::with_typed_shape(FunctionExprKind::UtfCodepoint(expression), shape)
539    }
540
541    pub(crate) fn custom(expression: CustomFunctionExpr) -> Self {
542        Self::new(FunctionExprKind::Custom(expression))
543    }
544
545    pub(crate) fn external(expression: ExternalFunctionExpr) -> Self {
546        Self::new(FunctionExprKind::External(expression))
547    }
548
549    pub(crate) fn float(expression: FloatFunctionExpr) -> Self {
550        Self::new(FunctionExprKind::Float(expression))
551    }
552
553    pub(crate) fn float_with_shape(
554        expression: FloatFunctionExpr,
555        shape: crate::plan::FunctionShape,
556    ) -> Self {
557        Self::with_typed_shape(FunctionExprKind::Float(expression), shape)
558    }
559
560    pub(crate) fn bool(expression: BoolFunctionExpr) -> Self {
561        Self::new(FunctionExprKind::Bool(expression))
562    }
563
564    pub(crate) fn bool_with_shape(
565        expression: BoolFunctionExpr,
566        shape: crate::plan::FunctionShape,
567    ) -> Self {
568        Self::with_typed_shape(FunctionExprKind::Bool(expression), shape)
569    }
570
571    pub(crate) fn nil(expression: NilFunctionExpr) -> Self {
572        Self::new(FunctionExprKind::Nil(expression))
573    }
574
575    pub(crate) fn nil_with_shape(
576        expression: NilFunctionExpr,
577        shape: crate::plan::FunctionShape,
578    ) -> Self {
579        Self::with_typed_shape(FunctionExprKind::Nil(expression), shape)
580    }
581
582    pub(crate) fn tuple(expression: TupleFunctionExpr) -> Self {
583        Self::new(FunctionExprKind::Tuple(expression))
584    }
585
586    pub(crate) fn tuple_with_shape(
587        expression: TupleFunctionExpr,
588        shape: crate::plan::FunctionShape,
589    ) -> Self {
590        Self::with_typed_shape(FunctionExprKind::Tuple(expression), shape)
591    }
592
593    pub(crate) fn list(expression: ListFunctionExpr) -> Self {
594        Self::new(FunctionExprKind::List(expression))
595    }
596
597    pub(crate) fn list_with_shape(
598        expression: ListFunctionExpr,
599        shape: crate::plan::FunctionShape,
600    ) -> Self {
601        Self::with_typed_shape(FunctionExprKind::List(expression), shape)
602    }
603
604    pub(crate) fn function(expression: FunctionFunctionExpr) -> Self {
605        Self::new(FunctionExprKind::Function(expression))
606    }
607
608    pub(crate) fn function_with_shape(
609        expression: FunctionFunctionExpr,
610        shape: crate::plan::FunctionShape,
611    ) -> Self {
612        Self::with_typed_shape(FunctionExprKind::Function(expression), shape)
613    }
614
615    fn with_typed_shape(kind: FunctionExprKind, shape: crate::plan::FunctionShape) -> Self {
616        Self { shape, kind }
617    }
618
619    fn new(kind: FunctionExprKind) -> Self {
620        let shape = match &kind {
621            FunctionExprKind::Generic(expression) => expression.shape(),
622            FunctionExprKind::Int(expression) => {
623                crate::plan::FunctionShape::from_function_type(expression.type_().clone())
624            }
625            FunctionExprKind::String(expression) => {
626                crate::plan::FunctionShape::from_function_type(expression.type_().clone())
627            }
628            FunctionExprKind::BitArray(expression) => {
629                crate::plan::FunctionShape::from_function_type(expression.type_().clone())
630            }
631            FunctionExprKind::UtfCodepoint(expression) => {
632                crate::plan::FunctionShape::from_function_type(expression.type_().clone())
633            }
634            FunctionExprKind::Custom(expression) => crate::plan::FunctionShape::new(
635                expression.custom_function_type().argument_shapes().to_vec(),
636                crate::plan::ValueShape::Custom(
637                    expression.custom_function_type().return_().clone(),
638                ),
639            ),
640            FunctionExprKind::External(expression) => crate::plan::FunctionShape::new(
641                expression
642                    .external_function_type()
643                    .argument_shapes()
644                    .to_vec(),
645                crate::plan::ValueShape::External(
646                    expression.external_function_type().return_().clone(),
647                ),
648            ),
649            FunctionExprKind::Float(expression) => {
650                crate::plan::FunctionShape::from_function_type(expression.type_().clone())
651            }
652            FunctionExprKind::Bool(expression) => {
653                crate::plan::FunctionShape::from_function_type(expression.type_().clone())
654            }
655            FunctionExprKind::Nil(expression) => {
656                crate::plan::FunctionShape::from_function_type(expression.type_().clone())
657            }
658            FunctionExprKind::Tuple(expression) => {
659                crate::plan::FunctionShape::from_function_type(expression.type_().clone())
660            }
661            FunctionExprKind::List(expression) => {
662                crate::plan::FunctionShape::from_function_type(expression.type_().clone())
663            }
664            FunctionExprKind::Function(expression) => crate::plan::FunctionShape::new(
665                expression
666                    .function_function_type()
667                    .argument_shapes()
668                    .to_vec(),
669                crate::plan::ValueShape::Function(Box::new(
670                    expression.function_function_type().return_shape().clone(),
671                )),
672            ),
673        };
674        Self { shape, kind }
675    }
676
677    pub(crate) fn block(steps: Vec<crate::plan::Step>, return_: Self) -> Self {
678        let Self { shape, kind } = return_;
679        let kind = match kind {
680            FunctionExprKind::Generic(return_) => {
681                FunctionExprKind::Generic(GenericFunctionExpr::block(steps, return_))
682            }
683            FunctionExprKind::Int(return_) => {
684                FunctionExprKind::Int(IntFunctionExpr::block(steps, return_))
685            }
686            FunctionExprKind::String(return_) => {
687                FunctionExprKind::String(StringFunctionExpr::block(steps, return_))
688            }
689            FunctionExprKind::BitArray(return_) => {
690                FunctionExprKind::BitArray(BitArrayFunctionExpr::block(steps, return_))
691            }
692            FunctionExprKind::UtfCodepoint(return_) => {
693                FunctionExprKind::UtfCodepoint(UtfCodepointFunctionExpr::block(steps, return_))
694            }
695            FunctionExprKind::Custom(return_) => {
696                FunctionExprKind::Custom(CustomFunctionExpr::block(steps, return_))
697            }
698            FunctionExprKind::External(return_) => {
699                FunctionExprKind::External(ExternalFunctionExpr::block(steps, return_))
700            }
701            FunctionExprKind::Float(return_) => {
702                FunctionExprKind::Float(FloatFunctionExpr::block(steps, return_))
703            }
704            FunctionExprKind::Bool(return_) => {
705                FunctionExprKind::Bool(BoolFunctionExpr::block(steps, return_))
706            }
707            FunctionExprKind::Nil(return_) => {
708                FunctionExprKind::Nil(NilFunctionExpr::block(steps, return_))
709            }
710            FunctionExprKind::Tuple(return_) => {
711                FunctionExprKind::Tuple(TupleFunctionExpr::block(steps, return_))
712            }
713            FunctionExprKind::List(return_) => {
714                FunctionExprKind::List(ListFunctionExpr::block(steps, return_))
715            }
716            FunctionExprKind::Function(return_) => {
717                FunctionExprKind::Function(FunctionFunctionExpr::block(steps, return_))
718            }
719        };
720        Self { shape, kind }
721    }
722
723    pub fn type_(&self) -> FunctionType {
724        self.shape.type_()
725    }
726
727    pub(crate) fn with_shape(self, shape: crate::plan::FunctionShape) -> Option<Self> {
728        if shape.type_() != self.type_() {
729            return None;
730        }
731        if !self.shape.can_flow_to(&shape) {
732            return None;
733        }
734
735        Some(self)
736    }
737
738    pub(crate) fn with_resolved_shape(self, shape: crate::plan::FunctionShape) -> Option<Self> {
739        if shape.type_() != self.type_() {
740            return None;
741        }
742
743        Some(self.set_resolved_shape(shape))
744    }
745
746    pub(crate) fn resolve_constructed_shape(self, shape: crate::plan::FunctionShape) -> Self {
747        self.set_resolved_shape(shape)
748    }
749
750    fn set_resolved_shape(mut self, shape: crate::plan::FunctionShape) -> Self {
751        self.kind = match (self.kind, shape.return_shape().clone()) {
752            (
753                FunctionExprKind::Generic(expression),
754                crate::plan::ValueShape::Parameter(return_),
755            ) => FunctionExprKind::Generic(expression.with_type(
756                crate::plan::GenericFunctionType::new(shape.argument_shapes().to_vec(), return_),
757            )),
758            (FunctionExprKind::Custom(expression), crate::plan::ValueShape::Custom(return_)) => {
759                FunctionExprKind::Custom(expression.with_type(
760                    crate::plan::CustomFunctionType::from_shapes(
761                        shape.argument_shapes().to_vec(),
762                        return_,
763                    ),
764                ))
765            }
766            (
767                FunctionExprKind::External(expression),
768                crate::plan::ValueShape::External(return_),
769            ) => FunctionExprKind::External(expression.with_type(
770                crate::plan::ExternalFunctionType::from_shapes(
771                    shape.argument_shapes().to_vec(),
772                    return_,
773                ),
774            )),
775            (
776                FunctionExprKind::Function(expression),
777                crate::plan::ValueShape::Function(return_),
778            ) => FunctionExprKind::Function(expression.with_type(
779                crate::plan::FunctionFunctionType::from_shapes(
780                    shape.argument_shapes().to_vec(),
781                    *return_,
782                ),
783            )),
784            (kind, _) => kind,
785        };
786        self.shape = shape;
787        self
788    }
789
790    pub(crate) fn kind(&self) -> &FunctionExprKind {
791        &self.kind
792    }
793
794    pub(crate) fn shape(&self) -> &crate::plan::FunctionShape {
795        &self.shape
796    }
797
798    pub(crate) fn into_kind(self) -> FunctionExprKind {
799        self.kind
800    }
801
802    pub(crate) fn into_parts(self) -> (crate::plan::FunctionShape, FunctionExprKind) {
803        (self.shape, self.kind)
804    }
805
806    pub(crate) fn into_typed_kind(self) -> TypedFunctionExprKind {
807        let Self { shape, kind } = self;
808        match kind {
809            FunctionExprKind::Generic(expression) => {
810                TypedFunctionExprKind::Generic(TypedFunctionExpr::new(shape, expression))
811            }
812            FunctionExprKind::Int(expression) => {
813                TypedFunctionExprKind::Int(TypedFunctionExpr::new(shape, expression))
814            }
815            FunctionExprKind::String(expression) => {
816                TypedFunctionExprKind::String(TypedFunctionExpr::new(shape, expression))
817            }
818            FunctionExprKind::BitArray(expression) => {
819                TypedFunctionExprKind::BitArray(TypedFunctionExpr::new(shape, expression))
820            }
821            FunctionExprKind::UtfCodepoint(expression) => {
822                TypedFunctionExprKind::UtfCodepoint(TypedFunctionExpr::new(shape, expression))
823            }
824            FunctionExprKind::Custom(expression) => {
825                TypedFunctionExprKind::Custom(TypedFunctionExpr::new(shape, expression))
826            }
827            FunctionExprKind::External(expression) => {
828                TypedFunctionExprKind::External(TypedFunctionExpr::new(shape, expression))
829            }
830            FunctionExprKind::Float(expression) => {
831                TypedFunctionExprKind::Float(TypedFunctionExpr::new(shape, expression))
832            }
833            FunctionExprKind::Bool(expression) => {
834                TypedFunctionExprKind::Bool(TypedFunctionExpr::new(shape, expression))
835            }
836            FunctionExprKind::Nil(expression) => {
837                TypedFunctionExprKind::Nil(TypedFunctionExpr::new(shape, expression))
838            }
839            FunctionExprKind::Tuple(expression) => {
840                TypedFunctionExprKind::Tuple(TypedFunctionExpr::new(shape, expression))
841            }
842            FunctionExprKind::List(expression) => {
843                TypedFunctionExprKind::List(TypedFunctionExpr::new(shape, expression))
844            }
845            FunctionExprKind::Function(expression) => {
846                TypedFunctionExprKind::Function(TypedFunctionExpr::new(shape, expression))
847            }
848        }
849    }
850
851    pub(crate) fn into_int(self) -> Option<IntFunctionExpr> {
852        match self.kind {
853            FunctionExprKind::Int(expression) => Some(expression),
854            _ => None,
855        }
856    }
857
858    pub(crate) fn into_generic(self) -> Option<GenericFunctionExpr> {
859        match self.kind {
860            FunctionExprKind::Generic(expression) => Some(expression),
861            _ => None,
862        }
863    }
864
865    pub(crate) fn into_string(self) -> Option<StringFunctionExpr> {
866        match self.kind {
867            FunctionExprKind::String(expression) => Some(expression),
868            _ => None,
869        }
870    }
871
872    pub(crate) fn into_bit_array(self) -> Option<BitArrayFunctionExpr> {
873        match self.kind {
874            FunctionExprKind::BitArray(expression) => Some(expression),
875            _ => None,
876        }
877    }
878
879    pub(crate) fn into_utf_codepoint(self) -> Option<UtfCodepointFunctionExpr> {
880        match self.kind {
881            FunctionExprKind::UtfCodepoint(expression) => Some(expression),
882            _ => None,
883        }
884    }
885
886    pub(crate) fn into_custom(self) -> Option<CustomFunctionExpr> {
887        match self.kind {
888            FunctionExprKind::Custom(expression) => Some(expression),
889            _ => None,
890        }
891    }
892
893    pub(crate) fn into_external(self) -> Option<ExternalFunctionExpr> {
894        match self.kind {
895            FunctionExprKind::External(expression) => Some(expression),
896            _ => None,
897        }
898    }
899
900    pub(crate) fn into_float(self) -> Option<FloatFunctionExpr> {
901        match self.kind {
902            FunctionExprKind::Float(expression) => Some(expression),
903            _ => None,
904        }
905    }
906
907    pub(crate) fn into_bool(self) -> Option<BoolFunctionExpr> {
908        match self.kind {
909            FunctionExprKind::Bool(expression) => Some(expression),
910            _ => None,
911        }
912    }
913
914    pub(crate) fn into_nil(self) -> Option<NilFunctionExpr> {
915        match self.kind {
916            FunctionExprKind::Nil(expression) => Some(expression),
917            _ => None,
918        }
919    }
920
921    pub(crate) fn into_tuple(self) -> Option<TupleFunctionExpr> {
922        match self.kind {
923            FunctionExprKind::Tuple(expression) => Some(expression),
924            _ => None,
925        }
926    }
927
928    pub(crate) fn into_list(self) -> Option<ListFunctionExpr> {
929        match self.kind {
930            FunctionExprKind::List(expression) => Some(expression),
931            _ => None,
932        }
933    }
934
935    pub(crate) fn into_function(self) -> Option<FunctionFunctionExpr> {
936        match self.kind {
937            FunctionExprKind::Function(expression) => Some(expression),
938            _ => None,
939        }
940    }
941}
942
943impl From<IntFunctionExpr> for FunctionExpr {
944    fn from(expression: IntFunctionExpr) -> Self {
945        Self::int(expression)
946    }
947}
948
949impl From<GenericFunctionExpr> for FunctionExpr {
950    fn from(expression: GenericFunctionExpr) -> Self {
951        Self::generic(expression)
952    }
953}
954
955impl From<StringFunctionExpr> for FunctionExpr {
956    fn from(expression: StringFunctionExpr) -> Self {
957        Self::string(expression)
958    }
959}
960
961impl From<BitArrayFunctionExpr> for FunctionExpr {
962    fn from(expression: BitArrayFunctionExpr) -> Self {
963        Self::bit_array(expression)
964    }
965}
966
967impl From<UtfCodepointFunctionExpr> for FunctionExpr {
968    fn from(expression: UtfCodepointFunctionExpr) -> Self {
969        Self::utf_codepoint(expression)
970    }
971}
972
973impl From<FloatFunctionExpr> for FunctionExpr {
974    fn from(expression: FloatFunctionExpr) -> Self {
975        Self::float(expression)
976    }
977}
978
979impl From<BoolFunctionExpr> for FunctionExpr {
980    fn from(expression: BoolFunctionExpr) -> Self {
981        Self::bool(expression)
982    }
983}
984
985impl From<NilFunctionExpr> for FunctionExpr {
986    fn from(expression: NilFunctionExpr) -> Self {
987        Self::nil(expression)
988    }
989}
990
991impl From<TupleFunctionExpr> for FunctionExpr {
992    fn from(expression: TupleFunctionExpr) -> Self {
993        Self::tuple(expression)
994    }
995}
996
997impl From<ListFunctionExpr> for FunctionExpr {
998    fn from(expression: ListFunctionExpr) -> Self {
999        Self::list(expression)
1000    }
1001}
1002
1003impl From<FunctionFunctionExpr> for FunctionExpr {
1004    fn from(expression: FunctionFunctionExpr) -> Self {
1005        Self::function(expression)
1006    }
1007}
1008
1009#[cfg(test)]
1010mod tests {
1011    use super::{
1012        BitArrayFunctionExpr, BoolFunctionExpr, FloatFunctionExpr, FunctionExpr, FunctionExprKind,
1013        FunctionFunctionExpr, GenericFunctionExpr, IntFunctionExpr, ListFunctionExpr,
1014        NilFunctionExpr, StringFunctionExpr, TupleFunctionExpr, UtfCodepointFunctionExpr,
1015    };
1016    use crate::plan::{
1017        BitArrayFunctionReference, BoolFunctionReference, FloatFunctionReference,
1018        FunctionFunctionReference, FunctionInstantiation, FunctionReference, FunctionShape,
1019        FunctionType, GenericFunctionType, IntFunctionReference, ListFunctionReference,
1020        NilFunctionReference, PanicExpr, PanicSite, StringFunctionReference,
1021        TupleFunctionReference, TypeParameterId, UtfCodepointFunctionReference, ValueShape,
1022        ValueType, monomorphic_function_instantiation,
1023    };
1024
1025    #[test]
1026    fn function_expr_kind_accessors() {
1027        assert_eq!(
1028            FunctionExpr::generic(generic_function_value()).kind(),
1029            &FunctionExprKind::Generic(generic_function_value()),
1030        );
1031        assert_eq!(
1032            FunctionExpr::int(int_function_value()).kind(),
1033            &FunctionExprKind::Int(int_function_value()),
1034        );
1035        assert_eq!(
1036            FunctionExpr::string(string_function_value()).kind(),
1037            &FunctionExprKind::String(string_function_value()),
1038        );
1039        assert_eq!(
1040            FunctionExpr::bit_array(bit_array_function_value()).kind(),
1041            &FunctionExprKind::BitArray(bit_array_function_value()),
1042        );
1043        assert_eq!(
1044            FunctionExpr::utf_codepoint(utf_codepoint_function_value()).kind(),
1045            &FunctionExprKind::UtfCodepoint(utf_codepoint_function_value()),
1046        );
1047        assert_eq!(
1048            FunctionExpr::float(float_function_value()).kind(),
1049            &FunctionExprKind::Float(float_function_value()),
1050        );
1051        assert_eq!(
1052            FunctionExpr::bool(bool_function_value()).kind(),
1053            &FunctionExprKind::Bool(bool_function_value()),
1054        );
1055        assert_eq!(
1056            FunctionExpr::nil(nil_function_value()).kind(),
1057            &FunctionExprKind::Nil(nil_function_value()),
1058        );
1059        assert_eq!(
1060            FunctionExpr::tuple(tuple_function_value()).kind(),
1061            &FunctionExprKind::Tuple(tuple_function_value()),
1062        );
1063        assert_eq!(
1064            FunctionExpr::list(list_function_value()).kind(),
1065            &FunctionExprKind::List(list_function_value()),
1066        );
1067        assert_eq!(
1068            FunctionExpr::function(function_function_value()).kind(),
1069            &FunctionExprKind::Function(function_function_value()),
1070        );
1071    }
1072
1073    #[test]
1074    fn function_expr_reference_preserves_runtime_family() {
1075        assert_eq!(
1076            FunctionExpr::reference(int_function_reference()).kind(),
1077            &FunctionExprKind::Int(int_function_value()),
1078        );
1079        assert_eq!(
1080            FunctionExpr::reference(string_function_reference()).kind(),
1081            &FunctionExprKind::String(string_function_value()),
1082        );
1083        assert_eq!(
1084            FunctionExpr::reference(bit_array_function_reference()).kind(),
1085            &FunctionExprKind::BitArray(bit_array_function_value()),
1086        );
1087        assert_eq!(
1088            FunctionExpr::reference(utf_codepoint_function_reference()).kind(),
1089            &FunctionExprKind::UtfCodepoint(utf_codepoint_function_value()),
1090        );
1091        assert_eq!(
1092            FunctionExpr::reference(float_function_reference()).kind(),
1093            &FunctionExprKind::Float(float_function_value()),
1094        );
1095        assert_eq!(
1096            FunctionExpr::reference(bool_function_reference()).kind(),
1097            &FunctionExprKind::Bool(bool_function_value()),
1098        );
1099        assert_eq!(
1100            FunctionExpr::reference(nil_function_reference()).kind(),
1101            &FunctionExprKind::Nil(nil_function_value()),
1102        );
1103        assert_eq!(
1104            FunctionExpr::reference(tuple_function_reference()).kind(),
1105            &FunctionExprKind::Tuple(tuple_function_value()),
1106        );
1107        assert_eq!(
1108            FunctionExpr::reference(list_function_reference()).kind(),
1109            &FunctionExprKind::List(list_function_value()),
1110        );
1111        assert_eq!(
1112            FunctionExpr::reference(function_function_reference()).kind(),
1113            &FunctionExprKind::Function(function_function_value()),
1114        );
1115    }
1116
1117    #[test]
1118    fn function_expr_type_accessors() {
1119        assert_eq!(
1120            FunctionExpr::generic(generic_function_value()).type_(),
1121            FunctionType::new(
1122                vec![ValueType::Int],
1123                ValueType::Parameter(TypeParameterId(0))
1124            ),
1125        );
1126        assert_eq!(
1127            FunctionExpr::int(int_function_value()).type_(),
1128            int_function_type(),
1129        );
1130        assert_eq!(
1131            FunctionExpr::string(string_function_value()).type_(),
1132            string_function_type(),
1133        );
1134        assert_eq!(
1135            FunctionExpr::bit_array(bit_array_function_value()).type_(),
1136            bit_array_function_type(),
1137        );
1138        assert_eq!(
1139            FunctionExpr::utf_codepoint(utf_codepoint_function_value()).type_(),
1140            utf_codepoint_function_type(),
1141        );
1142        assert_eq!(
1143            FunctionExpr::float(float_function_value()).type_(),
1144            float_function_type(),
1145        );
1146        assert_eq!(
1147            FunctionExpr::bool(bool_function_value()).type_(),
1148            bool_function_type()
1149        );
1150        assert_eq!(FunctionExpr::nil(nil_function_value()).type_(), nil_type());
1151        assert_eq!(
1152            FunctionExpr::tuple(tuple_function_value()).type_(),
1153            tuple_function_type(),
1154        );
1155        assert_eq!(
1156            FunctionExpr::list(list_function_value()).type_(),
1157            list_function_type()
1158        );
1159        assert_eq!(
1160            FunctionExpr::function(function_function_value()).type_(),
1161            function_function_type(),
1162        );
1163    }
1164
1165    #[test]
1166    fn function_expr_typed_conversions() {
1167        assert_eq!(
1168            FunctionExpr::generic(generic_function_value()).into_generic(),
1169            Some(generic_function_value()),
1170        );
1171        assert_eq!(
1172            FunctionExpr::int(int_function_value()).into_int(),
1173            Some(int_function_value()),
1174        );
1175        assert_eq!(
1176            FunctionExpr::string(string_function_value()).into_string(),
1177            Some(string_function_value()),
1178        );
1179        assert_eq!(
1180            FunctionExpr::bit_array(bit_array_function_value()).into_bit_array(),
1181            Some(bit_array_function_value()),
1182        );
1183        assert_eq!(
1184            FunctionExpr::utf_codepoint(utf_codepoint_function_value()).into_utf_codepoint(),
1185            Some(utf_codepoint_function_value()),
1186        );
1187        assert_eq!(
1188            FunctionExpr::float(float_function_value()).into_float(),
1189            Some(float_function_value()),
1190        );
1191        assert_eq!(
1192            FunctionExpr::bool(bool_function_value()).into_bool(),
1193            Some(bool_function_value()),
1194        );
1195        assert_eq!(
1196            FunctionExpr::nil(nil_function_value()).into_nil(),
1197            Some(nil_function_value()),
1198        );
1199        assert_eq!(
1200            FunctionExpr::tuple(tuple_function_value()).into_tuple(),
1201            Some(tuple_function_value()),
1202        );
1203        assert_eq!(
1204            FunctionExpr::list(list_function_value()).into_list(),
1205            Some(list_function_value()),
1206        );
1207        assert_eq!(
1208            FunctionExpr::function(function_function_value()).into_function(),
1209            Some(function_function_value()),
1210        );
1211
1212        assert_eq!(
1213            FunctionExpr::string(string_function_value()).into_int(),
1214            None
1215        );
1216        assert_eq!(FunctionExpr::int(int_function_value()).into_generic(), None);
1217        assert_eq!(FunctionExpr::int(int_function_value()).into_string(), None,);
1218        assert_eq!(
1219            FunctionExpr::int(int_function_value()).into_bit_array(),
1220            None
1221        );
1222        assert_eq!(
1223            FunctionExpr::int(int_function_value()).into_utf_codepoint(),
1224            None,
1225        );
1226        assert_eq!(FunctionExpr::int(int_function_value()).into_custom(), None,);
1227        assert_eq!(FunctionExpr::int(int_function_value()).into_float(), None);
1228        assert_eq!(FunctionExpr::int(int_function_value()).into_bool(), None);
1229        assert_eq!(FunctionExpr::int(int_function_value()).into_nil(), None);
1230        assert_eq!(FunctionExpr::int(int_function_value()).into_tuple(), None);
1231        assert_eq!(FunctionExpr::int(int_function_value()).into_list(), None);
1232        assert_eq!(
1233            FunctionExpr::int(int_function_value()).into_function(),
1234            None,
1235        );
1236
1237        assert_eq!(
1238            FunctionExpr::from(int_function_value()),
1239            FunctionExpr::int(int_function_value()),
1240        );
1241        assert_eq!(
1242            FunctionExpr::from(generic_function_value()),
1243            FunctionExpr::generic(generic_function_value()),
1244        );
1245        assert_eq!(
1246            FunctionExpr::from(string_function_value()),
1247            FunctionExpr::string(string_function_value()),
1248        );
1249        assert_eq!(
1250            FunctionExpr::from(bit_array_function_value()),
1251            FunctionExpr::bit_array(bit_array_function_value()),
1252        );
1253        assert_eq!(
1254            FunctionExpr::from(utf_codepoint_function_value()),
1255            FunctionExpr::utf_codepoint(utf_codepoint_function_value()),
1256        );
1257        assert_eq!(
1258            FunctionExpr::from(float_function_value()),
1259            FunctionExpr::float(float_function_value()),
1260        );
1261        assert_eq!(
1262            FunctionExpr::from(bool_function_value()),
1263            FunctionExpr::bool(bool_function_value()),
1264        );
1265        assert_eq!(
1266            FunctionExpr::from(nil_function_value()),
1267            FunctionExpr::nil(nil_function_value()),
1268        );
1269        assert_eq!(
1270            FunctionExpr::from(tuple_function_value()),
1271            FunctionExpr::tuple(tuple_function_value()),
1272        );
1273        assert_eq!(
1274            FunctionExpr::from(list_function_value()),
1275            FunctionExpr::list(list_function_value()),
1276        );
1277        assert_eq!(
1278            FunctionExpr::from(function_function_value()),
1279            FunctionExpr::function(function_function_value()),
1280        );
1281    }
1282
1283    fn int_function_reference() -> FunctionReference {
1284        FunctionReference::new(instantiation(int_function_type()))
1285    }
1286
1287    fn generic_function_value() -> GenericFunctionExpr {
1288        GenericFunctionExpr::panic(
1289            PanicExpr::panic_at(None, PanicSite::unknown()),
1290            GenericFunctionType::new(vec![ValueShape::Int], TypeParameterId(0)),
1291        )
1292    }
1293
1294    fn string_function_reference() -> FunctionReference {
1295        FunctionReference::new(instantiation(string_function_type()))
1296    }
1297
1298    fn bit_array_function_reference() -> FunctionReference {
1299        FunctionReference::new(instantiation(bit_array_function_type()))
1300    }
1301
1302    fn utf_codepoint_function_reference() -> FunctionReference {
1303        FunctionReference::new(instantiation(utf_codepoint_function_type()))
1304    }
1305
1306    fn float_function_reference() -> FunctionReference {
1307        FunctionReference::new(instantiation(float_function_type()))
1308    }
1309
1310    fn bool_function_reference() -> FunctionReference {
1311        FunctionReference::new(instantiation(bool_function_type()))
1312    }
1313
1314    fn nil_function_reference() -> FunctionReference {
1315        FunctionReference::new(instantiation(nil_type()))
1316    }
1317
1318    fn tuple_function_reference() -> FunctionReference {
1319        FunctionReference::new(instantiation(tuple_function_type()))
1320    }
1321
1322    fn list_function_reference() -> FunctionReference {
1323        FunctionReference::new(instantiation(list_function_type()))
1324    }
1325
1326    fn function_function_reference() -> FunctionReference {
1327        FunctionReference::new(instantiation(function_function_type()))
1328    }
1329
1330    fn int_function_value() -> IntFunctionExpr {
1331        IntFunctionExpr::reference(IntFunctionReference::new(
1332            instantiation(int_function_type()),
1333        ))
1334    }
1335
1336    fn string_function_value() -> StringFunctionExpr {
1337        StringFunctionExpr::reference(StringFunctionReference::new(instantiation(
1338            string_function_type(),
1339        )))
1340    }
1341
1342    fn bit_array_function_value() -> BitArrayFunctionExpr {
1343        BitArrayFunctionExpr::reference(BitArrayFunctionReference::new(instantiation(
1344            bit_array_function_type(),
1345        )))
1346    }
1347
1348    fn utf_codepoint_function_value() -> UtfCodepointFunctionExpr {
1349        UtfCodepointFunctionExpr::reference(UtfCodepointFunctionReference::new(instantiation(
1350            utf_codepoint_function_type(),
1351        )))
1352    }
1353
1354    fn float_function_value() -> FloatFunctionExpr {
1355        FloatFunctionExpr::reference(FloatFunctionReference::new(instantiation(
1356            float_function_type(),
1357        )))
1358    }
1359
1360    fn bool_function_value() -> BoolFunctionExpr {
1361        BoolFunctionExpr::reference(BoolFunctionReference::new(instantiation(
1362            bool_function_type(),
1363        )))
1364    }
1365
1366    fn nil_function_value() -> NilFunctionExpr {
1367        NilFunctionExpr::reference(NilFunctionReference::new(instantiation(nil_type())))
1368    }
1369
1370    fn tuple_function_value() -> TupleFunctionExpr {
1371        TupleFunctionExpr::reference(TupleFunctionReference::new(instantiation(
1372            tuple_function_type(),
1373        )))
1374    }
1375
1376    fn list_function_value() -> ListFunctionExpr {
1377        ListFunctionExpr::reference(
1378            ListFunctionReference::new(instantiation(list_function_type())),
1379            ValueType::Int,
1380        )
1381    }
1382
1383    fn function_function_value() -> FunctionFunctionExpr {
1384        FunctionFunctionExpr::reference(
1385            FunctionFunctionReference::new(instantiation(function_function_type())),
1386            int_function_type(),
1387        )
1388    }
1389
1390    fn instantiation(type_: FunctionType) -> FunctionInstantiation {
1391        monomorphic_function_instantiation(0, FunctionShape::from_function_type(type_))
1392    }
1393
1394    fn int_function_type() -> FunctionType {
1395        FunctionType::new(vec![ValueType::Int], ValueType::Int)
1396    }
1397
1398    fn string_function_type() -> FunctionType {
1399        FunctionType::new(vec![ValueType::String], ValueType::String)
1400    }
1401
1402    fn bit_array_function_type() -> FunctionType {
1403        FunctionType::new(vec![ValueType::BitArray], ValueType::BitArray)
1404    }
1405
1406    fn utf_codepoint_function_type() -> FunctionType {
1407        FunctionType::new(vec![ValueType::UtfCodepoint], ValueType::UtfCodepoint)
1408    }
1409
1410    fn float_function_type() -> FunctionType {
1411        FunctionType::new(vec![ValueType::Float], ValueType::Float)
1412    }
1413
1414    fn bool_function_type() -> FunctionType {
1415        FunctionType::new(vec![ValueType::Bool], ValueType::Bool)
1416    }
1417
1418    fn nil_type() -> FunctionType {
1419        FunctionType::new(vec![ValueType::Nil], ValueType::Nil)
1420    }
1421
1422    fn tuple_function_type() -> FunctionType {
1423        FunctionType::new(
1424            vec![ValueType::Tuple(vec![ValueType::Int])],
1425            ValueType::Tuple(vec![ValueType::Int]),
1426        )
1427    }
1428
1429    fn list_function_type() -> FunctionType {
1430        FunctionType::new(
1431            vec![ValueType::List(Box::new(ValueType::Int))],
1432            ValueType::List(Box::new(ValueType::Int)),
1433        )
1434    }
1435
1436    fn function_function_type() -> FunctionType {
1437        FunctionType::new(
1438            Vec::new(),
1439            ValueType::Function(Box::new(FunctionType::new(
1440                vec![ValueType::Int],
1441                ValueType::Int,
1442            ))),
1443        )
1444    }
1445}