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