pipeline_script/ast/
type.rs

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