|  |  |  | @ -145,6 +145,7 @@ fn fix_name(name: &String) -> String { | 
			
		
	
		
			
				
					|  |  |  |  |             .replace("-", "_") | 
			
		
	
		
			
				
					|  |  |  |  |             .replace("*", "p") | 
			
		
	
		
			
				
					|  |  |  |  |             .replace("<>", "void") | 
			
		
	
		
			
				
					|  |  |  |  |             .replace(".", "_") | 
			
		
	
		
			
				
					|  |  |  |  |     ) | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -223,9 +224,26 @@ pub fn spirv_meta(module: &mut Module) -> Vec<(Option<String>, Vec<String>)> { | 
			
		
	
		
			
				
					|  |  |  |  |             ], | 
			
		
	
		
			
				
					|  |  |  |  |         )); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     for global in module.globals.clone() { | 
			
		
	
		
			
				
					|  |  |  |  |         let name: String = fix_name(&global.name); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         for dec in global.decorations { | 
			
		
	
		
			
				
					|  |  |  |  |             // Decorations have the format Location 0, or Builtin FragCoord
 | 
			
		
	
		
			
				
					|  |  |  |  |             let dec = match dec { | 
			
		
	
		
			
				
					|  |  |  |  |                 crate::compiler::Decoration::Location(loc) => format!("Location {}", loc), | 
			
		
	
		
			
				
					|  |  |  |  |                 crate::compiler::Decoration::BuiltIn(builtin) => { | 
			
		
	
		
			
				
					|  |  |  |  |                     let builtin = match builtin { | 
			
		
	
		
			
				
					|  |  |  |  |                         crate::compiler::BuiltinDecoration::FragCoord => "FragCoord", | 
			
		
	
		
			
				
					|  |  |  |  |                     }; | 
			
		
	
		
			
				
					|  |  |  |  |                     format!("BuiltIn {}", builtin) | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |             }; | 
			
		
	
		
			
				
					|  |  |  |  |             ops.push((None, vec!["OpDecorate".to_string(), name.clone(), dec])); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     for global in module.globals.clone() { | 
			
		
	
		
			
				
					|  |  |  |  |         let name = fix_name(&global.name); | 
			
		
	
		
			
				
					|  |  |  |  |         let name: String = fix_name(&global.name); | 
			
		
	
		
			
				
					|  |  |  |  |         let _typ = global.typ; | 
			
		
	
		
			
				
					|  |  |  |  |         let storage_class = match global.storage_class { | 
			
		
	
		
			
				
					|  |  |  |  |             crate::compiler::StorageClass::Input => "Input", | 
			
		
	
	
		
			
				
					|  |  |  | @ -248,19 +266,6 @@ pub fn spirv_meta(module: &mut Module) -> Vec<(Option<String>, Vec<String>)> { | 
			
		
	
		
			
				
					|  |  |  |  |                 storage_class.to_string(), | 
			
		
	
		
			
				
					|  |  |  |  |             ], | 
			
		
	
		
			
				
					|  |  |  |  |         )); | 
			
		
	
		
			
				
					|  |  |  |  |         for dec in global.decorations { | 
			
		
	
		
			
				
					|  |  |  |  |             // Decorations have the format Location 0, or Builtin FragCoord
 | 
			
		
	
		
			
				
					|  |  |  |  |             let dec = match dec { | 
			
		
	
		
			
				
					|  |  |  |  |                 crate::compiler::Decoration::Location(loc) => format!("Location {}", loc), | 
			
		
	
		
			
				
					|  |  |  |  |                 crate::compiler::Decoration::BuiltIn(builtin) => { | 
			
		
	
		
			
				
					|  |  |  |  |                     let builtin = match builtin { | 
			
		
	
		
			
				
					|  |  |  |  |                         crate::compiler::BuiltinDecoration::FragCoord => "FragCoord", | 
			
		
	
		
			
				
					|  |  |  |  |                     }; | 
			
		
	
		
			
				
					|  |  |  |  |                     format!("BuiltIn {}", builtin) | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |             }; | 
			
		
	
		
			
				
					|  |  |  |  |             ops.push((None, vec!["OpDecorate".to_string(), name.clone(), dec])); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     for fun in module.functions.clone() { | 
			
		
	
	
		
			
				
					|  |  |  | @ -337,6 +342,7 @@ fn compile_biop( | 
			
		
	
		
			
				
					|  |  |  |  |     counter: &mut i32, | 
			
		
	
		
			
				
					|  |  |  |  |     stack: &mut Vec<String>, | 
			
		
	
		
			
				
					|  |  |  |  |     out: &mut Vec<(Option<String>, String)>, | 
			
		
	
		
			
				
					|  |  |  |  |     typ: &str, | 
			
		
	
		
			
				
					|  |  |  |  | ) { | 
			
		
	
		
			
				
					|  |  |  |  |     assert!(lst.len() == 2); | 
			
		
	
		
			
				
					|  |  |  |  |     let rhs = lst.pop().unwrap(); | 
			
		
	
	
		
			
				
					|  |  |  | @ -352,7 +358,7 @@ fn compile_biop( | 
			
		
	
		
			
				
					|  |  |  |  |         format!( | 
			
		
	
		
			
				
					|  |  |  |  |             "{} {} {} {}", | 
			
		
	
		
			
				
					|  |  |  |  |             op, | 
			
		
	
		
			
				
					|  |  |  |  |             fix_name(&String::from("f32")), | 
			
		
	
		
			
				
					|  |  |  |  |             fix_name(&String::from(typ)), | 
			
		
	
		
			
				
					|  |  |  |  |             fix_name(&lhs_id), | 
			
		
	
		
			
				
					|  |  |  |  |             fix_name(&rhs_id), | 
			
		
	
		
			
				
					|  |  |  |  |         ), | 
			
		
	
	
		
			
				
					|  |  |  | @ -360,6 +366,68 @@ fn compile_biop( | 
			
		
	
		
			
				
					|  |  |  |  |     stack.push(id); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | fn compile_comp_constr( | 
			
		
	
		
			
				
					|  |  |  |  |     lst: &mut Vec<Ast>, | 
			
		
	
		
			
				
					|  |  |  |  |     vars: &mut Vec<(String, String)>, | 
			
		
	
		
			
				
					|  |  |  |  |     constants: &mut Vec<(String, String)>, | 
			
		
	
		
			
				
					|  |  |  |  |     types: &mut Vec<String>, | 
			
		
	
		
			
				
					|  |  |  |  |     counter: &mut i32, | 
			
		
	
		
			
				
					|  |  |  |  |     stack: &mut Vec<String>, | 
			
		
	
		
			
				
					|  |  |  |  |     out: &mut Vec<(Option<String>, String)>, | 
			
		
	
		
			
				
					|  |  |  |  |     typ: &str, | 
			
		
	
		
			
				
					|  |  |  |  | ) { | 
			
		
	
		
			
				
					|  |  |  |  |     types.push(String::from(typ)); | 
			
		
	
		
			
				
					|  |  |  |  |     let typ_parsed = parse_type(&String::from(typ)); | 
			
		
	
		
			
				
					|  |  |  |  |     match typ_parsed { | 
			
		
	
		
			
				
					|  |  |  |  |         Type::Vector(_, size) => { | 
			
		
	
		
			
				
					|  |  |  |  |             assert!(lst.len() == size as usize); | 
			
		
	
		
			
				
					|  |  |  |  |             let mut inners: Vec<String> = vec![]; | 
			
		
	
		
			
				
					|  |  |  |  |             for _ in 0..size { | 
			
		
	
		
			
				
					|  |  |  |  |                 let ast = lst.pop().unwrap(); | 
			
		
	
		
			
				
					|  |  |  |  |                 compile_ast_ssa(ast, vars, constants, types, counter, stack, out); | 
			
		
	
		
			
				
					|  |  |  |  |                 let res_id = stack.pop().unwrap(); | 
			
		
	
		
			
				
					|  |  |  |  |                 inners.push(res_id); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |             let id = String::from(counter.to_string()); | 
			
		
	
		
			
				
					|  |  |  |  |             *counter += 1; | 
			
		
	
		
			
				
					|  |  |  |  |             let mut out_str = String::new(); | 
			
		
	
		
			
				
					|  |  |  |  |             out_str.push_str( | 
			
		
	
		
			
				
					|  |  |  |  |                 format!("OpCompositeConstruct {}", fix_name(&String::from(typ))).as_str(), | 
			
		
	
		
			
				
					|  |  |  |  |             ); | 
			
		
	
		
			
				
					|  |  |  |  |             inners.reverse(); | 
			
		
	
		
			
				
					|  |  |  |  |             for inn in inners { | 
			
		
	
		
			
				
					|  |  |  |  |                 out_str.push_str(format!(" {}", fix_name(&inn)).as_str()); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |             out.push((Some(id.clone()), out_str)); | 
			
		
	
		
			
				
					|  |  |  |  |             stack.push(id); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |         _ => { | 
			
		
	
		
			
				
					|  |  |  |  |             panic!("Invalid vector!") | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | fn compile_comp_extract(    lst: &mut Vec<Ast>, | 
			
		
	
		
			
				
					|  |  |  |  |     vars: &mut Vec<(String, String)>, | 
			
		
	
		
			
				
					|  |  |  |  |     constants: &mut Vec<(String, String)>, | 
			
		
	
		
			
				
					|  |  |  |  |     types: &mut Vec<String>, | 
			
		
	
		
			
				
					|  |  |  |  |     counter: &mut i32, | 
			
		
	
		
			
				
					|  |  |  |  |     stack: &mut Vec<String>, | 
			
		
	
		
			
				
					|  |  |  |  |     out: &mut Vec<(Option<String>, String)>, | 
			
		
	
		
			
				
					|  |  |  |  |     typ: &str, inx: u32) { | 
			
		
	
		
			
				
					|  |  |  |  |     assert!(lst.len() == 1); | 
			
		
	
		
			
				
					|  |  |  |  |     let vec = lst.pop().unwrap(); | 
			
		
	
		
			
				
					|  |  |  |  |     compile_ast_ssa(vec, vars, constants, types, counter, stack, out); | 
			
		
	
		
			
				
					|  |  |  |  |     let vec_id = stack.pop().unwrap(); | 
			
		
	
		
			
				
					|  |  |  |  |     let id = counter.to_string(); | 
			
		
	
		
			
				
					|  |  |  |  |     *counter += 1; | 
			
		
	
		
			
				
					|  |  |  |  |     out.push(( | 
			
		
	
		
			
				
					|  |  |  |  |         Some(id.clone()), | 
			
		
	
		
			
				
					|  |  |  |  |         format!("OpCompositeExtract {} {} {}", fix_name(&String::from(typ)), fix_name(&vec_id), inx), | 
			
		
	
		
			
				
					|  |  |  |  |     )); | 
			
		
	
		
			
				
					|  |  |  |  |     stack.push(id); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | pub fn compile_ast_ssa( | 
			
		
	
		
			
				
					|  |  |  |  |     ast: Ast, | 
			
		
	
		
			
				
					|  |  |  |  |     vars: &mut Vec<(String, String)>, | 
			
		
	
	
		
			
				
					|  |  |  | @ -378,13 +446,82 @@ pub fn compile_ast_ssa( | 
			
		
	
		
			
				
					|  |  |  |  |             let fun_name = fun.symbol(); | 
			
		
	
		
			
				
					|  |  |  |  |             assert!(fun_name.is_some()); | 
			
		
	
		
			
				
					|  |  |  |  |             let fun_name = fun_name.unwrap(); | 
			
		
	
		
			
				
					|  |  |  |  |             if fun_name.starts_with(".") { | 
			
		
	
		
			
				
					|  |  |  |  |                 let to_split = &fun_name[1..fun_name.len()]; | 
			
		
	
		
			
				
					|  |  |  |  |                 let split = to_split.split("-").collect::<Vec<&str>>(); | 
			
		
	
		
			
				
					|  |  |  |  |                 assert!(split.len() == 2); | 
			
		
	
		
			
				
					|  |  |  |  |                 let inx = split[0]; | 
			
		
	
		
			
				
					|  |  |  |  |                 let typ = split[1]; | 
			
		
	
		
			
				
					|  |  |  |  |                 let inx = str::parse::<u32>(inx).expect("Invalid index!"); | 
			
		
	
		
			
				
					|  |  |  |  |                 compile_comp_extract(&mut lst, vars, constants, types, counter, stack, out, typ, inx); | 
			
		
	
		
			
				
					|  |  |  |  |                 return; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if fun_name.starts_with("/") { | 
			
		
	
		
			
				
					|  |  |  |  |                 let typ = &fun_name[1..fun_name.len()]; | 
			
		
	
		
			
				
					|  |  |  |  |                 compile_biop( | 
			
		
	
		
			
				
					|  |  |  |  |                     "OpFDiv", &mut lst, vars, constants, types, counter, stack, out, typ, | 
			
		
	
		
			
				
					|  |  |  |  |                 ); | 
			
		
	
		
			
				
					|  |  |  |  |                 return; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if fun_name.starts_with("*") { | 
			
		
	
		
			
				
					|  |  |  |  |                 let typ = &fun_name[1..fun_name.len()]; | 
			
		
	
		
			
				
					|  |  |  |  |                 compile_biop( | 
			
		
	
		
			
				
					|  |  |  |  |                     "OpFMul", &mut lst, vars, constants, types, counter, stack, out, typ, | 
			
		
	
		
			
				
					|  |  |  |  |                 ); | 
			
		
	
		
			
				
					|  |  |  |  |                 return; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if fun_name.starts_with("+") { | 
			
		
	
		
			
				
					|  |  |  |  |                 let typ = &fun_name[1..fun_name.len()]; | 
			
		
	
		
			
				
					|  |  |  |  |                 compile_biop( | 
			
		
	
		
			
				
					|  |  |  |  |                     "OpFAdd", &mut lst, vars, constants, types, counter, stack, out, typ, | 
			
		
	
		
			
				
					|  |  |  |  |                 ); | 
			
		
	
		
			
				
					|  |  |  |  |                 return; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if fun_name.starts_with("-") { | 
			
		
	
		
			
				
					|  |  |  |  |                 let typ = &fun_name[1..fun_name.len()]; | 
			
		
	
		
			
				
					|  |  |  |  |                 compile_biop( | 
			
		
	
		
			
				
					|  |  |  |  |                     "OpFSub", &mut lst, vars, constants, types, counter, stack, out, typ, | 
			
		
	
		
			
				
					|  |  |  |  |                 ); | 
			
		
	
		
			
				
					|  |  |  |  |                 return; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if fun_name.starts_with("v") { | 
			
		
	
		
			
				
					|  |  |  |  |                 compile_comp_constr( | 
			
		
	
		
			
				
					|  |  |  |  |                     &mut lst, vars, constants, types, counter, stack, out, fun_name.as_str(), | 
			
		
	
		
			
				
					|  |  |  |  |                 ); | 
			
		
	
		
			
				
					|  |  |  |  |                 return; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if fun_name.starts_with("load-ptr-") { | 
			
		
	
		
			
				
					|  |  |  |  |                 let typ = &fun_name[9..fun_name.len()]; | 
			
		
	
		
			
				
					|  |  |  |  |                 assert!(lst.len() == 1); | 
			
		
	
		
			
				
					|  |  |  |  |                 let ptr = lst.pop().unwrap(); | 
			
		
	
		
			
				
					|  |  |  |  |                 compile_ast_ssa(ptr, vars, constants, types, counter, stack, out); | 
			
		
	
		
			
				
					|  |  |  |  |                 let ptr_id = stack.pop().unwrap(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let id: String = counter.to_string(); | 
			
		
	
		
			
				
					|  |  |  |  |                 *counter += 1; | 
			
		
	
		
			
				
					|  |  |  |  |                 out.push(( | 
			
		
	
		
			
				
					|  |  |  |  |                     Some(id.clone()), | 
			
		
	
		
			
				
					|  |  |  |  |                     format!("OpLoad {} {}", fix_name(&String::from(typ)), fix_name(&ptr_id)), | 
			
		
	
		
			
				
					|  |  |  |  |                 )); | 
			
		
	
		
			
				
					|  |  |  |  |                 stack.push(id); | 
			
		
	
		
			
				
					|  |  |  |  |                 return; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             match fun_name.as_str() { | 
			
		
	
		
			
				
					|  |  |  |  |                 "store-ptr" => { | 
			
		
	
		
			
				
					|  |  |  |  |                     assert!(lst.len() == 2); | 
			
		
	
		
			
				
					|  |  |  |  |                     let ptr = lst.pop().unwrap(); | 
			
		
	
		
			
				
					|  |  |  |  |                     let val = lst.pop().unwrap(); | 
			
		
	
		
			
				
					|  |  |  |  |                     compile_ast_ssa(ptr, vars, constants, types, counter, stack, out); | 
			
		
	
		
			
				
					|  |  |  |  |                     let ptr = lst.pop().unwrap(); | 
			
		
	
		
			
				
					|  |  |  |  |                     compile_ast_ssa(val, vars, constants, types, counter, stack, out); | 
			
		
	
		
			
				
					|  |  |  |  |                     compile_ast_ssa(ptr, vars, constants, types, counter, stack, out); | 
			
		
	
		
			
				
					|  |  |  |  |                     let val_id = stack.pop().unwrap(); | 
			
		
	
		
			
				
					|  |  |  |  |                     let ptr_id = stack.pop().unwrap(); | 
			
		
	
		
			
				
					|  |  |  |  |                     out.push(( | 
			
		
	
	
		
			
				
					|  |  |  | @ -392,26 +529,6 @@ pub fn compile_ast_ssa( | 
			
		
	
		
			
				
					|  |  |  |  |                         format!("OpStore {} {}", fix_name(&val_id), fix_name(&ptr_id)), | 
			
		
	
		
			
				
					|  |  |  |  |                     )); | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |                 "/" => { | 
			
		
	
		
			
				
					|  |  |  |  |                     compile_biop( | 
			
		
	
		
			
				
					|  |  |  |  |                         "OpFDiv", &mut lst, vars, constants, types, counter, stack, out, | 
			
		
	
		
			
				
					|  |  |  |  |                     ); | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |                 "*" => { | 
			
		
	
		
			
				
					|  |  |  |  |                     compile_biop( | 
			
		
	
		
			
				
					|  |  |  |  |                         "OpFMul", &mut lst, vars, constants, types, counter, stack, out, | 
			
		
	
		
			
				
					|  |  |  |  |                     ); | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |                 "+" => { | 
			
		
	
		
			
				
					|  |  |  |  |                     compile_biop( | 
			
		
	
		
			
				
					|  |  |  |  |                         "OpFAdd", &mut lst, vars, constants, types, counter, stack, out, | 
			
		
	
		
			
				
					|  |  |  |  |                     ); | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |                 "-" => { | 
			
		
	
		
			
				
					|  |  |  |  |                     compile_biop( | 
			
		
	
		
			
				
					|  |  |  |  |                         "OpFSub", &mut lst, vars, constants, types, counter, stack, out, | 
			
		
	
		
			
				
					|  |  |  |  |                     ); | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |                 s => { | 
			
		
	
		
			
				
					|  |  |  |  |                     panic!( | 
			
		
	
		
			
				
					|  |  |  |  |                         "Unknown function: {} with params {:#?} in context:\n{:#?}", | 
			
		
	
	
		
			
				
					|  |  |  | @ -534,6 +651,10 @@ pub fn compile_fun_ssa(module: &mut Module, ops: &Vec<(Option<String>, String)>) | 
			
		
	
		
			
				
					|  |  |  |  |                 out_ops.push((None, op.1)); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         out_ops.push((None, String::from("OpReturn"))); | 
			
		
	
		
			
				
					|  |  |  |  |         out_ops.push((None, String::from("OpFunctionEnd"))); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         for op in out_ops { | 
			
		
	
		
			
				
					|  |  |  |  |             let split: Vec<String> = op.1.split(" ").map(|s| s.to_string()).collect(); | 
			
		
	
		
			
				
					|  |  |  |  |             let op_name: String = (&split[0]).clone(); | 
			
		
	
	
		
			
				
					|  |  |  | 
 |