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