1use std::hash::{Hash, Hasher};
4use crate::shader::*;
5
6#[derive(Default, Clone, PartialEq)]
7pub struct ShaderGen {
8 pub log: i32,
9 pub name: String,
10 pub geometry_vertices: Vec<f32>,
11 pub geometry_indices: Vec<u32>,
12 pub asts: Vec<ShAst>,
13}
14
15impl Eq for ShaderGen {}
16
17impl Hash for ShaderGen {
18 fn hash<H: Hasher>(&self, state: &mut H) {
19 self.log.hash(state);
20 self.name.hash(state);
21 self.geometry_indices.hash(state);
22 for vertex in &self.geometry_vertices {
23 vertex.to_bits().hash(state);
24 }
25 self.asts.hash(state);
26 }
27}
28
29impl ShaderGen {
30 pub fn new() -> Self {
31 let sg = ShaderGen::default();
32 let sg = CxShader::def_builtins(sg);
33 let sg = CxShader::def_df(sg);
34 let sg = CxPass::def_uniforms(sg);
35 let sg = CxView::def_uniforms(sg);
36 sg
37 }
38
39 pub fn compose(mut self, ast: ShAst) -> Self {
40 self.asts.push(ast);
41 self
42 }
43
44 pub fn flat_vars<F>(&self, cb:F) -> Vec<ShVar>
46 where F: Fn(&ShVarStore)->bool{
47 let mut ret = Vec::new();
48 for ast in self.asts.iter() {
49 for shvar in &ast.vars {
50 if cb(&shvar.store){
51 ret.push(shvar.clone());
52 }
53 }
54 }
55 ret
56 }
57
58 pub fn flat_consts(&self) -> Vec<ShConst> {
60 let mut ret = Vec::new();
61 for ast in self.asts.iter().rev() {
62 for shconst in &ast.consts {
63 ret.push(shconst.clone());
64 }
65 };
66 ret
67 }
68
69 pub fn find_fn(&self, name: &str) -> Option<&ShFn> {
71 for ast in self.asts.iter().rev() {
72 for shfn in &ast.fns {
73 if shfn.name == name {
74 return Some(&shfn)
75 }
76 }
77 }
78 None
79 }
80
81 pub fn find_var(&self, name: &str) -> Option<&ShVar> {
82 for ast in self.asts.iter().rev() {
83 for shvar in &ast.vars {
84 if shvar.name == name {
85 return Some(&shvar)
86 }
87 }
88 }
89 None
90 }
91
92 pub fn find_const(&self, name: &str) -> Option<&ShConst> {
93 for ast in self.asts.iter().rev() {
94 for shconst in &ast.consts {
95 if shconst.name == name {
96 return Some(&shconst)
97 }
98 }
99 }
100 None
101 }
102
103 pub fn find_type(&self, name: &str) -> Option<&ShType> {
104 for ast in self.asts.iter().rev() {
105 for shtype in &ast.types {
106 if shtype.name == name {
107 return Some(&shtype)
108 }
109 }
110 }
111 None
112 }
113
114 pub fn get_type_slots(&self, name: &str) -> usize {
115 if let Some(ty) = self.find_type(name) {
116 return ty.slots;
117 }
118 0
119 }
120
121 pub fn compute_slot_total(&self, vars: &Vec<ShVar>) -> usize {
122 let mut slots: usize = 0;
123 for var in vars {
124 slots += self.get_type_slots(&var.ty);
125 }
126 slots
127 }
128}
129
130
131#[derive(Clone, Hash, PartialEq)]
133pub struct ShAst {
134 pub types: Vec<ShType>,
135 pub vars: Vec<ShVar>,
136 pub consts: Vec<ShConst>,
137 pub fns: Vec<ShFn>
138}
139
140#[derive(Clone, Hash, PartialEq)]
141pub struct ShFnArg {
142 pub name: String,
143 pub ty: String
144}
145
146
147#[inline(never)]
148pub fn sh_fnarg(name:&str, ty:&str)->ShFnArg{
149 ShFnArg{
150 name:name.to_string(),
151 ty:ty.to_string()
152 }
153}
154
155impl ShFnArg {
156 pub fn new(name: &str, ty: &str) -> Self {
157 Self {
158 name: name.to_string(),
159 ty: ty.to_string()
160 }
161 }
162}
163
164#[derive(Clone, Hash, PartialEq)]
165pub struct ShFn {
166 pub name: String,
167 pub args: Vec<ShFnArg>,
168 pub ret: String,
169 pub block: Option<ShBlock>,
170}
171
172#[inline(never)]
173pub fn sh_fn(name:&str, args:&[ShFnArg], ret:&str, block:Option<ShBlock>)->ShFn{
174 ShFn{
175 name:name.to_string(),
176 args:args.to_vec(),
177 ret:ret.to_string(),
178 block:block
179 }
180
181}
182
183#[derive(Clone, Hash, PartialEq)]
184pub enum UniformType {
185 Color(UniformColor),
186 Vec4(UniformVec4),
187 Vec3(UniformVec3),
188 Vec2(UniformVec2),
189 Float(UniformFloat)
190}
191
192impl UniformType{
193 fn type_name(&self)->String{
194 match self{
195 UniformType::Color(_)=>"vec4".to_string(),
196 UniformType::Vec4(_)=>"vec4".to_string(),
197 UniformType::Vec3(_)=>"vec3".to_string(),
198 UniformType::Vec2(_)=>"vec2".to_string(),
199 UniformType::Float(_)=>"float".to_string(),
200 }
201 }
202}
203
204#[derive(Clone, Hash, PartialEq)]
205pub enum InstanceType {
206 Color(InstanceColor),
207 Vec4(InstanceVec4),
208 Vec3(InstanceVec3),
209 Vec2(InstanceVec2),
210 Float(InstanceFloat)
211}
212
213impl InstanceType{
214 fn type_name(&self)->String{
215 match self{
216 InstanceType::Color(_)=>"vec4".to_string(),
217 InstanceType::Vec4(_)=>"vec4".to_string(),
218 InstanceType::Vec3(_)=>"vec3".to_string(),
219 InstanceType::Vec2(_)=>"vec2".to_string(),
220 InstanceType::Float(_)=>"float".to_string(),
221 }
222 }
223}
224
225#[derive(Clone, Hash, PartialEq)]
226pub enum ShVarStore {
227 Uniform(UniformType),
228 UniformColor(ColorId),
229 DrawUniform,
230 ViewUniform,
231 PassUniform,
232 Instance(InstanceType),
233 Geometry,
234 Texture,
235 Local,
236 Varying,
237}
238
239#[derive(Clone, Hash, PartialEq)]
240pub struct ShVar {
241 pub name: String,
242 pub ty: String,
243 pub store: ShVarStore
244}
245
246
247#[inline(never)]
248pub fn sh_var(name:&str, ty:&str, store:ShVarStore)->ShVar{
249 ShVar{
250 name:name.to_string(),
251 ty:ty.to_string(),
252 store:store
253 }
254}
255
256#[derive(Clone, Hash, PartialEq)]
257pub struct ShConst {
258 pub name: String,
259 pub ty: String,
260 pub value: ShExpr
261}
262
263#[derive(Clone, Hash, PartialEq)]
264pub struct ShTypeField {
265 pub name: String,
266 pub ty: String,
267}
268
269impl ShTypeField {
270 pub fn new(name: &str, ty: &str) -> Self {
271 Self {
272 name: name.to_string(),
273 ty: ty.to_string()
274 }
275 }
276}
277
278#[derive(Clone, Hash, PartialEq)]
279pub struct ShType {
280 pub name: String,
281 pub slots: usize,
282 pub prim: bool,
283 pub fields: Vec<ShTypeField>
284}
285
286#[derive(Clone, Hash, PartialEq)]
289pub enum ShExpr {
290 ShId(ShId),
291 ShLit(ShLit),
292 ShField(ShField),
293 ShIndex(ShIndex),
294 ShAssign(ShAssign),
295 ShAssignOp(ShAssignOp),
296 ShBinary(ShBinary),
297 ShUnary(ShUnary),
298 ShParen(ShParen),
299 ShBlock(ShBlock),
300 ShCall(ShCall),
301 ShIf(ShIf),
302 ShWhile(ShWhile),
303 ShForLoop(ShForLoop),
304 ShReturn(ShReturn),
305 ShBreak(ShBreak),
306 ShContinue(ShContinue)
307}
308
309#[derive(Clone, Hash, PartialEq)]
310pub enum ShOp {
311 Add,
312 Sub,
313 Mul,
314 Div,
315 Rem,
316 And,
317 Or,
318 BitXor,
319 BitAnd,
320 BitOr,
321 Shl,
322 Shr,
323 Eq,
324 Lt,
325 Le,
326 Ne,
327 Ge,
328 Gt,
329 AddEq,
330 SubEq,
331 MulEq,
332 DivEq,
333 RemEq,
334 BitXorEq,
335 BitAndEq,
336 BitOrEq,
337 ShlEq,
338 ShrEq
339}
340
341impl ShOp {
342 pub fn to_string(&self) -> &str {
343 match self {
344 ShOp::Add => "+",
345 ShOp::Sub => "-",
346 ShOp::Mul => "*",
347 ShOp::Div => "/",
348 ShOp::Rem => "%",
349 ShOp::And => "&&",
350 ShOp::Or => "||",
351 ShOp::BitXor => "^",
352 ShOp::BitAnd => "&",
353 ShOp::BitOr => "|",
354 ShOp::Shl => "<<",
355 ShOp::Shr => ">>",
356 ShOp::Eq => "==",
357 ShOp::Lt => "<",
358 ShOp::Le => "<=",
359 ShOp::Ne => "!=",
360 ShOp::Ge => ">=",
361 ShOp::Gt => ">",
362 ShOp::AddEq => "+=",
363 ShOp::SubEq => "-=",
364 ShOp::MulEq => "*=",
365 ShOp::DivEq => "/=",
366 ShOp::RemEq => "%=",
367 ShOp::BitXorEq => "^=",
368 ShOp::BitAndEq => "&=",
369 ShOp::BitOrEq => "|=",
370 ShOp::ShlEq => "<<=",
371 ShOp::ShrEq => ">>=",
372 }
373 }
374}
375
376#[derive(Clone, Hash, PartialEq)]
377pub struct ShId {
378 pub name: String
379}
380
381#[inline(never)]
382pub fn sh_id(name:&str)->ShExpr{
383 ShExpr::ShId(ShId{name:name.to_string()})
384}
385
386#[derive(Clone)]
387pub enum ShLit {
388 Int(i64),
389 Float(f64),
390 Str(String),
391 Bool(bool)
392}
393
394#[inline(never)]
395pub fn sh_int(val:i64)->ShExpr{
396 ShExpr::ShLit(ShLit::Int(val))
397}
398
399#[inline(never)]
400pub fn sh_fl(val:f64)->ShExpr{
401 ShExpr::ShLit(ShLit::Float(val))
402}
403
404
405#[inline(never)]
406pub fn sh_str(val:&str)->ShExpr{
407 ShExpr::ShLit(ShLit::Str(val.to_string()))
408}
409
410#[inline(never)]
411pub fn sh_bool(val:bool)->ShExpr{
412 ShExpr::ShLit(ShLit::Bool(val))
413}
414
415
416impl Hash for ShLit {
417 fn hash<H: Hasher>(&self, state: &mut H) {
418 match self {
419 ShLit::Int(iv) => iv.hash(state),
420 ShLit::Float(fv) => fv.to_bits().hash(state),
421 ShLit::Str(sv) => sv.hash(state),
422 ShLit::Bool(bv) => bv.hash(state)
423 }
424 }
425}
426
427impl PartialEq for ShLit {
428 fn eq(&self, other: &ShLit) -> bool {
429 match self {
430 ShLit::Int(iv) => match other {
431 ShLit::Int(ov) => iv == ov,
432 _ => false
433 },
434 ShLit::Float(iv) => match other {
435 ShLit::Float(ov) => iv.to_bits() == ov.to_bits(),
436 _ => false
437 },
438 ShLit::Str(iv) => match other {
439 ShLit::Str(ov) => iv == ov,
440 _ => false
441 },
442 ShLit::Bool(iv) => match other {
443 ShLit::Bool(ov) => iv == ov,
444 _ => false
445 },
446 }
447 }
448}
449
450#[derive(Clone, Hash, PartialEq)]
451pub struct ShField {
452 pub base: Box<ShExpr>,
453 pub member: String
454}
455
456#[inline(never)]
457pub fn sh_fd(base:ShExpr, member:&str)->ShExpr{
458 ShExpr::ShField(ShField{
459 base:Box::new(base),
460 member:member.to_string()
461 })
462}
463
464
465#[derive(Clone, Hash, PartialEq)]
466pub struct ShIndex {
467 pub base: Box<ShExpr>,
468 pub index: Box<ShExpr>
469}
470
471#[inline(never)]
472pub fn sh_idx(base:ShExpr, index:ShExpr)->ShExpr{
473 ShExpr::ShIndex(ShIndex{
474 base:Box::new(base),
475 index:Box::new(index)
476 })
477}
478
479
480
481#[derive(Clone, Hash, PartialEq)]
482pub struct ShAssign {
483 pub left: Box<ShExpr>,
484 pub right: Box<ShExpr>
485}
486
487#[inline(never)]
488pub fn sh_asn(left:ShExpr, right:ShExpr)->ShExpr{
489 ShExpr::ShAssign(ShAssign{
490 left:Box::new(left),
491 right:Box::new(right)
492 })
493}
494
495#[derive(Clone, Hash, PartialEq)]
496pub struct ShAssignOp {
497 pub left: Box<ShExpr>,
498 pub right: Box<ShExpr>,
499 pub op: ShOp
500}
501
502#[inline(never)]
503pub fn sh_asn_op(left:ShExpr, right:ShExpr, op:ShOp)->ShExpr{
504 ShExpr::ShAssignOp(ShAssignOp{
505 left:Box::new(left),
506 right:Box::new(right),
507 op:op
508 })
509}
510
511
512#[derive(Clone, Hash, PartialEq)]
513pub struct ShBinary {
514 pub left: Box<ShExpr>,
515 pub right: Box<ShExpr>,
516 pub op: ShOp
517}
518
519#[inline(never)]
520pub fn sh_bin(left:ShExpr, right:ShExpr, op:ShOp)->ShExpr{
521 ShExpr::ShBinary(ShBinary{
522 left:Box::new(left),
523 right:Box::new(right),
524 op:op
525 })
526}
527
528#[derive(Clone, Hash, PartialEq)]
529pub enum ShUnaryOp {
530 Not,
531 Neg
532}
533
534impl ShUnaryOp {
535 pub fn to_string(&self) -> &str {
536 match self {
537 ShUnaryOp::Not => "!",
538 ShUnaryOp::Neg => "-"
539 }
540 }
541}
542
543#[derive(Clone, Hash, PartialEq)]
544pub struct ShUnary {
545 pub expr: Box<ShExpr>,
546 pub op: ShUnaryOp
547}
548
549#[inline(never)]
550pub fn sh_unary(expr:ShExpr, op:ShUnaryOp)->ShExpr{
551 ShExpr::ShUnary(ShUnary{
552 expr:Box::new(expr),
553 op:op
554 })
555}
556
557
558#[derive(Clone, Hash, PartialEq)]
559pub struct ShParen {
560 pub expr: Box<ShExpr>,
561}
562
563#[inline(never)]
564pub fn sh_par(expr:ShExpr)->ShExpr{
565 ShExpr::ShParen(ShParen{expr:Box::new(expr)})
566}
567
568#[derive(Clone, Hash, PartialEq)]
569pub enum ShStmt {
570 ShLet(ShLet),
571 ShExpr(ShExpr),
572 ShSemi(ShExpr)
573}
574
575#[inline(never)]
576pub fn sh_sems(expr:ShExpr)->ShStmt{
577 ShStmt::ShSemi(expr)
578}
579
580#[inline(never)]
581pub fn sh_exps(expr:ShExpr)->ShStmt{
582 ShStmt::ShExpr(expr)
583}
584
585#[derive(Clone, Hash, PartialEq)]
586pub struct ShBlock {
587 pub stmts: Vec<ShStmt>
588}
589
590#[inline(never)]
591pub fn sh_block(stmts:&[ShStmt])->ShBlock{
592 ShBlock{stmts:stmts.to_vec()}
593}
594
595#[derive(Clone, Hash, PartialEq)]
596pub struct ShCall {
597 pub call: String,
598 pub args: Vec<ShExpr>
599}
600
601#[inline(never)]
602pub fn sh_call(call:&str, args:&[ShExpr])->ShExpr{
603 ShExpr::ShCall(ShCall{
604 call:call.to_string(),
605 args:args.to_vec()
606 })
607}
608
609#[derive(Clone, Hash, PartialEq)]
610pub struct ShIf {
611 pub cond: Box<ShExpr>,
612 pub then_branch: ShBlock,
613 pub else_branch: Option<Box<ShExpr>>,
614}
615
616#[inline(never)]
617pub fn sh_if(cond:ShExpr, then_branch:ShBlock)->ShExpr{
618 ShExpr::ShIf(ShIf{
619 cond:Box::new(cond),
620 then_branch:then_branch,
621 else_branch:None
622 })
623}
624
625#[inline(never)]
626pub fn sh_if_else(cond:ShExpr, then_branch:ShBlock, else_branch:ShExpr)->ShExpr{
627 ShExpr::ShIf(ShIf{
628 cond:Box::new(cond),
629 then_branch:then_branch,
630 else_branch:Some(Box::new(else_branch))
631 })
632}
633
634#[derive(Clone, Hash, PartialEq)]
635pub struct ShWhile {
636 pub cond: Box<ShExpr>,
637 pub body: ShBlock,
638}
639
640#[inline(never)]
641pub fn sh_while(cond:ShExpr, body:ShBlock)->ShExpr{
642 ShExpr::ShWhile(ShWhile{
643 cond:Box::new(cond),
644 body:body
645 })
646}
647
648
649#[derive(Clone, Hash, PartialEq)]
650pub struct ShForLoop {
651 pub iter: String,
652 pub from: Box<ShExpr>,
653 pub to: Box<ShExpr>,
654 pub body: ShBlock
655}
656
657#[inline(never)]
658pub fn sh_for(iter:&str, from_ts:ShExpr, to_ts:ShExpr, body:ShBlock)->ShExpr{
659 ShExpr::ShForLoop(ShForLoop{
660 iter:iter.to_string(),
661 from:Box::new(from_ts),
662 to:Box::new(to_ts),
663 body:body
664 })
665}
666
667#[derive(Clone, Hash, PartialEq)]
668pub struct ShReturn {
669 pub expr: Option<Box<ShExpr>>
670}
671
672#[inline(never)]
673pub fn sh_ret(expr:ShExpr)->ShExpr{
674 ShExpr::ShReturn(ShReturn{
675 expr:Some(Box::new(expr)),
676 })
677}
678
679#[inline(never)]
680pub fn sh_retn()->ShExpr{
681 ShExpr::ShReturn(ShReturn{
682 expr:None
683 })
684}
685
686
687#[derive(Clone, Hash, PartialEq)]
688pub struct ShBreak {
689}
690
691#[derive(Clone, Hash, PartialEq)]
692pub struct ShContinue {
693}
694
695#[derive(Clone, Hash, PartialEq)]
696pub struct ShLet {
697 pub name: String,
698 pub ty: String,
699 pub init: Box<ShExpr>
700}
701
702
703#[inline(never)]
704pub fn sh_let(name:&str, ty:&str, init:ShExpr)->ShStmt{
705 ShStmt::ShLet(ShLet{
706 name:name.to_string(),
707 ty:ty.to_string(),
708 init:Box::new(init)
709 })
710}
711
712#[derive(Clone)]
713pub struct Sl {
714 pub sl: String,
715 pub ty: String
716}
717
718#[derive(Clone)]
719pub struct SlErr {
720 pub msg: String
721}
722
723pub struct SlDecl {
724 pub name: String,
725 pub ty: String
726}
727
728#[derive(Clone)]
729pub enum SlTarget {
730 Pixel,
731 Vertex,
732 Constant
733}
734
735pub struct SlCx<'a> {
736 pub depth: usize,
737 pub target: SlTarget,
738 pub defargs_fn: String,
739 pub defargs_call: String,
740 pub call_prefix: String,
741 pub shader_gen: &'a ShaderGen,
742 pub scope: Vec<SlDecl>,
743 pub fn_deps: Vec<String>,
744 pub fn_done: Vec<Sl>,
745 pub auto_vary: Vec<ShVar>
746}
747
748pub enum MapCallResult {
749 Rename(String),
750 Rewrite(String, String),
751 None
752}
753
754impl<'a> SlCx<'a> {
755 pub fn scan_scope(&self, name: &str) -> Option<&str> {
756 if let Some(decl) = self.scope.iter().find( | i | i.name == name) {
757 return Some(&decl.ty);
758 }
759 None
760 }
761 pub fn get_type(&self, name: &str) -> Result<&ShType,
762 SlErr> {
763 if let Some(ty) = self.shader_gen.find_type(name) {
764 return Ok(ty);
765 }
766 Err(SlErr {msg: format!("Cannot find type {}", name)})
767 }
768}
769
770impl ShExpr {
771 pub fn sl(&self, slcx: &mut SlCx) -> Result<Sl, SlErr> {
772 match self {
773 ShExpr::ShId(x) => x.sl(slcx),
774 ShExpr::ShLit(x) => x.sl(slcx),
775 ShExpr::ShAssign(x) => x.sl(slcx),
776 ShExpr::ShCall(x) => x.sl(slcx),
777 ShExpr::ShBinary(x) => x.sl(slcx),
778 ShExpr::ShUnary(x) => x.sl(slcx),
779 ShExpr::ShAssignOp(x) => x.sl(slcx),
780 ShExpr::ShIf(x) => x.sl(slcx),
781 ShExpr::ShWhile(x) => x.sl(slcx),
782 ShExpr::ShForLoop(x) => x.sl(slcx),
783 ShExpr::ShBlock(x) => x.sl(slcx),
784 ShExpr::ShField(x) => x.sl(slcx),
785 ShExpr::ShIndex(x) => x.sl(slcx),
786 ShExpr::ShParen(x) => x.sl(slcx),
787 ShExpr::ShReturn(x) => x.sl(slcx),
788 ShExpr::ShBreak(x) => x.sl(slcx),
789 ShExpr::ShContinue(x) => x.sl(slcx),
790 }
791 }
792}
793
794
795impl ShId {
796 pub fn sl(&self, slcx: &mut SlCx) -> Result<Sl, SlErr> {
797 if let Some(ty) = slcx.scan_scope(&self.name) {
799 Ok(Sl {sl: self.name.to_string(), ty: ty.to_string()})
800 }
801 else if let Some(cnst) = slcx.shader_gen.find_const(&self.name) {
802 Ok(Sl {sl: self.name.to_string(), ty: cnst.ty.to_string()})
803 }
804 else if let Some(var) = slcx.shader_gen.find_var(&self.name) {
805 Ok(Sl {sl: slcx.map_var(var), ty: var.ty.to_string()})
806 }
807 else { Err(SlErr {
809 msg: format!("Id {} not resolved, is it declared?", self.name)
810 })
811 }
812 }
813}
814
815impl ShLit {
816 pub fn sl(&self, _slcx: &mut SlCx) -> Result<Sl, SlErr> {
817 match self {
819 ShLit::Int(val) => {
820 Ok(Sl {sl: format!("{}", val), ty: "int".to_string()})
821 }
822 ShLit::Str(val) => {
823 Ok(Sl {sl: format!("{}", val), ty: "string".to_string()})
824 }
825 ShLit::Float(val) => {
826 if val.ceil() == *val {
827 Ok(Sl {sl: format!("{}.0", val), ty: "float".to_string()})
828 }
829 else {
830 Ok(Sl {sl: format!("{}", val), ty: "float".to_string()})
831 }
832 }
833 ShLit::Bool(val) => {
834 Ok(Sl {sl: format!("{}", val), ty: "bool".to_string()})
835 }
836 }
837 }
838}
839
840impl ShField {
841 pub fn sl(&self, slcx: &mut SlCx) -> Result<Sl, SlErr> {
842 let base = self.base.sl(slcx) ?;
843 let shty = slcx.get_type(&base.ty) ?;
845 if let Some(field) = shty.fields.iter().find( | i | i.name == self.member) {
847 Ok(Sl {
848 sl: format!("{}.{}", base.sl, self.member),
849 ty: field.ty.to_string()
850 })
851 }
852 else {
853 let mut mode = 0;
854 let slots = shty.slots;
855
856 if shty.name != "float" && shty.name != "vec2" && shty.name != "vec3" && shty.name != "vec4" {
857 return Err(SlErr {
858 msg: format!("member {} not found {}", self.member, base.ty)
859 })
860 }
861 if self.member.len() >4 {
862 return Err(SlErr {
863 msg: format!("member {} not found or a valid swizzle of {} {}", self.member, base.ty, base.sl)
864 })
865 }
866 for chr in self.member.chars() {
867 if chr == 'x' || chr == 'y' || chr == 'z' || chr == 'w' {
868 if chr == 'y' && slots<2 {mode = 3;}
869 else if chr == 'z' && slots<3 {mode = 3;}
870 else if chr == 'w' && slots<4 {mode = 3;};
871 if mode == 0 {mode = 1;}
872 else if mode != 1 {
873 return Err(SlErr {
874 msg: format!("member {} not a valid swizzle of {} {}", self.member, base.ty, base.sl)
875 })
876 }
877 }
878 else if chr == 'r' || chr == 'g' || chr == 'b' || chr == 'a' {
879 if chr == 'r' && slots<2 {mode = 3;}
880 else if chr == 'g' && slots<3 {mode = 3;}
881 else if chr == 'b' && slots<4 {mode = 3;};
882 if mode == 0 {mode = 2;}
883 else if mode != 2 {
884 return Err(SlErr {
885 msg: format!("member {} not a valid swizzle of {} {}", self.member, base.ty, base.sl)
886 })
887 }
888 }
889 }
890
891 match self.member.len() {
892 1 => return Ok(Sl {
893 sl: format!("{}.{}", base.sl, self.member),
894 ty: "float".to_string()
895 }),
896 2 => return Ok(Sl {
897 sl: format!("{}.{}", base.sl, self.member),
898 ty: "vec2".to_string()
899 }),
900 3 => return Ok(Sl {
901 sl: format!("{}.{}", base.sl, self.member),
902 ty: "vec3".to_string()
903 }),
904 4 => return Ok(Sl {
905 sl: format!("{}.{}", base.sl, self.member),
906 ty: "vec4".to_string()
907 }),
908 _ => Err(SlErr {
909 msg: format!("member {} not cannot be found on type {} {}", self.member, base.ty, base.sl)
910 })
911 }
912 }
913 }
914}
915
916impl ShIndex {
917 pub fn sl(&self, slcx: &mut SlCx) -> Result<Sl, SlErr> {
918 let base = self.base.sl(slcx) ?;
919 let index = self.index.sl(slcx) ?;
920 if base.ty != "vec2" && base.ty != "vec3" && base.ty != "vec4" {
922 Err(SlErr {
923 msg: format!("index on unsupported type {}", base.ty)
924 })
925 }
926 else {
927 Ok(Sl {
928 sl: format!("{}[{}]", base.sl, index.sl),
929 ty: "float".to_string()
930 })
931 }
932 }
933}
934
935impl ShAssign {
936 pub fn sl(&self, slcx: &mut SlCx) -> Result<Sl, SlErr> {
937 let left = self.left.sl(slcx) ?;
940 let right = self.right.sl(slcx) ?;
941 if left.ty != right.ty {
942 Err(SlErr {
943 msg: format!("Left type {} not the same as right {} in assign {}={}", left.ty, right.ty, left.sl, right.sl)
944 })
945 }
946 else {
947 Ok(Sl {
948 sl: format!("{} = {}", left.sl, right.sl),
949 ty: left.ty
950 })
951 }
952 }
953}
954
955impl ShAssignOp {
956 pub fn sl(&self, slcx: &mut SlCx) -> Result<Sl, SlErr> {
957 let left = self.left.sl(slcx) ?;
958 let right = self.right.sl(slcx) ?;
959
960 if left.ty != right.ty {
961 Err(SlErr {
962 msg: format!("Left type {} not the same as right {} in assign op {}{}{}", left.ty, self.op.to_string(), right.ty, left.sl, right.sl)
963 })
964 }
965 else {
966 Ok(Sl {
967 sl: format!("{}{}{}", left.sl, self.op.to_string(), right.sl),
968 ty: left.ty
969 })
970 }
971 }
972}
973
974impl ShBinary {
975 pub fn sl(&self, slcx: &mut SlCx) -> Result<Sl, SlErr> {
976 let left = self.left.sl(slcx) ?;
977 let right = self.right.sl(slcx) ?;
978 if left.ty != right.ty {
979 if left.ty == "float" && (right.ty == "vec2" || right.ty == "vec3" || right.ty == "vec4") {
980 Ok(Sl {
981 sl: format!("{}{}{}", left.sl, self.op.to_string(), right.sl),
982 ty: right.ty
983 })
984 }
985 else if right.ty == "float" && (left.ty == "vec2" || left.ty == "vec3" || left.ty == "vec4") {
986 Ok(Sl {
987 sl: format!("{}{}{}", left.sl, self.op.to_string(), right.sl),
988 ty: left.ty
989 })
990 }
991 else if right.ty == "mat4" && left.ty == "vec4" {
992 Ok(Sl {
993 sl: slcx.mat_mul(&left.sl, &right.sl),
994 ty: left.ty
995 })
996 }
997 else if right.ty == "mat3" && left.ty == "vec3" {
998 Ok(Sl {
999 sl: slcx.mat_mul(&left.sl, &right.sl),
1000 ty: left.ty
1001 })
1002 }
1003 else if right.ty == "mat2" && left.ty == "vec2" {
1004 Ok(Sl {
1005 sl: slcx.mat_mul(&left.sl, &right.sl),
1006 ty: left.ty
1007 })
1008 }
1009 else if left.ty == "mat4" && right.ty == "vec4" {
1010 Ok(Sl {
1011 sl: slcx.mat_mul(&left.sl, &right.sl),
1012 ty: right.ty
1013 })
1014 }
1015 else if left.ty == "mat3" && right.ty == "vec3" {
1016 Ok(Sl {
1017 sl: slcx.mat_mul(&left.sl, &right.sl),
1018 ty: right.ty
1019 })
1020 }
1021 else if left.ty == "mat2" && right.ty == "vec2" {
1022 Ok(Sl {
1023 sl: slcx.mat_mul(&left.sl, &right.sl),
1024 ty: right.ty
1025 })
1026 }
1027 else {
1028 Err(SlErr {
1029 msg: format!("Left type {} not the same as right {} in binary op {}{}{}", left.ty, right.ty, left.sl, self.op.to_string(), right.sl)
1030 })
1031 }
1032 }
1033 else {
1034 if left.ty == "mat4" || left.ty == "mat3" || left.ty == "mat2" {
1035 Ok(Sl {
1036 sl: slcx.mat_mul(&left.sl, &right.sl),
1037 ty: left.ty
1038 })
1039
1040 }
1041 else {
1042 Ok(Sl {
1043 sl: format!("{}{}{}", left.sl, self.op.to_string(), right.sl),
1044 ty: left.ty
1045 })
1046 }
1047 }
1048 }
1049}
1050
1051impl ShUnary {
1052 pub fn sl(&self, slcx: &mut SlCx) -> Result<Sl, SlErr> {
1053 let expr = self.expr.sl(slcx) ?;
1054 Ok(Sl {
1055 sl: format!("{}{}", self.op.to_string(), expr.sl),
1056 ty: expr.ty
1057 })
1058 }
1059}
1060
1061impl ShParen {
1062 pub fn sl(&self, slcx: &mut SlCx) -> Result<Sl, SlErr> {
1063 let expr = self.expr.sl(slcx) ?;
1064 Ok(Sl {
1065 sl: format!("({})", expr.sl),
1066 ty: expr.ty
1067 })
1068 }
1069}
1070
1071impl ShBlock {
1072 pub fn sl(&self, slcx: &mut SlCx) -> Result<Sl, SlErr> {
1073 let mut sl = String::new();
1074 sl.push_str("{\n");
1075 slcx.depth += 1;
1076 for stmt in &self.stmts {
1077 for _i in 0..slcx.depth {
1078 sl.push_str(" ");
1079 }
1080 match stmt {
1081 ShStmt::ShLet(stmt) => {
1082 let out = stmt.sl(slcx) ?;
1083 sl.push_str(&out.sl);
1084 },
1085 ShStmt::ShExpr(stmt) => {
1086 let out = stmt.sl(slcx) ?;
1087 sl.push_str(&out.sl);
1088 }
1089 ShStmt::ShSemi(stmt) => {
1090 let out = stmt.sl(slcx) ?;
1091 sl.push_str(&out.sl);
1092 }
1093 }
1094 sl.push_str(";\n");
1095 }
1096 slcx.depth -= 1;
1097 sl.push_str("}");
1098 Ok(Sl {
1099 sl: sl,
1100 ty: "void".to_string()
1101 })
1102 }
1103}
1104
1105impl ShCall {
1106 pub fn sl(&self, slcx: &mut SlCx) -> Result<Sl, SlErr> {
1107 let mut out = String::new();
1109 if let Some(shfn) = slcx.shader_gen.find_fn(&self.call) {
1110 let mut defargs_call = "".to_string();
1111
1112 if let Some(_block) = &shfn.block { let index = slcx.fn_deps.iter().position( | i | **i == self.call);
1114 if let Some(index) = index {
1115 slcx.fn_deps.remove(index);
1116 }
1117 slcx.fn_deps.push(self.call.clone());
1118 defargs_call = slcx.defargs_call.to_string();
1119 out.push_str(&slcx.call_prefix);
1120 };
1121
1122
1123 let mut gen_t = "".to_string();
1125
1126 let mut args_gl = Vec::new();
1127 for arg in &self.args {
1129 let arg_gl = arg.sl(slcx) ?;
1130 args_gl.push(arg_gl);
1131 };
1132
1133 let map_call = slcx.map_call(&self.call, &args_gl);
1134 let ret_ty;
1135
1136 if let MapCallResult::Rewrite(rewrite, rty) = map_call {
1137 out.push_str(&rewrite);
1138 ret_ty = rty;
1139 }
1140 else {
1141 if let MapCallResult::Rename(name) = map_call {
1142 out.push_str(&name);
1143 }
1144 else {
1145 out.push_str(&self.call);
1146 }
1147 out.push_str("(");
1148
1149 for (i, arg_gl) in args_gl.iter().enumerate() {
1151 let in_ty = arg_gl.ty.clone();
1153 if i != 0 {
1154 out.push_str(", ");
1155 }
1156 out.push_str(&arg_gl.sl);
1157 if i >= shfn.args.len() {
1159 return Err(SlErr {
1160 msg: format!("Too many function arguments for call {} got:{} can use:{}", self.call, i + 1, shfn.args.len())
1161 })
1162 }
1163 let fnarg = &shfn.args[i];
1165 if fnarg.ty == "T" {
1167 if gen_t != "" && gen_t != in_ty {
1169 return Err(SlErr {
1170 msg: format!("Function type T incorrectly redefined for call {} type was {} given {} for arg {}", self.call, gen_t, in_ty, i)
1171 })
1172 }
1173 gen_t = in_ty;
1174 }
1175 else if fnarg.ty == "F" { if in_ty != "float" && in_ty != "vec2" && in_ty != "vec3" && in_ty != "vec4" {
1177 return Err(SlErr {
1178 msg: format!("Function type F is not a float-ty type for call {} for arg {} type {}", self.call, i, in_ty)
1179 })
1180 }
1181 }
1182 else if fnarg.ty == "B" { if in_ty != "bool" && in_ty != "bvec2" && in_ty != "bvec3" && in_ty != "bvec4" {
1184 return Err(SlErr {
1185 msg: format!("Function arg is not a bool-ty type for call {} for arg {} type {}", self.call, i, in_ty)
1186 })
1187 }
1188 gen_t = in_ty;
1189 }
1190 else if fnarg.ty != in_ty {
1191 return Err(SlErr {
1192 msg: format!("Arg wrong type for call {} for arg {} expected type {} got type {}", self.call, i, fnarg.ty, in_ty)
1193 })
1194 }
1195 }
1196 if self.args.len() < shfn.args.len() {
1199 for i in self.args.len()..shfn.args.len() {
1200 let fnarg = &shfn.args[i];
1201 if fnarg.ty != "O" {
1202 return Err(SlErr {
1203 msg: format!("Not enough args for call {} not enough args provided at {}, possible {}", self.call, i, shfn.args.len())
1204 })
1205 }
1206 }
1207 };
1208 ret_ty = if shfn.ret == "T" || shfn.ret == "B" {
1209 gen_t
1210 }
1211 else {
1212 shfn.ret.clone()
1213 };
1214 if defargs_call.len() != 0 {
1215 if self.args.len() != 0 {
1216 out.push_str(", ");
1217 }
1218 out.push_str(&defargs_call);
1219 }
1220 out.push_str(")");
1221 }
1222 Ok(Sl {
1227 sl: out,
1228 ty: ret_ty
1229 })
1230 }
1231 else {
1232 if let Some(slty) = slcx.shader_gen.find_type(&self.call) {
1234
1235 let mut args = Vec::new();
1238
1239 let mut arg_slots = 0;
1241 for arg in &self.args {
1242 let arg_sl = arg.sl(slcx) ?;
1243 if let Some(arg_ty) = slcx.shader_gen.find_type(&arg_sl.ty) {
1244 arg_slots += arg_ty.slots;
1245 }
1246 else{
1247 return Err(SlErr {
1248 msg: format!("Cannot find constructor arg type {}", arg_sl.ty)
1249 })
1250 }
1251 args.push(arg_sl);
1252 }
1253 if arg_slots > slty.slots{
1254 let mut out = String::new();
1255 out.push_str(&self.call);
1256 out.push_str("(");
1257 for (i,arg) in args.iter().enumerate(){
1258 if i != 0{
1259 out.push_str(", ")
1260 }
1261 out.push_str(&arg.sl);
1262 }
1263 out.push_str(")");
1264 return Err(SlErr {
1265 msg: format!("Constructor slots don't match given {} need {} - {}", arg_slots, slty.slots, out)
1266 })
1267 }
1268
1269 out.push_str(&slcx.map_constructor(&self.call, &args));
1273 Ok(Sl {
1274 sl: out,
1275 ty: slty.name.clone()
1276 })
1277 }
1278 else {
1279 Err(SlErr {
1280 msg: format!("Cannot find function {}", self.call)
1281 })
1282 }
1283 }
1284
1285 }
1286}
1287
1288impl ShIf {
1289 pub fn sl(&self, cx: &mut SlCx) -> Result<Sl, SlErr> {
1290 let mut out = "".to_string();
1291 out.push_str("if(");
1292 let cond = self.cond.sl(cx) ?;
1293 out.push_str(&cond.sl);
1294 out.push_str(")");
1295
1296 let then = self.then_branch.sl(cx) ?;
1297
1298 out.push_str(&then.sl);
1299 if let Some(else_branch) = &self.else_branch {
1300 let else_gl = else_branch.sl(cx) ?;
1301 out.push_str("else ");
1302 out.push_str(&else_gl.sl);
1303 }
1304
1305 Ok(Sl {
1306 sl: out,
1307 ty: "void".to_string()
1308 })
1309 }
1310}
1311
1312impl ShWhile {
1313 pub fn sl(&self, cx: &mut SlCx) -> Result<Sl, SlErr> {
1314 let mut out = "".to_string();
1315 out.push_str("while(");
1316 let cond = self.cond.sl(cx) ?;
1317 out.push_str(&cond.sl);
1318 out.push_str(")");
1319
1320 let body = self.body.sl(cx) ?;
1321
1322 out.push_str(&body.sl);
1323
1324 Ok(Sl {
1325 sl: out,
1326 ty: "void".to_string()
1327 })
1328 }
1329}
1330
1331impl ShForLoop {
1332 pub fn sl(&self, cx: &mut SlCx) -> Result<Sl, SlErr> {
1333 let mut out = "".to_string();
1334
1335 out.push_str("for(int ");
1336 out.push_str(&self.iter);
1337 out.push_str("=");
1338
1339 let from = self.from.sl(cx) ?;
1340 out.push_str(&from.sl);
1341
1342 out.push_str(";");
1343 out.push_str(&self.iter);
1344 out.push_str(" < ");
1345
1346 let to = self.to.sl(cx) ?;
1347 out.push_str(&to.sl);
1348
1349 out.push_str(";");
1350 out.push_str(&self.iter);
1351 out.push_str("++)");
1352
1353 let body = self.body.sl(cx) ?;
1354
1355 out.push_str(&body.sl);
1356
1357 Ok(Sl {
1358 sl: out,
1359 ty: "void".to_string()
1360 })
1361 }
1362}
1363
1364impl ShReturn {
1365 pub fn sl(&self, cx: &mut SlCx) -> Result<Sl, SlErr> {
1366 let mut out = "".to_string();
1367 if let Some(expr) = &self.expr {
1368 let expr_gl = expr.sl(cx) ?;
1369 out.push_str("return ");
1370 out.push_str(&expr_gl.sl);
1371 }
1372 else {
1373 out.push_str("return;");
1374 }
1375 Ok(Sl {
1376 sl: out,
1377 ty: "void".to_string()
1378 })
1379 }
1380}
1381
1382impl ShBreak {
1383 pub fn sl(&self, _cx: &mut SlCx) -> Result<Sl, SlErr> {
1384 Ok(Sl {
1385 sl: "break".to_string(),
1386 ty: "void".to_string()
1387 })
1388 }
1389}
1390
1391impl ShContinue {
1392 pub fn sl(&self, _cx: &mut SlCx) -> Result<Sl, SlErr> {
1393 Ok(Sl {
1394 sl: "continue".to_string(),
1395 ty: "void".to_string()
1396 })
1397 }
1398}
1399
1400impl ShLet {
1401 pub fn sl(&self, cx: &mut SlCx) -> Result<Sl, SlErr> {
1402 let mut out = "".to_string();
1403 let init = self.init.sl(cx) ?;
1404
1405 let ty = init.ty.clone();
1406 if self.ty != "" && self.ty != init.ty {
1407 return Err(SlErr {
1408 msg: format!("Let definition {} type {} is different from initializer {}", self.name, self.ty, init.ty)
1409 })
1410 }
1411
1412 out.push_str(&cx.map_type(&ty));
1413 out.push_str(" ");
1414 out.push_str(&self.name);
1415 out.push_str(" = ");
1416
1417 cx.scope.push(SlDecl {
1419 name: self.name.clone(),
1420 ty: init.ty.clone()
1421 });
1422
1423 out.push_str(&init.sl);
1424 Ok(Sl {
1425 sl: out,
1426 ty: "void".to_string()
1427 })
1428 }
1429}
1430
1431impl ShFn {
1432 pub fn sl(&self, cx: &mut SlCx) -> Result<Sl, SlErr> {
1433 let mut out = "".to_string();
1434 out.push_str(&cx.map_type(&self.ret));
1435 out.push_str(" ");
1436 out.push_str(&cx.call_prefix);
1437 out.push_str(&self.name);
1438 out.push_str("(");
1439 for (i, arg) in self.args.iter().enumerate() {
1440 if i != 0 {
1441 out.push_str(", ");
1442 }
1443 out.push_str(&cx.map_type(&arg.ty));
1444 out.push_str(" ");
1445 out.push_str(&arg.name);
1446 cx.scope.push(SlDecl {
1447 name: arg.name.clone(),
1448 ty: arg.ty.clone()
1449 });
1450 };
1451 if cx.defargs_fn.len() != 0 {
1452 if self.args.len() != 0 {
1453 out.push_str(", ");
1454 }
1455 out.push_str(&cx.defargs_fn);
1456 }
1457 out.push_str(")");
1458 if let Some(block) = &self.block {
1459 let block = block.sl(cx) ?;
1460 out.push_str(&block.sl);
1461 };
1462 Ok(Sl {
1463 sl: out,
1464 ty: self.name.clone()
1465 })
1466 }
1467}
1468
1469pub fn assemble_fn_and_deps(sg: &ShaderGen, cx: &mut SlCx) -> Result<String, SlErr> {
1470
1471 let mut fn_local = Vec::new();
1472 loop {
1473
1474 let fn_not_done = cx.fn_deps.iter().find( | cxfn | {
1476 if let Some(_done) = cx.fn_done.iter().find( | i | i.ty == **cxfn) {
1477 false
1478 }
1479 else {
1480 true
1481 }
1482 });
1483 if let Some(fn_not_done) = fn_not_done {
1485 let fn_name = fn_not_done.clone();
1486 let fn_to_do = sg.find_fn(&fn_name);
1487 if let Some(fn_to_do) = fn_to_do {
1488 cx.scope.clear();
1489 let result = fn_to_do.sl(cx) ?;
1490 cx.fn_done.push(result.clone());
1491 fn_local.push((fn_name, result.clone()));
1492 }
1493 else {
1494 return Err(SlErr {msg: format!("Cannot find entry function {}", fn_not_done)})
1495 }
1496 }
1497 else {
1498 break;
1499 }
1500 }
1501 let mut out = String::new();
1503 for dep in cx.fn_deps.iter().rev() {
1504 if let Some((_, fnd)) = fn_local.iter().find( | (name, _) | name == dep) {
1505 out.push_str(&fnd.sl);
1506 out.push_str("\n");
1507 }
1508 };
1509 Ok(out)
1510}
1511
1512pub fn assemble_const_init(cnst: &ShConst, cx: &mut SlCx) -> Result<Sl, SlErr> {
1513 let result = cnst.value.sl(cx) ?;
1515 if cx.fn_deps.len() > 0 {
1516 return Err(SlErr {msg: "Const cant have function call deps".to_string()});
1517 }
1518 return Ok(result)
1519}
1520