pipeline_script/ast/
type.rs

1use crate::context::Context;
2use crate::llvm::global::Global;
3use crate::llvm::types::LLVMType;
4#[derive(Clone, Debug, PartialEq, Eq, Hash)]
5pub enum Type {
6    Int8,
7    Int16,
8    Int32,
9    Int64,
10    Float,
11    Double,
12    String,
13    Bool,
14    Inject(Box<Type>),
15    Provide(Box<Type>),
16    Pointer(Box<Type>),
17    // 引用类型和指针类型底层一致,但是使用时默认获取值
18    Ref(Box<Type>),
19    // 泛型 例如:Array<Int32>,即Generic(Array,[Int32])
20    Generic(Box<Type>, Vec<Type>),
21    GenericInstance {
22        template: Box<Type>,
23        instance: Box<Type>,
24    },
25    Alias(String),
26    Struct(Option<String>, Vec<(String, Type)>),
27    // 枚举类型,Option<String>是枚举名称,Vec<(String, Option<Type>)>是枚举变体列表
28    // 每个变体包含名称和可选的关联类型
29    Enum(Option<String>, Vec<(String, Option<Type>)>),
30    /// Function(返回值,参数列表,是否Vararg)
31    Function(Box<Type>, Vec<(String, Type)>, bool),
32    Array(Box<Type>),
33    Map(Box<Type>, Box<Type>),
34    Closure {
35        name: Option<String>,
36        ptr: (Box<Type>, Vec<(String, Type)>),
37        env: Vec<(String, Type)>,
38    },
39    Any,
40    Unit,
41    ArrayVarArg(Box<Type>),
42    VarArg,
43    Module,
44}
45impl From<&str> for Type {
46    fn from(s: &str) -> Self {
47        match s {
48            "Unit" => Type::Unit,
49            "Int8" => Type::Int8,
50            "Int16" => Type::Int16,
51            "Int32" => Type::Int32,
52            "Int64" => Type::Int64,
53            "Float" => Type::Float,
54            "Double" => Type::Double,
55            "String" => Type::String,
56            "Bool" => Type::Bool,
57            "Any" => Type::Any,
58            "Pointer" => Type::Pointer(Box::new(Type::Any)),
59            "Ref" => Type::Ref(Box::new(Type::Any)),
60            //            t=>Type::Struct(t.into()),
61            _ => panic!("Unknown type: {}", s),
62        }
63    }
64}
65
66impl From<LLVMType> for Type {
67    fn from(value: LLVMType) -> Self {
68        match value {
69            LLVMType::Int1(_) => Type::Bool,
70            LLVMType::Int8(_) => Type::Int8,
71            LLVMType::Int16(_) => Type::Int16,
72            LLVMType::Int32(_) => Type::Int32,
73            LLVMType::Int64(_) => Type::Int64,
74            LLVMType::Float(_) => Type::Float,
75            LLVMType::Double(_) => Type::Double,
76            LLVMType::Pointer(e, _) => Type::Pointer(Box::new((*e).into())),
77            LLVMType::Unit(_) => Type::Any,
78            t => panic!("{t:?}"),
79        }
80    }
81}
82impl From<String> for Type {
83    fn from(s: String) -> Self {
84        match s.as_str() {
85            "Unit" => Type::Unit,
86            "Int16" => Type::Int16,
87            "Int8" => Type::Int8,
88            "Int32" => Type::Int32,
89            "Int64" => Type::Int64,
90            "Float" => Type::Float,
91            "Double" => Type::Double,
92            "String" => Type::String,
93            "Bool" => Type::Bool,
94            "Any" => Type::Any,
95            s if s.starts_with("*") => {
96                let s = s.strip_prefix("*").unwrap();
97                let t = s.into();
98                Type::Pointer(Box::new(t))
99            }
100
101            s if s.starts_with("[]") => {
102                let s = s.strip_prefix("[]").unwrap();
103                let t = s.into();
104                Type::Array(Box::new(t))
105            }
106            s if s.starts_with("..") => {
107                let s = s.strip_prefix("..").unwrap();
108                let t = s.into();
109                Type::ArrayVarArg(Box::new(t))
110            }
111            t => Type::Alias(t.into()),
112        }
113    }
114}
115impl Type {
116    pub fn get_struct_name(&self) -> Option<&str> {
117        match self {
118            Type::Struct(name, _) => name.as_deref(),
119            Type::Array(_) => Some("Array"),
120            _ => None,
121        }
122    }
123    pub fn get_composite_type_name(&self) -> Option<&str> {
124        match self {
125            Type::Struct(name, _) => name.as_deref(),
126            Type::Array(_) => Some("Array"),
127            Type::Enum(name, _) => name.as_deref(),
128            Type::GenericInstance { instance, .. } => instance.get_composite_type_name(),
129            Type::Ref(t) => t.get_composite_type_name(),
130            _ => None,
131        }
132    }
133    pub fn get_generic_wrapper(&self) -> Option<&Type> {
134        match self {
135            Type::Generic(wrapper, _) => Some(wrapper),
136            _ => None,
137        }
138    }
139    pub fn unwrap_ref(&self) -> Type {
140        match self {
141            Type::Ref(t) => *t.clone(),
142            Type::Inject(t) => *t.clone(),
143            _ => self.clone(),
144        }
145    }
146    pub fn has_name(&self) -> bool {
147        match self {
148            Type::Struct(name, _) => name.is_some(),
149            Type::Enum(name, _) => name.is_some(),
150            _ => false,
151        }
152    }
153    pub fn set_name(&mut self, name: String) {
154        match self {
155            Type::Struct(n, _) => *n = Some(name),
156            Type::Enum(n, _) => *n = Some(name),
157            _ => panic!("Not a composite type"),
158        }
159    }
160    pub fn is_generic_instance(&self) -> bool {
161        matches!(self, Type::GenericInstance { .. })
162    }
163    pub fn set_composite_type_name(&mut self, name: Option<String>) {
164        match self {
165            Type::Struct(n, _) => *n = name,
166            Type::Array(_) => panic!("Array type cannot be set name"),
167            Type::Enum(n, _) => *n = name,
168            _ => panic!("Not a composite type"),
169        }
170    }
171    pub fn is_integer(&self) -> bool {
172        matches!(self, Type::Int8 | Type::Int16 | Type::Int32 | Type::Int64)
173    }
174    pub fn get_enum_variant_type(&self, name: &str) -> Option<Type> {
175        match self {
176            Type::Enum(_, variants) => {
177                for (name0, t) in variants {
178                    if name0 == name {
179                        return t.clone();
180                    }
181                }
182                None
183            }
184            Type::Ref(t) => t.get_enum_variant_type(name),
185            Type::GenericInstance { instance, .. } => instance.get_enum_variant_type(name),
186            _ => None,
187        }
188    }
189    pub fn is_float(&self) -> bool {
190        matches!(self, Type::Float)
191    }
192    pub fn is_double(&self) -> bool {
193        matches!(self, Type::Double)
194    }
195    pub fn is_generic(&self) -> bool {
196        matches!(self, Type::Generic(_, _))
197    }
198    pub fn id(&self) -> i32 {
199        match self {
200            Type::Unit => 0,
201            Type::Bool => 1,
202            Type::Int8 => 3,
203            Type::Int16 => 5,
204            Type::Int32 => 7,
205            Type::Int64 => 9,
206            Type::Float => 11,
207            Type::Double => 13,
208            Type::String => 15,
209            Type::Any => 17,
210            Type::Pointer(t) => match t.as_ref() {
211                Type::Bool => 2,
212                Type::Int8 => 4,
213                Type::Int16 => 6,
214                Type::Int32 => 8,
215                Type::Int64 => 10,
216                Type::Float => 12,
217                Type::Double => 14,
218                Type::String => 16,
219                _ => 18, // 其他指针类型的默认ID
220            },
221            Type::Ref(t) => t.id(),
222            Type::Struct(_, _) => 19,
223            Type::Array(_) => 20,
224            Type::Function(_, _, _) => 21,
225            Type::Closure { .. } => 22,
226            Type::Enum(_, _) => 23,
227            Type::ArrayVarArg(_) => 24,
228            Type::Generic(_, _) => 25,
229            Type::GenericInstance { .. } => 26,
230            Type::Alias(_) => 27,
231            Type::VarArg => 28,
232            Type::Module => 29,
233            Type::Map(_, _) => 30,
234            Type::Inject(_) => 31,
235            Type::Provide(_) => 32,
236        }
237    }
238    pub fn is_primitive(&self) -> bool {
239        matches!(
240            self,
241            Type::Int32 | Type::Int64 | Type::Float | Type::Double | Type::String | Type::Bool
242        )
243    }
244
245    pub fn as_struct(&self) -> Option<&Vec<(String, Type)>> {
246        match self {
247            Type::Struct(_, m) => Some(m),
248            _ => None,
249        }
250    }
251    pub fn get_generic_template(&self) -> Option<&Type> {
252        match self {
253            Type::GenericInstance { template, .. } => Some(template),
254            _ => None,
255        }
256    }
257    pub fn is_function(&self) -> bool {
258        matches!(self, Type::Function(_, _, _))
259    }
260    pub fn is_module(&self) -> bool {
261        matches!(self, Type::Module)
262    }
263    pub fn is_pointer(&self) -> bool {
264        matches!(self, Type::Pointer(_))
265    }
266    pub fn is_array_vararg(&self) -> bool {
267        matches!(self, Type::ArrayVarArg(_))
268    }
269    pub fn with_return_type(&self, return_type: Type) -> Type {
270        match self {
271            Type::Function(_, args, is_vararg) => {
272                Type::Function(Box::new(return_type), args.clone(), *is_vararg)
273            }
274            _ => panic!("Not a function type"),
275        }
276    }
277    pub fn is_ref(&self) -> bool {
278        matches!(self, Type::Ref(_))
279    }
280    pub fn get_struct_field(&self, ctx: &Context, name: impl AsRef<str>) -> Option<(usize, Type)> {
281        match self {
282            Type::Struct(_, m) => {
283                for (i, (field_name, t)) in m.iter().enumerate() {
284                    if field_name == name.as_ref() {
285                        return Some((i, t.clone()));
286                    }
287                }
288                None
289            }
290            Type::Alias(name0) => {
291                let ty = ctx.get_alias_type(name0);
292                match ty {
293                    Some(ty) => ty.get_struct_field(ctx, name),
294                    None => None,
295                }
296            }
297            Type::Ref(t) => t.get_struct_field(ctx, name),
298            Type::Pointer(t) => t.get_struct_field(ctx, name),
299            Type::GenericInstance { instance, .. } => instance.get_struct_field(ctx, name),
300            _ => None,
301        }
302    }
303    pub fn get_function_arg_count(&self) -> usize {
304        match self {
305            Type::Function(_, args, _) => args.len(),
306            Type::Ref(t) => t.get_function_arg_count(),
307            Type::Closure { ptr, .. } => ptr.1.len(),
308            Type::Pointer(t) => t.get_function_arg_count(),
309            Type::GenericInstance { instance, .. } => instance.get_function_arg_count(),
310            _ => panic!("{self:?} Not a function type"),
311        }
312    }
313    pub fn get_closure_fn_name(&self) -> Option<String> {
314        match self {
315            Type::Closure { name, .. } => name.clone(),
316            Type::Ref(t) => t.get_closure_fn_name(),
317            _ => None,
318        }
319    }
320    pub fn get_function_arg_type(&self, index: usize) -> Option<Type> {
321        match self {
322            Type::Function(_, args, _) => args.get(index).cloned().map(|(_, t)| t),
323            _ => None,
324        }
325    }
326    pub fn is_i8(&self) -> bool {
327        matches!(self, Type::Int8)
328    }
329    pub fn is_any(&self) -> bool {
330        matches!(self, Type::Any)
331    }
332    pub fn is_string(&self) -> bool {
333        matches!(self, Type::String)
334    }
335    pub fn is_i16(&self) -> bool {
336        matches!(self, Type::Int16)
337    }
338    pub fn is_i32(&self) -> bool {
339        matches!(self, Type::Int32)
340    }
341    pub fn is_i64(&self) -> bool {
342        matches!(self, Type::Int64)
343    }
344    pub fn is_struct(&self) -> bool {
345        matches!(self, Type::Struct(_, _))
346    }
347    pub fn is_array(&self) -> bool {
348        matches!(self, Type::Array(_))
349    }
350
351    pub fn as_llvm_type(&self) -> LLVMType {
352        match self {
353            Type::Int8 => Global::i8_type(),
354            Type::Int16 => Global::i16_type(),
355            Type::Int32 => Global::i32_type(),
356            Type::Int64 => Global::i64_type(),
357            Type::Float => Global::float_type(),
358            Type::Double => Global::double_type(),
359            Type::Bool => Global::i8_type(),
360            Type::String => Global::string_type(),
361            Type::Pointer(t) => Global::pointer_type(t.as_llvm_type()),
362            Type::Array(t) => Global::pointer_type(t.as_llvm_type()),
363            Type::Struct(_, _) => Global::pointer_type(Global::i8_type()),
364            Type::Enum(_, _) => {
365                // 枚举类型编译为包含标签和数据的结构体
366                // 标签是一个整数,表示枚举变体的索引
367                // 数据是一个联合体,包含所有变体的数据
368
369                // 创建枚举结构体类型
370                let fields = vec![
371                    // 标签字段,用于区分不同的变体
372                    ("id".into(), Global::i32_type()),
373                    // 数据字段,使用i64作为默认类型
374                    ("data".into(), Global::i64_type()),
375                ];
376
377                Global::struct_type("Enum".into(), fields)
378            }
379            Type::Function(ret, args, is_vararg) => {
380                let mut v = vec![];
381                for (name, t) in args.iter() {
382                    v.push((name.clone(), t.as_llvm_type()));
383                }
384                if *is_vararg {
385                    return Global::function_type_with_var_arg(ret.as_llvm_type(), v);
386                }
387                Global::function_type(ret.as_llvm_type(), v)
388            }
389            Type::ArrayVarArg(t) => Global::pointer_type(t.as_llvm_type()),
390            Type::Ref(t) => Global::pointer_type(t.as_llvm_type()),
391            Type::Any => Global::struct_type(
392                "Any".into(),
393                vec![
394                    ("id".into(), Global::i32_type()),
395                    ("data".into(), Global::pointer_type(Global::i8_type())),
396                ],
397            ),
398            Type::Unit => Global::unit_type(),
399            _ => panic!("Unknown type: {:?}", self),
400        }
401    }
402    pub fn get_alias_name(&self) -> Option<String> {
403        match self {
404            Type::Alias(s) => Some(s.clone()),
405            _ => None,
406        }
407    }
408    pub fn get_struct_fields(&self) -> Option<&Vec<(String, Type)>> {
409        match self {
410            Type::Struct(_, s) => Some(s),
411            _ => None,
412        }
413    }
414    pub fn is_closure(&self) -> bool {
415        matches!(self, Type::Closure { .. })
416    }
417    pub fn is_alias(&self) -> bool {
418        matches!(self, Type::Alias(_))
419    }
420    pub fn get_function_return_type(&self) -> Option<Type> {
421        match self {
422            Type::Pointer(f) => f.get_function_return_type(),
423            Type::Function(r, _, _) => Some(*r.clone()),
424            Type::Ref(t) => t.get_function_return_type(),
425            Type::Closure { ptr, .. } => Some(*ptr.0.clone()),
426            _ => None,
427        }
428    }
429    pub fn get_element_type(&self) -> Option<&Type> {
430        match self {
431            Type::Array(t) => Some(t),
432            Type::Pointer(t) => Some(t),
433            Type::ArrayVarArg(t) => Some(t),
434            Type::Ref(t) => Some(t),
435            _ => None,
436        }
437    }
438    pub fn get_env_type(&self) -> Option<Type> {
439        match self {
440            Type::Closure {
441                name: _,
442                ptr: _,
443                env,
444            } => Some(Type::Pointer(Box::new(Type::Struct(None, env.clone())))),
445            _ => None,
446        }
447    }
448    pub fn get_closure_name(&self) -> Option<String> {
449        match self {
450            Type::Closure {
451                name,
452                ptr: _,
453                env: _,
454            } => name.clone(),
455            _ => None,
456        }
457    }
458    pub fn get_closure_fn_gen_type(&self) -> Option<Type> {
459        match self {
460            Type::Closure { name: _, ptr, env } => {
461                let mut gen_fn_params_type = ptr.1.clone();
462                gen_fn_params_type.push((
463                    "env".into(),
464                    Type::Pointer(Box::new(Type::Struct(None, env.clone()))),
465                ));
466                Some(Type::Function(ptr.0.clone(), gen_fn_params_type, false))
467            }
468            _ => None,
469        }
470    }
471    // pub fn try_replace_alias(&mut self, alias_map: &HashMap<String, Type>) {
472    //     match self {
473    //         Type::Alias(s) => {
474    //             let t = alias_map.get(s).unwrap();
475    //             *self = t.clone();
476    //         }
477    //         Type::Struct(_, s) => {
478    //             for (_, t) in s.iter_mut() {
479    //                 t.try_replace_alias(alias_map);
480    //             }
481    //         }
482    //         Type::Function(_, args) => {
483    //             for (_, t) in args.iter_mut() {
484    //                 t.try_replace_alias(alias_map);
485    //             }
486    //         }
487    //         Type::Array(t) => {
488    //             t.try_replace_alias(alias_map);
489    //         }
490    //         Type::Pointer(t) => {
491    //             t.try_replace_alias(alias_map);
492    //         }
493    //         Type::ArrayVarArg(t) => {
494    //             t.try_replace_alias(alias_map);
495    //         }
496    //         Type::Closure { ptr, env, .. } => {
497    //             ptr.0.try_replace_alias(alias_map);
498    //             ptr.1
499    //                 .iter_mut()
500    //                 .for_each(|t| t.try_replace_alias(alias_map));
501    //             env.iter_mut()
502    //                 .for_each(|(_, t)| t.try_replace_alias(alias_map));
503    //         }
504    //         Type::Generic(t, _) => {
505    //             t.try_replace_alias(alias_map);
506    //         }
507    //         Type::Map(k, v) => {
508    //             k.try_replace_alias(alias_map);
509    //             v.try_replace_alias(alias_map);
510    //         }
511    //         Type::Enum(_, variants) => {
512    //             for (_, t) in variants.iter_mut() {
513    //                 if let Some(ty) = t {
514    //                     ty.try_replace_alias(alias_map);
515    //                 }
516    //             }
517    //         }
518    //         _ => {}
519    //     }
520    // }
521    pub fn set_enum_name(&mut self, name: String) {
522        match self {
523            Type::Enum(n, _) => *n = Some(name),
524            _ => panic!("Not an enum type"),
525        }
526    }
527    pub fn has_alias(&self) -> bool {
528        // 递归判断是否存在Alias
529        match self {
530            Type::Alias(_) => true,
531            Type::Struct(_, s) => {
532                for (_, t) in s.iter() {
533                    if t.has_alias() {
534                        return true;
535                    }
536                }
537                false
538            }
539            Type::Function(_, args, _) => {
540                for (_, t) in args.iter() {
541                    if t.has_alias() {
542                        return true;
543                    }
544                }
545                false
546            }
547            Type::Array(t) => {
548                if t.has_alias() {
549                    return true;
550                }
551                false
552            }
553            Type::Pointer(t) => {
554                if t.has_alias() {
555                    return true;
556                }
557                false
558            }
559            Type::ArrayVarArg(t) => {
560                if t.has_alias() {
561                    return true;
562                }
563                false
564            }
565            Type::Closure { ptr, env, .. } => {
566                if ptr.0.has_alias()
567                    || ptr.1.iter().any(|(_, t)| t.has_alias())
568                    || env.iter().any(|(_, t)| t.has_alias())
569                {
570                    return true;
571                }
572                false
573            }
574            Type::Generic(t, _) => {
575                if t.has_alias() {
576                    return true;
577                }
578                false
579            }
580            Type::Map(k, v) => {
581                if k.has_alias() || v.has_alias() {
582                    return true;
583                }
584                false
585            }
586            Type::Enum(_, variants) => {
587                for (_, t) in variants.iter() {
588                    if let Some(ty) = t {
589                        if ty.has_alias() {
590                            return true;
591                        }
592                    }
593                }
594                false
595            }
596            _ => false,
597        }
598    }
599    pub fn as_str(&self) -> String {
600        match self {
601            Type::Alias(s) => s.clone(),
602            Type::Struct(_, s) => {
603                let mut v = vec![];
604                for (_, t) in s.iter() {
605                    v.push(t.as_str());
606                }
607                v.join(".")
608            }
609            Type::Function(_, args, _) => {
610                let mut v = vec![];
611                for (name, t) in args.iter() {
612                    v.push(format!("{}:{}", name, t.as_str()));
613                }
614                v.join(",")
615            }
616
617            Type::Array(t) => {
618                format!("[]{}", t.as_str())
619            }
620            Type::Pointer(t) => {
621                format!("*{}", t.as_str())
622            }
623            Type::Ref(t) => {
624                format!("&{}", t.as_str())
625            }
626            Type::ArrayVarArg(t) => {
627                format!("..{}", t.as_str())
628            }
629            Type::Closure {
630                name,
631                ptr: _,
632                env: _,
633            } => name.as_deref().unwrap_or("").to_string(),
634            Type::VarArg => "..".to_string(),
635            Type::Generic(t, _) => t.as_str().to_string(),
636
637            Type::Map(k, v) => {
638                format!("Map<{},{}>", k.as_str(), v.as_str())
639            }
640            Type::Enum(name, variants) => {
641                let mut result = String::new();
642                if let Some(name) = name {
643                    result.push_str(name);
644                } else {
645                    result.push_str("Enum");
646                }
647
648                if !variants.is_empty() {
649                    result.push('<');
650                    for (i, (variant_name, variant_type)) in variants.iter().enumerate() {
651                        if i > 0 {
652                            result.push(',');
653                        }
654                        result.push_str(variant_name);
655                        if let Some(ty) = variant_type {
656                            result.push_str(&format!("({})", ty.as_str()));
657                        }
658                    }
659                    result.push('>');
660                }
661                result
662            }
663            Type::Module => "Module".to_string(),
664            Type::Int8 => "Int8".to_string(),
665            Type::Int16 => "Int16".to_string(),
666            Type::Int32 => "Int32".to_string(),
667            Type::Int64 => "Int64".to_string(),
668            Type::Float => "Float".to_string(),
669            Type::Double => "Double".to_string(),
670            Type::String => "String".to_string(),
671            Type::Bool => "Bool".to_string(),
672            Type::Any => "Any".to_string(),
673            Type::Unit => "Unit".to_string(),
674            Type::Provide(t) => format!("provide({})", t.as_str()),
675            Type::Inject(t) => format!("inject({})", t.as_str()),
676            _ => panic!("Unknown type: {:?}", self),
677        }
678    }
679    pub fn is_enum(&self) -> bool {
680        matches!(self, Type::Enum(_, _))
681    }
682
683    pub fn get_enum_name(&self) -> Option<&str> {
684        match self {
685            Type::Enum(name, _) => name.as_ref().map(|s| s.as_str()),
686            _ => None,
687        }
688    }
689
690    pub fn get_enum_variants(&self) -> Option<&Vec<(String, Option<Type>)>> {
691        match self {
692            Type::Enum(_, variants) => Some(variants),
693            _ => None,
694        }
695    }
696    pub fn is_vararg_function(&self) -> bool {
697        matches!(self, Type::Function(_, _, true))
698    }
699    pub fn is_array_vararg_fucntion(&self) -> bool {
700        if let Type::Function(_, args, _) = self {
701            for (_, ty) in args {
702                if ty.is_array_vararg() {
703                    return true;
704                }
705            }
706        }
707        false
708    }
709}