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