swamp_script_semantic/
lib.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/script
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5pub mod intr;
6pub mod modules;
7pub mod ns;
8pub mod prelude;
9pub mod symtbl;
10
11use crate::intr::IntrinsicFunction;
12pub use fixed32::Fp;
13use seq_map::SeqMap;
14use std::cmp::PartialEq;
15use std::fmt;
16use std::fmt::{Debug, Display, Formatter};
17use std::rc::Rc;
18use swamp_script_node::Node;
19use swamp_script_types::prelude::*;
20use tracing::error;
21
22#[derive(Debug, Clone)]
23pub struct TypeWithMut {
24    pub resolved_type: Type,
25    pub is_mutable: bool,
26}
27
28#[derive(Debug)]
29pub enum SemanticError {
30    CouldNotInsertStruct,
31    DuplicateTypeAlias(String),
32    CanOnlyUseStructForMemberFunctions,
33    ResolveNotStruct,
34    DuplicateStructName(String),
35    DuplicateEnumType(String),
36    DuplicateEnumVariantType(String, String),
37    DuplicateFieldName(String),
38    DuplicateExternalFunction(String),
39    DuplicateRustType(String),
40    DuplicateConstName(String),
41    CircularConstantDependency(Vec<ConstantId>),
42    DuplicateConstantId(ConstantId),
43    IncompatibleTypes,
44    WasNotImmutable,
45    WasNotMutable,
46    DuplicateSymbolName,
47    DuplicateNamespaceLink(String),
48    MismatchedTypes { expected: Type, found: Vec<Type> },
49    UnknownImplOnType,
50}
51
52#[derive(Debug, Eq, PartialEq)]
53pub struct LocalIdentifier(pub Node);
54
55//#[derive(Debug)]
56pub struct InternalFunctionDefinition {
57    pub body: Expression,
58    pub name: LocalIdentifier,
59    pub assigned_name: String,
60    pub signature: Signature,
61}
62
63impl Debug for InternalFunctionDefinition {
64    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
65        write!(f, "{:?}\n{:?}", self.signature, self.body)
66    }
67}
68
69impl PartialEq<Self> for InternalFunctionDefinition {
70    fn eq(&self, other: &Self) -> bool {
71        self.name == other.name
72    }
73}
74
75impl Eq for InternalFunctionDefinition {}
76
77pub type InternalFunctionDefinitionRef = Rc<InternalFunctionDefinition>;
78
79pub type ExternalFunctionId = u32;
80
81pub type ConstantId = u32;
82
83pub struct ExternalFunctionDefinition {
84    pub name: Option<Node>,
85    pub assigned_name: String,
86    pub signature: Signature,
87    pub id: ExternalFunctionId,
88}
89
90impl PartialEq<Self> for ExternalFunctionDefinition {
91    fn eq(&self, other: &Self) -> bool {
92        self.id == other.id
93    }
94}
95
96impl Eq for ExternalFunctionDefinition {}
97
98impl Debug for ExternalFunctionDefinition {
99    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
100        write!(f, "external fn")
101    }
102}
103
104pub type ExternalFunctionDefinitionRef = Rc<crate::ExternalFunctionDefinition>;
105
106#[derive(Debug)]
107pub struct Variable {
108    pub name: Node,
109    pub resolved_type: Type,
110    pub mutable_node: Option<Node>,
111
112    pub scope_index: usize,
113    pub variable_index: usize,
114}
115
116impl Variable {
117    #[must_use]
118    pub const fn is_mutable(&self) -> bool {
119        self.mutable_node.is_some()
120    }
121}
122
123pub type VariableRef = Rc<Variable>;
124
125#[derive(Debug)]
126pub struct MutVariable {
127    pub variable_ref: VariableRef,
128}
129
130//type MutVariableRef = Rc<MutVariable>;
131
132#[derive(Debug)]
133pub enum BinaryOperatorKind {
134    Add,
135    Subtract,
136    Multiply,
137    Divide,
138    Modulo,
139    LogicalOr,
140    LogicalAnd,
141    Equal,
142    NotEqual,
143    LessThan,
144    LessEqual,
145    GreaterThan,
146    GreaterEqual,
147    RangeExclusive,
148}
149
150#[derive(Debug)]
151pub struct BinaryOperator {
152    pub left: Box<Expression>,
153    pub right: Box<Expression>,
154    pub kind: BinaryOperatorKind,
155    pub node: Node,
156}
157
158#[derive(Debug)]
159pub enum UnaryOperatorKind {
160    Not,
161    Negate,
162}
163#[derive(Debug)]
164pub struct UnaryOperator {
165    pub left: Box<Expression>,
166    pub kind: UnaryOperatorKind,
167    pub node: Node,
168}
169
170#[derive()]
171pub struct InternalFunctionCall {
172    pub arguments: Vec<ArgumentExpressionOrLocation>,
173
174    pub function_definition: InternalFunctionDefinitionRef,
175    pub function_expression: Box<Expression>,
176}
177
178impl Debug for InternalFunctionCall {
179    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
180        write!(
181            f,
182            "InFuncCall({:?} {:?})",
183            self.function_expression, self.arguments
184        )
185    }
186}
187
188#[derive(Debug)]
189pub struct ExternalFunctionCall {
190    pub arguments: Vec<ArgumentExpressionOrLocation>,
191    pub function_definition: ExternalFunctionDefinitionRef,
192    pub function_expression: Box<Expression>,
193}
194
195pub fn comma_tuple_ref<K: Display, V: Display>(values: &[(&K, &V)]) -> String {
196    let mut result = String::new();
197    for (i, (key, value)) in values.iter().enumerate() {
198        if i > 0 {
199            result.push_str(", ");
200        }
201        result.push_str(format!("{}: {}", key, value).as_str());
202    }
203    result
204}
205
206#[derive(Debug)]
207pub struct MemberCall {
208    pub function: FunctionRef,
209    pub arguments: Vec<ArgumentExpressionOrLocation>,
210}
211
212#[derive(Debug)]
213pub struct ArrayItem {
214    pub item_type: Type,
215    pub int_expression: Expression,
216    pub array_expression: Expression,
217    pub array_type: Type,
218}
219
220pub type ArrayItemRef = Rc<ArrayItem>;
221
222#[derive(Debug)]
223pub enum PrecisionType {
224    Float,
225    String,
226}
227
228#[derive(Debug)]
229pub enum FormatSpecifierKind {
230    LowerHex,                            // :x
231    UpperHex,                            // :X
232    Binary,                              // :b
233    Float,                               // :f
234    Precision(u32, Node, PrecisionType), // :..2f or :..5s
235}
236
237#[derive(Debug)]
238pub struct FormatSpecifier {
239    pub node: Node,
240    pub kind: FormatSpecifierKind,
241}
242
243#[derive(Debug)]
244pub enum StringPart {
245    Literal(Node, String),
246    Interpolation(Expression, Option<FormatSpecifier>),
247}
248
249pub type FunctionRef = Rc<Function>;
250
251#[derive(Debug, Eq, PartialEq)]
252pub enum Function {
253    Internal(InternalFunctionDefinitionRef),
254    External(ExternalFunctionDefinitionRef),
255}
256
257impl Function {
258    #[must_use]
259    pub fn name(&self) -> String {
260        match self {
261            Self::Internal(x) => x.assigned_name.clone(),
262            Self::External(y) => y.assigned_name.clone(),
263        }
264    }
265
266    #[must_use]
267    pub fn maybe_node(&self) -> Option<&Node> {
268        match self {
269            Self::Internal(x) => Some(&x.name.0),
270            Self::External(y) => y.name.as_ref(),
271        }
272    }
273
274    #[must_use]
275    pub fn node(&self) -> Node {
276        match self {
277            Self::Internal(x) => x.name.0.clone(),
278            Self::External(_y) => Node::new_unknown(),
279        }
280    }
281
282    #[must_use]
283    pub fn signature(&self) -> &Signature {
284        match self {
285            Self::Internal(internal) => &internal.signature,
286            Self::External(external) => &external.signature,
287        }
288    }
289}
290
291#[derive(Debug)]
292pub struct BooleanExpression {
293    #[allow(unused)]
294    pub expression: Box<Expression>,
295}
296
297#[derive(Debug)]
298pub struct Match {
299    pub arms: Vec<MatchArm>,
300    pub expression: Box<MutOrImmutableExpression>,
301}
302
303#[derive(Debug)]
304pub struct MatchArm {
305    #[allow(unused)]
306    pub pattern: Pattern,
307    pub expression: Box<Expression>,
308    pub expression_type: Type,
309}
310
311#[derive(Debug)]
312pub enum Pattern {
313    Normal(NormalPattern, Option<BooleanExpression>),
314    Wildcard(Node),
315}
316
317#[derive(Debug)]
318pub enum NormalPattern {
319    PatternList(Vec<PatternElement>),
320    EnumPattern(EnumVariantTypeRef, Option<Vec<PatternElement>>),
321    Literal(Literal),
322}
323
324#[derive(Debug)]
325pub enum PatternElement {
326    Variable(VariableRef),
327    VariableWithFieldIndex(VariableRef, usize),
328    Wildcard(Node),
329}
330
331#[derive(Debug)]
332pub struct Iterable {
333    pub key_type: Option<Type>, // It does not have to support a key type
334    pub value_type: Type,
335
336    pub resolved_expression: Box<MutOrImmutableExpression>,
337}
338
339#[derive(Debug)]
340pub struct StructInstantiation {
341    pub source_order_expressions: Vec<(usize, Expression)>,
342    pub struct_type_ref: NamedStructTypeRef,
343}
344
345#[derive(Debug)]
346pub struct AnonymousStructLiteral {
347    pub source_order_expressions: Vec<(usize, Expression)>,
348    pub anonymous_struct_type: AnonymousStructType,
349}
350
351#[derive(Debug, Eq, PartialEq)]
352pub enum CompoundOperatorKind {
353    Add,
354    Sub,
355    Mul,
356    Div,
357    Modulo,
358}
359
360#[derive(Debug)]
361pub struct CompoundOperator {
362    pub node: Node,
363    pub kind: CompoundOperatorKind,
364}
365
366#[derive(Debug)]
367pub struct VariableCompoundAssignment {
368    pub variable_ref: VariableRef, // compound only support single variable
369    pub expression: Box<Expression>,
370    pub compound_operator: CompoundOperator,
371}
372
373pub fn create_rust_type(name: &str, type_number: TypeNumber) -> ExternalTypeRef {
374    let rust_type = ExternalType {
375        type_name: name.to_string(),
376        number: type_number,
377    };
378    Rc::new(rust_type)
379}
380
381#[derive(Debug)]
382pub struct Guard {
383    pub condition: Option<BooleanExpression>,
384    pub result: Expression,
385}
386
387#[derive(Debug, Clone, Eq, PartialEq)]
388pub enum RangeMode {
389    Inclusive,
390    Exclusive,
391}
392
393#[derive(Debug)]
394pub struct Postfix {
395    pub node: Node,
396    pub ty: Type,
397    pub kind: PostfixKind,
398}
399
400#[derive(Debug)]
401pub struct Range {
402    pub min: Expression,
403    pub max: Expression,
404    pub mode: RangeMode,
405}
406
407#[derive(Debug)]
408pub enum PostfixKind {
409    StructField(AnonymousStructType, usize),
410    ArrayIndex(Type, Expression),
411    ArrayRangeIndex(Type, Range),
412    StringIndex(Expression),
413    StringRangeIndex(Range),
414    MapIndex(Type, Type, Expression),
415    ExternalTypeIndexRef(ExternalTypeRef, Expression),
416    MemberCall(FunctionRef, Vec<ArgumentExpressionOrLocation>),
417    FunctionCall(Vec<ArgumentExpressionOrLocation>),
418    OptionUnwrap, // ? operator
419    NoneCoalesce(Expression),
420
421    IntrinsicCallEx(IntrinsicFunction, Vec<ArgumentExpressionOrLocation>),
422    IntrinsicCall(IntrinsicFunction, Vec<Expression>),
423}
424
425#[derive(Debug)]
426pub enum LocationAccessKind {
427    FieldIndex(AnonymousStructType, usize),
428    ArrayIndex(Type, Expression),
429    ArrayRange(Type, Range),
430    StringIndex(Expression),
431    StringRange(Range),
432    MapIndex(Type, Type, Expression),
433    MapIndexInsertIfNonExisting(Type, Type, Expression),
434    ExternalTypeIndex(ExternalTypeRef, Expression),
435}
436
437#[derive(Debug)]
438pub struct LocationAccess {
439    pub node: Node,
440    pub ty: Type,
441    pub kind: LocationAccessKind,
442}
443
444#[derive(Debug)]
445pub struct SingleLocationExpression {
446    pub kind: SingleLocationExpressionKind,
447    pub node: Node,
448    pub ty: Type,
449
450    pub starting_variable: VariableRef,
451    pub access_chain: Vec<LocationAccess>,
452}
453
454#[derive(Debug)]
455pub struct SingleMutLocationExpression(pub SingleLocationExpression);
456
457#[derive(Debug)]
458pub enum SingleLocationExpressionKind {
459    MutVariableRef,
460    MutStructFieldRef(NamedStructTypeRef, usize),
461    MutArrayIndexRef(Type),
462    MutMapIndexRef(Type, Type),
463    MutExternalTypeIndexRef(ExternalTypeRef),
464}
465
466#[derive(Debug)]
467pub struct SliceLocationExpression {
468    pub start: Box<Expression>,
469    pub range_start: Box<Expression>,
470    pub range_end: Box<Expression>,
471    pub mode: RangeMode,
472    pub ty: Type,
473}
474
475#[derive(Debug)]
476pub struct MutOrImmutableExpression {
477    pub expression_or_location: ArgumentExpressionOrLocation,
478    pub is_mutable: Option<Node>,
479}
480
481impl MutOrImmutableExpression {}
482
483impl MutOrImmutableExpression {
484    pub fn expect_immutable(self) -> Result<Expression, SemanticError> {
485        match self.expression_or_location {
486            ArgumentExpressionOrLocation::Expression(expr) => Ok(expr),
487            ArgumentExpressionOrLocation::Location(_) => Err(SemanticError::WasNotImmutable),
488        }
489    }
490
491    pub fn expect_immutable_ref(&self) -> Result<&Expression, SemanticError> {
492        match &self.expression_or_location {
493            ArgumentExpressionOrLocation::Expression(expr) => Ok(expr),
494            ArgumentExpressionOrLocation::Location(_) => Err(SemanticError::WasNotImmutable),
495        }
496    }
497
498    pub fn ty(&self) -> &Type {
499        match &self.expression_or_location {
500            ArgumentExpressionOrLocation::Expression(expr) => &expr.ty,
501            ArgumentExpressionOrLocation::Location(loc) => &loc.ty,
502        }
503    }
504}
505
506#[derive(Debug)]
507pub enum ArgumentExpressionOrLocation {
508    Expression(Expression),
509    Location(SingleLocationExpression),
510}
511
512#[derive()]
513pub struct Expression {
514    pub ty: Type,
515    pub node: Node,
516    pub kind: ExpressionKind,
517}
518
519impl Debug for Expression {
520    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
521        write!(f, "{:?}{},{:?}", self.node, self.ty, self.kind)
522    }
523}
524
525#[derive(Debug)]
526pub struct WhenBinding {
527    pub variable: VariableRef,
528    pub expr: MutOrImmutableExpression,
529}
530
531#[derive(Debug)]
532pub enum ExpressionKind {
533    // Access Lookup values
534    ConstantAccess(ConstantRef),
535    VariableAccess(VariableRef),
536    FieldAccess(Box<Expression>, usize),
537    ArrayAccess(
538        Box<Expression>,
539        Type,
540        Box<Expression>, // int index lookup
541    ), // Read from an array: arr[3]
542    MapIndexAccess(Box<Expression>, Type, Type, Box<Expression>),
543    StringRangeAccess(Box<Expression>, Box<Range>),
544    ArrayRangeAccess(Box<Expression>, Box<Range>),
545
546    // ----
547    InternalFunctionAccess(InternalFunctionDefinitionRef),
548    ExternalFunctionAccess(ExternalFunctionDefinitionRef),
549
550    // Adding to a collection
551    MapAssignment(
552        Box<SingleMutLocationExpression>,
553        Box<Expression>,
554        Box<Expression>,
555    ), // Motivation: Can not use location since adding is more complex
556
557    // Operators
558    BinaryOp(BinaryOperator),
559    UnaryOp(UnaryOperator),
560    PostfixChain(Box<Expression>, Vec<Postfix>),
561
562    // Conversion
563    // the `?` operator. unwraps the value, unless it is none
564    //NoneCoalesceOperator(Box<Expression>, Box<Expression>),
565    CoerceOptionToBool(Box<Expression>),
566
567    // Calls
568
569    // For calls from returned function values
570    FunctionCall(
571        Signature,
572        Box<Expression>,
573        Vec<ArgumentExpressionOrLocation>,
574    ),
575
576    MemberCall(MemberCall),
577    InterpolatedString(Vec<StringPart>),
578
579    // Constructing
580    VariableDefinition(VariableRef, Box<MutOrImmutableExpression>), // First time assignment
581    VariableReassignment(VariableRef, Box<MutOrImmutableExpression>),
582
583    StructInstantiation(StructInstantiation),
584    AnonymousStructLiteral(AnonymousStructLiteral),
585    Array(ArrayInstantiation),
586    Tuple(Vec<Expression>),
587    Literal(Literal),
588    Option(Option<Box<Expression>>), // Wrapping an expression in `Some()`
589    Range(Box<Expression>, Box<Expression>, RangeMode),
590
591    // Control
592    ForLoop(ForPattern, Iterable, Box<Expression>),
593    WhileLoop(BooleanExpression, Box<Expression>),
594    Return(Option<Box<Expression>>),
595    Break,
596    Continue, //
597
598    Block(Vec<Expression>),
599
600    // Match and compare
601    Match(Match),
602    Guard(Vec<Guard>),
603    If(BooleanExpression, Box<Expression>, Option<Box<Expression>>),
604
605    When(Vec<WhenBinding>, Box<Expression>, Option<Box<Expression>>),
606
607    TupleDestructuring(Vec<VariableRef>, Vec<Type>, Box<Expression>),
608
609    Assignment(Box<SingleMutLocationExpression>, Box<Expression>),
610    AssignmentSlice(Box<SliceLocationExpression>, Box<Expression>),
611    CompoundAssignment(
612        SingleMutLocationExpression,
613        CompoundOperatorKind,
614        Box<Expression>,
615    ),
616
617    // --------------------------------------------------------------------
618    // Built In members
619    // --------------------------------------------------------------------
620    IntrinsicCallMut(
621        IntrinsicFunction,
622        SingleMutLocationExpression,
623        Vec<Expression>,
624    ),
625
626    IntrinsicCallGeneric(IntrinsicFunction, Vec<Type>, Vec<Expression>),
627}
628
629#[derive(Debug)]
630pub struct StringConst(pub Node);
631
632#[derive(Debug)]
633pub enum Literal {
634    FloatLiteral(Fp),
635    NoneLiteral,
636    IntLiteral(i32),
637    StringLiteral(String),
638    BoolLiteral(bool),
639
640    EnumVariantLiteral(EnumVariantTypeRef, EnumLiteralData),
641    TupleLiteral(Vec<Type>, Vec<Expression>),
642
643    Vec(Type, Vec<Expression>),
644    Map(Type, Type, Vec<(Expression, Expression)>),
645
646    Slice(Type, Vec<Expression>),
647    SlicePair(Type, Type, Vec<(Expression, Expression)>),
648}
649
650#[derive(Debug)]
651pub struct ArrayInstantiation {
652    pub expressions: Vec<Expression>,
653    pub item_type: Type,
654    pub array_type: Type,
655    pub array_type_ref: Type,
656}
657
658#[derive(Debug)]
659pub enum ForPattern {
660    Single(VariableRef),
661    Pair(VariableRef, VariableRef),
662}
663
664impl ForPattern {
665    #[must_use]
666    pub fn is_mutable(&self) -> bool {
667        match self {
668            Self::Single(variable) => variable.is_mutable(),
669            Self::Pair(a, b) => a.is_mutable() || b.is_mutable(),
670        }
671    }
672}
673
674impl Display for ForPattern {
675    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
676        write!(f, "resolved_for_pattern")
677    }
678}
679
680#[derive(Debug, Eq, PartialEq)]
681pub struct ModulePathItem(pub Node);
682
683#[derive(Debug, Clone, Eq, PartialEq)]
684pub struct LocalTypeIdentifier(pub Node);
685
686#[derive(Debug)]
687pub struct Constant {
688    pub name: Node,
689    pub assigned_name: String,
690    pub id: ConstantId,
691    pub expr: Expression,
692    pub resolved_type: Type,
693}
694pub type ConstantRef = Rc<Constant>;
695
696pub type OptionTypeRef = Rc<crate::OptionType>;
697
698#[derive(Debug)]
699pub struct OptionType {
700    pub item_type: Type,
701}
702
703/*
704pub fn sort_struct_fields(
705    unordered_seq_map: &SeqMap<String, StructTypeField>,
706) -> SeqMap<String, StructTypeField> {
707    let mut sorted_pairs: Vec<(&String, &StructTypeField)> = unordered_seq_map.iter().collect();
708    sorted_pairs.sort_by(|a, b| a.0.cmp(b.0));
709    let mut ordered_seq_map = SeqMap::new();
710
711    for (name, field) in sorted_pairs {
712        ordered_seq_map.insert(name, field).unwrap() // We know already that the key fields are unique
713    }
714
715    ordered_seq_map
716}
717
718 */
719
720#[derive(Debug)]
721pub struct ImplMember {}
722
723#[derive(Debug)]
724pub enum UseItem {
725    Identifier(Node),
726    TypeIdentifier(Node),
727}
728
729#[derive(Debug)]
730pub struct Use {
731    pub path: Vec<Node>,
732    pub items: Vec<UseItem>,
733}
734
735#[derive(Debug)]
736pub struct ImplFunctions {
737    pub functions: SeqMap<String, FunctionRef>,
738}
739
740impl Default for ImplFunctions {
741    fn default() -> Self {
742        Self::new()
743    }
744}
745
746impl ImplFunctions {
747    #[must_use]
748    pub fn new() -> Self {
749        Self {
750            functions: SeqMap::default(),
751        }
752    }
753}
754
755#[derive(Debug)]
756pub struct AssociatedImpls {
757    pub functions: SeqMap<TypeNumber, ImplFunctions>,
758}
759
760impl Default for AssociatedImpls {
761    fn default() -> Self {
762        Self::new()
763    }
764}
765
766impl AssociatedImpls {
767    #[must_use]
768    pub fn new() -> Self {
769        Self {
770            functions: SeqMap::default(),
771        }
772    }
773}
774
775impl AssociatedImpls {
776    pub fn prepare(&mut self, ty: &Type) {
777        let type_id = ty.id().expect(&format!("type can not be attached to {ty}"));
778        self.functions
779            .insert(type_id, ImplFunctions::new())
780            .expect("should work");
781    }
782    #[must_use]
783    pub fn get_member_function(&self, ty: &Type, function_name: &str) -> Option<&FunctionRef> {
784        let type_id = ty.id().expect(&format!("type can not be attached to {ty}"));
785        let maybe_found_impl = self.functions.get(&type_id);
786        if let Some(found_impl) = maybe_found_impl {
787            if let Some(func) = found_impl.functions.get(&function_name.to_string()) {
788                return Some(func);
789            }
790        }
791        None
792    }
793
794    pub fn get_internal_member_function(
795        &self,
796        ty: &Type,
797        function_name: &str,
798    ) -> Option<&InternalFunctionDefinitionRef> {
799        if let Some(found) = self.get_member_function(ty, function_name) {
800            if let Function::Internal(int_fn) = &**found {
801                return Some(int_fn);
802            }
803        }
804        None
805    }
806
807    pub fn add_member_function(
808        &mut self,
809        ty: &Type,
810        name: &str,
811        func: FunctionRef,
812    ) -> Result<(), SemanticError> {
813        let type_id = ty.id().expect("type can not have associated functions");
814        let maybe_found_impl = self.functions.get_mut(&type_id);
815
816        if let Some(found_impl) = maybe_found_impl {
817            found_impl
818                .functions
819                .insert(name.to_string(), func)
820                .expect("todo");
821            Ok(())
822        } else {
823            error!(%ty, %type_id, ?name, "wasn't prepared");
824            Err(SemanticError::UnknownImplOnType)
825        }
826    }
827
828    pub fn add_external_member_function(
829        &mut self,
830        ty: &Type,
831        func: ExternalFunctionDefinition,
832    ) -> Result<(), SemanticError> {
833        self.add_member_function(
834            ty,
835            &func.assigned_name.clone(),
836            Function::External(func.into()).into(),
837        )
838    }
839
840    pub fn add_external_struct_member_function(
841        &mut self,
842        named_struct_type: &NamedStructTypeRef,
843        func: Function,
844    ) -> Result<(), SemanticError> {
845        self.add_member_function(
846            &Type::NamedStruct(named_struct_type.clone()),
847            &func.name().clone(),
848            func.into(),
849        )
850    }
851
852    pub fn add_external_struct_member_function_external(
853        &mut self,
854        named_struct_type: NamedStructTypeRef,
855        func: ExternalFunctionDefinition,
856    ) -> Result<(), SemanticError> {
857        self.add_member_function(
858            &Type::NamedStruct(named_struct_type.clone()),
859            &func.assigned_name.clone(),
860            Function::External(func.into()).into(),
861        )
862    }
863
864    pub fn add_external_struct_member_function_external_ref(
865        &mut self,
866        named_struct_type: NamedStructTypeRef,
867        func: ExternalFunctionDefinitionRef,
868    ) -> Result<(), SemanticError> {
869        self.add_member_function(
870            &Type::NamedStruct(named_struct_type.clone()),
871            &func.assigned_name.clone(),
872            Function::External(func.into()).into(),
873        )
874    }
875}
876
877// Mutable part
878#[derive(Debug)]
879pub struct ProgramState {
880    pub number: TypeNumber,
881    pub external_function_number: ExternalFunctionId,
882    // It is just so we don't have to do another dependency check of the
883    // modules, we know that these constants have been
884    // evaluated in order already
885    pub constants_in_dependency_order: Vec<ConstantRef>,
886    pub associated_impls: AssociatedImpls,
887}
888
889impl Default for ProgramState {
890    fn default() -> Self {
891        Self::new()
892    }
893}
894
895impl ProgramState {
896    #[must_use]
897    pub fn new() -> Self {
898        Self {
899            number: 0,
900            external_function_number: 0,
901            constants_in_dependency_order: Vec::new(),
902            associated_impls: AssociatedImpls::new(),
903        }
904    }
905
906    pub fn allocate_number(&mut self) -> TypeNumber {
907        self.number += 1;
908        self.number
909    }
910
911    pub fn allocate_external_function_id(&mut self) -> ExternalFunctionId {
912        self.external_function_number += 1;
913        self.external_function_number
914    }
915}
916
917#[derive()]
918pub enum EnumLiteralData {
919    Nothing,
920    Tuple(Vec<Expression>),
921    Struct(Vec<(usize, Expression)>),
922}
923
924impl Debug for EnumLiteralData {
925    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
926        match self {
927            Self::Nothing => Ok(()),
928            Self::Tuple(x) => write!(f, "{x:?}"),
929            Self::Struct(s) => write!(f, "{s:?}"),
930        }
931    }
932}