1use{
2 std::{
3 cell::{RefCell, Cell},
4 collections::{BTreeMap, BTreeSet, HashMap}
5 },
6 crate::{
7 makepad_live_compiler::{
8 makepad_live_id::{
9 live_id,
10 LiveId,
11 },
12 LiveRegistry,
13 LiveError,
14 live_error_origin,
15 LiveErrorOrigin,
16 TokenSpan
17 },
18 shader_ast::*,
19 const_eval::ConstEvaluator,
20 const_gather::ConstGatherer,
21 dep_analyse::DepAnalyser,
22 ty_check::TyChecker,
23 shader_registry::ShaderRegistry
24 }
25};
26
27
28#[derive(Clone, Copy)]
29pub struct ShaderAnalyseOptions {
30 pub no_const_collapse: bool
31}
32
33pub struct StructAnalyser<'a> {
34 pub struct_def: &'a StructDef,
35 pub scopes: &'a mut Scopes,
36 pub live_registry: &'a LiveRegistry,
37 pub shader_registry: &'a ShaderRegistry,
38 pub options: ShaderAnalyseOptions,
39}
40
41impl<'a> StructAnalyser<'a> {
42 fn ty_checker(&self) -> TyChecker {
43 TyChecker {
44 live_registry: self.live_registry,
45 shader_registry: self.shader_registry,
46 scopes: self.scopes,
47 }
48 }
49
50 pub fn analyse_struct(&mut self) -> Result<(), LiveError> {
51 self.scopes.push_scope();
52 self.struct_def.init_analysis();
53 for field in &self.struct_def.fields {
55 self.analyse_field_def(field) ?;
56 }
57 for fn_node_ptr in &self.struct_def.methods {
59 let fn_decl = self.shader_registry.all_fns.get(fn_node_ptr).unwrap();
60 self.analyse_method_decl(fn_decl) ?;
61 }
62 for fn_node_ptr in &self.struct_def.methods {
64 let fn_def = self.shader_registry.all_fns.get(fn_node_ptr).unwrap();
65 FnDefAnalyser {
66 live_registry: self.live_registry,
67 shader_registry: self.shader_registry,
68 closure_return_ty: None,
69 fn_def,
70 scopes: &mut self.scopes,
71 options: self.options,
72 is_inside_loop: false,
73 }
74 .analyse_fn_def() ?;
75 }
76 self.scopes.pop_scope();
77 Ok(())
78 }
79
80 fn analyse_field_def(&mut self, field_def: &StructFieldDef) -> Result<(), LiveError> {
81 self.ty_checker().ty_check_ty_expr(&field_def.ty_expr) ?;
82 match field_def.ty_expr.ty.borrow().as_ref().unwrap() {
84 Ty::Struct(struct_ptr) => {
85 self.struct_def.struct_refs.borrow_mut().as_mut().unwrap().insert(*struct_ptr);
86 }
87 Ty::Array {..} => {
88 todo!();
89 }
90 _ => ()
91 }
92 Ok(())
93 }
94
95 fn analyse_method_decl(&mut self, decl: &FnDef) -> Result<(), LiveError> {
96 for param in &decl.params {
97 self.ty_checker().ty_check_ty_expr(¶m.ty_expr) ?;
98 }
99 let return_ty = decl
100 .return_ty_expr
101 .as_ref()
102 .map( | return_ty_expr | self.ty_checker().ty_check_ty_expr(return_ty_expr))
103 .transpose() ?
104 .unwrap_or(Ty::Void);
105 *decl.return_ty.borrow_mut() = Some(return_ty);
106 *decl.hidden_args.borrow_mut() = Some(BTreeSet::new());
107 Ok(())
108 }
109
110}
111
112pub struct DrawShaderAnalyser<'a> {
113 pub draw_shader_def: &'a DrawShaderDef,
114 pub scopes: &'a mut Scopes,
115 pub live_registry: &'a LiveRegistry,
116 pub shader_registry: &'a ShaderRegistry,
117 pub options: ShaderAnalyseOptions,
118}
119
120impl<'a> DrawShaderAnalyser<'a> {
121 fn ty_checker(&self) -> TyChecker {
122 TyChecker {
123 live_registry: self.live_registry,
124 scopes: self.scopes,
125 shader_registry: self.shader_registry,
126 }
127 }
128
129 pub fn analyse_shader(&mut self) -> Result<(), LiveError> {
130 self.scopes.push_scope();
131
132 for field in &self.draw_shader_def.fields {
134 self.analyse_field_decl(field) ?;
135 }
136
137 for fn_node_ptr in &self.draw_shader_def.methods {
139 let fn_def = self.shader_registry.all_fns.get(fn_node_ptr).unwrap();
140 self.analyse_method_def(fn_def) ?;
141 }
142
143 for fn_node_ptr in &self.draw_shader_def.methods {
145 let fn_def = self.shader_registry.all_fns.get(fn_node_ptr).unwrap();
146 FnDefAnalyser {
147 live_registry: self.live_registry,
148 shader_registry: self.shader_registry,
149 closure_return_ty: None,
150 fn_def,
151 scopes: &mut self.scopes,
152 options: self.options,
153 is_inside_loop: false,
154 }
155 .analyse_fn_def() ?;
156 }
157
158 self.scopes.pop_scope();
159
160 let mut all_fns = Vec::new();
161 let mut vertex_fns = Vec::new();
162 self.analyse_call_tree(
165 &mut Vec::new(),
166 self.shader_registry.draw_shader_method_decl_from_ident(self.draw_shader_def, Ident(live_id!(vertex))).unwrap(),
167 &mut vertex_fns,
168 &mut all_fns,
169 ) ?;
170
171 let mut pixel_fns = Vec::new();
172 self.analyse_call_tree(
173 &mut Vec::new(),
174 self.shader_registry.draw_shader_method_decl_from_ident(self.draw_shader_def, Ident(live_id!(pixel))).unwrap(),
175 &mut pixel_fns,
176 &mut all_fns,
177 ) ?;
178
179 for pixel_fn in &pixel_fns {
181 if let Some(fn_def) = self.shader_registry.all_fns.get(pixel_fn) {
183 if let Some(FnSelfKind::DrawShader(_)) = fn_def.self_kind {
184 for dsr in fn_def.draw_shader_refs.borrow().as_ref().unwrap() {
186 for field in &self.draw_shader_def.fields {
188 if field.ident == *dsr { match &field.kind {
190 DrawShaderFieldKind::Geometry {ref is_used_in_pixel_shader, ..} => {
191 is_used_in_pixel_shader.set(true);
192 }
193 DrawShaderFieldKind::Instance {ref is_used_in_pixel_shader, ..} => {
194 is_used_in_pixel_shader.set(true);
195 }
196 _ => ()
197 }
198 }
199 }
200 }
201 }
202 }
203 }
204
205 let mut all_structs = Vec::new();
206 let mut pixel_structs = Vec::new();
207 let mut vertex_structs = Vec::new();
208 let mut all_live_refs = BTreeMap::new();
209
210 for pixel_fn in &pixel_fns {
211 let fn_decl = self.shader_registry.all_fns.get(pixel_fn).unwrap();
212 for struct_ptr in fn_decl.struct_refs.borrow().as_ref().unwrap().iter() {
214 let struct_def = self.shader_registry.structs.get(struct_ptr).unwrap();
215 self.analyse_struct_tree(&mut Vec::new(), *struct_ptr, struct_def, &mut pixel_structs, &mut all_structs) ?;
216 }
217 }
218 for vertex_fn in &vertex_fns {
219 let fn_decl = self.shader_registry.all_fns.get(vertex_fn).unwrap();
220 for struct_ptr in fn_decl.struct_refs.borrow().as_ref().unwrap().iter() {
222 let struct_def = self.shader_registry.structs.get(struct_ptr).unwrap();
223 self.analyse_struct_tree(&mut Vec::new(), *struct_ptr, struct_def, &mut vertex_structs, &mut all_structs) ?;
224 }
225 }
226
227 for any_fn in all_fns.iter().rev() {
228 let fn_def = self.shader_registry.all_fns.get(any_fn).unwrap();
229 all_live_refs.extend(fn_def.live_refs.borrow().as_ref().cloned().unwrap());
230 self.analyse_hidden_args(fn_def);
233 }
235
236 *self.draw_shader_def.all_live_refs.borrow_mut() = all_live_refs;
237
238 *self.draw_shader_def.all_fns.borrow_mut() = all_fns;
239 *self.draw_shader_def.vertex_fns.borrow_mut() = vertex_fns;
240 *self.draw_shader_def.pixel_fns.borrow_mut() = pixel_fns;
241
242 *self.draw_shader_def.all_structs.borrow_mut() = all_structs;
243 *self.draw_shader_def.vertex_structs.borrow_mut() = vertex_structs;
244 *self.draw_shader_def.pixel_structs.borrow_mut() = pixel_structs;
245 Ok(())
246 }
247
248 fn analyse_hidden_args(&mut self, fn_def: &FnDef) {
249 let mut hidden_args = BTreeSet::new();
251 for ident in fn_def.draw_shader_refs.borrow().as_ref().unwrap() {
252 let field_def = self.draw_shader_def.fields.iter().find( | field | field.ident == *ident).unwrap();
253 match &field_def.kind {
254 DrawShaderFieldKind::Geometry {is_used_in_pixel_shader, ..} => {
255 if is_used_in_pixel_shader.get() {
256 hidden_args.insert(HiddenArgKind::Varyings);
257 }
258 else {
259 hidden_args.insert(HiddenArgKind::Geometries);
260 }
261 }
262 DrawShaderFieldKind::Instance {is_used_in_pixel_shader, ..} => {
263 if is_used_in_pixel_shader.get() {
264 hidden_args.insert(HiddenArgKind::Varyings);
265 }
266 else {
267 hidden_args.insert(HiddenArgKind::Instances);
268 }
269 }
270 DrawShaderFieldKind::Texture {..} => {
271 hidden_args.insert(HiddenArgKind::Textures);
272 }
273 DrawShaderFieldKind::Uniform {block_ident, ..} => {
274 hidden_args.insert(HiddenArgKind::Uniform(*block_ident));
275 }
276 DrawShaderFieldKind::Varying {..} => {
277 hidden_args.insert(HiddenArgKind::Varyings);
278 }
279 }
280 }
281 if fn_def.live_refs.borrow().as_ref().unwrap().len() > 0 {
282 hidden_args.insert(HiddenArgKind::LiveUniforms);
283 }
284 for callee in fn_def.callees.borrow().as_ref().unwrap().iter() {
286 let other_fn_def = self.shader_registry.all_fns.get(callee).unwrap();
287
288 hidden_args.extend(other_fn_def.hidden_args.borrow().as_ref().unwrap().iter().cloned());
289 }
290 *fn_def.hidden_args.borrow_mut() = Some(hidden_args);
291 }
292
293
294 fn analyse_field_decl(&mut self, decl: &DrawShaderFieldDef) -> Result<(), LiveError> {
295 let ty = match decl.kind {
296 DrawShaderFieldKind::Geometry {..} => {
297 let ty = self.ty_checker().ty_check_ty_expr(&decl.ty_expr) ?;
298 match ty {
299 Ty::Float | Ty::Vec2 | Ty::Vec3 | Ty::Vec4 | Ty::Mat4 => {}
300 _ => {
301 return Err(LiveError {
302 origin: live_error_origin!(),
303 span: decl.span.into(),
304 message: String::from(
305 "attribute must be either a floating-point scalar or vector or mat4",
306 ),
307 })
308 }
309 }
310 ty
311 }
312 DrawShaderFieldKind::Instance {..} => {
313 let ty = self.ty_checker().ty_check_ty_expr(&decl.ty_expr) ?;
314 match ty {
315 Ty::Float | Ty::Vec2 | Ty::Vec3 | Ty::Vec4 | Ty::Mat2 | Ty::Mat3 | Ty::Mat4 | Ty::Enum(_) => {}
316 _ => {
317 return Err(LiveError {
318 origin: live_error_origin!(),
319 span: decl.span.into(),
320 message: String::from(
321 "attribute must be either a floating-point scalar or vector or mat4",
322 ),
323 })
324 }
325 }
326 ty
327 }
328 DrawShaderFieldKind::Texture {..} => {
329 let ty = self.ty_checker().ty_check_ty_expr(&decl.ty_expr) ?;
330 match ty {
331 Ty::Texture2D => {}
332 _ => {
333 return Err(LiveError {
334 origin: live_error_origin!(),
335 span: decl.span.into(),
336 message: String::from("texture must be a texture2D"),
337 })
338 }
339 }
340 ty
341 }
342 DrawShaderFieldKind::Uniform {..} => {
343 let ty = self.ty_checker().ty_check_ty_expr(&decl.ty_expr) ?;
344 ty
345 },
346 DrawShaderFieldKind::Varying {..} => {
347 let ty = self.ty_checker().ty_check_ty_expr(&decl.ty_expr) ?;
348 match ty {
349 Ty::Float | Ty::Vec2 | Ty::Vec3 | Ty::Vec4 => {}
350 _ => {
351 return Err(LiveError {
352 origin: live_error_origin!(),
353 span: decl.span.into(),
354 message: String::from(
355 "varying must be either a floating-point scalar or vector",
356 ),
357 })
358 }
359 }
360 ty
361 }
362 };
363 *decl.ty_expr.ty.borrow_mut() = Some(ty);
364 Ok(())
365 }
366
367 fn analyse_method_def(&mut self, def: &FnDef) -> Result<(), LiveError> {
368 for param in &def.params {
369 self.ty_checker().ty_check_ty_expr(¶m.ty_expr) ?;
370 }
371 let return_ty = def
372 .return_ty_expr
373 .as_ref()
374 .map( | return_ty_expr | self.ty_checker().ty_check_ty_expr(return_ty_expr))
375 .transpose() ?
376 .unwrap_or(Ty::Void);
377
378 if def.ident == Ident(live_id!(vertex)) {
379 match return_ty {
380 Ty::Vec4 => {}
381 _ => {
382 return Err(LiveError {
383 origin: live_error_origin!(),
384 span: def.span.into(),
385 message: String::from(
386 "function `vertex` must return a value of type `vec4`",
387 ),
388 })
389 }
390 }
391 } else if def.ident == Ident(live_id!(pixel)) {
392 match return_ty {
393 Ty::Vec4 => {}
394 _ => {
395 return Err(LiveError {
396 origin: live_error_origin!(),
397 span: def.span.into(),
398 message: String::from(
399 "function `fragment` must return a value of type `vec4`",
400 ),
401 })
402 }
403 }
404 } else {
405 match return_ty {
406 Ty::Array {..} => {
407 return Err(LiveError {
408 origin: live_error_origin!(),
409 span: def.span.into(),
410 message: String::from("functions can't return arrays"),
411 })
412 }
413 _ => {}
414 }
415 }
416 *def.return_ty.borrow_mut() = Some(return_ty);
417 Ok(())
419 }
420
421 fn analyse_struct_tree(
422 &self,
423 call_stack: &mut Vec<StructPtr>,
424 struct_ptr: StructPtr,
425 struct_def: &StructDef,
426 deps: &mut Vec<StructPtr>,
427 all_deps: &mut Vec<StructPtr>,
428 ) -> Result<(), LiveError> {
429 if let Some(index) = deps.iter().position( | v | v == &struct_ptr) {
431 deps.remove(index);
432 }
433 deps.push(struct_ptr);
434
435 if let Some(index) = all_deps.iter().position( | v | v == &struct_ptr) {
436 all_deps.remove(index);
437 }
438 all_deps.push(struct_ptr);
439
440 call_stack.push(struct_ptr);
441
442 for sub_ptr in struct_def.struct_refs.borrow().as_ref().unwrap().iter() {
443 let sub_decl = self.shader_registry.structs.get(sub_ptr).unwrap();
445 if call_stack.contains(&sub_ptr) {
446 return Err(LiveError {
447 origin: live_error_origin!(),
448 span: sub_decl.span.into(),
449 message: format!("Struct has recursively dependency"),
450 });
451 }
452
453 self.analyse_struct_tree(call_stack, *sub_ptr, sub_decl, deps, all_deps) ?;
454 }
455 call_stack.pop();
456 Ok(())
457 }
458
459
460 fn analyse_call_tree(
461 &self,
462 call_stack: &mut Vec<FnPtr>,
463 def: &FnDef,
464 deps: &mut Vec<FnPtr>,
466 all_deps: &mut Vec<FnPtr>,
467 ) -> Result<(), LiveError> {
468 if let Some(index) = deps.iter().position( | v | v == &def.fn_ptr) {
470 deps.remove(index);
471 }
472 deps.push(def.fn_ptr);
473
474 if let Some(index) = all_deps.iter().position( | v | v == &def.fn_ptr) {
475 all_deps.remove(index);
476 }
477 all_deps.push(def.fn_ptr);
478
479 call_stack.push(def.fn_ptr);
480 for callee in def.callees.borrow().as_ref().unwrap().iter() {
481 let callee_decl = self.shader_registry.all_fns.get(&callee).unwrap();
483 if call_stack.contains(&callee_decl.fn_ptr) {
484 return Err(LiveError {
485 origin: live_error_origin!(),
486 span: def.span.into(),
487 message: format!("function `{}` recursively calls `{}`", def.ident, callee_decl.ident),
488 });
489 }
490
491 self.analyse_call_tree(call_stack, callee_decl, deps, all_deps) ?;
492 }
493 call_stack.pop();
494
495 Ok(())
496 }
497}
498
499pub struct ConstAnalyser<'a> {
500 pub const_def: &'a ConstDef,
501 pub scopes: &'a mut Scopes,
502 pub live_registry: &'a LiveRegistry,
503 pub shader_registry: &'a ShaderRegistry,
504 pub options: ShaderAnalyseOptions,
505}
506
507impl<'a> ConstAnalyser<'a> {
508 fn ty_checker(&self) -> TyChecker {
509 TyChecker {
510 live_registry: self.live_registry,
511 shader_registry: self.shader_registry,
512 scopes: self.scopes,
513 }
514 }
515
516 fn const_evaluator(&self) -> ConstEvaluator {
517 ConstEvaluator {
518 options: self.options
519 }
520 }
521
522 pub fn analyse_const_decl(&mut self) -> Result<(), LiveError> {
523 let expected_ty = self.ty_checker().ty_check_ty_expr(&self.const_def.ty_expr) ?;
524 let actual_ty = self.ty_checker().ty_check_expr_with_expected_ty(
525 self.const_def.span,
526 &self.const_def.expr,
527 &expected_ty,
528 ) ?;
529 if expected_ty != actual_ty {
530 return Err(LiveError {
531 origin: live_error_origin!(),
532 span: self.const_def.span.into(),
533 message: String::from("Declared type and inferred type not the same"),
534 } .into());
535 }
536 self.const_evaluator().const_eval_expr(&self.const_def.expr) ?;
537 Ok(())
538 }
539}
540
541pub struct FnDefAnalyser<'a> {
542 pub fn_def: &'a FnDef,
543 pub closure_return_ty: Option<&'a RefCell<Option<Ty >> >,
544 pub scopes: &'a mut Scopes,
545 pub live_registry: &'a LiveRegistry,
546 pub shader_registry: &'a ShaderRegistry,
547 pub options: ShaderAnalyseOptions,
548 pub is_inside_loop: bool,
549}
550
551impl<'a> FnDefAnalyser<'a> {
552 fn ty_checker(&self) -> TyChecker {
553 TyChecker {
554 live_registry: self.live_registry,
555 shader_registry: self.shader_registry,
556 scopes: self.scopes,
557 }
558 }
559
560 fn const_evaluator(&self) -> ConstEvaluator {
561 ConstEvaluator {
562 options: self.options
563 }
564 }
565
566 fn const_gatherer(&self) -> ConstGatherer {
567 ConstGatherer {
568 fn_def: self.fn_def
569 }
570 }
571
572 fn dep_analyser(&self) -> DepAnalyser {
573 DepAnalyser {
574 shader_registry: self.shader_registry,
575 fn_def: self.fn_def,
576 scopes: &self.scopes,
577 }
578 }
579
580 pub fn analyse_fn_decl(&mut self) -> Result<(), LiveError> {
581 for param in &self.fn_def.params {
582 self.ty_checker().ty_check_ty_expr(¶m.ty_expr) ?;
583 }
584 let return_ty = self.fn_def
585 .return_ty_expr
586 .as_ref()
587 .map( | return_ty_expr | self.ty_checker().ty_check_ty_expr(return_ty_expr))
588 .transpose() ?
589 .unwrap_or(Ty::Void);
590 *self.fn_def.return_ty.borrow_mut() = Some(return_ty);
591 Ok(())
592 }
593
594 pub fn analyse_fn_def(&mut self) -> Result<(), LiveError> {
595 self.scopes.push_scope();
596 for (param_index, param) in self.fn_def.params.iter().enumerate() {
597 match ¶m.ty_expr.kind {
598 TyExprKind::ClosureDecl {return_ty, params, ..} => {
599 self.scopes.insert_sym(
600 param.span,
601 param.ident,
602 Ty::ClosureDecl,
603 ScopeSymKind::Closure {
604 param_index,
605 return_ty: return_ty.borrow().clone().unwrap(),
606 params: params.clone()
607 },
608 );
609 }
610 _ => {
611 let shadow = self.scopes.insert_sym(
612 param.span,
613 param.ident,
614 param.ty_expr.ty.borrow().as_ref().unwrap().clone(),
615 ScopeSymKind::MutLocal,
616 );
617 param.shadow.set(Some(shadow));
618 }
619 }
620
621 }
622 *self.fn_def.return_ty.borrow_mut() = Some(
623 self.fn_def
624 .return_ty_expr
625 .as_ref()
626 .map( | return_ty_expr | return_ty_expr.ty.borrow().as_ref().unwrap().clone())
627 .unwrap_or(Ty::Void),
628 );
629 self.fn_def.init_analysis();
630 self.analyse_block(&self.fn_def.block) ?;
631 self.scopes.pop_scope();
632 self.analyse_closures() ?;
637
638 if let Some(ty_expr) = &self.fn_def.return_ty_expr {
642 if let Ty::Void = ty_expr.ty.borrow().as_ref().unwrap() {
643 }
644 else {
645 if !self.fn_def.has_return.get() {
646 return Err(LiveError {
647 origin: live_error_origin!(),
648 span: self.fn_def.span.into(),
649 message: format!(
650 "Function has no return",
651 ),
652 });
653 }
654 }
655 }
656
657 Ok(())
658 }
659
660 fn analyse_closures(&mut self) -> Result<(), LiveError> {
661
662 let mut closure_sites = self.scopes.closure_sites.replace(Vec::new());
663 let mut closure_scopes = self.scopes.closure_scopes.replace(HashMap::new());
664
665 for closure_site in &mut closure_sites {
666 let fn_decl = self.shader_registry.all_fns.get(&closure_site.call_to).unwrap();
667
668 for closure_arg in &closure_site.closure_args {
670
671 let mut scopes = closure_scopes.get_mut(&closure_arg.closure_def_index).unwrap();
672 std::mem::swap(&mut self.scopes.scopes, &mut scopes);
674
675 let closure_def = &self.fn_def.closure_defs[closure_arg.closure_def_index.0];
678 let fn_param = &fn_decl.params[closure_arg.param_index];
679
680 if let TyExprKind::ClosureDecl {params, return_ty, ..} = &fn_param.ty_expr.kind {
681 self.scopes.clear_referenced_syms();
682 self.scopes.push_scope();
683 if closure_def.params.len() != params.len() {
686 return Err(LiveError {
687 origin: live_error_origin!(),
688 span: closure_def.span.into(),
689 message: format!(
690 "Closure does not have the same number of arguments as function decl: {} expected: {}",
691 closure_def.params.len(),
692 params.len()
693 ),
694 });
695 }
696 for i in 0..closure_def.params.len() {
698 let def_param = &closure_def.params[i];
699 let decl_param = ¶ms[i];
700 let shadow = self.scopes.insert_sym(
703 def_param.span,
704 def_param.ident,
705 decl_param.ty_expr.ty.borrow().as_ref().unwrap().clone(),
706 ScopeSymKind::MutLocal,
707 );
708 def_param.shadow.set(Some(shadow));
709 }
710 match &closure_def.kind {
712 ClosureDefKind::Expr(expr) => {
713 self.analyse_expr_stmt(closure_def.span, expr) ?;
714 if expr.ty.borrow().as_ref() != return_ty.borrow().as_ref() {
716 return Err(LiveError {
717 origin: live_error_origin!(),
718 span: closure_def.span.into(),
719 message: format!(
720 "Closure return type not correct: {} expected: {}",
721 expr.ty.borrow().as_ref().unwrap(),
722 return_ty.borrow().as_ref().unwrap()
723 ),
724 });
725 }
726 }
727 ClosureDefKind::Block(block) => {
728 self.closure_return_ty = Some(return_ty);
729 self.analyse_block(block) ?;
732 self.closure_return_ty = None;
733 }
734 }
735 self.scopes.pop_scope();
738 let all_syms = self.scopes.all_referenced_syms();
741 for sym in &all_syms {
742 closure_site.all_closed_over.insert(sym.clone());
743 }
744 *closure_def.closed_over_syms.borrow_mut() = Some(all_syms);
745 }
746 else {
747 panic!()
748 }
749 std::mem::swap(&mut self.scopes.scopes, &mut scopes);
751 }
752 }
754 let mut closure_sites_out = self.fn_def.closure_sites.borrow_mut();
756 if closure_sites_out.is_some() {
757 closure_sites_out.as_mut().unwrap().extend(closure_sites);
758 }
759 else {
760 *closure_sites_out = Some(closure_sites);
761 }
762 if self.scopes.closure_sites.borrow().len()>0 {
764 return Err(LiveError {
765 origin: live_error_origin!(),
766 span: self.fn_def.span.into(),
767 message: format!("Nesting closures is not supported at the moment"),
768 });
769
770 }
771 Ok(())
772 }
773
774 fn analyse_block(&mut self, block: &Block) -> Result<(), LiveError> {
775 for stmt in &block.stmts {
776 self.analyse_stmt(stmt) ?;
777 }
778 Ok(())
779 }
780
781 fn analyse_stmt(&mut self, stmt: &Stmt) -> Result<(), LiveError> {
782 match *stmt {
783 Stmt::Break {span} => self.analyse_break_stmt(span),
784 Stmt::Continue {span} => self.analyse_continue_stmt(span),
785 Stmt::For {
786 span,
787 ident,
788 ref from_expr,
789 ref to_expr,
790 ref step_expr,
791 ref block,
792 } => self.analyse_for_stmt(span, ident, from_expr, to_expr, step_expr, block),
793 Stmt::If {
794 span,
795 ref expr,
796 ref block_if_true,
797 ref block_if_false,
798 } => self.analyse_if_stmt(span, expr, block_if_true, block_if_false),
799 Stmt::Match {
800 span,
801 ref expr,
802 ref matches,
803 } => self.analyse_match_stmt(span, expr, matches),
804 Stmt::Let {
805 span,
806 ref ty,
807 ident,
808 ref shadow,
809 ref ty_expr,
810 ref expr,
811 } => self.analyse_let_stmt(span, ty, ident, ty_expr, expr, shadow),
812 Stmt::Return {span, ref expr} => self.analyse_return_stmt(span, expr),
813 Stmt::Block {span, ref block} => self.analyse_block_stmt(span, block),
814 Stmt::Expr {span, ref expr} => self.analyse_expr_stmt(span, expr),
815 }
816 }
817
818 fn analyse_break_stmt(&self, span: TokenSpan) -> Result<(), LiveError> {
819 if !self.is_inside_loop {
820 return Err(LiveError {
821 origin: live_error_origin!(),
822 span:span.into(),
823 message: String::from("break outside loop"),
824 } .into());
825 }
826 Ok(())
827 }
828
829 fn analyse_continue_stmt(&self, span: TokenSpan) -> Result<(), LiveError> {
830 if !self.is_inside_loop {
831 return Err(LiveError {
832 origin: live_error_origin!(),
833 span:span.into(),
834 message: String::from("continue outside loop"),
835 } .into());
836 }
837 Ok(())
838 }
839
840 fn analyse_for_stmt(
841 &mut self,
842 span: TokenSpan,
843 ident: Ident,
844 from_expr: &Expr,
845 to_expr: &Expr,
846 step_expr: &Option<Expr>,
847 block: &Block,
848 ) -> Result<(), LiveError> {
849
850 self.ty_checker()
851 .ty_check_expr_with_expected_ty(span, from_expr, &Ty::Float) ?;
852
853 let from = self
854 .const_evaluator()
855 .const_eval_expr(from_expr) ?
856 .to_int()
857 .unwrap();
858
859 self.dep_analyser().dep_analyse_expr(from_expr);
860
861 self.ty_checker()
862 .ty_check_expr_with_expected_ty(span, to_expr, &Ty::Float) ?;
863
864 let to = self
865 .const_evaluator()
866 .const_eval_expr(to_expr) ?
867 .to_int()
868 .unwrap();
869 self.dep_analyser().dep_analyse_expr(to_expr);
870 if let Some(step_expr) = step_expr {
871 self.ty_checker()
872 .ty_check_expr_with_expected_ty(span, step_expr, &Ty::Float) ?;
873 let step = self
874 .const_evaluator()
875 .const_eval_expr(step_expr) ?
876 .to_int()
877 .unwrap();
878 if step == 0 {
879 return Err(LiveError {
880 origin: live_error_origin!(),
881 span:span.into(),
882 message: String::from("step must not be zero"),
883 } .into());
884 }
885 if from < to && step < 0 {
886 return Err(LiveError {
887 origin: live_error_origin!(),
888 span:span.into(),
889 message: String::from("step must not be positive"),
890 } .into());
891 }
892 if from > to && step > 0 {
893 return Err(LiveError {
894 origin: live_error_origin!(),
895 span:span.into(),
896 message: String::from("step must not be negative"),
897 } .into());
898 }
899 self.dep_analyser().dep_analyse_expr(step_expr);
900 }
901 self.scopes.push_scope();
902 self.scopes.insert_sym(
903 span,
904 ident,
905 Ty::Int,
906 ScopeSymKind::Local,
907 );
908 let was_inside_loop = self.is_inside_loop;
909 self.is_inside_loop = true;
910 self.analyse_block(block) ?;
911 self.is_inside_loop = was_inside_loop;
912 self.scopes.pop_scope();
913 Ok(())
914 }
915
916 fn analyse_if_stmt(
917 &mut self,
918 span: TokenSpan,
919 expr: &Expr,
920 block_if_true: &Block,
921 block_if_false: &Option<Box<Block >>,
922 ) -> Result<(), LiveError> {
923 self.ty_checker()
924 .ty_check_expr_with_expected_ty(span, expr, &Ty::Bool) ?;
925 self.const_evaluator().try_const_eval_expr(expr);
926 self.const_gatherer().const_gather_expr(expr);
927 self.dep_analyser().dep_analyse_expr(expr);
928 self.scopes.push_scope();
929 self.analyse_block(block_if_true) ?;
930 self.scopes.pop_scope();
931 if let Some(block_if_false) = block_if_false {
932 self.scopes.push_scope();
933 self.analyse_block(block_if_false) ?;
934 self.scopes.pop_scope();
935 }
936 Ok(())
937 }
938
939 fn analyse_match_stmt(
940 &mut self,
941 span: TokenSpan,
942 expr: &Expr,
943 matches: &Vec<Match>,
944 ) -> Result<(), LiveError> {
945 let ty = self.ty_checker()
946 .ty_check_expr(expr) ?;
947 if let Ty::Enum(live_type) = ty {
949 self.const_evaluator().try_const_eval_expr(expr);
950 self.const_gatherer().const_gather_expr(expr);
951 self.dep_analyser().dep_analyse_expr(expr);
952
953 for match_item in matches {
954 let shader_enum = self.shader_registry.enums.get(&live_type).unwrap();
956 if match_item.enum_name.0 != shader_enum.enum_name{
958 return Err(LiveError {
959 origin: live_error_origin!(),
960 span:span.into(),
961 message: format!("Enum name mismatched, expected {} got {}", shader_enum.enum_name, match_item.enum_name.0),
962 } .into())
963 }
964
965 if let Some(pos) = shader_enum.variants.iter().position( | id | *id == match_item.enum_variant.0) {
966 match_item.enum_value.set(Some(pos + 1));
967 }
968 else{
969 return Err(LiveError {
970 origin: live_error_origin!(),
971 span:span.into(),
972 message: format!("Variant not found on enum {}::{}", match_item.enum_name.0, match_item.enum_variant.0),
973 } .into())
974 }
975
976 self.scopes.push_scope();
978 self.analyse_block(&match_item.block) ?;
979 self.scopes.pop_scope();
980 }
981 Ok(())
982 }
983 else {
984 Err(LiveError {
985 origin: live_error_origin!(),
986 span:span.into(),
987 message: String::from("Can only match on enum types"),
988 } .into())
989 }
990 }
991
992 fn analyse_let_stmt(
993 &mut self,
994 span: TokenSpan,
995 ty: &RefCell<Option<Ty >>,
996 ident: Ident,
997 ty_expr: &Option<TyExpr>,
998 expr: &Option<Expr>,
999 shadow: &Cell<Option<ScopeSymShadow >>,
1000 ) -> Result<(), LiveError> {
1001 *ty.borrow_mut() = Some(if let Some(ty_expr) = ty_expr {
1002 if expr.is_none() {
1003 return Err(LiveError {
1004 origin: live_error_origin!(),
1005 span:span.into(),
1006 message: format!("cannot define an uninitialised variable `{}`", ident),
1007 });
1008 }
1009 let expected_ty = self.ty_checker().ty_check_ty_expr(ty_expr) ?;
1010 if let Some(expr) = expr {
1011 let actual_ty =
1012 self.ty_checker()
1013 .ty_check_expr_with_expected_ty(span, expr, &expected_ty) ?;
1014 self.dep_analyser().dep_analyse_expr(expr);
1015 actual_ty
1016 } else {
1017 expected_ty
1018 }
1019
1020 } else if let Some(expr) = expr {
1021 let ty = self.ty_checker().ty_check_expr(expr) ?;
1022 if ty == Ty::Void {
1023 return Err(LiveError {
1024 origin: live_error_origin!(),
1025 span:span.into(),
1026 message: String::from("init expression cannot be void")
1027 });
1028 }
1029 self.const_evaluator().try_const_eval_expr(expr);
1030 self.const_gatherer().const_gather_expr(expr);
1031 self.dep_analyser().dep_analyse_expr(expr);
1032 ty
1033 } else {
1034 return Err(LiveError {
1035 origin: live_error_origin!(),
1036 span:span.into(),
1037 message: format!("can't infer type of variable `{}`", ident),
1038 });
1039 });
1040 let new_shadow = self.scopes.insert_sym(
1041 span,
1042 ident,
1043 ty.borrow().as_ref().unwrap().clone(),
1044 ScopeSymKind::MutLocal,
1045 );
1046 shadow.set(Some(new_shadow));
1047 Ok(())
1048 }
1049
1050 fn analyse_return_stmt(&mut self, span: TokenSpan, expr: &Option<Expr>) -> Result<(), LiveError> {
1051
1052 self.fn_def.has_return.set(true);
1053 if let Some(expr) = expr {
1054 if let Some(ty) = self.closure_return_ty {
1055 self.ty_checker().ty_check_expr_with_expected_ty(
1056 span,
1057 expr,
1058 ty.borrow().as_ref().unwrap()
1059 ) ?;
1060 }
1061 else {
1062 self.ty_checker().ty_check_expr_with_expected_ty(
1063 span,
1064 expr,
1065 self.fn_def.return_ty.borrow().as_ref().unwrap()
1066 ) ?;
1067 }
1068
1069 self.const_evaluator().try_const_eval_expr(expr);
1070 self.const_gatherer().const_gather_expr(expr);
1071 self.dep_analyser().dep_analyse_expr(expr);
1072 } else if self.fn_def.return_ty.borrow().as_ref().unwrap() != &Ty::Void {
1073 return Err(LiveError {
1074 origin: live_error_origin!(),
1075 span:span.into(),
1076 message: String::from("missing return expression"),
1077 } .into());
1078 }
1079 Ok(())
1080 }
1081
1082 fn analyse_block_stmt(&mut self, _span: TokenSpan, block: &Block) -> Result<(), LiveError> {
1083 self.scopes.push_scope();
1084 self.analyse_block(block) ?;
1085 self.scopes.pop_scope();
1086 Ok(())
1087 }
1088
1089 fn analyse_expr_stmt(&mut self, _span: TokenSpan, expr: &Expr) -> Result<(), LiveError> {
1090 self.ty_checker().ty_check_expr(expr) ?;
1091 self.const_evaluator().try_const_eval_expr(expr);
1092 self.const_gatherer().const_gather_expr(expr);
1093 self.dep_analyser().dep_analyse_expr(expr);
1094 Ok(())
1095 }
1096}
1097
1098#[derive(Clone, Copy, Debug)]
1099enum ShaderKind {
1100 Vertex,
1101 Fragment,
1102}