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