1mod literal;
2mod printer;
3
4pub use crate::generated::ir::*;
5#[cfg(feature = "std")]
6pub use printer::{print, print_no_color, print_ty};
7
8use crate::{boxed, string, vec};
9
10impl Program {
11 pub fn get_output_ty(&self) -> &Ty {
12 let main_ty = self.main.ty.kind.as_function().unwrap();
13 &main_ty.body
14 }
15
16 pub fn get_input_ty(&self) -> &Ty {
17 let main_ty = self.main.ty.kind.as_function().unwrap();
18 assert_eq!(main_ty.params.len(), 1);
19 &main_ty.params[0]
20 }
21}
22
23impl Expr {
24 pub fn new(kind: impl Into<ExprKind>, ty: Ty) -> Expr {
25 Expr {
26 kind: kind.into(),
27 ty,
28 }
29 }
30 pub fn new_lit_bool(value: bool) -> Self {
31 Expr {
32 kind: ExprKind::Literal(Literal::bool(value)),
33 ty: Ty::new(TyPrimitive::bool),
34 }
35 }
36}
37impl From<ParameterPtr> for ExprKind {
38 fn from(ptr: ParameterPtr) -> Self {
39 ExprKind::Pointer(Pointer::Parameter(ptr))
40 }
41}
42impl From<ExternalPtr> for ExprKind {
43 fn from(ptr: ExternalPtr) -> Self {
44 ExprKind::Pointer(Pointer::External(ptr))
45 }
46}
47impl From<TupleLookup> for ExprKind {
48 fn from(v: TupleLookup) -> Self {
49 ExprKind::TupleLookup(boxed::Box::new(v))
50 }
51}
52impl From<Binding> for ExprKind {
53 fn from(v: Binding) -> Self {
54 ExprKind::Binding(boxed::Box::new(v))
55 }
56}
57impl From<Call> for ExprKind {
58 fn from(v: Call) -> Self {
59 ExprKind::Call(boxed::Box::new(v))
60 }
61}
62impl From<Function> for ExprKind {
63 fn from(v: Function) -> Self {
64 ExprKind::Function(boxed::Box::new(v))
65 }
66}
67impl From<EnumEq> for ExprKind {
68 fn from(eq: EnumEq) -> Self {
69 ExprKind::EnumEq(boxed::Box::new(eq))
70 }
71}
72
73impl PartialEq for Ty {
74 fn eq(&self, other: &Self) -> bool {
75 self.kind == other.kind
76 }
77}
78
79impl Eq for Ty {}
80
81impl Ty {
82 pub fn new(kind: impl Into<TyKind>) -> Self {
83 Ty {
84 kind: kind.into(),
85 layout: None,
86 name: None,
87 variants_recursive: vec![],
88 }
89 }
90 pub fn new_unit() -> Self {
91 Ty {
92 kind: TyKind::Tuple(vec![]),
93 layout: Some(TyLayout {
94 head_size: 0,
95 body_ptrs: vec![],
96 }),
97 name: None,
98 variants_recursive: vec![],
99 }
100 }
101 pub fn is_unit(&self) -> bool {
102 self.kind.is_unit()
103 }
104}
105
106impl TyKind {
107 pub fn is_unit(&self) -> bool {
108 self.as_tuple().is_some_and(|f| f.is_empty())
109 }
110
111 pub fn as_option(&self) -> Option<&Ty> {
112 self.as_enum()
113 .filter(|v| v.len() == 2 && v[0].ty.is_unit() && !v[1].ty.is_unit())
114 .map(|v| &v[1].ty)
115 }
116}
117
118impl From<TyPrimitive> for TyKind {
119 fn from(value: TyPrimitive) -> Self {
120 TyKind::Primitive(value)
121 }
122}
123impl From<vec::Vec<TyTupleField>> for TyKind {
124 fn from(value: vec::Vec<TyTupleField>) -> Self {
125 TyKind::Tuple(value)
126 }
127}
128impl From<TyFunction> for TyKind {
129 fn from(value: TyFunction) -> Self {
130 TyKind::Function(boxed::Box::new(value))
131 }
132}
133impl From<Path> for TyKind {
134 fn from(value: Path) -> Self {
135 TyKind::Ident(value)
136 }
137}
138
139impl Module {
140 pub fn insert(&mut self, path: &[string::String], decl: Decl) {
141 if path.is_empty() {
142 panic!();
143 }
144
145 if path.len() == 1 {
146 self.decls.retain(|d| d.name != path[0]);
147 self.decls.push(ModuledeclsItems {
148 name: path[0].clone(),
149 decl,
150 });
151 } else {
152 let exists = self.decls.iter().any(|d| d.name == path[0]);
153 if !exists {
154 self.decls.push(ModuledeclsItems {
155 name: path[0].clone(),
156 decl: Decl::Module(boxed::Box::new(Module {
157 decls: vec::Vec::new(),
158 })),
159 });
160 }
161
162 let sub_module = self.decls.iter_mut().find(|d| d.name == path[0]);
163 let Decl::Module(sub_module) = &mut sub_module.unwrap().decl else {
164 panic!()
165 };
166 sub_module.insert(&path[1..], decl)
167 }
168 }
169
170 pub fn iter_defs_re(&self) -> impl Iterator<Item = (Path, &Decl)> {
171 self.decls.iter().flat_map(|item| match &item.decl {
172 Decl::Module(sub_module) => sub_module
173 .iter_defs_re()
174 .map(|(mut p, d)| {
175 p.0.insert(0, item.name.clone());
176 (p, d)
177 })
178 .collect::<vec::Vec<_>>(),
179 _ => {
180 vec![(Path(vec![item.name.clone()]), &item.decl)]
181 }
182 })
183 }
184
185 pub fn iter_types_re(&self) -> impl Iterator<Item = (Path, &Ty)> {
186 self.iter_defs_re().filter_map(|(p, d)| {
187 if let Decl::Type(ty) = d {
188 Some((p, ty))
189 } else {
190 None
191 }
192 })
193 }
194}