1use super::mangle::Mangle;
2use super::*;
3use crate::parse;
4use either::Either;
5use py_declare::mir::IntoIR;
6use py_declare::*;
7use py_lex::PU;
8use terl::*;
9
10py_ir::custom_ir_variable!(pub IR<py_ir::value::Value>);
11
12pub trait Generate<Item: ?Sized> {
13 type Forward;
14
15 fn generate(&mut self, item: &Item) -> Self::Forward;
16}
17
18type Errors = Either<Error, Vec<Error>>;
19
20type ItemsGenerateResult = Result<Vec<Item>, Either<Vec<Error>, Vec<Vec<Error>>>>;
21
22#[derive(Debug, Clone)]
23struct Results<T, E> {
24 inner: Result<Vec<T>, Vec<E>>,
25}
26
27impl<T, E> Default for Results<T, E> {
28 fn default() -> Self {
29 Self { inner: Ok(vec![]) }
30 }
31}
32
33impl<T, E> Results<T, E> {
34 fn new() -> Self {
35 Self::default()
36 }
37
38 fn add_ok(&mut self, item: T) -> Result<(), T> {
39 match &mut self.inner {
40 Ok(state) => {
41 state.push(item);
42 Ok(())
43 }
44 _ => Err(item),
45 }
46 }
47
48 fn add_err(&mut self, err: E) {
49 match &mut self.inner {
50 Ok(_) => self.inner = Err(vec![err]),
51 Err(errs) => errs.push(err),
52 }
53 }
54
55 fn add_result(&mut self, result: Result<T, E>) {
56 match result {
57 Ok(ok) => _ = self.add_ok(ok),
58 Err(err) => self.add_err(err),
59 }
60 }
61
62 fn take(self) -> Result<Vec<T>, Vec<E>> {
63 self.inner
64 }
65}
66
67impl<T, E> Extend<Result<T, E>> for Results<T, E> {
68 fn extend<I>(&mut self, iter: I)
69 where
70 I: IntoIterator<Item = Result<T, E>>,
71 {
72 for item in iter {
73 self.add_result(item);
74 }
75 }
76}
77
78impl<T, E> FromIterator<Result<T, E>> for Results<T, E> {
79 fn from_iter<I>(iter: I) -> Self
80 where
81 I: IntoIterator<Item = Result<T, E>>,
82 {
83 let mut results = Self::new();
84 results.extend(iter);
85 results
86 }
87}
88
89fn fn_define_task<'d, M: Mangle>(
90 define: &mut Defines<M>,
91 fn_define: &'d parse::FnDefine,
92) -> Result<impl FnOnce(&'d Defines<M>) -> Result<FnDefine, Vec<Error>>, Error> {
93 let ty = fn_define.ty.to_mir_ty()?;
94
95 let params = fn_define
96 .params
97 .iter()
98 .try_fold(Vec::new(), |mut vec, pu| {
99 let name = pu.name.to_string();
100 let ty = pu.ty.to_mir_ty()?;
101 vec.push(defs::Parameter { name, ty });
102 Result::Ok(vec)
103 })?;
104
105 let fn_sign = defs::FnSign::new(
106 ty.clone(),
107 params.clone(),
108 fn_define.retty_span,
109 fn_define.sign_span,
110 );
111
112 let mangled_name = define.regist_fn(fn_define, fn_sign)?;
113
114 Ok(|define: &Defines<M>| -> Result<FnDefine, Vec<Error>> {
115 let mut statement_transmuter = {
116 let scopes = BasicScopes::default();
117 let spans = fn_define.params.iter().map(WithSpan::get_span);
118 let fn_scope = FnScope::new(&mangled_name, params.iter(), spans);
119 StatementGenerator::new(&define.defs, fn_scope, scopes)
120 };
121
122 let body = match statement_transmuter.generate(&fn_define.codes) {
123 Err(error) => Err(vec![error]),
124 Ok(body) if !body.returned => {
125 let reason = format!("function `{}` is never return", fn_define.name);
126 let error = fn_define.sign_span.make_error(reason);
127 Err(vec![error])
128 }
129
130 Ok(body) => Ok(body),
131 }?;
132
133 statement_transmuter.fn_scope.declare_map.declare_all()?;
134
135 let export = fn_define.export.is_some();
136 let mir_fn = mir::FnDefine {
137 export,
138 ty,
139 body,
140 params,
141 name: mangled_name,
142 };
143 Ok(mir_fn.into_ir(&statement_transmuter.fn_scope.declare_map))
144 })
145}
146
147#[cfg(feature = "parallel")]
148mod parallel {
149 use super::*;
150 use rayon::prelude::*;
151
152 impl<T, E> FromParallelIterator<Result<T, E>> for Results<T, E>
153 where
154 T: Send + 'static,
155 E: Send + 'static,
156 {
157 fn from_par_iter<I>(iter: I) -> Self
158 where
159 I: IntoParallelIterator<Item = Result<T, E>>,
160 {
161 let (result_s, result_r) = std::sync::mpsc::channel();
162 let state = std::thread::spawn(move || {
163 let mut items = Self::new();
164 while let Ok(result) = result_r.recv() {
165 items.add_result(result);
166 }
167 items
168 });
169 iter.into_par_iter()
170 .for_each_with(result_s, |sender, item| {
171 sender.send(item).unwrap();
172 });
173 state.join().unwrap()
174 }
175 }
176
177 impl<M: Mangle> Generate<[parse::Item]> for Defines<M> {
178 type Forward = ItemsGenerateResult;
179
180 fn generate(&mut self, items: &[parse::Item]) -> Self::Forward {
181 items
182 .iter()
183 .filter_map(|item| match item {
184 parse::Item::FnDefine(fn_define) => Some(fn_define),
185 parse::Item::Comment(_) => None,
186 })
187 .map(|fn_define| fn_define_task(self, fn_define).map(Box::new))
188 .collect::<Results<_, _>>()
189 .take()
190 .map_err(Either::Left)?
191 .into_par_iter()
192 .map(|task| task(self).map(Into::into))
193 .collect::<Results<_, _>>()
194 .take()
195 .map_err(Either::Right)
196 }
197 }
198}
199
200#[cfg(not(feature = "parallel"))]
201mod normal {
202 use super::*;
203 impl<M: Mangle> Generate<[parse::Item]> for Defines<M> {
204 type Forward = ItemsGenerateResult;
205
206 fn generate(&mut self, items: &[parse::Item]) -> Self::Forward {
207 items
208 .iter()
209 .filter_map(|item| match item {
210 parse::Item::FnDefine(fn_define) => Some(fn_define),
211 parse::Item::Comment(_) => None,
212 })
213 .map(|fn_define| fn_define_task(self, fn_define).map(Box::new))
214 .collect::<Results<_, _>>()
215 .take()
216 .map_err(Either::Left)?
217 .into_iter()
218 .map(|task| task(self).map(Into::into))
219 .collect::<Results<_, _>>()
220 .take()
221 .map_err(Either::Right)
222 }
223 }
224}
225
226impl<M: Mangle> Generate<parse::Item> for Defines<M> {
227 type Forward = Result<Option<Item>, Errors>;
228
229 fn generate(&mut self, item: &parse::Item) -> Self::Forward {
230 match item {
231 parse::Item::FnDefine(fn_define) => self.generate(fn_define).map(Into::into).map(Some),
232 parse::Item::Comment(..) => Ok(None),
233 }
234 }
235}
236
237impl<M: Mangle> Generate<parse::FnDefine> for Defines<M> {
238 type Forward = Result<FnDefine, Errors>;
239
240 fn generate(&mut self, fn_define: &parse::FnDefine) -> Self::Forward {
241 fn_define_task(self, fn_define).map_err(Either::Left)?(self).map_err(Either::Right)
242 }
243}
244
245struct StatementGenerator<'w> {
246 pub defs: &'w Defs,
247 pub fn_scope: FnScope,
248 pub scopes: BasicScopes,
249 stmts: mir::Statements,
250}
251
252struct VarDeineLoc(usize);
253
254impl StatementGenerator<'_> {
255 fn new(defs: &Defs, fn_scope: FnScope, scopes: BasicScopes) -> StatementGenerator<'_> {
256 StatementGenerator {
257 defs,
258 fn_scope,
259 scopes,
260 stmts: Default::default(),
261 }
262 }
263
264 #[inline]
265 fn push_stmt(&mut self, stmt: impl Into<mir::Statement>) {
266 self.stmts.push(stmt.into());
267 }
268
269 fn temp_var_define<I>(
270 &mut self,
271 param_ty: GroupIdx,
272 result_ty: GroupIdx,
273 init: I,
274 ) -> ValueHandle
275 where
276 I: Into<mir::AssignValue>,
277 {
278 let init = mir::Undeclared::new(init.into(), param_ty);
279 let temp_name = self.fn_scope.temp_name();
280 let loc = self.push_var_define(mir::VarDefine {
281 ty: param_ty,
282 name: temp_name.clone(),
283 init: Some(init),
284 is_temp: true,
285 });
286 let handle = mir::Undeclared::new(mir::Value::Variable(temp_name), result_ty);
287 ValueHandle::new(loc, handle)
288 }
289
290 fn push_var_define(&mut self, var_define: mir::VarDefine) -> VarDeineLoc {
291 let loc = VarDeineLoc(self.stmts.len());
292 self.stmts.push(mir::Statement::VarDefine(var_define));
293 loc
294 }
295
296 fn rename_var_define(&mut self, loc: VarDeineLoc, new_name: &str) {
297 match &mut self.stmts[loc.0] {
298 py_ir::Statement::VarDefine(define) => {
299 define.name = new_name.to_owned();
300 define.is_temp = false;
301 }
302 _ => unreachable!(),
303 }
304 }
305
306 fn take_stmts(&mut self) -> mir::Statements {
307 std::mem::take(&mut self.stmts)
308 }
309
310 fn replace_stmts(&mut self, new: mir::Statements) -> mir::Statements {
311 std::mem::replace(&mut self.stmts, new)
312 }
313
314 fn search_value(&mut self, name: &str) -> Option<defs::VarDef> {
315 self.fn_scope
316 .search_parameter(name)
317 .or_else(|| self.scopes.search_variable(name))
318 }
319
320 fn in_new_basic_scope<R>(&mut self, active: impl FnOnce(&mut Self) -> R) -> R {
321 self.scopes.push(Default::default());
322 let r = active(self);
323 self.scopes.pop();
324 r
325 }
326}
327
328impl Generate<parse::Statement> for StatementGenerator<'_> {
329 type Forward = Result<Option<mir::Statement>>;
330
331 fn generate(&mut self, stmt: &parse::Statement) -> Self::Forward {
332 match stmt {
333 parse::Statement::VarStoreStmt(stmt) => self.generate(&****stmt).map(Into::into),
334 parse::Statement::If(stmt) => self.generate(&**stmt).map(Into::into),
335 parse::Statement::While(stmt) => self.generate(&**stmt).map(Into::into),
336 parse::Statement::Return(stmt) => self.generate(&**stmt).map(Into::into),
337 parse::Statement::CodeBlock(stmt) => self.generate(&**stmt).map(Into::into),
338 parse::Statement::VarDefineStmt(stmt) => match self.generate(&****stmt)? {
339 Some(var_define) => Ok(var_define.into()),
340 None => return Ok(None),
341 },
342 parse::Statement::FnCallStmt(stmt) => {
343 self.generate(&****stmt)?;
344 return Ok(None);
345 }
346 parse::Statement::Comment(..) => return Ok(None),
347 }
348 .map(Some)
349 }
350}
351
352struct ValueHandle {
353 loc: Option<VarDeineLoc>,
354 handle: mir::Undeclared<mir::Value>,
355}
356
357impl std::ops::Deref for ValueHandle {
358 type Target = mir::Undeclared<mir::Value>;
359
360 fn deref(&self) -> &Self::Target {
361 &self.handle
362 }
363}
364
365impl ValueHandle {
366 fn new(loc: VarDeineLoc, handle: mir::Undeclared<mir::Value>) -> Self {
367 Self {
368 loc: Some(loc),
369 handle,
370 }
371 }
372}
373
374impl From<mir::Undeclared<mir::Value>> for ValueHandle {
375 fn from(handle: mir::Undeclared<mir::Value>) -> Self {
376 Self { loc: None, handle }
377 }
378}
379
380impl Generate<parse::FnCall> for StatementGenerator<'_> {
381 type Forward = Result<ValueHandle>;
382
383 fn generate(&mut self, fn_call: &parse::FnCall) -> Self::Forward {
384 let args = fn_call.args.iter().try_fold(vec![], |mut args, expr| {
385 args.push(self.generate(expr)?.handle);
386 Result::Ok(args)
387 })?;
388
389 let Some(overloads) = self.defs.get_unmangled(&fn_call.fn_name) else {
390 return Err(fn_call.make_error(format!("call undefinded function {}", fn_call.fn_name)));
391 };
392
393 let args_spans = fn_call
394 .args
395 .iter()
396 .map(|pu| pu.get_span())
397 .collect::<Vec<_>>();
398
399 let overload_len_filter =
400 filters::FnParamLen::new(Some(&fn_call.fn_name), args.len(), fn_call.get_span());
401
402 let branch_builder = |overload: &Overload| {
403 let mut branch_builder = BranchesBuilder::new(Type::Overload(overload.clone()));
404 if branch_builder.filter_self(self.defs, &overload_len_filter) {
405 for ((param, arg), span) in overload.params.iter().zip(&args).zip(&args_spans) {
407 let filter = filters::TypeEqual::new(¶m.ty, *span);
408 let declare_map = &mut self.fn_scope.declare_map;
409 branch_builder = branch_builder.new_depend::<Directly, _>(
410 declare_map,
411 self.defs,
412 arg.ty,
413 &filter,
414 );
415 }
416 }
417 branch_builder
418 };
419
420 let branch_builders = overloads.iter().map(branch_builder).collect();
421 let overload = self
422 .fn_scope
423 .declare_map
424 .build_group(GroupBuilder::new(fn_call.get_span(), branch_builders));
425
426 Ok(self.temp_var_define(overload, overload, mir::FnCall { args }))
427 }
428}
429
430impl Generate<parse::VarStore> for StatementGenerator<'_> {
431 type Forward = Result<mir::VarStore>;
432
433 fn generate(&mut self, var_store: &parse::VarStore) -> Self::Forward {
434 let name = var_store.name.to_string();
435 let val = self.generate(&var_store.assign.val)?.handle;
436
437 let val_at = var_store.assign.val.get_span();
438
439 let Some(var_def) = self.search_value(&name) else {
440 return Err(val_at.make_error(format!("use of undefined variable {}", name)));
441 };
442 if !var_def.mutable {
443 return Err(val_at.make_error(format!("cant assign to a immmutable variable {}", name)));
444 }
445
446 self.fn_scope
447 .declare_map
448 .merge_group(val_at, var_def.ty, val.ty);
449
450 Ok(mir::VarStore { name, val })
451 }
452}
453
454impl Generate<parse::VarDefine> for StatementGenerator<'_> {
455 type Forward = Result<Option<mir::VarDefine>>;
456
457 fn generate(&mut self, var_define: &parse::VarDefine) -> Self::Forward {
458 let ty = var_define.ty.to_mir_ty()?;
459 let ty = self
460 .fn_scope
461 .declare_map
462 .new_static_group(var_define.ty.get_span(), std::iter::once(ty.into()));
463 self.scopes
464 .regist_variable(&var_define.name, defs::VarDef { ty, mutable: true });
465
466 let init = match &var_define.init {
467 Some(var_assign) => {
468 let init = self.generate(&var_assign.val)?;
469
470 if let Some(loc) = init.loc {
471 self.rename_var_define(loc, &var_define.name);
472 return Ok(None);
473 }
474 let at = var_assign.val.get_span();
475 self.fn_scope.declare_map.merge_group(at, ty, init.ty);
476
477 Some(mir::Undeclared::new(init.handle.val.into(), init.handle.ty))
478 }
479 None => None,
480 };
481
482 let name = var_define.name.to_string();
483 Ok(Some(mir::VarDefine {
484 ty,
485 name,
486 init,
487 is_temp: false,
488 }))
489 }
490}
491
492impl Generate<parse::If> for StatementGenerator<'_> {
493 type Forward = Result<mir::If>;
494
495 fn generate(&mut self, if_: &parse::If) -> Self::Forward {
496 let branches = if_
497 .branches
498 .iter()
499 .try_fold(vec![], |mut branches, branch| {
500 branches.push(self.generate(branch)?);
501 Ok(branches)
502 })?;
503 let else_ = match &if_.else_ {
504 Some(else_) => Some(self.generate(&else_.block)?),
505 None => None,
506 };
507 Ok(mir::If { branches, else_ })
508 }
509}
510
511impl Generate<parse::While> for StatementGenerator<'_> {
512 type Forward = Result<mir::While>;
513
514 fn generate(&mut self, while_: &parse::While) -> Self::Forward {
515 let cond = self.generate(&while_.conds)?;
516 let body = self.generate(&while_.block)?;
517 Ok(mir::While { cond, body })
518 }
519}
520
521impl Generate<parse::IfBranch> for StatementGenerator<'_> {
522 type Forward = Result<mir::IfBranch>;
523
524 fn generate(&mut self, branch: &parse::IfBranch) -> Self::Forward {
525 let cond = self.generate(&branch.conds)?;
526 let body = self.generate(&branch.body)?;
527 Ok(mir::IfBranch { cond, body })
528 }
529}
530
531impl Generate<parse::Return> for StatementGenerator<'_> {
532 type Forward = Result<mir::Return>;
533
534 fn generate(&mut self, ret: &parse::Return) -> Self::Forward {
535 let val = match &ret.val {
536 Some(expr) => {
537 let val = self.generate(expr)?;
538 let mangled_fn = self.defs.get_mangled(&self.fn_scope.fn_name);
539 self.fn_scope
540 .declare_map
541 .declare_type(expr.get_span(), val.ty, &mangled_fn.ty);
542 Some(val.handle)
543 }
544 None => None,
545 };
546 Ok(mir::Return { val })
547 }
548}
549
550impl Generate<parse::CodeBlock> for StatementGenerator<'_> {
551 type Forward = Result<mir::Statements>;
552
553 fn generate(&mut self, item: &parse::CodeBlock) -> Self::Forward {
554 self.in_new_basic_scope(|g| {
555 let current_scope = g.take_stmts();
556 for stmt in &item.stmts {
557 if let Some(stmt) = g.generate(stmt)? {
558 g.push_stmt(stmt);
559 }
560 }
561 Ok(g.replace_stmts(current_scope))
562 })
563 }
564}
565
566impl Generate<parse::Conditions> for StatementGenerator<'_> {
567 type Forward = Result<mir::Condition>;
568
569 fn generate(&mut self, conds: &parse::Conditions) -> Self::Forward {
570 let (compute, val) = self.in_new_basic_scope(|g| {
571 let mut last_condition = g.generate(&conds[0])?;
572 for arg in conds.iter().skip(1) {
573 last_condition = g.generate(arg)?;
574 }
575 Ok((g.take_stmts(), last_condition.handle))
576 })?;
577
578 let bool = py_ir::types::PrimitiveType::Bool.into();
580 let last_cond_span = conds.last().unwrap().get_span();
581 self.fn_scope
582 .declare_map
583 .declare_type(last_cond_span, val.ty, &bool);
584 Ok(mir::Condition { val, compute })
585 }
586}
587
588impl Generate<parse::Expr> for StatementGenerator<'_> {
589 type Forward = Result<ValueHandle>;
590
591 fn generate(&mut self, expr: &parse::Expr) -> Self::Forward {
592 let mut vals = Vec::new();
593 for item in expr.iter() {
594 match item {
595 parse::ExprItem::AtomicExpr(atomic) => vals.push(self.generate(atomic)?),
596 parse::ExprItem::Operators(op) => match op.associativity() {
597 py_lex::ops::OperatorAssociativity::Binary => {
598 let r = vals.pop().unwrap();
599 let l = vals.pop().unwrap();
600 self.fn_scope
601 .declare_map
602 .merge_group(expr.get_span(), l.ty, r.ty);
603 use py_ir::types::PrimitiveType;
604 use py_lex::ops::OperatorTypes::CompareOperator;
605
606 let param_ty = l.ty;
609 let result_ty = if op.op_ty() == CompareOperator {
610 self.fn_scope
611 .declare_map
612 .new_static_group(expr.get_span(), [PrimitiveType::Bool.into()])
613 } else {
614 l.ty
615 };
616
617 let init = mir::Operate::Binary(**op, l.handle, r.handle);
618 vals.push(self.temp_var_define(param_ty, result_ty, init));
619 }
620 py_lex::ops::OperatorAssociativity::Unary => {
621 let v = vals.pop().unwrap();
622 let ty = v.ty;
623
624 let init = mir::Operate::Unary(**op, v.handle);
625 vals.push(self.temp_var_define(ty, ty, init));
626 }
627
628 py_lex::ops::OperatorAssociativity::None => unreachable!(),
629 },
630 }
631 }
632 vals.pop().ok_or_else(|| unreachable!())
633 }
634}
635
636impl Generate<PU<parse::AtomicExpr>> for StatementGenerator<'_> {
637 type Forward = Result<ValueHandle>;
638
639 fn generate(&mut self, atomic: &PU<parse::AtomicExpr>) -> Self::Forward {
640 let literal = match &**atomic {
641 parse::AtomicExpr::CharLiteral(char) => py_ir::value::Literal::Char(char.parsed),
644 parse::AtomicExpr::NumberLiteral(n) => match n {
645 parse::NumberLiteral::Float(number) => py_ir::value::Literal::Float(*number),
646 parse::NumberLiteral::Digit(number) => py_ir::value::Literal::Integer(*number),
647 },
648
649 parse::AtomicExpr::StringLiteral(_str) => {
650 todo!("a VarDefine statement will be generate...")
652 }
653 parse::AtomicExpr::FnCall(fn_call) => return self.generate(fn_call),
654 parse::AtomicExpr::Variable(name) => {
655 let Some(def) = self.search_value(name) else {
656 return Err(atomic.make_error("use of undefined variable"));
657 };
658
659 let val = mir::Value::Variable(name.to_string());
660 return Ok(mir::Undeclared::new(val, def.ty).into());
661 }
662 parse::AtomicExpr::Array(ref _array) => {
663 todo!()
665 }
666 };
667
668 let ty = self.fn_scope.declare_map.build_group({
669 let branches = mir::Undeclared::literal_branches(&literal);
670 GroupBuilder::new(atomic.get_span(), branches)
671 });
672 Ok(mir::Undeclared::new(literal.into(), ty).into())
673 }
674}