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