1pub mod inst_cache;
6pub mod instantiator;
7pub mod intr;
8pub mod prelude;
9pub mod type_var_stack;
10use crate::instantiator::Instantiator;
11use crate::intr::IntrinsicFunction;
12use crate::prelude::IntrinsicFunctionDefinitionRef;
13pub use fixed32::Fp;
14use seq_map::SeqMap;
15use source_map_node::Node;
16use std::cmp::PartialEq;
17use std::fmt;
18use std::fmt::{Debug, Display, Formatter};
19use std::rc::Rc;
20use swamp_types::GenericAwareSignature;
21use swamp_types::prelude::*;
22use tracing::error;
23
24#[derive(Debug, Clone)]
25pub struct TypeWithMut {
26 pub resolved_type: Type,
27 pub is_mutable: bool,
28}
29
30#[derive(Debug, Clone)]
31pub enum SemanticError {
32 CouldNotInsertStruct,
33 DuplicateTypeAlias(String),
34 CanOnlyUseStructForMemberFunctions,
35 ResolveNotStruct,
36 DuplicateStructName(String),
37 DuplicateEnumType(String),
38 DuplicateEnumVariantType(String, String),
39 DuplicateFieldName(String),
40 DuplicateExternalFunction(String),
41 DuplicateRustType(String),
42 DuplicateConstName(String),
43 CircularConstantDependency(Vec<ConstantId>),
44 DuplicateConstantId(ConstantId),
45 IncompatibleTypes,
46 WasNotImmutable,
47 WasNotMutable,
48 DuplicateSymbolName(String),
49 DuplicateNamespaceLink(String),
50 MismatchedTypes { expected: Type, found: Vec<Type> },
51 UnknownImplOnType,
52 UnknownTypeVariable,
53}
54
55#[derive(Debug, Eq, PartialEq)]
56pub struct LocalIdentifier(pub Node);
57
58#[derive(Debug)]
59pub struct InternalMainExpression {
60 pub expression: Expression,
61 pub function_scope_state: Vec<VariableRef>,
62 pub program_unique_id: InternalFunctionId,
63}
64
65pub struct InternalFunctionDefinition {
67 pub body: Expression,
68 pub name: LocalIdentifier,
69 pub assigned_name: String,
70 pub signature: GenericAwareSignature,
71 pub variable_scopes: FunctionScopeState,
72 pub function_scope_state: Vec<VariableRef>,
73 pub program_unique_id: InternalFunctionId,
74}
75
76impl Default for InternalFunctionDefinition {
77 fn default() -> Self {
78 Self {
79 body: Expression {
80 ty: Type::Never,
81 node: Node::default(),
82 kind: ExpressionKind::Block(vec![]),
83 },
84 name: LocalIdentifier(Node::default()),
85 assigned_name: String::new(),
86 signature: GenericAwareSignature {
87 signature: Signature {
88 parameters: vec![],
89 return_type: Box::new(Type::Never),
90 },
91 generic_type_variables: vec![],
92 },
93 variable_scopes: FunctionScopeState::new(),
94 function_scope_state: Vec::new(),
95 program_unique_id: 0,
96 }
97 }
98}
99
100impl Debug for InternalFunctionDefinition {
101 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
102 write!(f, "{:?}\n{:?}", self.signature, self.body)
103 }
104}
105
106impl PartialEq<Self> for InternalFunctionDefinition {
107 fn eq(&self, other: &Self) -> bool {
108 self.name == other.name
109 }
110}
111
112impl Eq for InternalFunctionDefinition {}
113
114pub type InternalFunctionDefinitionRef = Rc<InternalFunctionDefinition>;
115
116pub type ExternalFunctionId = u32;
117
118pub type InternalFunctionId = u16;
119
120pub type ConstantId = u32;
121
122#[derive(Eq, PartialEq)]
123pub struct ExternalFunctionDefinition {
124 pub name: Option<Node>,
125 pub assigned_name: String,
126 pub signature: Signature,
127 pub id: ExternalFunctionId,
128}
129
130impl Debug for ExternalFunctionDefinition {
131 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
132 write!(f, "external fn")
133 }
134}
135
136pub type ExternalFunctionDefinitionRef = Rc<crate::ExternalFunctionDefinition>;
137
138#[derive(Debug, Eq, Clone, PartialEq)]
139pub enum BlockScopeMode {
140 Open,
141 Closed,
142}
143
144#[derive(Debug, Clone)]
145pub struct BlockScope {
146 pub mode: BlockScopeMode,
147 pub variables: SeqMap<String, VariableRef>,
148}
149
150impl Display for BlockScope {
151 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
152 writeln!(f, "-- scope {:?}", self.mode)?;
153
154 for (index, (name, var)) in self.variables.iter().enumerate() {
155 writeln!(f, " var({index}): {name}:{var:?}")?;
156 }
157 Ok(())
158 }
159}
160
161impl Default for BlockScope {
162 fn default() -> Self {
163 Self::new()
164 }
165}
166
167impl BlockScope {
168 #[must_use]
169 pub fn new() -> Self {
170 Self {
171 mode: BlockScopeMode::Open,
172 variables: SeqMap::new(),
173 }
174 }
175}
176
177#[derive(Clone)]
178pub struct FunctionScopeState {
179 pub block_scope_stack: Vec<BlockScope>,
180 pub variable_index: usize,
182}
183
184impl Display for FunctionScopeState {
185 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
186 for (index, scope) in self.block_scope_stack.iter().enumerate() {
187 writeln!(f, "block({index}):\n{scope}")?;
188 }
189 Ok(())
190 }
191}
192
193impl FunctionScopeState {
194 pub fn gen_variable_index(&mut self) -> usize {
195 let index = self.variable_index;
196 self.variable_index += 1;
197 index
198 }
199}
200
201impl FunctionScopeState {
202 #[must_use]
203 pub fn new() -> Self {
204 Self {
205 block_scope_stack: vec![BlockScope::new()],
206 variable_index: 0,
208 }
209 }
210}
211
212#[derive(Debug, Clone)]
213pub struct Variable {
214 pub name: Node,
215 pub assigned_name: String,
216 pub resolved_type: Type,
217 pub mutable_node: Option<Node>,
218
219 pub scope_index: usize,
220 pub variable_index: usize,
221
222 pub unique_id_within_function: usize,
223 pub is_unused: bool,
224}
225
226impl Variable {
227 #[must_use]
228 pub const fn is_mutable(&self) -> bool {
229 self.mutable_node.is_some()
230 }
231}
232
233pub type VariableRef = Rc<Variable>;
234
235#[derive(Debug, Clone)]
236pub struct MutVariable {
237 pub variable_ref: VariableRef,
238}
239
240#[derive(Debug, Clone)]
243pub enum BinaryOperatorKind {
244 Add,
245 Subtract,
246 Multiply,
247 Divide,
248 Modulo,
249 LogicalOr,
250 LogicalAnd,
251 Equal,
252 NotEqual,
253 LessThan,
254 LessEqual,
255 GreaterThan,
256 GreaterEqual,
257 RangeExclusive,
258}
259
260#[derive(Debug, Clone)]
261pub struct BinaryOperator {
262 pub left: Box<Expression>,
263 pub right: Box<Expression>,
264 pub kind: BinaryOperatorKind,
265 pub node: Node,
266}
267
268#[derive(Debug, Clone)]
269pub enum UnaryOperatorKind {
270 Not,
271 Negate,
272}
273#[derive(Debug, Clone)]
274pub struct UnaryOperator {
275 pub left: Box<Expression>,
276 pub kind: UnaryOperatorKind,
277 pub node: Node,
278}
279
280#[derive()]
281pub struct InternalFunctionCall {
282 pub arguments: Vec<ArgumentExpressionOrLocation>,
283
284 pub function_definition: InternalFunctionDefinitionRef,
285 pub function_expression: Box<Expression>,
286}
287
288impl Debug for InternalFunctionCall {
289 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
290 write!(
291 f,
292 "InFuncCall({:?} {:?})",
293 self.function_expression, self.arguments
294 )
295 }
296}
297
298#[derive(Debug, Clone)]
299pub struct ExternalFunctionCall {
300 pub arguments: Vec<ArgumentExpressionOrLocation>,
301 pub function_definition: ExternalFunctionDefinitionRef,
302 pub function_expression: Box<Expression>,
303}
304
305pub fn comma_tuple_ref<K: Display, V: Display>(values: &[(&K, &V)]) -> String {
306 let mut result = String::new();
307 for (i, (key, value)) in values.iter().enumerate() {
308 if i > 0 {
309 result.push_str(", ");
310 }
311 result.push_str(format!("{key}: {value}").as_str());
312 }
313 result
314}
315
316#[derive(Debug, Clone)]
317pub struct MemberCall {
318 pub function: FunctionRef,
319 pub arguments: Vec<ArgumentExpressionOrLocation>,
320}
321
322#[derive(Debug, Clone)]
323pub struct ArrayItem {
324 pub item_type: Type,
325 pub int_expression: Expression,
326 pub array_expression: Expression,
327 pub array_type: Type,
328}
329
330pub type ArrayItemRef = Rc<ArrayItem>;
331
332#[derive(Debug, Clone)]
333pub enum PrecisionType {
334 Float,
335 String,
336}
337
338#[derive(Debug, Clone)]
339pub enum FormatSpecifierKind {
340 LowerHex, UpperHex, Binary, Float, Precision(u32, Node, PrecisionType), }
346
347#[derive(Debug, Clone)]
348pub struct FormatSpecifier {
349 pub node: Node,
350 pub kind: FormatSpecifierKind,
351}
352
353#[derive(Debug, Clone)]
354pub enum StringPart {
355 Literal(Node, String),
356 Interpolation(Expression, Option<FormatSpecifier>),
357}
358
359pub type FunctionRef = Rc<Function>;
360
361#[derive(Debug, Eq, Clone, PartialEq)]
362pub enum Function {
363 Internal(InternalFunctionDefinitionRef),
364 External(ExternalFunctionDefinitionRef),
365}
366
367impl Function {
368 #[must_use]
369 pub fn name(&self) -> String {
370 match self {
371 Self::Internal(x) => x.assigned_name.clone(),
372 Self::External(y) => y.assigned_name.clone(),
373 }
374 }
375
376 #[must_use]
377 pub fn maybe_node(&self) -> Option<&Node> {
378 match self {
379 Self::Internal(x) => Some(&x.name.0),
380 Self::External(y) => y.name.as_ref(),
381 }
382 }
383
384 #[must_use]
385 pub fn node(&self) -> Node {
386 match self {
387 Self::Internal(x) => x.name.0.clone(),
388 Self::External(_y) => Node::new_unknown(),
389 }
390 }
391
392 #[must_use]
393 pub fn signature(&self) -> &Signature {
394 match self {
395 Self::Internal(internal) => &internal.signature.signature,
396 Self::External(external) => &external.signature,
397 }
398 }
399
400 #[must_use]
401 pub fn signatures(&self) -> (Option<&GenericAwareSignature>, &Signature) {
402 match self {
403 Self::Internal(internal) => (Some(&internal.signature), &internal.signature.signature),
404 Self::External(external) => (None, &external.signature),
405 }
406 }
407}
408
409#[derive(Debug, Clone)]
410pub struct BooleanExpression {
411 #[allow(unused)]
412 pub expression: Box<Expression>,
413}
414
415#[derive(Debug, Clone)]
417pub struct Match {
418 pub arms: Vec<MatchArm>,
419 pub expression: Box<MutOrImmutableExpression>,
420}
421
422impl Match {
423 #[must_use]
424 pub fn contains_wildcard(&self) -> bool {
425 for arm in &self.arms {
426 if let Pattern::Wildcard(_) = arm.pattern {
427 return true;
428 }
429 }
430 false
431 }
432}
433
434#[derive(Debug, Clone)]
435pub struct MatchArm {
436 #[allow(unused)]
437 pub pattern: Pattern,
438 pub expression: Box<Expression>,
439 pub expression_type: Type,
440}
441
442#[derive(Debug, Clone)]
443pub enum Pattern {
444 Normal(NormalPattern, Option<BooleanExpression>),
445 Wildcard(Node),
446}
447
448#[derive(Debug, Clone)]
449pub enum NormalPattern {
450 PatternList(Vec<PatternElement>),
451 EnumPattern(EnumVariantType, Option<Vec<PatternElement>>),
452 Literal(Literal),
453}
454
455#[derive(Debug, Clone)]
456pub enum PatternElement {
457 Variable(VariableRef),
458 VariableWithFieldIndex(VariableRef, usize),
459 Wildcard(Node),
460}
461
462#[derive(Debug, Clone)]
463pub struct Iterable {
464 pub key_type: Option<Type>, pub value_type: Type,
466
467 pub resolved_expression: Box<MutOrImmutableExpression>,
468}
469
470#[derive(Debug, Clone)]
471pub struct StructInstantiation {
472 pub source_order_expressions: Vec<(usize, Expression)>,
473 pub struct_type_ref: NamedStructType,
474}
475
476#[derive(Debug, Clone)]
477pub struct AnonymousStructLiteral {
478 pub source_order_expressions: Vec<(usize, Expression)>,
479 pub anonymous_struct_type: AnonymousStructType,
480}
481
482#[derive(Debug, Clone, Eq, PartialEq)]
483pub enum CompoundOperatorKind {
484 Add,
485 Sub,
486 Mul,
487 Div,
488 Modulo,
489}
490
491#[derive(Debug, Clone)]
492pub struct CompoundOperator {
493 pub node: Node,
494 pub kind: CompoundOperatorKind,
495}
496
497#[derive(Debug, Clone)]
498pub struct VariableCompoundAssignment {
499 pub variable_ref: VariableRef, pub expression: Box<Expression>,
501 pub compound_operator: CompoundOperator,
502}
503
504#[must_use]
505pub fn create_rust_type(name: &str, external_number: u32) -> ExternalType {
506 ExternalType {
507 type_name: name.to_string(),
508 number: external_number,
509 }
510}
511
512#[derive(Debug, Clone)]
513pub struct Guard {
514 pub condition: Option<BooleanExpression>,
515 pub result: Expression,
516}
517
518#[derive(Debug, Clone)]
519pub struct Postfix {
520 pub node: Node,
521 pub ty: Type,
522 pub kind: PostfixKind,
523}
524
525#[derive(Debug, Clone)]
526pub enum PostfixKind {
527 StructField(AnonymousStructType, usize),
528 MemberCall(FunctionRef, Vec<ArgumentExpressionOrLocation>),
529 FunctionCall(Vec<ArgumentExpressionOrLocation>),
530 OptionalChainingOperator, NoneCoalescingOperator(Expression), }
533
534#[derive(Debug, Clone)]
535pub enum LocationAccessKind {
536 FieldIndex(AnonymousStructType, usize),
537 IntrinsicCallMut(IntrinsicFunction, Vec<Expression>),
538}
539
540#[derive(Debug, Clone)]
541pub struct LocationAccess {
542 pub node: Node,
543 pub ty: Type,
544 pub kind: LocationAccessKind,
545}
546
547#[derive(Debug, Clone)]
548pub struct SingleLocationExpression {
549 pub kind: SingleLocationExpressionKind,
550 pub node: Node,
551 pub ty: Type,
552
553 pub starting_variable: VariableRef,
554 pub access_chain: Vec<LocationAccess>,
555}
556
557#[derive(Debug, Clone)]
558pub struct SingleMutLocationExpression(pub SingleLocationExpression);
559
560#[derive(Debug, Clone)]
561pub enum SingleLocationExpressionKind {
562 MutVariableRef,
563 MutStructFieldRef(NamedStructType, usize),
564}
565
566#[derive(Debug, Clone)]
567pub struct MutOrImmutableExpression {
568 pub expression_or_location: ArgumentExpressionOrLocation,
569 pub is_mutable: Option<Node>,
570}
571
572impl MutOrImmutableExpression {
573 pub fn expect_immutable(self) -> Result<Expression, SemanticError> {
574 match self.expression_or_location {
575 ArgumentExpressionOrLocation::Expression(expr) => Ok(expr),
576 ArgumentExpressionOrLocation::Location(_) => Err(SemanticError::WasNotImmutable),
577 }
578 }
579
580 pub const fn expect_immutable_ref(&self) -> Result<&Expression, SemanticError> {
581 match &self.expression_or_location {
582 ArgumentExpressionOrLocation::Expression(expr) => Ok(expr),
583 ArgumentExpressionOrLocation::Location(_) => Err(SemanticError::WasNotImmutable),
584 }
585 }
586
587 #[must_use]
588 pub const fn ty(&self) -> &Type {
589 match &self.expression_or_location {
590 ArgumentExpressionOrLocation::Expression(expr) => &expr.ty,
591 ArgumentExpressionOrLocation::Location(loc) => &loc.ty,
592 }
593 }
594
595 #[must_use]
596 pub const fn node(&self) -> &Node {
597 match &self.expression_or_location {
598 ArgumentExpressionOrLocation::Expression(expr) => &expr.node,
599 ArgumentExpressionOrLocation::Location(loc) => &loc.node,
600 }
601 }
602}
603
604#[derive(Debug, Clone)]
605pub enum ArgumentExpressionOrLocation {
606 Expression(Expression),
607 Location(SingleLocationExpression),
608}
609
610impl ArgumentExpressionOrLocation {
611 #[must_use]
612 pub fn ty(&self) -> Type {
613 match self {
614 Self::Expression(expr) => expr.ty.clone(),
615 Self::Location(location) => location.ty.clone(),
616 }
617 }
618}
619
620#[derive(Clone)]
621pub struct Expression {
622 pub ty: Type,
623 pub node: Node,
624 pub kind: ExpressionKind,
625}
626
627impl Debug for Expression {
628 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
629 write!(f, "{:?}{},{:?}", self.node, self.ty, self.kind)
630 }
631}
632
633#[derive(Debug, Clone)]
634pub struct WhenBinding {
635 pub variable: VariableRef,
636 pub expr: MutOrImmutableExpression,
637}
638
639impl WhenBinding {
640 #[must_use]
641 pub const fn has_expression(&self) -> bool {
642 match &self.expr.expression_or_location {
643 ArgumentExpressionOrLocation::Expression(expr) => {
644 !matches!(expr.kind, ExpressionKind::VariableAccess(_))
645 }
646 ArgumentExpressionOrLocation::Location(_) => true,
647 }
648 }
649}
650
651#[derive(Debug, Clone)]
652pub enum ExpressionKind {
653 ConstantAccess(ConstantRef),
655 VariableAccess(VariableRef),
656
657 IntrinsicFunctionAccess(IntrinsicFunctionDefinitionRef),
659 InternalFunctionAccess(InternalFunctionDefinitionRef),
660 ExternalFunctionAccess(ExternalFunctionDefinitionRef),
661
662 BinaryOp(BinaryOperator),
664 UnaryOp(UnaryOperator),
665 PostfixChain(Box<Expression>, Vec<Postfix>),
666
667 CoerceOptionToBool(Box<Expression>),
670
671 FunctionValueCall(
675 Signature,
676 Box<Expression>,
677 Vec<ArgumentExpressionOrLocation>,
678 ),
679
680 InterpolatedString(Vec<StringPart>),
681
682 VariableDefinition(VariableRef, Box<MutOrImmutableExpression>), VariableReassignment(VariableRef, Box<MutOrImmutableExpression>),
685 Assignment(Box<SingleMutLocationExpression>, Box<Expression>),
686 CompoundAssignment(
687 SingleMutLocationExpression,
688 CompoundOperatorKind,
689 Box<Expression>,
690 ),
691
692 StructInstantiation(StructInstantiation),
693 AnonymousStructLiteral(AnonymousStructLiteral),
694 Literal(Literal),
695 Option(Option<Box<Expression>>), ForLoop(ForPattern, Iterable, Box<Expression>),
699 WhileLoop(BooleanExpression, Box<Expression>),
700
701 Block(Vec<Expression>),
702
703 Match(Match),
705 Guard(Vec<Guard>),
706 If(BooleanExpression, Box<Expression>, Option<Box<Expression>>),
707 When(Vec<WhenBinding>, Box<Expression>, Option<Box<Expression>>),
708
709 TupleDestructuring(Vec<VariableRef>, Vec<Type>, Box<Expression>),
710
711 IntrinsicCallEx(IntrinsicFunction, Vec<ArgumentExpressionOrLocation>),
715 Lambda(Vec<VariableRef>, Box<Expression>),
725}
726
727#[derive(Debug, Clone)]
728pub struct StringConst(pub Node);
729
730#[derive(Debug, Clone)]
731pub enum Literal {
732 FloatLiteral(Fp),
733 NoneLiteral,
734 IntLiteral(i32),
735 StringLiteral(String),
736 BoolLiteral(bool),
737
738 EnumVariantLiteral(EnumType, EnumVariantType, EnumLiteralData),
739 TupleLiteral(Vec<Type>, Vec<Expression>),
740
741 Slice(Type, Vec<Expression>),
742 SlicePair(Type, Vec<(Expression, Expression)>),
743}
744
745#[derive(Debug, Clone)]
746pub struct ArrayInstantiation {
747 pub expressions: Vec<Expression>,
748 pub item_type: Type,
749 pub array_type: Type,
750 pub array_type_ref: Type,
751}
752
753#[derive(Debug, Clone)]
754pub enum ForPattern {
755 Single(VariableRef),
756 Pair(VariableRef, VariableRef),
757}
758
759impl ForPattern {
760 #[must_use]
761 pub fn is_mutable(&self) -> bool {
762 match self {
763 Self::Single(variable) => variable.is_mutable(),
764 Self::Pair(a, b) => a.is_mutable() || b.is_mutable(),
765 }
766 }
767}
768
769impl Display for ForPattern {
770 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
771 write!(f, "resolved_for_pattern")
772 }
773}
774
775#[derive(Debug, Eq, PartialEq)]
776pub struct ModulePathItem(pub Node);
777
778#[derive(Debug, Clone, Eq, PartialEq)]
779pub struct LocalTypeIdentifier(pub Node);
780
781#[derive(Debug, Clone)]
782pub struct Constant {
783 pub name: Node,
784 pub assigned_name: String,
785 pub id: ConstantId,
786 pub expr: Expression,
787 pub resolved_type: Type,
788}
789pub type ConstantRef = Rc<Constant>;
790
791pub type OptionTypeRef = Rc<crate::OptionType>;
792
793#[derive(Debug, Clone)]
794pub struct OptionType {
795 pub item_type: Type,
796}
797
798#[derive(Debug, Clone)]
815pub struct ImplMember {}
816
817#[derive(Debug, Clone)]
818pub enum UseItem {
819 Identifier(Node),
820 TypeIdentifier(Node),
821}
822
823#[derive(Debug, Clone)]
824pub struct Use {
825 pub path: Vec<Node>,
826 pub items: Vec<UseItem>,
827}
828
829#[derive(Debug, Clone)]
830pub struct ImplFunctions {
831 pub functions: SeqMap<String, FunctionRef>,
832}
833
834impl Default for ImplFunctions {
835 fn default() -> Self {
836 Self::new()
837 }
838}
839
840impl ImplFunctions {
841 #[must_use]
842 pub fn new() -> Self {
843 Self {
844 functions: SeqMap::default(),
845 }
846 }
847}
848
849#[derive(Debug, Clone)]
850pub struct AssociatedImpls {
851 pub functions: SeqMap<Type, ImplFunctions>,
852}
853
854impl Default for AssociatedImpls {
855 fn default() -> Self {
856 Self::new()
857 }
858}
859
860impl AssociatedImpls {
861 #[must_use]
862 pub fn new() -> Self {
863 Self {
864 functions: SeqMap::default(),
865 }
866 }
867}
868
869impl AssociatedImpls {
870 pub fn prepare(&mut self, ty: &Type) {
871 self.functions
872 .insert(ty.clone(), ImplFunctions::new())
873 .expect("should work");
874 }
875 #[must_use]
876 pub fn get_member_function(&self, ty: &Type, function_name: &str) -> Option<&FunctionRef> {
877 let maybe_found_impl = self.functions.get(ty);
878 if let Some(found_impl) = maybe_found_impl {
879 if let Some(func) = found_impl.functions.get(&function_name.to_string()) {
880 return Some(func);
881 }
882 }
883 None
884 }
885
886 #[must_use]
887 pub fn api_get_external_function(
888 &self,
889 ty: &Type,
890 function_name: &str,
891 ) -> Option<&ExternalFunctionDefinitionRef> {
892 if let Some(found) = self.get_member_function(ty, function_name) {
893 if let Function::External(ext_fn) = &**found {
894 return Some(ext_fn);
895 }
896 }
897 None
898 }
899
900 #[must_use]
901 pub fn api_fetch_external_function_id(
902 &self,
903 ty: &Type,
904 function_name: &str,
905 ) -> ExternalFunctionId {
906 self.api_get_external_function(ty, function_name)
907 .unwrap()
908 .id
909 }
910
911 #[must_use]
912 pub fn get_internal_member_function(
913 &self,
914 ty: &Type,
915 function_name: &str,
916 ) -> Option<&InternalFunctionDefinitionRef> {
917 if let Some(found) = self.get_member_function(ty, function_name) {
918 if let Function::Internal(int_fn) = &**found {
919 return Some(int_fn);
920 }
921 }
922 None
923 }
924
925 pub fn add_member_function(
926 &mut self,
927 ty: &Type,
928 name: &str,
929 func: FunctionRef,
930 ) -> Result<(), SemanticError> {
931 let maybe_found_impl = self.functions.get_mut(ty);
932
933 if let Some(found_impl) = maybe_found_impl {
934 found_impl
935 .functions
936 .insert(name.to_string(), func)
937 .expect("todo");
938 Ok(())
939 } else {
940 error!(%ty, ?name, "wasn't prepared");
941 Err(SemanticError::UnknownImplOnType)
942 }
943 }
944
945 pub fn add_external_member_function(
946 &mut self,
947 ty: &Type,
948 func: ExternalFunctionDefinition,
949 ) -> Result<(), SemanticError> {
950 self.add_member_function(
951 ty,
952 &func.assigned_name.clone(),
953 Function::External(func.into()).into(),
954 )
955 }
956
957 pub fn add_external_struct_member_function(
958 &mut self,
959 named_struct_type: &NamedStructType,
960 func: Function,
961 ) -> Result<(), SemanticError> {
962 self.add_member_function(
963 &Type::NamedStruct(named_struct_type.clone()),
964 &func.name(),
965 func.into(),
966 )
967 }
968
969 pub fn add_external_struct_member_function_external(
970 &mut self,
971 named_struct_type: NamedStructType,
972 func: ExternalFunctionDefinition,
973 ) -> Result<(), SemanticError> {
974 self.add_member_function(
975 &Type::NamedStruct(named_struct_type),
976 &func.assigned_name.clone(),
977 Function::External(func.into()).into(),
978 )
979 }
980
981 pub fn add_external_struct_member_function_external_ref(
982 &mut self,
983 named_struct_type: NamedStructType,
984 func: ExternalFunctionDefinitionRef,
985 ) -> Result<(), SemanticError> {
986 self.add_member_function(
987 &Type::NamedStruct(named_struct_type),
988 &func.assigned_name.clone(),
989 Function::External(func).into(),
990 )
991 }
992}
993
994#[derive(Debug, Clone)]
996pub struct ProgramState {
997 pub external_function_number: ExternalFunctionId,
998 pub internal_function_id_allocator: InternalFunctionIdAllocator,
999 pub constants_in_dependency_order: Vec<ConstantRef>,
1003 pub instantiator: Instantiator,
1004}
1005
1006impl Default for ProgramState {
1007 fn default() -> Self {
1008 Self::new()
1009 }
1010}
1011
1012#[derive(Debug, Clone)]
1013pub struct InternalFunctionIdAllocator {
1014 pub internal_function_number: InternalFunctionId,
1015}
1016
1017impl Default for InternalFunctionIdAllocator {
1018 fn default() -> Self {
1019 Self::new()
1020 }
1021}
1022
1023impl InternalFunctionIdAllocator {
1024 #[must_use]
1025 pub const fn new() -> Self {
1026 Self {
1027 internal_function_number: 0,
1028 }
1029 }
1030 pub fn alloc(&mut self) -> InternalFunctionId {
1031 self.internal_function_number += 1;
1032 self.internal_function_number
1033 }
1034}
1035
1036impl ProgramState {
1037 #[must_use]
1038 pub fn new() -> Self {
1039 Self {
1040 external_function_number: 0,
1041 internal_function_id_allocator: InternalFunctionIdAllocator::new(),
1042 constants_in_dependency_order: Vec::new(),
1043 instantiator: Instantiator::new(),
1044 }
1045 }
1046
1047 pub fn allocate_external_function_id(&mut self) -> ExternalFunctionId {
1048 self.external_function_number += 1;
1049 self.external_function_number
1050 }
1051
1052 pub fn allocate_internal_function_id(&mut self) -> InternalFunctionId {
1053 self.internal_function_id_allocator.alloc()
1054 }
1055}
1056
1057#[derive(Clone)]
1058pub enum EnumLiteralData {
1059 Nothing,
1060 Tuple(Vec<Expression>),
1061 Struct(Vec<(usize, Expression)>),
1062}
1063
1064impl Debug for EnumLiteralData {
1065 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
1066 match self {
1067 Self::Nothing => Ok(()),
1068 Self::Tuple(x) => write!(f, "{x:?}"),
1069 Self::Struct(s) => write!(f, "{s:?}"),
1070 }
1071 }
1072}