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