1use {
2 std::{
3 cell::{Cell, RefCell},
4 collections::HashMap,
5 collections::BTreeSet,
6 collections::BTreeMap,
7 fmt,
8 rc::Rc,
9 ops::Deref,
10 ops::DerefMut
11 },
12 makepad_live_id::*,
13 makepad_live_compiler::*,
14 makepad_live_compiler::makepad_math::*,
15};
16#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Ord, PartialOrd)]
21pub struct FnPtr(pub LivePtr);
22impl Deref for FnPtr {type Target = LivePtr; fn deref(&self) -> &Self::Target {&self.0}}
23impl DerefMut for FnPtr {fn deref_mut(&mut self) -> &mut Self::Target {&mut self.0}}
24
25#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Ord, PartialOrd)]
26pub struct StructPtr(pub LivePtr);
27impl Deref for StructPtr {type Target = LivePtr; fn deref(&self) -> &Self::Target {&self.0}}
28impl DerefMut for StructPtr {fn deref_mut(&mut self) -> &mut Self::Target {&mut self.0}}
29
30#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Ord, PartialOrd)]
31pub struct DrawShaderPtr(pub LivePtr);
32impl Deref for DrawShaderPtr {type Target = LivePtr; fn deref(&self) -> &Self::Target {&self.0}}
33impl DerefMut for DrawShaderPtr {fn deref_mut(&mut self) -> &mut Self::Target {&mut self.0}}
34
35#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Ord, PartialOrd)]
41pub struct ValuePtr(pub LivePtr);
42impl Deref for ValuePtr {type Target = LivePtr; fn deref(&self) -> &Self::Target {&self.0}}
43impl DerefMut for ValuePtr {fn deref_mut(&mut self) -> &mut Self::Target {&mut self.0}}
44
45#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Ord, PartialOrd)]
46pub struct VarDefPtr(pub LivePtr);
47impl Deref for VarDefPtr {type Target = LivePtr; fn deref(&self) -> &Self::Target {&self.0}}
48impl DerefMut for VarDefPtr {fn deref_mut(&mut self) -> &mut Self::Target {&mut self.0}}
49
50#[derive(Clone, Default, Debug)]
51pub struct ConstTableItem {
52 pub offset: usize,
53 pub slots: usize
54}
55
56#[derive(Clone, Debug)]
57pub struct ConstTableSpan {
58 pub token_id: LiveTokenId,
59 pub offset: usize,
60 pub slots: usize
61}
62
63#[derive(Clone, Default, Debug)]
64pub struct DrawShaderConstTable {
65 pub table: Vec<f32>,
66 pub offsets: BTreeMap<FnPtr, usize>,
67 pub table_index: BTreeMap<LiveTokenId, ConstTableItem>
68}
69
70#[derive(Clone, Copy, Default, Debug)]
71pub struct DrawShaderFlags {
72 pub debug: bool,
73 pub draw_call_nocompare: bool,
74 pub draw_call_always: bool,
75}
76
77#[derive(Clone, Default, Debug)]
78pub struct DrawShaderDef {
79 pub flags: DrawShaderFlags,
80 pub fields: Vec<DrawShaderFieldDef>,
82 pub methods: Vec<FnPtr>,
83 pub enums: Vec<LiveType>,
84 pub all_live_refs: RefCell<BTreeMap<ValuePtr, Ty >>,
87 pub all_fns: RefCell<Vec<FnPtr >>,
88 pub vertex_fns: RefCell<Vec<FnPtr >>,
89 pub pixel_fns: RefCell<Vec<FnPtr >>,
90 pub all_structs: RefCell<Vec<StructPtr >>,
91 pub vertex_structs: RefCell<Vec<StructPtr >>,
92 pub pixel_structs: RefCell<Vec<StructPtr >>,
93 pub uses_time: Cell<bool>,
94 pub ignore_idents: Vec<Ident>,
95 }
99
100
101#[derive(Clone, Debug)]
102pub struct DrawShaderFieldDef {
103 pub span: TokenSpan,
104 pub ident: Ident,
105 pub ty_expr: TyExpr,
106 pub kind: DrawShaderFieldKind
107}
108
109#[derive(Clone, Debug)]
119pub enum DrawShaderFieldKind {
120 Geometry {
121 is_used_in_pixel_shader: Cell<bool >,
122 var_def_ptr: Option<VarDefPtr>,
123 },
124 Instance {
125 is_used_in_pixel_shader: Cell<bool >,
126 live_field_kind: LiveFieldKind,
127 var_def_ptr: Option<VarDefPtr>,
128 },
130 Texture {
131 var_def_ptr: Option<VarDefPtr>,
132 },
134 Uniform {
135 var_def_ptr: Option<VarDefPtr>,
136 block_ident: Ident,
138 },
139 Varying {
140 var_def_ptr: VarDefPtr,
141 }
142}
143
144#[derive(Clone, Debug)]
145pub struct ConstDef {
146 pub span: TokenSpan,
147 pub ident: Ident,
148 pub ty_expr: TyExpr,
149 pub expr: Expr,
150}
151
152#[derive(Clone, Copy, Eq, Hash, PartialEq, Ord, PartialOrd, Debug)]
161pub enum FnSelfKind {
162 Struct(StructPtr),
163 DrawShader(DrawShaderPtr)
164}
165
166impl FnSelfKind {
167 pub fn to_ty_expr_kind(self) -> TyExprKind {
168 match self {
169 FnSelfKind::DrawShader(shader_ptr) => {
170 TyExprKind::DrawShader(shader_ptr)
171 },
172 FnSelfKind::Struct(struct_ptr) => {
173 TyExprKind::Struct(struct_ptr)
174 },
175 }
176 }
177}
178
179#[derive(Clone, Copy, Eq, Hash, PartialEq, Ord, PartialOrd, Debug)]
180pub enum HiddenArgKind {
181 Geometries,
182 Instances,
183 Varyings,
184 Textures,
185 Uniform(Ident),
186 LiveUniforms,
187}
188
189#[derive(Clone, Debug)]
190pub struct FnDef {
191 pub fn_ptr: FnPtr,
192
193 pub ident: Ident,
194
195 pub self_kind: Option<FnSelfKind>,
196 pub has_return: Cell<bool>,
197
198 pub callees: RefCell<Option<BTreeSet<FnPtr >> >,
199 pub builtin_deps: RefCell<Option<BTreeSet<Ident >> >,
200 pub const_table: RefCell<Option<Vec<f32 >> >,
204 pub const_table_spans: RefCell<Option<Vec<ConstTableSpan >> >,
205
206 pub hidden_args: RefCell<Option<BTreeSet<HiddenArgKind >> >,
207 pub draw_shader_refs: RefCell<Option<BTreeSet<Ident >> >,
208 pub live_refs: RefCell<Option<BTreeMap<ValuePtr, Ty >> >,
210
211 pub struct_refs: RefCell<Option<BTreeSet<StructPtr >> >,
212 pub constructor_fn_deps: RefCell<Option<BTreeSet<(TyLit, Vec<Ty>) >> >,
213
214 pub closure_defs: Vec<ClosureDef>,
215 pub closure_sites: RefCell<Option<Vec<ClosureSite >> >,
216
217 pub span: TokenSpan,
219 pub return_ty: RefCell<Option<Ty >>,
220 pub params: Vec<Param>,
221 pub return_ty_expr: Option<TyExpr>,
222 pub block: Block,
223}
224
225
226#[derive(Clone, Debug, Copy, Eq, Hash, PartialEq, Ord, PartialOrd)]
227pub struct ClosureDefIndex(pub usize);
228
229#[derive(Clone, Debug)]
230pub struct ClosureParam {
231 pub span: TokenSpan,
232 pub ident: Ident,
233 pub shadow: Cell<Option<ScopeSymShadow >>
234}
235
236#[derive(Clone, Debug)]
237pub struct ClosureDef {
238 pub span: TokenSpan,
239 pub closed_over_syms: RefCell<Option<Vec<Sym >> >,
240 pub params: Vec<ClosureParam>,
241 pub kind: ClosureDefKind
242}
243
244#[derive(Clone, Debug)]
245pub enum ClosureDefKind {
246 Expr(Expr),
247 Block(Block)
248}
249
250#[derive(Clone, Debug)]
251pub struct ClosureSite { pub call_to: FnPtr,
253 pub all_closed_over: BTreeSet<Sym>,
254 pub closure_args: Vec<ClosureSiteArg>
255}
256
257#[derive(Clone, Copy, Debug)]
258pub struct ClosureSiteArg {
259 pub param_index: usize,
260 pub closure_def_index: ClosureDefIndex
261}
262
263#[derive(Clone, Debug)]
264pub struct StructDef {
265 pub span: TokenSpan,
266 pub struct_refs: RefCell<Option<BTreeSet<StructPtr >> >,
268 pub fields: Vec<StructFieldDef>,
269 pub methods: Vec<FnPtr>,
270}
271
272#[derive(Clone, Debug)]
273pub struct StructFieldDef {
274 pub var_def_ptr: VarDefPtr,
275 pub span: TokenSpan,
276 pub ident: Ident,
277 pub ty_expr: TyExpr,
278}
279
280impl StructDef {
281 pub fn find_field(&self, ident: Ident) -> Option<&StructFieldDef> {
282 self.fields.iter().find( | field | field.ident == ident)
283 }
284
285}
286
287
288#[derive(Clone, Debug)]
289pub struct Param {
290 pub span: TokenSpan,
291 pub is_inout: bool,
292 pub ident: Ident,
293 pub shadow: Cell<Option<ScopeSymShadow >>,
294 pub ty_expr: TyExpr,
295}
296
297#[derive(Clone, Debug)]
298pub struct Block {
299 pub stmts: Vec<Stmt>,
300}
301
302#[derive(Clone, Debug)]
303pub enum Stmt {
304 Break {
305 span: TokenSpan,
306 },
307 Continue {
308 span: TokenSpan,
309 },
310 For {
311 span: TokenSpan,
312 ident: Ident,
313 from_expr: Expr,
314 to_expr: Expr,
315 step_expr: Option<Expr>,
316 block: Box<Block>,
317 },
318 If {
319 span: TokenSpan,
320 expr: Expr,
321 block_if_true: Box<Block>,
322 block_if_false: Option<Box<Block >>,
323 },
324 Match {
325 span: TokenSpan,
326 expr: Expr,
327 matches: Vec<Match>,
328 },
329
330 Let {
331 span: TokenSpan,
332 ty: RefCell<Option<Ty >>,
333 shadow: Cell<Option<ScopeSymShadow >>,
334 ident: Ident,
335 ty_expr: Option<TyExpr>,
336 expr: Option<Expr>,
337 },
338 Return {
339 span: TokenSpan,
340 expr: Option<Expr>,
341 },
342 Block {
343 span: TokenSpan,
344 block: Box<Block>,
345 },
346 Expr {
347 span: TokenSpan,
348 expr: Expr,
349 },
350}
351
352#[derive(Clone, Debug)]
353pub struct Match {
354 pub span: TokenSpan,
355 pub enum_name: Ident,
356 pub enum_variant: Ident,
357 pub enum_value: Cell<Option<usize >>,
358 pub block: Block
359}
360
361#[derive(Clone, Debug)]
362pub struct Expr {
363 pub span: TokenSpan,
364 pub ty: RefCell<Option<Ty >>,
365 pub const_val: RefCell<Option<Option<Val >> >,
366 pub const_index: Cell<Option<usize >>,
367 pub kind: ExprKind,
368}
369
370#[derive(Clone, Debug)]
371pub enum ExprKind {
372 Cond {
373 span: TokenSpan,
374 expr: Box<Expr>,
375 expr_if_true: Box<Expr>,
376 expr_if_false: Box<Expr>,
377 },
378 Bin {
379 span: TokenSpan,
380 op: BinOp,
381 left_expr: Box<Expr>,
382 right_expr: Box<Expr>,
383 },
384 Un {
385 span: TokenSpan,
386 op: UnOp,
387 expr: Box<Expr>,
388 },
389 Field {
390 span: TokenSpan,
391 expr: Box<Expr>,
392 field_ident: Ident,
393 },
394 Index {
395 span: TokenSpan,
396 expr: Box<Expr>,
397 index_expr: Box<Expr>,
398 },
399 MethodCall {
400 span: TokenSpan,
401 ident: Ident,
402 closure_site_index: Cell<Option<usize >>,
403 arg_exprs: Vec<Expr>,
404 },
405 PlainCall { span: TokenSpan,
408 fn_ptr: Option<FnPtr>,
409 ident: Option<Ident>,
410 param_index: Cell<Option<usize >>, closure_site_index: Cell<Option<usize >>, arg_exprs: Vec<Expr>,
413 },
414 BuiltinCall {
415 span: TokenSpan,
416 ident: Ident,
417 arg_exprs: Vec<Expr>,
418 },
419 ClosureDef(ClosureDefIndex),
420 ConsCall {
421 span: TokenSpan,
422 ty_lit: TyLit,
423 arg_exprs: Vec<Expr>,
424 },
425 StructCons {
426 struct_ptr: StructPtr,
427 span: TokenSpan,
428 args: Vec<(Ident, Expr)>
429 },
430 Var {
431 span: TokenSpan,
432 ident: Option<Ident>,
433 kind: Cell<Option<VarKind >>,
434 var_resolve: VarResolve,
435 },
437 Lit {
438 span: TokenSpan,
439 lit: Lit,
440 },
441}
442
443pub enum PlainCallType {
444 Plain {
445
446 }
447}
448
449#[derive(Clone, Copy, Debug)]
450pub enum VarResolve {
451 NotFound,
452 Function(FnPtr),
453 LiveValue(ValuePtr, TyLit)
454}
455
456#[derive(Clone, Copy, Debug)]
457pub enum VarKind {
458 Local {ident: Ident, shadow: ScopeSymShadow},
459 MutLocal {ident: Ident, shadow: ScopeSymShadow},
460 LiveValue(ValuePtr)
461}
462
463#[derive(Clone, Debug)]
464pub struct TyExpr {
465 pub span: TokenSpan,
466 pub ty: RefCell<Option<Ty >>,
467 pub kind: TyExprKind,
468}
469
470#[derive(Clone, Debug)]
471pub enum TyExprKind {
472 Array {
473 elem_ty_expr: Box<TyExpr>,
474 len: u32,
475 },
476 Struct(StructPtr),
477 Enum(LiveType),
478 DrawShader(DrawShaderPtr),
479 Lit {
480 ty_lit: TyLit,
481 },
482 ClosureDecl {
483 return_ty: RefCell<Option<Ty >>,
484 return_ty_expr: Box<Option<TyExpr >>,
485 params: Vec<Param>
486 },
487}
488
489
490#[derive(Clone, Copy)]
491pub enum MacroCallAnalysis {
492}
493
494#[derive(Clone, Copy, Debug)]
495pub enum BinOp {
496 Assign,
497 AddAssign,
498 SubAssign,
499 MulAssign,
500 DivAssign,
501 Or,
502 And,
503 Eq,
504 Ne,
505 Lt,
506 Le,
507 Gt,
508 Ge,
509 Add,
510 Sub,
511 Mul,
512 Div,
513}
514
515
516
517#[derive(Clone, Copy, Debug)]
518pub enum UnOp {
519 Not,
520 Neg,
521}
522
523#[derive(Clone, Debug, Eq, Hash, PartialEq, Ord, PartialOrd)]
524pub enum ShaderTy {
525 Void,
526 Bool,
527 Int,
528 Float,
529 Bvec2,
530 Bvec3,
531 Bvec4,
532 Ivec2,
533 Ivec3,
534 Ivec4,
535 Vec2,
536 Vec3,
537 Vec4,
538 Mat2,
539 Mat3,
540 Mat4,
541 Texture2D,
542 TextureOES,
543 Array {elem_ty: Rc<ShaderTy>, len: usize},
544 Struct(StructPtr),
545 Enum(LiveType),
546 DrawShader(DrawShaderPtr),
547 ClosureDef(ClosureDefIndex),
548 ClosureDecl
549}
550
551pub type Ty = ShaderTy;
552
553
554#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Ord, PartialOrd)]
555pub enum TyLit {
556 Bool,
557 Int,
558 Float,
559 Bvec2,
560 Bvec3,
561 Bvec4,
562 Ivec2,
563 Ivec3,
564 Ivec4,
565 Vec2,
566 Vec3,
567 Vec4,
568 Mat2,
569 Mat3,
570 Mat4,
571 Texture2D,
572 TextureOES,
573}
574
575#[derive(Clone, Copy, PartialEq, Debug)]
576pub enum Lit {
577 Bool(bool),
578 Int(i32),
579 Float(f32),
580 Color(u32),
581}
582
583#[derive(Clone, PartialEq, Debug)]
584pub enum Val {
585 Bool(bool),
586 Int(i32),
587 Float(f32),
588 Vec4(Vec4),
589}
590
591
592pub type Scope = HashMap<Ident, ScopeSym>;
593
594#[derive(Clone, Debug)]
595pub struct Scopes {
596 pub scopes: Vec<Scope>,
597 pub closure_scopes: RefCell<HashMap<ClosureDefIndex, Vec<Scope >> >,
598 pub closure_sites: RefCell<Vec<ClosureSite >>,
599}
600
601#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Ord, PartialOrd)]
602pub struct ScopeSymShadow(pub usize);
603
604#[derive(Clone, Eq, Hash, PartialEq, Ord, PartialOrd, Debug)]
605pub struct Sym {
606 pub ident: Ident,
607 pub ty: Ty,
608 pub shadow: ScopeSymShadow, }
610
611#[derive(Clone, Debug)]
612pub struct ScopeSym {
613 pub span: TokenSpan,
614 pub sym: Sym,
615 pub referenced: Cell<bool>,
616 pub kind: ScopeSymKind
617}
618
619#[derive(Clone, Debug)]
620pub enum ScopeSymKind {
621 Local,
622 MutLocal,
623 Closure {
624 return_ty: Ty,
625 param_index: usize,
626 params: Vec<Param>
627 }
628}
629
630impl Scopes {
631 pub fn new() -> Scopes {
632 Scopes {
633 closure_scopes: RefCell::new(HashMap::new()),
634 closure_sites: RefCell::new(Vec::new()),
635 scopes: Vec::new(),
636 }
637 }
638
639 pub fn find_sym_on_scopes(&self, ident: Ident, _span: TokenSpan) -> Option<&ScopeSym> {
640 let ret = self.scopes.iter().rev().find_map( | scope | scope.get(&ident));
641 if ret.is_some() {
642 return Some(ret.unwrap())
643 }
644 return None
645 }
646
647 pub fn capture_closure_scope(&self, index: ClosureDefIndex) {
648 self.closure_scopes.borrow_mut().insert(index, self.scopes.clone());
649 }
650
651 pub fn push_scope(&mut self) {
652 self.scopes.push(Scope::new())
653 }
654
655 pub fn pop_scope(&mut self) {
656 self.scopes.pop().unwrap();
657 }
658
659 pub fn clear_referenced_syms(&self) {
660 for scope in self.scopes.iter().rev() {
661 for (_, sym) in scope {
662 sym.referenced.set(false);
663 }
664 }
665 }
666
667 pub fn all_referenced_syms(&self) -> Vec<Sym> {
668 let mut ret = Vec::new();
669 for scope in self.scopes.iter().rev() {
670 for (_, sym) in scope {
671 if sym.referenced.get() {
672 ret.push(sym.sym.clone());
673 }
674 }
675 }
676 ret
677 }
678
679 pub fn insert_sym(&mut self, span: TokenSpan, ident: Ident, ty: Ty, sym_kind: ScopeSymKind) -> ScopeSymShadow {
680
681 if let Some(item) = self.scopes.last_mut().unwrap().get_mut(&ident) {
682 item.sym.shadow = ScopeSymShadow(item.sym.shadow.0 + 1);
683 item.kind = sym_kind;
684 item.sym.shadow
685 }
686 else {
687 let shadow = if let Some(ret) = self.scopes.iter().rev().find_map( | scope | scope.get(&ident)) {
689 ScopeSymShadow(ret.sym.shadow.0 + 1)
690 }
691 else {
692 ScopeSymShadow(0)
693 };
694 self.scopes.last_mut().unwrap().insert(ident, ScopeSym {
695 sym: Sym {
696 ty,
697 ident,
698 shadow,
699 },
700 span,
701 referenced: Cell::new(false),
702 kind: sym_kind
703 });
704 shadow
705 }
706 }
707}
708
709#[derive(Clone, Copy, Ord, PartialOrd, Default, Eq, Hash, PartialEq)]
710pub struct Ident(pub LiveId);
711
712
713impl StructDef {
714 pub fn init_analysis(&self) {
715 *self.struct_refs.borrow_mut() = Some(BTreeSet::new());
716 }
717}
718
719
720impl FnDef {
721
722 pub fn new(
723 fn_ptr: FnPtr,
724 span: TokenSpan,
725 ident: Ident,
726 self_kind: Option<FnSelfKind>,
727 params: Vec<Param>,
728 return_ty_expr: Option<TyExpr>,
729 block: Block,
730 closure_defs: Vec<ClosureDef>
731 ) -> Self {
732 FnDef {
733 fn_ptr,
734 span,
735 ident,
736 self_kind,
737 params,
738 return_ty_expr,
739 block,
740 closure_defs,
741 has_return: Cell::new(false),
742 hidden_args: RefCell::new(None),
743 closure_sites: RefCell::new(None),
744 live_refs: RefCell::new(None),
745 struct_refs: RefCell::new(None),
746 draw_shader_refs: RefCell::new(None),
747 return_ty: RefCell::new(None),
748 callees: RefCell::new(None),
749 builtin_deps: RefCell::new(None),
750 constructor_fn_deps: RefCell::new(None),
751 const_table: RefCell::new(None),
752 const_table_spans: RefCell::new(None),
753 }
754 }
755
756 pub fn init_analysis(&self) {
757 *self.struct_refs.borrow_mut() = Some(BTreeSet::new());
758 *self.callees.borrow_mut() = Some(BTreeSet::new());
759 *self.builtin_deps.borrow_mut() = Some(BTreeSet::new());
760 *self.constructor_fn_deps.borrow_mut() = Some(BTreeSet::new());
762 *self.draw_shader_refs.borrow_mut() = Some(BTreeSet::new());
763 *self.live_refs.borrow_mut() = Some(BTreeMap::new());
764 *self.const_table.borrow_mut() = Some(Vec::new());
765 *self.const_table_spans.borrow_mut() = Some(Vec::new());
766 }
767
768 pub fn has_closure_args(&self) -> bool {
769 for param in &self.params {
770 if let TyExprKind::ClosureDecl {..} = ¶m.ty_expr.kind {
771 return true
772 }
773 }
774 return false
775 }
776}
777
778impl DrawShaderDef {
779
780 pub fn find_field(&self, ident: Ident) -> Option<&DrawShaderFieldDef> {
781 self.fields.iter().find( | decl | {
782 decl.ident == ident
783 })
784 }
785
786 pub fn fields_as_uniform_blocks(&self) -> BTreeMap<Ident, Vec<(usize, Ident) >> {
787 let mut uniform_blocks = BTreeMap::new();
788 for (field_index, field) in self.fields.iter().enumerate() {
789 match &field.kind {
790 DrawShaderFieldKind::Uniform {
791 block_ident,
792 ..
793 } => {
794 let uniform_block = uniform_blocks
795 .entry(*block_ident)
796 .or_insert(Vec::new());
797 uniform_block.push((field_index, field.ident));
798 }
799 _ => {}
800 }
801 }
802 uniform_blocks
803 }
804
805 pub fn add_uniform(&mut self, id: LiveId, block: LiveId, ty: Ty, span: TokenSpan) {
806 self.fields.push(
807 DrawShaderFieldDef {
808 kind: DrawShaderFieldKind::Uniform {
809 block_ident: Ident(block),
810 var_def_ptr: None
811 },
812 span,
813 ident: Ident(id),
814 ty_expr: ty.to_ty_expr(),
815 }
816 )
817 }
818
819 pub fn add_instance(&mut self, id: LiveId, ty: Ty, span: TokenSpan, live_field_kind: LiveFieldKind) {
820 self.fields.push(
821 DrawShaderFieldDef {
822 kind: DrawShaderFieldKind::Instance {
823 live_field_kind,
824 is_used_in_pixel_shader: Cell::new(false),
825 var_def_ptr: None
826 },
827 span,
828 ident: Ident(id),
829 ty_expr: ty.to_ty_expr(),
830 }
831 )
832 }
833
834 pub fn add_geometry(&mut self, id: LiveId, ty: Ty, span: TokenSpan) {
835 self.fields.push(
836 DrawShaderFieldDef {
837 kind: DrawShaderFieldKind::Geometry {
838 is_used_in_pixel_shader: Cell::new(false),
839 var_def_ptr: None
840 },
841 span,
842 ident: Ident(id),
843 ty_expr: ty.to_ty_expr(),
844 }
845 )
846 }
847
848
849 pub fn add_texture(&mut self, id: LiveId, ty: Ty, span: TokenSpan) {
850 self.fields.push(
851 DrawShaderFieldDef {
852 kind: DrawShaderFieldKind::Texture {
853 var_def_ptr: None
854 },
855 span,
856 ident: Ident(id),
857 ty_expr: ty.to_ty_expr(),
858 }
859 )
860 }
861}
862
863impl BinOp {
864 pub fn from_assign_op(token: LiveToken) -> Option<BinOp> {
865 match token {
866 LiveToken::Punct(live_id!( =)) => Some(BinOp::Assign),
867 LiveToken::Punct(live_id!( +=)) => Some(BinOp::AddAssign),
868 LiveToken::Punct(live_id!( -=)) => Some(BinOp::SubAssign),
869 LiveToken::Punct(live_id!( *=)) => Some(BinOp::MulAssign),
870 LiveToken::Punct(live_id!( /=)) => Some(BinOp::DivAssign),
871 _ => None,
872 }
873 }
874
875 pub fn from_or_op(token: LiveToken) -> Option<BinOp> {
876 match token {
877 LiveToken::Punct(live_id!( ||)) => Some(BinOp::Or),
878 _ => None,
879 }
880 }
881
882 pub fn from_and_op(token: LiveToken) -> Option<BinOp> {
883 match token {
884 LiveToken::Punct(live_id!( &&)) => Some(BinOp::And),
885 _ => None,
886 }
887 }
888
889 pub fn from_eq_op(token: LiveToken) -> Option<BinOp> {
890 match token {
891 LiveToken::Punct(live_id!( ==)) => Some(BinOp::Eq),
892 LiveToken::Punct(live_id!( !=)) => Some(BinOp::Ne),
893 _ => None,
894 }
895 }
896
897 pub fn from_rel_op(token: LiveToken) -> Option<BinOp> {
898 match token {
899 LiveToken::Punct(live_id!(<)) => Some(BinOp::Lt),
900 LiveToken::Punct(live_id!( <=)) => Some(BinOp::Le),
901 LiveToken::Punct(live_id!(>)) => Some(BinOp::Gt),
902 LiveToken::Punct(live_id!( >=)) => Some(BinOp::Ge),
903 _ => None,
904 }
905 }
906
907 pub fn from_add_op(token: LiveToken) -> Option<BinOp> {
908 match token {
909 LiveToken::Punct(live_id!( +)) => Some(BinOp::Add),
910 LiveToken::Punct(live_id!(-)) => Some(BinOp::Sub),
911 _ => None,
912 }
913 }
914
915 pub fn from_mul_op(token: LiveToken) -> Option<BinOp> {
916 match token {
917 LiveToken::Punct(live_id!(*)) => Some(BinOp::Mul),
918 LiveToken::Punct(live_id!( /)) => Some(BinOp::Div),
919 _ => None,
920 }
921 }
922}
923
924impl fmt::Display for BinOp {
925 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
926 write!(
927 f,
928 "{}",
929 match self {
930 BinOp::Assign => "=",
931 BinOp::AddAssign => "+=",
932 BinOp::SubAssign => "-=",
933 BinOp::MulAssign => "*=",
934 BinOp::DivAssign => "/=",
935 BinOp::Or => "||",
936 BinOp::And => "&&",
937 BinOp::Eq => "==",
938 BinOp::Ne => "!=",
939 BinOp::Lt => "<",
940 BinOp::Le => "<=",
941 BinOp::Gt => ">",
942 BinOp::Ge => ">=",
943 BinOp::Add => "+",
944 BinOp::Sub => "-",
945 BinOp::Mul => "*",
946 BinOp::Div => "/",
947 }
948 )
949 }
950}
951
952impl UnOp {
953 pub fn from_un_op(token: LiveToken) -> Option<UnOp> {
954 match token {
955 LiveToken::Punct(live_id!(!)) => Some(UnOp::Not),
956 LiveToken::Punct(live_id!(-)) => Some(UnOp::Neg),
957 _ => None,
958 }
959 }
960}
961
962impl fmt::Display for UnOp {
963 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
964 write!(
965 f,
966 "{}",
967 match self {
968 UnOp::Not => "!",
969 UnOp::Neg => "-",
970 }
971 )
972 }
973}
974
975
976impl Ty {
977
978 pub fn maybe_ty_lit(&self) -> Option<TyLit> {
979 match self {
980 Ty::Void => None,
981 Ty::Bool => Some(TyLit::Bool),
982 Ty::Int => Some(TyLit::Int),
983 Ty::Float => Some(TyLit::Float),
984 Ty::Bvec2 => Some(TyLit::Bvec2),
985 Ty::Bvec3 => Some(TyLit::Bvec3),
986 Ty::Bvec4 => Some(TyLit::Bvec4),
987 Ty::Ivec2 => Some(TyLit::Ivec2),
988 Ty::Ivec3 => Some(TyLit::Ivec3),
989 Ty::Ivec4 => Some(TyLit::Ivec4),
990 Ty::Vec2 => Some(TyLit::Vec2),
991 Ty::Vec3 => Some(TyLit::Vec3),
992 Ty::Vec4 => Some(TyLit::Vec4),
993 Ty::Mat2 => Some(TyLit::Mat2),
994 Ty::Mat3 => Some(TyLit::Mat3),
995 Ty::Mat4 => Some(TyLit::Mat4),
996 Ty::Texture2D => Some(TyLit::Bool),
997 Ty::TextureOES => Some(TyLit::Bool),
998 Ty::Array {..} => None,
999 Ty::Struct(_) => None,
1000 Ty::Enum(_) => None,
1001 Ty::DrawShader(_) => None,
1002 Ty::ClosureDecl => None,
1003 Ty::ClosureDef {..} => None
1004 }
1005 }
1006
1007 pub fn is_scalar(&self) -> bool {
1008 match self {
1009 Ty::Bool | Ty::Int | Ty::Float => true,
1010 _ => false,
1011 }
1012 }
1013
1014 pub fn is_vector(&self) -> bool {
1015 match self {
1016 Ty::Bvec2
1017 | Ty::Bvec3
1018 | Ty::Bvec4
1019 | Ty::Ivec2
1020 | Ty::Ivec3
1021 | Ty::Ivec4
1022 | Ty::Vec2
1023 | Ty::Vec3
1024 | Ty::Vec4 => true,
1025 _ => false,
1026 }
1027 }
1028
1029 pub fn is_matrix(&self) -> bool {
1030 match self {
1031 Ty::Mat2 | Ty::Mat3 | Ty::Mat4 => true,
1032 _ => false,
1033 }
1034 }
1035
1036 pub fn slots(&self) -> usize {
1037 match self {
1038 Ty::Void => 0,
1039 Ty::Bool | Ty::Int | Ty::Float => 1,
1040 Ty::Bvec2 | Ty::Ivec2 | Ty::Vec2 => 2,
1041 Ty::Bvec3 | Ty::Ivec3 | Ty::Vec3 => 3,
1042 Ty::Bvec4 | Ty::Ivec4 | Ty::Vec4 | Ty::Mat2 => 4,
1043 Ty::Mat3 => 9,
1044 Ty::Mat4 => 16,
1045 Ty::Texture2D {..} => panic!(),
1046 Ty::TextureOES {..} => panic!(),
1047 Ty::Array {elem_ty, len} => elem_ty.slots() * len,
1048 Ty::Enum(_) => 1,
1049 Ty::Struct(_) => panic!(),
1050 Ty::DrawShader(_) => panic!(),
1051 Ty::ClosureDecl => panic!(),
1052 Ty::ClosureDef {..} => panic!(),
1053 }
1054 }
1055
1056 pub fn to_ty_expr(&self) -> TyExpr {
1057 TyExpr {
1058 ty: RefCell::new(None),
1059 span: TokenSpan::default(),
1060 kind: match self {
1061 Ty::Void => panic!(),
1062 Ty::Bool => TyExprKind::Lit {ty_lit: TyLit::Bool},
1063 Ty::Int => TyExprKind::Lit {ty_lit: TyLit::Int},
1064 Ty::Float => TyExprKind::Lit {ty_lit: TyLit::Float},
1065 Ty::Bvec2 => TyExprKind::Lit {ty_lit: TyLit::Bvec2},
1066 Ty::Bvec3 => TyExprKind::Lit {ty_lit: TyLit::Bvec3},
1067 Ty::Bvec4 => TyExprKind::Lit {ty_lit: TyLit::Bvec4},
1068 Ty::Ivec2 => TyExprKind::Lit {ty_lit: TyLit::Ivec2},
1069 Ty::Ivec3 => TyExprKind::Lit {ty_lit: TyLit::Ivec3},
1070 Ty::Ivec4 => TyExprKind::Lit {ty_lit: TyLit::Ivec4},
1071 Ty::Vec2 => TyExprKind::Lit {ty_lit: TyLit::Vec2},
1072 Ty::Vec3 => TyExprKind::Lit {ty_lit: TyLit::Vec3},
1073 Ty::Vec4 => TyExprKind::Lit {ty_lit: TyLit::Vec4},
1074 Ty::Mat2 => TyExprKind::Lit {ty_lit: TyLit::Mat2},
1075 Ty::Mat3 => TyExprKind::Lit {ty_lit: TyLit::Mat3},
1076 Ty::Mat4 => TyExprKind::Lit {ty_lit: TyLit::Mat4},
1077 Ty::Texture2D => TyExprKind::Lit {ty_lit: TyLit::Texture2D},
1078 Ty::TextureOES => TyExprKind::Lit {ty_lit: TyLit::TextureOES},
1079 Ty::Array {elem_ty, len} => {
1080 TyExprKind::Array {
1081 elem_ty_expr: Box::new(elem_ty.to_ty_expr()),
1082 len: *len as u32
1083 }
1084 }
1085 Ty::Struct(struct_node_ptr) => {
1086 TyExprKind::Struct(*struct_node_ptr)
1087 }
1088 Ty::DrawShader(draw_shader_node_ptr) => {
1089 TyExprKind::DrawShader(*draw_shader_node_ptr)
1090 },
1091 Ty::Enum(live_type) => {
1092 TyExprKind::Enum(*live_type)
1093 },
1094 Ty::ClosureDef(_) => panic!(),
1095 Ty::ClosureDecl => panic!()
1096 }
1097 }
1098 }
1099 pub fn from_live_value(value:&LiveValue, origin:LiveNodeOrigin) -> Result<Self,
1113 LiveError> {
1114 Ok(match value {
1115 LiveValue::Expr {..} => {
1116 panic!()
1117 }
1118 LiveValue::Id(id) => match id {
1119 live_id!(bool) => Self::Bool,
1120 live_id!(int) => Self::Int,
1121 live_id!(float) => Self::Float,
1122 live_id!(vec2) => Self::Vec2,
1123 live_id!(vec3) => Self::Vec3,
1124 live_id!(vec4) => Self::Vec4,
1125 live_id!(texture2d) => Self::Texture2D,
1126 live_id!(textureOES) => Self::TextureOES,
1127 _ => {
1128 return Err(LiveError {
1129 origin: live_error_origin!(),
1130 message: format!("Id does not resolve to a shader type {}", id),
1131 span: origin.token_id().unwrap().into()
1132 })
1133 }
1134 }
1135 LiveValue::Bool(_) => Self::Int,
1136 LiveValue::Int64(_) => Self::Int,
1137 LiveValue::Float32(_) => Self::Float,
1138 LiveValue::Float64(_) => Self::Float,
1139 LiveValue::Color(_) => Self::Vec4,
1140 LiveValue::Vec2(_) => Self::Vec2,
1141 LiveValue::Vec3(_) => Self::Vec3,
1142 LiveValue::Vec4(_) => Self::Vec4,
1143 _ => return Err(LiveError {
1144 origin: live_error_origin!(),
1145 message: format!("Live value {:?} does not resolve to a shader type", value),
1146 span: origin.token_id().unwrap().into()
1147 })
1148 })
1149 }
1150
1151 pub fn from_live_node(live_registry: &LiveRegistry, index: usize, nodes: &[LiveNode]) -> Result<Self,
1152 LiveError> {
1153 match &nodes[index].value {
1154 LiveValue::Expr {..} => {
1155 match live_eval_value(live_registry, &mut (index + 1), nodes, nodes){
1156 Ok(v)=>{
1157 return Self::from_live_value(&v, nodes[index].origin)
1158 }
1159 Err(v)=>{
1160 return Err(v)
1161 }
1162 }
1163 }
1164 v=>{
1165 return Self::from_live_value(v, nodes[index].origin);
1166 }
1167 }
1168 }
1169}
1170
1171impl fmt::Display for Ty {
1172 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1173 match self {
1174 Ty::Void => write!(f, "void"),
1175 Ty::Bool => write!(f, "bool"),
1176 Ty::Int => write!(f, "int"),
1177 Ty::Float => write!(f, "float"),
1178 Ty::Bvec2 => write!(f, "bvec2"),
1179 Ty::Bvec3 => write!(f, "bvec3"),
1180 Ty::Bvec4 => write!(f, "bvec4"),
1181 Ty::Ivec2 => write!(f, "ivec2"),
1182 Ty::Ivec3 => write!(f, "ivec3"),
1183 Ty::Ivec4 => write!(f, "ivec4"),
1184 Ty::Vec2 => write!(f, "vec2"),
1185 Ty::Vec3 => write!(f, "vec3"),
1186 Ty::Vec4 => write!(f, "vec4"),
1187 Ty::Mat2 => write!(f, "mat2"),
1188 Ty::Mat3 => write!(f, "mat3"),
1189 Ty::Mat4 => write!(f, "mat4"),
1190 Ty::Texture2D => write!(f, "texture2D"),
1191 Ty::TextureOES => write!(f, "textureOES"),
1192 Ty::Array {elem_ty, len} => write!(f, "{}[{}]", elem_ty, len),
1193 Ty::Struct(struct_ptr) => write!(f, "Struct:{:?}", struct_ptr),
1194 Ty::DrawShader(shader_ptr) => write!(f, "DrawShader:{:?}", shader_ptr),
1195 Ty::Enum(_) => write!(f, "Enum"),
1196 Ty::ClosureDecl => write!(f, "ClosureDecl"),
1197 Ty::ClosureDef {..} => write!(f, "ClosureDef"),
1198 }
1199 }
1200}
1201
1202impl TyLit {
1203 pub fn from_id(id: LiveId) -> Option<TyLit> {
1204 match id {
1205 live_id!(vec4) => Some(TyLit::Vec4),
1206 live_id!(vec3) => Some(TyLit::Vec3),
1207 live_id!(vec2) => Some(TyLit::Vec2),
1208 live_id!(mat4) => Some(TyLit::Mat4),
1209 live_id!(mat3) => Some(TyLit::Mat3),
1210 live_id!(mat2) => Some(TyLit::Mat2),
1211 live_id!(float) => Some(TyLit::Float),
1212 live_id!(bool) => Some(TyLit::Bool),
1213 live_id!(int) => Some(TyLit::Int),
1214 live_id!(bvec2) => Some(TyLit::Bvec2),
1215 live_id!(bvec3) => Some(TyLit::Bvec3),
1216 live_id!(bvec4) => Some(TyLit::Bvec4),
1217 live_id!(ivec2) => Some(TyLit::Ivec4),
1218 live_id!(ivec3) => Some(TyLit::Ivec4),
1219 live_id!(ivec4) => Some(TyLit::Ivec4),
1220 live_id!(texture2D) => Some(TyLit::Texture2D),
1221 _ => None
1222 }
1223 }
1224
1225 pub fn to_ty(self) -> Ty {
1226 match self {
1227 TyLit::Bool => Ty::Bool,
1228 TyLit::Int => Ty::Int,
1229 TyLit::Float => Ty::Float,
1230 TyLit::Bvec2 => Ty::Bvec2,
1231 TyLit::Bvec3 => Ty::Bvec3,
1232 TyLit::Bvec4 => Ty::Bvec4,
1233 TyLit::Ivec2 => Ty::Ivec2,
1234 TyLit::Ivec3 => Ty::Ivec3,
1235 TyLit::Ivec4 => Ty::Ivec4,
1236 TyLit::Vec2 => Ty::Vec2,
1237 TyLit::Vec3 => Ty::Vec3,
1238 TyLit::Vec4 => Ty::Vec4,
1239 TyLit::Mat2 => Ty::Mat2,
1240 TyLit::Mat3 => Ty::Mat3,
1241 TyLit::Mat4 => Ty::Mat4,
1242 TyLit::Texture2D => Ty::Texture2D,
1243 TyLit::TextureOES => Ty::TextureOES,
1244 }
1245 }
1246
1247}
1248
1249impl fmt::Display for TyLit {
1250 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1251 write!(
1252 f,
1253 "{}",
1254 match self {
1255 TyLit::Bool => "bool",
1256 TyLit::Int => "int",
1257 TyLit::Float => "float",
1258 TyLit::Bvec2 => "bvec2",
1259 TyLit::Bvec3 => "bvec3",
1260 TyLit::Bvec4 => "bvec4",
1261 TyLit::Ivec2 => "ivec2",
1262 TyLit::Ivec3 => "ivec3",
1263 TyLit::Ivec4 => "ivec4",
1264 TyLit::Vec2 => "vec2",
1265 TyLit::Vec3 => "vec3",
1266 TyLit::Vec4 => "vec4",
1267 TyLit::Mat2 => "mat2",
1268 TyLit::Mat3 => "mat3",
1269 TyLit::Mat4 => "mat4",
1270 TyLit::Texture2D => "texture2D",
1271 TyLit::TextureOES => "textureOES",
1272 }
1273 )
1274 }
1275}
1276
1277
1278impl Lit {
1279 pub fn to_ty(self) -> Ty {
1280 match self {
1281 Lit::Bool(_) => Ty::Bool,
1282 Lit::Int(_) => Ty::Int,
1283 Lit::Float(_) => Ty::Float,
1284 Lit::Color(_) => Ty::Vec4
1285 }
1286 }
1287
1288 pub fn to_val(self) -> Val {
1289 match self {
1290 Lit::Bool(v) => Val::Bool(v),
1291 Lit::Int(v) => Val::Int(v),
1292 Lit::Float(v) => Val::Float(v),
1293 Lit::Color(v) => Val::Vec4(Vec4::from_u32(v))
1294 }
1295 }
1296
1297 pub fn from_token(token: &LiveToken) -> Option<Lit> {
1298 match token {
1299 LiveToken::Bool(v) => Some(Lit::Bool(*v)),
1300 LiveToken::Int(v) => Some(Lit::Int(*v as i32)),
1301 LiveToken::Float(v) => Some(Lit::Float(*v as f32)),
1302 LiveToken::Color(v) => Some(Lit::Color(*v)),
1303 _ => None
1304 }
1305 }
1306}
1307
1308impl fmt::Display for Lit {
1309 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1310 match self {
1311 Lit::Bool(lit) => write!(f, "{}", lit),
1312 Lit::Int(lit) => write!(f, "{}", lit),
1313 Lit::Float(lit) => write!(f, "{}", PrettyPrintedF32(*lit)),
1314 Lit::Color(lit) => {
1315 let v = Vec4::from_u32(*lit);
1316 write!(
1317 f,
1318 "vec4({},{},{},{})",
1319 PrettyPrintedF32(v.x),
1320 PrettyPrintedF32(v.y),
1321 PrettyPrintedF32(v.z),
1322 PrettyPrintedF32(v.w)
1323 )
1324 }
1325 }
1326 }
1327}
1328
1329
1330impl Ident {
1331 pub fn to_id(self) -> LiveId {self.0}
1332
1333}
1334
1335impl fmt::Debug for Ident {
1336 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1337 write!(f, "{}", self.0)
1338 }
1339}
1340
1341impl fmt::Display for Ident {
1342 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1343 write!(f, "{}", self.0)
1344 }
1345}
1346
1347#[derive(Clone, Default, Copy, Eq, PartialEq, Hash, PartialOrd, Ord)]
1348pub struct IdentPath {
1349 pub segs: [LiveId; 6],
1350 pub len: usize
1351}
1352
1353impl IdentPath {
1354
1355 pub fn len(&self) -> usize {
1356 self.len
1357 }
1358
1359 pub fn push(&mut self, ident: Ident) -> bool {
1360 if self.len >= self.segs.len() {
1361 return false
1362 }
1363 self.segs[self.len] = ident.0;
1364 self.len += 1;
1365 return true
1366 }
1367}
1368
1369impl fmt::Debug for IdentPath {
1370 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1371 for i in 0..self.len {
1372 if i != 0 {
1373 let _ = write!(f, "::").unwrap();
1374 }
1375 let _ = write!(f, "{}", self.segs[i]);
1376 }
1377 Ok(())
1378 }
1379}
1380
1381impl fmt::Display for IdentPath {
1382 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1383 for i in 0..self.len {
1384 if i != 0 {
1385 let _ = write!(f, "::").unwrap();
1386 }
1387 let _ = write!(f, "{}", self.segs[i]);
1388 }
1389 Ok(())
1390 }
1391}
1392
1393impl Val {
1394 pub fn to_bool(&self) -> Option<bool> {
1395 match *self {
1396 Val::Bool(val) => Some(val),
1397 _ => None,
1398 }
1399 }
1400
1401 pub fn to_int(&self) -> Option<i32> {
1402 match *self {
1403 Val::Int(val) => Some(val),
1404 Val::Float(val) => Some(val as i32),
1405 _ => None,
1406 }
1407 }
1408}
1409
1410impl fmt::Display for Val {
1411 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1412 match *self {
1413 Val::Bool(val) => write!(f, "{}", val),
1414 Val::Int(val) => write!(f, "{}", val),
1415 Val::Float(v) => write!(f, "{}", PrettyPrintedF32(v)),
1416 Val::Vec4(val) => write!(f, "{}", val),
1417 }
1418 }
1419}
1420
1421impl fmt::Display for StructPtr {
1422 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1423 write!(f, "struct_{}", self.0)
1424 }
1425}
1426
1427impl fmt::Display for FnPtr {
1428 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1429 write!(f, "fn_{}", self.0)
1430 }
1431}
1432
1433impl fmt::Display for ValuePtr {
1434 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1435 write!(f, "live_{}", self.0)
1436 }
1437}