1pub mod prelude;
7
8use fmt::{Debug, Display};
9use seq_fmt::comma;
10use seq_map::SeqMap;
11use std::cmp::PartialEq;
12use std::fmt;
13use std::hash::Hash;
14use swamp_script_node::Node;
15use tracing::info;
16
17#[derive(Eq, PartialEq, Hash, Clone)]
18pub enum Type {
19 Int,
21 Float,
22 String,
23 Bool,
24
25 Unit, Never, Slice(Box<Type>),
29 SlicePair(Box<Type>, Box<Type>),
30
31 Tuple(Vec<Type>),
33 NamedStruct(NamedStructType),
34 AnonymousStruct(AnonymousStructType),
35
36 Enum(EnumType),
37
38 Function(Signature),
39 Iterable(Box<Type>),
40
41 Optional(Box<Type>),
42
43 Generic(ParameterizedTypeBlueprint, Vec<Type>),
44 Blueprint(ParameterizedTypeBlueprint),
45 Variable(String),
46
47 MutableReference(Box<Type>),
48
49 External(ExternalType),
50}
51
52#[derive(Debug, Clone, PartialEq, Eq, Hash)]
53pub enum ParameterizedTypeKind {
54 Struct(NamedStructType),
55 Enum(EnumType),
56}
57
58impl ParameterizedTypeKind {
59 pub fn name(&self) -> String {
60 match self {
61 Self::Struct(struct_type_ref) => struct_type_ref.assigned_name.clone(),
62 Self::Enum(enum_type_ref) => enum_type_ref.assigned_name.clone(),
63 }
64 }
65}
66
67#[derive(Debug, PartialEq, Eq, Hash, Clone)]
68pub struct ParameterizedTypeBlueprint {
69 pub kind: ParameterizedTypeKind,
70 pub type_variables: Vec<String>,
71
72 pub defined_in_module_path: Vec<String>,
73}
74
75impl ParameterizedTypeBlueprint {
76 pub fn name(&self) -> String {
77 self.kind.name()
78 }
79}
80
81#[derive(Clone, Eq, PartialEq, Hash)]
82pub struct ParameterNode {
83 pub name: Node,
84 pub is_mutable: Option<Node>,
85}
86
87impl Debug for ParameterNode {
88 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89 write!(f, "Parameter")
90 }
91}
92
93impl ParameterNode {
94 #[inline]
95 #[must_use]
96 pub const fn is_mutable(&self) -> bool {
97 self.is_mutable.is_some()
98 }
99}
100
101#[derive(Debug, Clone, Eq, PartialEq, Hash)]
102pub struct ExternalType {
103 pub type_name: String, pub number: u32, }
106
107#[derive(Debug, Eq, PartialEq, Clone, Hash)]
108pub struct TypeForParameter {
109 pub name: String,
110 pub resolved_type: Type,
111 pub is_mutable: bool,
112 pub node: Option<ParameterNode>,
113}
114
115impl Display for TypeForParameter {
116 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
117 write!(
118 f,
119 "{}{}: {:?}",
120 if self.is_mutable { "mut " } else { "" },
121 self.name,
122 self.resolved_type
123 )
124 }
125}
126
127#[derive(Debug, Eq, PartialEq, Clone, Hash)]
128pub struct Signature {
129 pub parameters: Vec<TypeForParameter>,
130 pub return_type: Box<Type>,
131}
132
133impl Display for Signature {
134 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
135 write!(f, "({})->{}", comma(&self.parameters), self.return_type)
136 }
137}
138
139impl Signature {
140 #[must_use]
141 pub fn same_type(&self, other: &Self) -> bool {
142 if self.parameters.len() != other.parameters.len()
143 || !self.return_type.compatible_with(&other.return_type)
144 {
145 return false;
146 }
147
148 for (param, other_param) in self.parameters.iter().zip(other.parameters.clone()) {
149 if !¶m
150 .resolved_type
151 .compatible_with(&other_param.resolved_type)
152 {
153 return false;
154 }
155
156 if param.is_mutable != other_param.is_mutable {
157 return false;
158 }
159 }
160
161 true
162 }
163}
164
165impl Type {
166 #[must_use]
167 pub const fn is_concrete(&self) -> bool {
168 !matches!(
169 self,
170 Self::Unit | Self::Never | Self::Variable(_) | Self::Generic(_, _) | Self::Blueprint(_)
171 )
172 }
173}
174
175impl Debug for Type {
176 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
177 match self {
178 Self::Int => write!(f, "Int"),
179 Self::Float => write!(f, "Float"),
180 Self::String => write!(f, "String"),
181 Self::Bool => write!(f, "Bool"),
182 Self::Unit => write!(f, "Unit"),
183 Self::Never => write!(f, "!"),
184 Self::Tuple(tuple_type_ref) => write!(f, "( {tuple_type_ref:?} )"),
185 Self::NamedStruct(struct_type_ref) => {
186 write!(f, "{}", struct_type_ref.assigned_name)
187 }
188 Self::AnonymousStruct(anonymous_struct_type) => {
189 write!(f, "{anonymous_struct_type:?}")
190 }
191 Self::Enum(enum_type_ref) => write!(f, "{:?}", enum_type_ref.assigned_name),
192 Self::Function(function_type_signature) => {
193 write!(f, "{function_type_signature:?}")
194 }
195 Self::Iterable(type_generated) => write!(f, "Iterable<{type_generated:?}>"),
196 Self::Optional(base_type) => write!(f, "{base_type:?}?"),
197 Self::MutableReference(base_type) => write!(f, "mut ref {base_type:?}?"),
198 Self::External(rust_type) => write!(f, "{:?}?", rust_type.type_name),
199 Self::Variable(variable_name) => write!(f, "<|{variable_name}|>"),
200 Self::Generic(blueprint, non_concrete_arguments) => {
201 write!(f, "{blueprint:?}<{non_concrete_arguments:?}>")
202 }
203 Self::Slice(value_type) => {
204 write!(f, "Slice<{value_type:?}>")
205 }
206 Self::SlicePair(key_type, value_type) => {
207 write!(f, "SlicePair<{key_type:?}, {value_type:?}>")
208 }
209 Self::Blueprint(blueprint) => {
210 write!(f, "{blueprint:?}")
211 }
212 }
213 }
214}
215
216impl Display for Type {
217 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
218 match self {
219 Self::Int => write!(f, "Int"),
220 Self::Float => write!(f, "Float"),
221 Self::String => write!(f, "String"),
222 Self::Bool => write!(f, "Bool"),
223 Self::Unit => write!(f, "Unit"),
224 Self::Never => write!(f, "!"),
225 Self::Tuple(tuple) => write!(f, "({})", comma(tuple)),
226 Self::NamedStruct(struct_ref) => write!(f, "{}", struct_ref.assigned_name),
227 Self::AnonymousStruct(struct_ref) => write!(f, "{struct_ref:?}"),
228 Self::Enum(enum_type) => write!(f, "{}", enum_type.assigned_name),
229 Self::Function(signature) => write!(f, "function {signature}"),
230 Self::Iterable(generating_type) => write!(f, "Iterable<{generating_type}>"),
231 Self::Optional(base_type) => write!(f, "{base_type}?"),
232 Self::MutableReference(base_type) => write!(f, "mut ref {base_type:?}?"),
233 Self::External(rust_type) => write!(f, "RustType {}", rust_type.type_name),
234 Self::Variable(variable_name) => write!(f, "<|{variable_name}|>"),
235 Self::Generic(blueprint, non_concrete_arguments) => {
236 write!(f, "{blueprint:?}<{non_concrete_arguments:?}>")
237 }
238 Self::Slice(value_type) => {
239 write!(f, "Slice<{value_type:?}>")
240 }
241 Self::SlicePair(key_type, value_type) => {
242 write!(f, "SlicePair<{key_type:?}, {value_type:?}>")
243 }
244 Self::Blueprint(blueprint) => {
245 write!(f, "{blueprint:?}")
246 }
247 }
248 }
249}
250
251impl Type {
252 #[must_use]
253 pub fn assignable_type(&self, other: &Self) -> bool {
254 if self.compatible_with(other) {
255 true
256 } else if let Self::Optional(inner_type) = self {
257 inner_type.compatible_with(other)
258 } else {
259 false
260 }
261 }
262
263 #[must_use]
264 pub fn compatible_with(&self, other: &Self) -> bool {
265 match (self, other) {
266 (Self::Function(a), Self::Function(b)) => a.same_type(b),
267
268 (_, Self::Never)
269 | (Self::Never, _)
270 | (Self::Int, Self::Int)
271 | (Self::Float, Self::Float)
272 | (Self::String, Self::String)
273 | (Self::Bool, Self::Bool)
274 | (Self::Unit, Self::Unit) => true,
275
276 (Self::Enum(a), Self::Enum(b)) => a == b,
277
278 (Self::NamedStruct(a), Self::NamedStruct(b)) => compare_struct_types(a, b),
279
280 (Self::AnonymousStruct(a), Self::AnonymousStruct(b)) => {
281 compare_anonymous_struct_types(a, b)
282 }
283 (Self::MutableReference(a), Self::MutableReference(b)) => a.compatible_with(b),
284
285 (Self::Tuple(a), Self::Tuple(b)) => {
286 if a.len() != b.len() {
287 return false;
288 }
289 a.iter().zip(b.iter()).all(|(a, b)| a.compatible_with(b))
290 }
291
292 (Self::Optional(inner_type_a), Self::Optional(inner_type_b)) => {
293 inner_type_a.compatible_with(inner_type_b)
294 }
295
296 (Self::Generic(blueprint_a, args_a), Self::Generic(blueprint_b, args_b)) => {
297 blueprint_a == blueprint_b && (args_a == args_b)
298 }
299
300 (
301 Self::SlicePair(a_key_type, a_value_type),
302 Self::SlicePair(b_key_type, b_value_type),
303 ) => a_key_type == b_key_type && (a_value_type == b_value_type),
304 (Self::Slice(inner_type_a), Self::Slice(inner_type_b)) => {
305 inner_type_a.compatible_with(inner_type_b)
306 }
307
308 (Self::Blueprint(a), Self::Blueprint(b)) => a == b,
309
310 (Self::Variable(a), Self::Variable(b)) => a == b,
311
312 (Self::External(type_ref_a), Self::External(type_ref_b)) => {
313 type_ref_a.number == type_ref_b.number
314 }
315
316 _ => false,
317 }
318 }
319}
320
321fn compare_struct_types(a: &NamedStructType, b: &NamedStructType) -> bool {
322 let a_borrow = a;
323 let b_borrow = b;
324
325 if a_borrow.assigned_name != b_borrow.assigned_name {
326 return false;
327 }
328
329 compare_anonymous_struct_types(&a_borrow.anon_struct_type, &b_borrow.anon_struct_type)
330}
331
332#[must_use]
333pub fn same_anon_struct_ref(a: &AnonymousStructType, b: &AnonymousStructType) -> bool {
334 compare_anonymous_struct_types(a, b)
335}
336
337pub fn same_named_struct_ref(a: &NamedStructType, b: &NamedStructType) -> bool {
338 if a.assigned_name != b.assigned_name {
339 return false;
340 }
341
342 compare_anonymous_struct_types(&a.anon_struct_type, &b.anon_struct_type)
343}
344
345#[must_use]
346pub fn compare_anonymous_struct_types(a: &AnonymousStructType, b: &AnonymousStructType) -> bool {
347 if a.field_name_sorted_fields.len() != b.field_name_sorted_fields.len() {
348 info!("different lengths");
349 return false;
350 }
351
352 for ((a_name, a_type), (b_name, b_type)) in a
353 .field_name_sorted_fields
354 .iter()
355 .zip(b.field_name_sorted_fields.clone())
356 {
357 if *a_name != b_name {
358 info!(?a_name, ?b_name, "different field names");
359
360 return false;
361 }
362
363 if !a_type.field_type.compatible_with(&b_type.field_type) {
364 info!(?a_type.field_type, ?b_type.field_type, "different field types");
365 return false;
366 }
367 }
368
369 true
370}
371
372#[must_use]
373pub fn check_assignable_anonymous_struct_types(
374 a: &AnonymousStructType,
375 b: &AnonymousStructType,
376) -> bool {
377 if a.field_name_sorted_fields.len() != b.field_name_sorted_fields.len() {
378 return false;
379 }
380
381 for (name, field) in &a.field_name_sorted_fields {
382 if let Some(found_field) = b.field_name_sorted_fields.get(name) {
383 if !found_field.field_type.compatible_with(&field.field_type) {
384 return false;
385 }
386 } else {
387 return false;
388 }
389 }
390
391 true
392}
393
394#[must_use]
395pub fn comma_seq<K: Clone + Hash + Eq + Display, V: Display>(values: &SeqMap<K, V>) -> String {
396 let mut result = String::new();
397 for (i, (key, value)) in values.iter().enumerate() {
398 if i > 0 {
399 result.push_str(", ");
400 }
401 result.push_str(format!("{key}: {value}").as_str());
402 }
403 result
404}
405
406#[must_use]
407pub fn comma_seq_nl<K: Clone + Hash + Eq + Display, V: Display>(
408 values: &SeqMap<K, V>,
409 prefix: &str,
410) -> String {
411 let mut result = String::new();
412 for (key, value) in values.iter() {
413 result.push_str(format!("{prefix}{key}: {value}\n").as_str());
414 }
415 result
416}
417
418#[derive(Clone, Eq, PartialEq, Hash)]
419pub struct StructTypeField {
420 pub identifier: Option<Node>,
421 pub field_type: Type,
422}
423
424impl Display for StructTypeField {
425 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
426 write!(f, "{:?}:{}", self.identifier, self.field_type)
427 }
428}
429
430#[derive(Clone, Eq, PartialEq, Hash)]
431pub struct AnonymousStructType {
432 pub field_name_sorted_fields: SeqMap<String, StructTypeField>,
434}
435
436impl Debug for AnonymousStructType {
437 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
438 write!(f, "{}", comma_seq(&self.field_name_sorted_fields))
439 }
440}
441
442#[must_use]
443pub fn sort_struct_fields2(
444 unordered_seq_map: &SeqMap<String, StructTypeField>,
445) -> SeqMap<String, StructTypeField> {
446 let mut sorted_pairs: Vec<(&String, &StructTypeField)> = unordered_seq_map.iter().collect();
447 sorted_pairs.sort_by(|a, b| a.0.cmp(b.0));
448
449 sorted_pairs
450 .into_iter()
451 .map(|(name, field)| (name.clone(), field.clone()))
452 .collect()
453}
454
455impl AnonymousStructType {
456 #[must_use]
457 pub fn new_and_sort_fields(source_ordered_fields: &SeqMap<String, StructTypeField>) -> Self {
458 Self {
459 field_name_sorted_fields: sort_struct_fields2(source_ordered_fields),
460 }
461 }
462
463 #[must_use]
464 pub const fn new(defined_order: SeqMap<String, StructTypeField>) -> Self {
465 Self {
466 field_name_sorted_fields: defined_order,
467 }
468 }
469}
470
471#[derive(Clone, Debug, Eq, PartialEq, Hash)]
472pub struct EnumVariantStructType {
473 pub common: EnumVariantCommon,
474 pub anon_struct: AnonymousStructType,
475}
476
477#[derive(Clone, Debug, Eq, PartialEq, Hash)]
478pub struct EnumVariantTupleType {
479 pub common: EnumVariantCommon,
480 pub fields_in_order: Vec<Type>,
481}
482
483#[derive(Clone, Eq, PartialEq, Hash)]
484pub struct EnumType {
485 pub name: Node,
486 pub assigned_name: String,
487 pub module_path: Vec<String>,
488 pub variants: SeqMap<String, EnumVariantType>,
489 pub instantiated_type_parameters: Vec<Type>,
490}
491
492impl Debug for EnumType {
493 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
494 write!(f, "{}", self.assigned_name)?;
495 let s = comma(
496 &self
497 .variants
498 .iter()
499 .map(|(name, _variant)| name)
500 .collect::<Vec<&String>>(),
501 );
502 write!(f, "{{ {s} }}")
503 }
504}
505
506impl EnumType {
507 #[must_use]
508 pub fn new(name: Node, assigned_name: &str, module_path: Vec<String>) -> Self {
509 Self {
510 name,
511 assigned_name: assigned_name.to_string(),
512 module_path,
513 variants: SeqMap::new(),
514 instantiated_type_parameters: Vec::default(),
515 }
516 }
517
518 #[must_use]
519 pub const fn name(&self) -> &Node {
520 &self.name
521 }
522
523 #[must_use]
524 pub fn get_variant(&self, name: &str) -> Option<&EnumVariantType> {
525 self.variants.get(&name.to_string())
526 }
527
528 #[must_use]
529 pub fn get_variant_from_index(&self, index: usize) -> Option<&EnumVariantType> {
530 Some(self.variants.values().collect::<Vec<_>>()[index])
531 }
532}
533
534#[derive(Clone, Eq, PartialEq, Hash)]
535pub struct EnumVariantCommon {
536 pub name: Node,
537 pub assigned_name: String,
538 pub container_index: u8,
539}
540
541impl Debug for EnumVariantCommon {
542 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
543 write!(f, "{}::{}", self.assigned_name, self.assigned_name)
544 }
545}
546
547#[derive(Debug)]
548pub struct EnumVariantStructFieldType {
549 pub name: Node,
550 pub enum_variant: EnumVariantType,
551 pub resolved_type: Type,
552
553 pub field_index: usize,
554}
555
556#[derive(Debug, Eq, PartialEq)]
557pub struct EnumVariantTupleFieldType {
558 pub name: Node,
559 pub enum_variant: EnumVariantType,
560 pub resolved_type: Type,
561
562 pub field_index: usize,
563}
564
565#[derive(Clone, Debug, Eq, PartialEq, Hash)]
566pub struct EnumVariantSimpleType {
567 pub common: EnumVariantCommon,
568}
569
570#[derive(Clone, Eq, PartialEq, Hash)]
571pub enum EnumVariantType {
572 Struct(EnumVariantStructType),
573 Tuple(EnumVariantTupleType),
574 Nothing(EnumVariantSimpleType),
575}
576impl EnumVariantType {
577 #[must_use]
578 pub fn common(&self) -> &EnumVariantCommon {
579 match self {
580 Self::Tuple(tuple) => &tuple.common,
581 Self::Struct(c) => &c.common,
582 Self::Nothing(c) => &c.common,
583 }
584 }
585}
586
587impl Debug for EnumVariantType {
588 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
589 match self {
590 Self::Struct(x) => write!(f, "{{ {x:?} }}"),
591 Self::Tuple(x) => write!(f, "({x:?})"),
592 Self::Nothing(_x) => Ok(()),
593 }
594 }
595}
596
597#[derive(Debug, Clone)]
598pub struct AliasType {
599 pub name: Node,
600 pub assigned_name: String,
601 pub referenced_type: Type,
602}
603
604#[derive(Clone, PartialEq, Eq, Hash)]
605pub struct NamedStructType {
606 pub name: Node,
607 pub module_path: Vec<String>,
608 pub assigned_name: String,
609 pub anon_struct_type: AnonymousStructType,
610 pub instantiated_type_parameters: Vec<Type>,
611}
612
613impl Debug for NamedStructType {
614 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
615 write!(
616 f,
617 "struct {} anon: {:?}",
618 self.assigned_name, self.anon_struct_type
619 )
620 }
621}
622
623impl NamedStructType {
624 #[must_use]
625 pub fn new(
626 name: Node,
627 assigned_name: &str,
628 anon_struct_type: AnonymousStructType,
629 module_path: &[String],
630 ) -> Self {
631 Self {
632 anon_struct_type,
634 name,
635 module_path: module_path.to_vec(),
636 assigned_name: assigned_name.to_string(),
637 instantiated_type_parameters: Vec::default(),
638 }
639 }
640
641 #[must_use]
642 pub fn field_index(&self, field_name: &str) -> Option<usize> {
643 self.anon_struct_type
644 .field_name_sorted_fields
645 .get_index(&field_name.to_string())
646 }
647
648 #[must_use]
649 pub const fn name(&self) -> &Node {
650 &self.name
651 }
652}
653
654pub fn all_types_are_concrete(types: &[Type]) -> bool {
655 for ty in types {
656 if !ty.is_concrete() {
657 return false;
658 }
659 }
660 true
661}
662
663pub fn all_types_are_concrete_or_unit(types: &[Type]) -> bool {
664 for ty in types {
665 if !ty.is_concrete() && *ty != Type::Unit {
666 return false;
667 }
668 }
669 true
670}
671
672pub fn all_types_are_variables(types: &[Type]) -> bool {
673 for ty in types {
674 if let Type::Variable(_) = ty {
675 } else {
676 return false;
677 }
678 }
679 true
680}