1use{
2 std::{
3 cell::{Cell, RefCell},
4 fmt,
5 fmt::Write,
6 collections::BTreeSet,
7 },
8 crate::{
9 makepad_live_id::{LiveId, live_id},
10 makepad_live_compiler::{
11 makepad_math::PrettyPrintedF32,
12 TokenSpan
13 },
14 shader_ast::*,
15 shader_registry::ShaderRegistry
16 }
17};
18
19
20struct VoidWrap();
21impl VoidWrap{
22 pub fn unwrap(&self){}
23}
24
25macro_rules! write {
26 ($dst:expr, $($arg:tt)*) => ({let _ =$dst.write_fmt(std::format_args!($($arg)*));VoidWrap()})
27}
28
29macro_rules! writeln {
30 ($dst:expr $(,)?) => (
31 write!($dst, "\n")
32 );
33 ($dst:expr, $($arg:tt)*) => (
34 {let _ = $dst.write_fmt(std::format_args!($($arg)*));VoidWrap()}
35 );
36}
37
38#[derive(Clone)]
39pub struct ClosureSiteInfo<'a> {
40 pub site_index: usize,
41 pub closure_site: &'a ClosureSite,
42 pub call_ptr: FnPtr
43}
44
45pub enum StructConsType{
46 Paren,
47 Brace,
48 ConsFn
49}
50
51pub trait BackendWriter {
52 fn get_struct_cons_type(&self)->StructConsType;
53 fn needs_mul_fn_for_matrix_multiplication(&self) -> bool;
54 fn needs_unpack_for_matrix_multiplication(&self) -> bool;
55 fn const_table_is_vec4(&self) -> bool;
56
57 fn enum_is_float(&self)->bool;
58
59 fn use_cons_fn(&self, what: &str) -> bool;
60
61 fn write_var_decl(
62 &self,
63 string: &mut String,
64 sep: &'static str,
65 is_inout: bool,
66 is_packed: bool,
67 ident: &dyn fmt::Display,
68 ty: &Ty,
69 ) -> bool;
70
71 fn write_call_expr_hidden_args(&self, string: &mut String, hidden_args:&BTreeSet<HiddenArgKind >, sep: &str);
72 fn write_fn_def_hidden_params(&self, string: &mut String, hidden_args:&BTreeSet<HiddenArgKind >, sep: &str);
73
74 fn generate_live_value_prefix(&self, string: &mut String);
75 fn generate_draw_shader_field_expr(&self, string: &mut String, field_ident: Ident, ty:&Ty);
76
77 fn write_ty_lit(&self, string: &mut String, ty_lit: TyLit);
78 fn write_builtin_call_ident(&self, string: &mut String, ident: Ident, arg_exprs: &[Expr]);
79
80}
81
82pub struct BlockGenerator<'a> {
83 pub fn_def: &'a FnDef,
84 pub closure_site_info: Option<ClosureSiteInfo<'a >>,
85 pub shader_registry: &'a ShaderRegistry,
87 pub backend_writer: &'a dyn BackendWriter,
88 pub const_table_offset: Option<usize>,
89 pub indent_level: usize,
91 pub string: &'a mut String,
92}
93
94
95pub fn generate_cons_fn(backend_writer:&dyn BackendWriter, string: &mut String, ty_lit: TyLit, param_tys: &[Ty]) {
96 let mut cons_name = format!("consfn_{}", ty_lit);
97 for param_ty in param_tys {
98 write!(cons_name, "_{}", param_ty).unwrap();
99 }
100 if !backend_writer.use_cons_fn(&cons_name) {
101 return
102 }
103 backend_writer.write_ty_lit(string, ty_lit);
104 write!(string, " {}(", cons_name).unwrap();
105
106 let mut sep = "";
107 if param_tys.len() == 1 {
108 backend_writer.write_var_decl(string, sep, false, false, &Ident(live_id!(x)), ¶m_tys[0]);
109 } else {
110 for (index, param_ty) in param_tys.iter().enumerate() {
111 backend_writer.write_var_decl(string, sep, false, false,&DisplaConstructorArg(index), param_ty);
113 sep = ", ";
114 }
115 }
116
117 writeln!(string, ") {{").unwrap();
118 write!(string, " return ").unwrap();
119 backend_writer.write_ty_lit(string, ty_lit);
120 write!(string, "(").unwrap();
121 let ty = ty_lit.to_ty();
122 if param_tys.len() == 1 {
123 let param_ty = ¶m_tys[0];
124 match param_ty {
125 Ty::Bool | Ty::Int | Ty::Float => {
126 let mut sep = "";
127 for _ in 0..ty.slots() {
128 write!(string, "{}x", sep).unwrap();
129 sep = ", ";
130 }
131 }
132 Ty::Mat2 | Ty::Mat3 | Ty::Mat4 => {
133 let dst_size = match ty {
134 Ty::Mat2 => 2,
135 Ty::Mat3 => 3,
136 Ty::Mat4 => 4,
137 _ => panic!(),
138 };
139 let src_size = match param_ty {
140 Ty::Mat2 => 2,
141 Ty::Mat3 => 3,
142 Ty::Mat4 => 4,
143 _ => panic!(),
144 };
145 let mut sep = "";
146 for col_index in 0..dst_size {
147 for row_index in 0..dst_size {
148 if row_index < src_size && col_index < src_size {
149 write!(string, "{}x[{}][{}]", sep, col_index, row_index)
150 .unwrap();
151 } else {
152 write!(
153 string,
154 "{}{}",
155 sep,
156 if col_index == row_index {1.0} else {0.0}
157 )
158 .unwrap();
159 }
160 sep = ", ";
161 }
162 }
163 }
164 _ => panic!(),
165 }
166 } else {
167 let mut sep = "";
168 for (index_0, param_ty) in param_tys.iter().enumerate() {
169 if param_ty.slots() == 1 {
170 write!(string, "{}x{}", sep, index_0).unwrap();
171 sep = ", ";
172 } else {
173 for index_1 in 0..param_ty.slots() {
174 write!(string, "{}x{}[{}]", sep, index_0, index_1).unwrap();
175 sep = ", ";
176 }
177 }
178 }
179 }
180 writeln!(string, ");").unwrap();
181 writeln!(string, "}}\n").unwrap();
182}
183
184impl<'a> BlockGenerator<'a> {
185 pub fn generate_block(&mut self, block: &Block) {
186 write!(self.string, "{{\n").unwrap();
187 self.write_indent();
188 if !block.stmts.is_empty() {
189 self.indent_level += 1;
190 for stmt in &block.stmts {
191 self.generate_stmt(stmt);
192 writeln!(self.string).unwrap();
193 }
194 self.indent_level -= 1;
195 self.write_indent();
196 }
197 write!(self.string, "}}").unwrap();
198 }
199
200 fn generate_stmt(&mut self, stmt: &Stmt) {
201 self.write_indent();
202 match *stmt {
203 Stmt::Break {span} => self.generate_break_stmt(span),
204 Stmt::Continue {span} => self.generate_continue_stmt(span),
205 Stmt::For {
206 span,
207 ident,
208 ref from_expr,
209 ref to_expr,
210 ref step_expr,
211 ref block,
212 } => self.generate_for_stmt(span, ident, from_expr, to_expr, step_expr, block),
213 Stmt::If {
214 span,
215 ref expr,
216 ref block_if_true,
217 ref block_if_false,
218 } => self.generate_if_stmt(span, expr, block_if_true, block_if_false),
219 Stmt::Match {
220 span,
221 ref expr,
222 ref matches,
223 } => self.generate_match_stmt(span, expr, matches),
224 Stmt::Let {
225 span,
226 ref ty,
227 ident,
228 ref ty_expr,
229 ref expr,
230 ref shadow
231 } => self.generate_let_stmt(span, ty, ident, ty_expr, expr, shadow),
232 Stmt::Return {span, ref expr} => self.generate_return_stmt(span, expr),
233 Stmt::Block {span, ref block} => self.generate_block_stmt(span, block),
234 Stmt::Expr {span, ref expr} => self.generate_expr_stmt(span, expr),
235 }
236 }
237
238 fn generate_break_stmt(&mut self, _span: TokenSpan) {
239 writeln!(self.string, "break;").unwrap();
240 }
241
242 fn generate_continue_stmt(&mut self, _span: TokenSpan) {
243 writeln!(self.string, "continue;").unwrap();
244 }
245
246 fn generate_for_stmt(
247 &mut self,
248 _span: TokenSpan,
249 ident: Ident,
250 from_expr: &Expr,
251 to_expr: &Expr,
252 step_expr: &Option<Expr>,
253 block: &Block,
254 ) {
255 let from = from_expr
256 .const_val
257 .borrow()
258 .as_ref()
259 .unwrap()
260 .as_ref()
261 .unwrap()
262 .to_int()
263 .unwrap();
264 let to = to_expr
265 .const_val
266 .borrow()
267 .as_ref()
268 .unwrap()
269 .as_ref()
270 .unwrap()
271 .to_int()
272 .unwrap();
273 let step = if let Some(step_expr) = step_expr {
274 step_expr
275 .const_val
276 .borrow()
277 .as_ref()
278 .unwrap()
279 .as_ref()
280 .unwrap()
281 .to_int()
282 .unwrap()
283 } else if from < to {
284 1
285 } else {
286 -1
287 };
288 write!(
289 self.string,
290 "for (int {0} = {1}; {0} {2} {3}; {0} {4} {5}) ",
291 ident,
292 if from <= to {from} else {from - 1},
293 if from <= to {"<"} else {">="},
294 to,
295 if step > 0 {"+="} else {"-="},
296 step.abs()
297 )
298 .unwrap();
299 self.generate_block(block);
300 writeln!(self.string).unwrap();
301 }
302
303 fn generate_if_stmt(
304 &mut self,
305 _span: TokenSpan,
306 expr: &Expr,
307 block_if_true: &Block,
308 block_if_false: &Option<Box<Block >>,
309 ) {
310 write!(self.string, "if").unwrap();
311 self.generate_expr(expr);
312 write!(self.string, " ").unwrap();
313 self.generate_block(block_if_true);
314 if let Some(block_if_false) = block_if_false {
315 write!(self.string, "else").unwrap();
316 self.generate_block(block_if_false);
317 }
318 writeln!(self.string).unwrap();
319 }
320
321 fn generate_match_stmt(
322 &mut self,
323 _span: TokenSpan,
324 expr: &Expr,
325 matches: &Vec<Match>,
326 ) {
327 for (index,match_item) in matches.iter().enumerate(){
328
329 if index != 0{
330 write!(self.string, "else ").unwrap();
331 }
332
333 if self.backend_writer.enum_is_float(){
334 write!(self.string, "if(").unwrap();
335 self.backend_writer.write_builtin_call_ident(&mut self.string, Ident(live_id!(abs)),&[]);
336 write!(self.string, "(");
337 self.generate_expr(expr);
338 write!(self.string, " - {}.0)<0.5)", match_item.enum_value.get().unwrap()).unwrap();
341 }
342 else {
343 write!(self.string, "if(").unwrap();
344 self.generate_expr(expr);
345 write!(self.string, " == {})", match_item.enum_value.get().unwrap()).unwrap();
346 }
347
348 self.generate_block(&match_item.block);
349 }
350 }
351
352 fn generate_let_stmt(
353 &mut self,
354 _span: TokenSpan,
355 ty: &RefCell<Option<Ty >>,
356 ident: Ident,
357 _ty_expr: &Option<TyExpr>,
358 expr: &Option<Expr>,
359 shadow: &Cell<Option<ScopeSymShadow >>
360 ) {
361 self.backend_writer.write_var_decl(
362 &mut self.string,
363 "",
364 false,
365 false,
366 &DisplayVarName(ident, shadow.get().unwrap()),
367 ty.borrow().as_ref().unwrap()
368 );
369 if let Some(expr) = expr {
370 write!(self.string, " = ").unwrap();
371 self.generate_expr(expr);
372 }
373 writeln!(self.string, ";").unwrap();
374 }
375
376 fn generate_return_stmt(&mut self, _span: TokenSpan, expr: &Option<Expr>) {
377 write!(self.string, "return").unwrap();
378 if let Some(expr) = expr {
379 write!(self.string, " ").unwrap();
380 self.generate_expr(expr);
381 }
382 writeln!(self.string, ";").unwrap();
383 }
384
385 fn generate_block_stmt(&mut self, _span: TokenSpan, block: &Block) {
386 self.generate_block(block);
387 writeln!(self.string).unwrap();
388 }
389
390 fn generate_expr_stmt(&mut self, _span: TokenSpan, expr: &Expr) {
391 self.generate_expr(expr);
392 writeln!(self.string, ";").unwrap();
393 }
394
395 fn generate_expr(&mut self, expr: &Expr) {
396 ExprGenerator {
397 closure_site_info: self.closure_site_info.clone(),
398 fn_def: Some(self.fn_def),
399 shader_registry: self.shader_registry,
400 backend_writer: self.backend_writer,
401 const_table_offset: self.const_table_offset,
402 string: self.string,
405 }
406 .generate_expr(expr)
407 }
408
409 fn write_indent(&mut self) {
410 for _ in 0..self.indent_level {
411 write!(self.string, " ").unwrap();
412 }
413 }
414
415 }
420
421pub struct ExprGenerator<'a> {
422 pub fn_def: Option<&'a FnDef>,
423 pub closure_site_info: Option<ClosureSiteInfo<'a >>,
424 pub shader_registry: &'a ShaderRegistry,
426 pub backend_writer: &'a dyn BackendWriter,
427 pub const_table_offset: Option<usize>,
428 pub string: &'a mut String,
431}
432
433impl<'a> ExprGenerator<'a> {
434 pub fn generate_expr(&mut self, in_expr: &Expr) {
435 fn const_table_index_to_vec4(string: &mut String, index: usize) {
436 let base = index >> 2;
437 let sub = index - (base << 2);
438 match sub {
439 0 => write!(string, "[{}].x", base).unwrap(),
440 1 => write!(string, "[{}].y", base).unwrap(),
441 2 => write!(string, "[{}].z", base).unwrap(),
442 _ => write!(string, "[{}].w", base).unwrap(),
443 };
444 }
445 match (in_expr.const_val.borrow().as_ref(), in_expr.const_index.get()) {
446 (Some(Some(Val::Vec4(_))), Some(mut index)) if self.const_table_offset.is_some() => {
447 let const_table_offset = self.const_table_offset.unwrap();
448 self.write_ty_lit(TyLit::Vec4);
449 write!(self.string, "(").unwrap();
450 let mut sep = "";
451 for _ in 0..4 {
452 write!(self.string, "{}const_table", sep).unwrap();
453 if self.backend_writer.const_table_is_vec4() {
454 const_table_index_to_vec4(self.string, index + const_table_offset);
455 }
456 else {
457 write!(self.string, "[{}]", index + const_table_offset).unwrap();
458 }
459 sep = ", ";
460 index += 1;
461 }
462 write!(self.string, ")").unwrap();
463 },
464 (Some(Some(Val::Float(_))), Some(index)) if self.const_table_offset.is_some() => {
465 let const_table_offset = self.const_table_offset.unwrap();
466 write!(self.string, "const_table").unwrap();
467 if self.backend_writer.const_table_is_vec4() {
468 const_table_index_to_vec4(self.string, index + const_table_offset);
469 }
470 else {
471 write!(self.string, "[{}]", index + const_table_offset).unwrap();
472 }
473 }
474 (Some(Some(Val::Vec4(val))), _) => {
476 self.write_ty_lit(TyLit::Vec4);
477 write!(
478 self.string,
479 "({}, {}, {}, {})",
480 PrettyPrintedF32(val.x),
481 PrettyPrintedF32(val.y),
482 PrettyPrintedF32(val.z),
483 PrettyPrintedF32(val.w),
484 ).unwrap();
485 }
486 (Some(Some(Val::Float(val))), _) => {
487 write!(self.string, "{}f", PrettyPrintedF32(*val)).unwrap();
488 },
489 (Some(Some(val)), _) => {
490 write!(self.string, "{}", val).unwrap();
491 },
492 _ => match in_expr.kind {
493 ExprKind::Cond {
494 span,
495 ref expr,
496 ref expr_if_true,
497 ref expr_if_false,
498 } => self.generate_cond_expr(span, expr, expr_if_true, expr_if_false),
499 ExprKind::Bin {
500 span,
501 op,
502 ref left_expr,
503 ref right_expr,
504 } => self.generate_bin_expr(span, op, left_expr, right_expr),
505 ExprKind::Un {span, op, ref expr} => self.generate_un_expr(span, op, expr),
506 ExprKind::Field {
507 span,
508 ref expr,
509 field_ident,
510 } => self.generate_field_expr(span, expr, field_ident, in_expr.ty.borrow().as_ref().unwrap()),
511 ExprKind::Index {
512 span,
513 ref expr,
514 ref index_expr,
515 } => self.generate_index_expr(span, expr, index_expr),
516 ExprKind::MethodCall {
517 span,
518 ident,
519 ref arg_exprs,
520 ref closure_site_index,
521 } => self.generate_method_call_expr(span, ident, arg_exprs, closure_site_index),
522 ExprKind::PlainCall {
523 span,
524 fn_ptr,
525 ident,
526 ref arg_exprs,
527 ref closure_site_index,
528 ref param_index,
529 } => self.generate_plain_call_expr(span, ident, fn_ptr, arg_exprs, closure_site_index, param_index),
530 ExprKind::BuiltinCall {
531 span,
532 ident,
533 ref arg_exprs,
534 } => self.generate_builtin_call_expr(span, ident, arg_exprs),
535 ExprKind::ClosureDef(_) => (),
542 ExprKind::ConsCall {
543 span,
544 ty_lit,
545 ref arg_exprs,
546 } => self.generate_cons_call_expr(span, ty_lit, arg_exprs),
547 ExprKind::StructCons {
548 struct_ptr,
549 span,
550 ref args
551 } => self.generate_struct_cons(struct_ptr, span, args),
552 ExprKind::Var {
553 span,
554 ref kind,
555 ..
556 } => self.generate_var_expr(span, kind, &in_expr.ty.borrow()),
557 ExprKind::Lit {span, lit} => self.generate_lit_expr(span, lit),
558 },
559 }
560 }
561
562 fn generate_cond_expr(
563 &mut self,
564 _span: TokenSpan,
565 expr: &Expr,
566 expr_if_true: &Expr,
567 expr_if_false: &Expr,
568 ) {
569 write!(self.string, "(").unwrap();
570 self.generate_expr(expr);
571 write!(self.string, " ? ").unwrap();
572 self.generate_expr(expr_if_true);
573 write!(self.string, " : ").unwrap();
574 self.generate_expr(expr_if_false);
575 write!(self.string, ")").unwrap();
576 }
577
578 fn generate_bin_expr(&mut self, _span: TokenSpan, op: BinOp, left_expr: &Expr, right_expr: &Expr) {
579
580 let left_is_mat = match left_expr.ty.borrow().as_ref().unwrap() {
582 Ty::Mat2 | Ty::Mat3 | Ty::Mat4 => true,
583 _ => false
584 };
585 let right_is_mat = match right_expr.ty.borrow().as_ref().unwrap() {
586 Ty::Mat2 | Ty::Mat3 | Ty::Mat4 => true,
587 _ => false
588 };
589
590 if self.backend_writer.needs_mul_fn_for_matrix_multiplication() {
591 if left_is_mat || right_is_mat {
592 write!(self.string, "mul(").unwrap();
593 self.generate_expr(left_expr);
594 write!(self.string, ", ").unwrap();
595 self.generate_expr(right_expr);
596 write!(self.string, ")").unwrap();
597 return
598 }
599 }
600 else if self.backend_writer.needs_unpack_for_matrix_multiplication() {
601 if left_is_mat && !right_is_mat {
602 match right_expr.ty.borrow().as_ref().unwrap() {
603 Ty::Vec4 => {
604 write!(self.string, "(").unwrap();
605 self.generate_expr(left_expr);
606 write!(self.string, " {} ", op).unwrap();
607 self.backend_writer.write_ty_lit(self.string, TyLit::Vec4);
608 write!(self.string, "(").unwrap();
609 self.generate_expr(right_expr);
610 write!(self.string, "))").unwrap();
611 return
612 },
613 Ty::Vec3 => {
614 write!(self.string, "(").unwrap();
615 self.generate_expr(left_expr);
616 write!(self.string, " {} ", op).unwrap();
617 self.backend_writer.write_ty_lit(self.string, TyLit::Vec3);
618 write!(self.string, "(").unwrap();
619 self.generate_expr(right_expr);
620 write!(self.string, "))").unwrap();
621 return
622 },
623 _ => ()
624 };
625 }
626 else if !left_is_mat && right_is_mat {
627 match left_expr.ty.borrow().as_ref().unwrap() {
628 Ty::Vec4 => {
629 write!(self.string, "(").unwrap();
630 self.backend_writer.write_ty_lit(self.string, TyLit::Vec4);
631 write!(self.string, "(").unwrap();
632 self.generate_expr(left_expr);
633 write!(self.string, ") {} ", op).unwrap();
634 self.generate_expr(right_expr);
635 write!(self.string, ")").unwrap();
636 return
637 },
638 Ty::Vec3 => {
639 write!(self.string, "(").unwrap();
640 self.backend_writer.write_ty_lit(self.string, TyLit::Vec3);
641 write!(self.string, "(").unwrap();
642 self.generate_expr(left_expr);
643 write!(self.string, ") {} ", op).unwrap();
644 self.generate_expr(right_expr);
645 write!(self.string, ")").unwrap();
646 return
647 },
648 _ => ()
649 };
650 }
651 }
652
653 write!(self.string, "(").unwrap();
654 self.generate_expr(left_expr);
655 write!(self.string, " {} ", op).unwrap();
656 self.generate_expr(right_expr);
657 write!(self.string, ")").unwrap();
658 }
659
660 fn generate_un_expr(&mut self, _span: TokenSpan, op: UnOp, expr: &Expr) {
661 write!(self.string, "{}", op).unwrap();
662 self.generate_expr(expr);
663 }
664
665 fn generate_method_call_expr(&mut self, _span: TokenSpan, ident: Ident, arg_exprs: &[Expr], closure_site_index: &Cell<Option<usize >>) {
666 match arg_exprs[0].ty.borrow().as_ref().unwrap() {
671 Ty::Struct(struct_ptr) => {
672 let fn_def = self.shader_registry.struct_method_decl_from_ident(
673 self.shader_registry.structs.get(struct_ptr).unwrap(),
674 ident
675 ).unwrap();
676
677 self.generate_call_body(_span, fn_def, arg_exprs, closure_site_index);
678 }
679 Ty::DrawShader(shader_ptr) => {
680 let fn_def = self.shader_registry.draw_shader_method_decl_from_ident(
681 self.shader_registry.draw_shader_defs.get(shader_ptr).unwrap(),
682 ident
683 ).unwrap();
684
685 if fn_def.has_closure_args() {
686 }
689 self.generate_call_body(_span, fn_def, &arg_exprs[1..], closure_site_index);
690 }
691 _ => panic!(),
692 }
693 }
694
695
696 fn generate_call_body(&mut self, _span: TokenSpan, fn_def: &FnDef, arg_exprs: &[Expr], closure_site_index: &Cell<Option<usize >>) {
697 if let Some(closure_site_index) = closure_site_index.get() {
699 let call_def = self.fn_def.unwrap();
701 let closure_sites = &call_def.closure_sites.borrow();
702
703 let closure_site = &closure_sites.as_ref().unwrap()[closure_site_index];
704 write!(self.string, "{} (", DisplayFnNameWithClosureArgs(
708 closure_site_index,
709 call_def.fn_ptr,
710 fn_def.ident
711 )).unwrap();
712
713 let mut sep = "";
714 for arg_expr in arg_exprs {
715 match arg_expr.ty.borrow().as_ref().unwrap(){
717 Ty::ClosureDef(_)=>{
718 continue;
719 },
720 _=>()
721 }
722
723 write!(self.string, "{}", sep).unwrap();
724 self.generate_expr(arg_expr);
725 sep = ", ";
726 }
727 for sym in &closure_site.all_closed_over {
729 match sym.ty{
730 Ty::DrawShader(_)=>{
731 continue;
732 }
733 Ty::ClosureDef(_) | Ty::ClosureDecl=>panic!(),
734 _=>()
735 }
736 write!(self.string, "{}", sep).unwrap();
737 write!(self.string, "{}", DisplayVarName(sym.ident, sym.shadow)).unwrap();
738 sep = ", ";
739 }
740
741 let mut merged_hidden_args = BTreeSet::new();
742 merged_hidden_args.extend(fn_def.hidden_args.borrow().as_ref().unwrap().iter().cloned());
743 merged_hidden_args.extend(call_def.hidden_args.borrow().as_ref().unwrap().iter().cloned());
744 self.backend_writer.write_call_expr_hidden_args(self.string, &merged_hidden_args, sep);
745
746 write!(self.string, ")").unwrap();
747 }
748 else {
749 write!(self.string, "{}_{} (", fn_def.fn_ptr, fn_def.ident).unwrap();
750 let mut sep = "";
751 for arg_expr in arg_exprs {
752 write!(self.string, "{}", sep).unwrap();
753 self.generate_expr(arg_expr);
754 sep = ", ";
755 }
756
757 self.backend_writer.write_call_expr_hidden_args(self.string, fn_def.hidden_args.borrow().as_ref().unwrap(), sep);
758
759 write!(self.string, ")").unwrap();
760 }
761 }
762
763 fn generate_field_expr(&mut self, _span: TokenSpan, expr: &Expr, field_ident: Ident, ty:&Ty) {
764 match expr.ty.borrow().as_ref() {
765 Some(Ty::DrawShader(_)) => {
766 self.backend_writer.generate_draw_shader_field_expr(&mut self.string, field_ident, ty);
767 }
769 Some(Ty::Struct{..})=>{
770 self.generate_expr(expr);
771 write!(self.string, ".{}", &DisplayStructField(field_ident)).unwrap();
772 }
773 _=>{
774 self.generate_expr(expr);
775 write!(self.string, ".{}", field_ident).unwrap();
776 }
777 }
778 }
779
780 fn generate_struct_cons(
781 &mut self,
782 struct_ptr: StructPtr,
783 _span: TokenSpan,
784 args: &Vec<(Ident, Expr)>,
785 ) {
786 let struct_decl = self.shader_registry.structs.get(&struct_ptr).unwrap();
787
788 let term = match self.backend_writer.get_struct_cons_type(){
789 StructConsType::Brace=>{
790 write!(self.string, "{}{{", struct_ptr).unwrap();
791 "}"
792 }
793 StructConsType::Paren=>{
794 write!(self.string, "{}(", struct_ptr).unwrap();
795 ")"
796 }
797 StructConsType::ConsFn=>{
798 write!(self.string, "consfn_{}(", struct_ptr).unwrap();
799 ")"
800 }
801 };
802
803 for (index, field) in struct_decl.fields.iter().enumerate() {
804 if index != 0 {
805 write!(self.string, ",").unwrap();
806 }
807 let arg = args.iter().find( | (ident, _) | field.ident == *ident).unwrap();
808 self.generate_expr(&arg.1);
809 }
810 write!(self.string, "{}", term).unwrap();
811 }
812
813 fn generate_index_expr(&mut self, _span: TokenSpan, expr: &Expr, index_expr: &Expr) {
814 self.generate_expr(expr);
815 write!(self.string, "[").unwrap();
816 self.generate_expr(index_expr);
817 write!(self.string, "]").unwrap();
818 }
819
820
821 fn generate_builtin_call_expr(&mut self, _span: TokenSpan, ident: Ident, arg_exprs: &[Expr]) {
822 self.backend_writer.write_builtin_call_ident(&mut self.string, ident, arg_exprs);
825
826 write!(self.string, "(").unwrap();
827 let mut sep = "";
828 for arg_expr in arg_exprs {
829 write!(self.string, "{}", sep).unwrap();
830
831 self.generate_expr(arg_expr);
832
833 sep = ", ";
834 }
835
836 write!(self.string, ")").unwrap();
837 }
838
839
840 fn generate_plain_call_expr(&mut self, _span: TokenSpan, _ident: Option<Ident>, fn_ptr: Option<FnPtr>, arg_exprs: &[Expr], closure_site_index: &Cell<Option<usize >>, param_index: &Cell<Option<usize >>) {
841 if param_index.get().is_some(){ self.generate_closure_call_expr(_span, arg_exprs, param_index);
844 }
845 else{
846 let fn_def = self.shader_registry.all_fns.get(&fn_ptr.unwrap()).unwrap();
847 self.generate_call_body(_span, fn_def, arg_exprs, closure_site_index);
848 }
849 }
850
851
852 fn generate_closure_call_expr(&mut self, _span: TokenSpan, arg_exprs: &[Expr], param_index: &Cell<Option<usize >>) {
853
854 let param_index = param_index.get().unwrap();
855
856 let closure_site_info = self.closure_site_info.as_ref().unwrap();
857 let closure_def_index = closure_site_info.closure_site.closure_args.iter().find( | arg | arg.param_index == param_index).unwrap().closure_def_index;
859 let call_def = self.shader_registry.all_fns.get(&closure_site_info.call_ptr).unwrap();
860 let closure_def = &call_def.closure_defs[closure_def_index.0];
861
862 write!(self.string, "{}", DisplayClosureName(closure_site_info.call_ptr, closure_def_index)).unwrap();
863
864 write!(self.string, "(").unwrap();
865 let mut sep = "";
866 for arg_expr in arg_exprs {
867 write!(self.string, "{}", sep).unwrap();
868 self.generate_expr(arg_expr);
869 sep = ", ";
870 }
871 for sym in closure_def.closed_over_syms.borrow().as_ref().unwrap() {
873 if let Ty::DrawShader(_) = sym.ty {
874 continue;
875 }
876 write!(self.string, "{}", sep).unwrap();
877 write!(self.string, "{}", DisplayClosedOverArg(sym.ident, sym.shadow)).unwrap();
878 sep = ", ";
879 }
880
881 let mut merged_hidden_args = BTreeSet::new();
883 merged_hidden_args.extend(self.fn_def.unwrap().hidden_args.borrow().as_ref().unwrap().iter().cloned());
884 merged_hidden_args.extend(call_def.hidden_args.borrow().as_ref().unwrap().iter().cloned());
885 self.backend_writer.write_call_expr_hidden_args(self.string, &merged_hidden_args, sep);
886
887 write!(self.string, ")").unwrap();
888
889 }
890
891 fn generate_macro_call_expr(
892 &mut self,
893 _analysis: &Cell<Option<MacroCallAnalysis >>,
894 _span: TokenSpan,
895 _ident: Ident,
896 _arg_exprs: &[Expr],
897 ) {
898
899 }
900
901 fn generate_cons_call_expr(&mut self, _span: TokenSpan, ty_lit: TyLit, arg_exprs: &[Expr]) {
902 let mut cons_name = format!("consfn_{}", ty_lit);
904 for arg_expr in arg_exprs {
905 write!(cons_name, "_{}", arg_expr.ty.borrow().as_ref().unwrap()).unwrap();
906 }
907 if self.backend_writer.use_cons_fn(&cons_name) {
908 write!(self.string, "{}", cons_name).unwrap();
909 } else {
910 self.write_ty_lit(ty_lit);
911 }
912 write!(self.string, "(").unwrap();
913 let mut sep = "";
914 for arg_expr in arg_exprs {
915 write!(self.string, "{}", sep).unwrap();
916 self.generate_expr(arg_expr);
917 sep = ", ";
918 }
919 write!(self.string, ")").unwrap();
920 }
921
922 fn generate_var_expr(&mut self, _span: TokenSpan, kind: &Cell<Option<VarKind >>, _ty: &Option<Ty>) {
923 match kind.get().unwrap() {
925 VarKind::Local {ident, shadow} => {
926 write!(self.string, "{}", DisplayVarName(ident, shadow)).unwrap();
927 }
928 VarKind::MutLocal {ident, shadow} => {
929 write!(self.string, "{}", DisplayVarName(ident, shadow)).unwrap();
930 }
931 VarKind::LiveValue(value_node_ptr) => {
932 self.backend_writer.generate_live_value_prefix(self.string);
934 write!(self.string, "{}", value_node_ptr).unwrap();
935 }
936 }
937 }
938
939 fn generate_lit_expr(&mut self, _span: TokenSpan, lit: Lit) {
940 write!(self.string, "{}", lit).unwrap();
941 }
942
943 fn write_ty_lit(&mut self, ty_lit: TyLit) {
948 self.backend_writer.write_ty_lit(&mut self.string, ty_lit);
949 }
950}
951
952pub struct FnDefGenerator<'a> {
953 pub fn_def: &'a FnDef,
954 pub shader_registry: &'a ShaderRegistry,
955 pub const_table_offset: Option<usize>,
956 pub string: &'a mut String,
957 pub backend_writer: &'a dyn BackendWriter
958}
959
960impl<'a> FnDefGenerator<'a> {
961 pub fn generate_fn_def(&mut self) {
962
963 self.backend_writer.write_var_decl(
964 &mut self.string,
965 "",
966 false,
967 false,
968 &DisplayFnName(self.fn_def.fn_ptr, self.fn_def.ident), self.fn_def.return_ty.borrow().as_ref().unwrap()
970 );
971 write!(self.string, "(").unwrap();
972 let mut sep = "";
973 for param in &self.fn_def.params {
974 if !param.shadow.get().is_none() {
975 if self.backend_writer.write_var_decl(
976 &mut self.string,
977 sep,
978 param.is_inout,
979 false,
980 &DisplayVarName(param.ident, param.shadow.get().unwrap()),
981 param.ty_expr.ty.borrow().as_ref().unwrap(),
982 ) {
983 sep = ", ";
984 }
985 }
986 }
987 self.backend_writer.write_fn_def_hidden_params(self.string, self.fn_def.hidden_args.borrow().as_ref().unwrap(), sep);
988 write!(self.string, ") ").unwrap();
989 self.generate_block(&self.fn_def.block);
990 writeln!(self.string).unwrap();
991 }
993
994 fn generate_block(&mut self, block: &Block) {
995 BlockGenerator {
996 shader_registry: self.shader_registry,
997 closure_site_info: None,
998 fn_def: self.fn_def,
1000 backend_writer: self.backend_writer,
1001 const_table_offset: self.const_table_offset,
1002 indent_level: 0,
1003 string: self.string,
1004 }
1005 .generate_block(block)
1006 }
1007}
1008
1009pub struct FnDefWithClosureArgsGenerator<'a> {
1010 pub closure_site_info: ClosureSiteInfo<'a>,
1011 pub fn_def: &'a FnDef,
1012 pub call_def: &'a FnDef,
1013 pub shader_registry: &'a ShaderRegistry,
1014 pub const_table_offset: Option<usize>,
1015 pub string: &'a mut String,
1016 pub backend_writer: &'a dyn BackendWriter
1017}
1018
1019
1020impl<'a> FnDefWithClosureArgsGenerator<'a> {
1021 pub fn generate_fn_def_with_all_closures(
1022 string:&mut String,
1023 shader_registry: &ShaderRegistry,
1024 fn_def: &FnDef,
1025 call_def: &FnDef,
1026 backend_writer: &dyn BackendWriter,
1027 const_table_offset: Option<usize>
1028 ) {
1029 for (closure_def_index, closure_def) in call_def.closure_defs.iter().enumerate() {
1031 let closure_def_index = ClosureDefIndex(closure_def_index);
1032 for site in call_def.closure_sites.borrow().as_ref().unwrap() {
1033 if site.call_to == fn_def.fn_ptr { for closure_site_arg in &site.closure_args {
1035 if closure_site_arg.closure_def_index == closure_def_index {
1036 ClosureDefGenerator {
1038 closure_site_arg: *closure_site_arg,
1039 closure_def,
1040 fn_def,
1041 call_def,
1042 shader_registry: shader_registry,
1043 const_table_offset,
1045 backend_writer,
1046 string: string,
1047 }
1048 .generate_fn_def()
1049 }
1050 }
1051 }
1052 }
1053 }
1054
1055 for (site_index, closure_site) in call_def.closure_sites.borrow().as_ref().unwrap().iter().enumerate() {
1056 if closure_site.call_to == fn_def.fn_ptr { FnDefWithClosureArgsGenerator {
1060 closure_site_info: ClosureSiteInfo {
1061 site_index,
1062 closure_site,
1063 call_ptr: call_def.fn_ptr,
1064 },
1065 fn_def,
1066 call_def,
1067 shader_registry,
1068 const_table_offset,
1070 backend_writer,
1071 string,
1072 }
1073 .generate_fn_def_with_closure_args()
1074 }
1075 }
1076 }
1077
1078 pub fn generate_fn_def_with_closure_args(&mut self) {
1079
1080 self.backend_writer.write_var_decl(
1081 &mut self.string,
1082 "",
1083 false,
1084 false,
1085 &DisplayFnNameWithClosureArgs(
1086 self.closure_site_info.site_index,
1087 self.call_def.fn_ptr,
1088 self.fn_def.ident
1089 ), self.fn_def.return_ty.borrow().as_ref().unwrap()
1091 );
1092 write!(self.string, "(").unwrap();
1093 let mut sep = "";
1094 for param in &self.fn_def.params {
1095 if !param.shadow.get().is_none() {
1096 if self.backend_writer.write_var_decl(
1097 &mut self.string,
1098 sep,
1099 param.is_inout,
1100 false,
1101 &DisplayVarName(param.ident, param.shadow.get().unwrap()),
1102 param.ty_expr.ty.borrow().as_ref().unwrap(),
1103 ) {
1104 sep = ", ";
1105 }
1106 }
1107 }
1108 for sym in &self.closure_site_info.closure_site.all_closed_over {
1111 if self.backend_writer.write_var_decl(
1112 &mut self.string,
1113 sep,
1114 false,
1115 false,
1116 &DisplayClosedOverArg(sym.ident, sym.shadow),
1117 &sym.ty,
1118 ) {
1119 sep = ", ";
1120 }
1121 }
1122 let mut merged_hidden_args = BTreeSet::new();
1124 merged_hidden_args.extend(self.fn_def.hidden_args.borrow().as_ref().unwrap().iter().cloned());
1125 merged_hidden_args.extend(self.call_def.hidden_args.borrow().as_ref().unwrap().iter().cloned());
1126 self.backend_writer.write_fn_def_hidden_params(self.string, &merged_hidden_args, sep);
1127
1128 write!(self.string, ") ").unwrap();
1129 self.generate_block(&self.fn_def.block);
1132
1133
1134 writeln!(self.string).unwrap();
1135 }
1137
1138 fn generate_block(&mut self, block: &Block) {
1139 BlockGenerator {
1140 shader_registry: self.shader_registry,
1141 closure_site_info: Some(self.closure_site_info.clone()),
1142 fn_def: self.fn_def,
1144 backend_writer: self.backend_writer,
1145 const_table_offset: self.const_table_offset,
1146 indent_level: 0,
1147 string: self.string,
1148 }
1149 .generate_block(block)
1150 }
1151}
1152
1153pub struct ClosureDefGenerator<'a> {
1154 pub closure_def: &'a ClosureDef,
1155 pub closure_site_arg: ClosureSiteArg,
1156 pub fn_def: &'a FnDef,
1157 pub call_def: &'a FnDef,
1158 pub shader_registry: &'a ShaderRegistry,
1159 pub const_table_offset: Option<usize>,
1160 pub string: &'a mut String,
1161 pub backend_writer: &'a dyn BackendWriter
1162}
1163
1164impl<'a> ClosureDefGenerator<'a> {
1165 pub fn generate_fn_def(&mut self) {
1166
1167 let fn_param = &self.fn_def.params[self.closure_site_arg.param_index];
1168
1169 let mut sep = "";
1170
1171 if let TyExprKind::ClosureDecl {params, return_ty, ..} = &fn_param.ty_expr.kind {
1172
1173 self.backend_writer.write_var_decl(
1174 &mut self.string,
1175 "",
1176 false,
1177 false,
1178 &DisplayClosureName(self.call_def.fn_ptr, self.closure_site_arg.closure_def_index), return_ty.borrow().as_ref().unwrap(),
1180 );
1181 write!(self.string, "(").unwrap();
1182
1183 for (param_index, param) in params.iter().enumerate() {
1185 let closure_param = &self.closure_def.params[param_index];
1187 let shadow = closure_param.shadow.get().unwrap();
1188 if self.backend_writer.write_var_decl(
1189 &mut self.string,
1190 sep,
1191 param.is_inout,
1192 false,
1193 &DisplayVarName(closure_param.ident, shadow),
1194 param.ty_expr.ty.borrow().as_ref().unwrap(),
1195 ) {
1196 sep = ", ";
1197 }
1198 }
1199 }
1200 else {
1201 panic!()
1202 }
1203
1204 for sym in self.closure_def.closed_over_syms.borrow().as_ref().unwrap() {
1205 if self.backend_writer.write_var_decl(
1206 &mut self.string,
1207 sep,
1208 false,
1209 false,
1210 &DisplayVarName(sym.ident, sym.shadow),
1211 &sym.ty,
1212 ) {
1213 sep = ", ";
1214 }
1215 }
1216
1217 let mut merged_hidden_args = BTreeSet::new();
1218 merged_hidden_args.extend(self.fn_def.hidden_args.borrow().as_ref().unwrap().iter().cloned());
1219 merged_hidden_args.extend(self.call_def.hidden_args.borrow().as_ref().unwrap().iter().cloned());
1220 self.backend_writer.write_fn_def_hidden_params(self.string, &merged_hidden_args, sep);
1221
1222 writeln!(self.string, ") {{").unwrap();
1223
1224 match &self.closure_def.kind {
1225 ClosureDefKind::Expr(expr) => {
1226 write!(self.string, " return ").unwrap();
1227 self.generate_expr(expr);
1228 writeln!(self.string, ";").unwrap();
1229 writeln!(self.string, "}}").unwrap();
1230 }
1231 ClosureDefKind::Block(block) => {
1232 self.generate_block(block);
1233 writeln!(self.string).unwrap();
1234 }
1235 }
1236 }
1238
1239 fn generate_block(&mut self, block: &Block) {
1240 BlockGenerator {
1241 shader_registry: self.shader_registry,
1242 closure_site_info: None,
1243 fn_def: self.fn_def,
1245 backend_writer: self.backend_writer,
1246 const_table_offset: self.const_table_offset,
1247 indent_level: 0,
1248 string: self.string,
1249 }
1250 .generate_block(block)
1251 }
1252
1253
1254 fn generate_expr(&mut self, expr: &Expr) {
1255 ExprGenerator {
1256 shader_registry: self.shader_registry,
1257 closure_site_info: None,
1258 fn_def: Some(self.fn_def),
1260 backend_writer: self.backend_writer,
1261 const_table_offset: self.const_table_offset,
1262 string: self.string,
1263 }
1264 .generate_expr(expr)
1265 }
1266}
1267
1268pub struct DisplayDsIdent(pub Ident);
1269impl fmt::Display for DisplayDsIdent {
1270 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1271 write!(f, "ds_{}", self.0);
1272 fmt::Result::Ok(())
1273 }
1274}
1275
1276pub struct DisplayPadding(pub usize);
1277impl fmt::Display for DisplayPadding {
1278 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1279 write!(f, "pad_{}", self.0);
1280 fmt::Result::Ok(())
1281 }
1282}
1283
1284pub struct DisplayStructField(pub Ident);
1285impl fmt::Display for DisplayStructField {
1286 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1287 write!(f, "f_{}", self.0);
1288 fmt::Result::Ok(())
1289 }
1290}
1291
1292pub struct DisplayFnName(pub FnPtr, pub Ident);
1293impl fmt::Display for DisplayFnName {
1294 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1295 write!(f, "{}_{}", self.0, self.1);
1296 fmt::Result::Ok(())
1297 }
1298}
1299
1300pub struct DisplayFnNameWithClosureArgs(pub usize, pub FnPtr, pub Ident);
1301impl fmt::Display for DisplayFnNameWithClosureArgs {
1302 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1303 write!(f, "site_{}_of_{}_{}", self.0, self.1, self.2);
1304 fmt::Result::Ok(())
1305 }
1306}
1307
1308pub struct DisplayClosureName(pub FnPtr, pub ClosureDefIndex);
1309impl fmt::Display for DisplayClosureName {
1310 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1311 write!(f, "closure_{}_in_{}", self.1.0, self.0);
1312 fmt::Result::Ok(())
1313 }
1314}
1315
1316pub struct DisplayVarName(pub Ident, pub ScopeSymShadow);
1317impl fmt::Display for DisplayVarName {
1318 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1319 write!(f, "var_{}_{}", self.0, self.1.0);
1320 fmt::Result::Ok(())
1321 }
1322}
1323
1324pub struct DisplayClosedOverArg(pub Ident, pub ScopeSymShadow);
1325impl fmt::Display for DisplayClosedOverArg {
1326 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1327 write!(f, "pass_{}_{}", self.0, self.1.0);
1328 fmt::Result::Ok(())
1329 }
1330}
1331
1332pub struct DisplaConstructorArg(pub usize);
1333impl fmt::Display for DisplaConstructorArg {
1334 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1335 write!(f, "x{}", self.0);
1336 fmt::Result::Ok(())
1337 }
1338}