|  |  |  | @ -1,4 +1,4 @@ | 
			
		
	
		
			
				
					|  |  |  |  | use crate::parser::Ast; | 
			
		
	
		
			
				
					|  |  |  |  | use crate::parser::{Ast, Localised, Location}; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | pub mod backend; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -10,13 +10,13 @@ mod tests; | 
			
		
	
		
			
				
					|  |  |  |  | #[derive(Debug, PartialEq, Default, Clone)] | 
			
		
	
		
			
				
					|  |  |  |  | pub enum Capability { | 
			
		
	
		
			
				
					|  |  |  |  |     #[default] | 
			
		
	
		
			
				
					|  |  |  |  |     Shader | 
			
		
	
		
			
				
					|  |  |  |  |     Shader, | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #[derive(Debug, PartialEq, Default, Clone)] | 
			
		
	
		
			
				
					|  |  |  |  | pub enum ExecutionMode { | 
			
		
	
		
			
				
					|  |  |  |  |     #[default] | 
			
		
	
		
			
				
					|  |  |  |  |     OriginUpperLeft | 
			
		
	
		
			
				
					|  |  |  |  |     OriginUpperLeft, | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #[derive(Debug, PartialEq, Default, Clone)] | 
			
		
	
	
		
			
				
					|  |  |  | @ -40,7 +40,7 @@ pub enum AddressingModel { | 
			
		
	
		
			
				
					|  |  |  |  |     Logical, | 
			
		
	
		
			
				
					|  |  |  |  |     Physical32, | 
			
		
	
		
			
				
					|  |  |  |  |     Physical64, | 
			
		
	
		
			
				
					|  |  |  |  |     PhysicalStorageBuffer64 | 
			
		
	
		
			
				
					|  |  |  |  |     PhysicalStorageBuffer64, | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | #[derive(Debug, PartialEq, Default, Clone)] | 
			
		
	
		
			
				
					|  |  |  |  | pub enum MemoryModel { | 
			
		
	
	
		
			
				
					|  |  |  | @ -48,7 +48,7 @@ pub enum MemoryModel { | 
			
		
	
		
			
				
					|  |  |  |  |     GLSL450, | 
			
		
	
		
			
				
					|  |  |  |  |     OpenCL, | 
			
		
	
		
			
				
					|  |  |  |  |     VulkanKHR, | 
			
		
	
		
			
				
					|  |  |  |  |     Simple | 
			
		
	
		
			
				
					|  |  |  |  |     Simple, | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #[derive(Debug, PartialEq, Default, Clone)] | 
			
		
	
	
		
			
				
					|  |  |  | @ -147,9 +147,9 @@ pub fn meta_compile(ast: &mut Ast) -> Module { | 
			
		
	
		
			
				
					|  |  |  |  |                                             memory_model: MemoryModel::GLSL450, | 
			
		
	
		
			
				
					|  |  |  |  |                                         }; | 
			
		
	
		
			
				
					|  |  |  |  |                                         module.capabilities.push(Capability::Shader); | 
			
		
	
		
			
				
					|  |  |  |  |                                         assert_eq!(exec, Ast::Symbol("Logical".to_string())); | 
			
		
	
		
			
				
					|  |  |  |  |                                         assert_eq!(memory, Ast::Symbol("GLSL450".to_string())); | 
			
		
	
		
			
				
					|  |  |  |  |                                         assert_eq!(cap, Ast::Symbol("Shader".to_string())); | 
			
		
	
		
			
				
					|  |  |  |  |                                         assert_eq!(exec.symbol(), Some("Logical".to_string())); | 
			
		
	
		
			
				
					|  |  |  |  |                                         assert_eq!(memory.symbol(), Some("GLSL450".to_string())); | 
			
		
	
		
			
				
					|  |  |  |  |                                         assert_eq!(cap.symbol(), Some("Shader".to_string())); | 
			
		
	
		
			
				
					|  |  |  |  |                                     } | 
			
		
	
		
			
				
					|  |  |  |  |                                     "import" => { | 
			
		
	
		
			
				
					|  |  |  |  |                                         let name = match &list[1] { | 
			
		
	
	
		
			
				
					|  |  |  | @ -170,28 +170,38 @@ pub fn meta_compile(ast: &mut Ast) -> Module { | 
			
		
	
		
			
				
					|  |  |  |  |                                             Ast::List(l) => l, | 
			
		
	
		
			
				
					|  |  |  |  |                                             _ => panic!("Expected list! {:?}", list[1]), | 
			
		
	
		
			
				
					|  |  |  |  |                                         }; | 
			
		
	
		
			
				
					|  |  |  |  |                                         let name_and_type: String = name_and_type.iter().map(|x| { | 
			
		
	
		
			
				
					|  |  |  |  |                                             match x { | 
			
		
	
		
			
				
					|  |  |  |  |                                         let name_and_type: String = name_and_type | 
			
		
	
		
			
				
					|  |  |  |  |                                             .iter() | 
			
		
	
		
			
				
					|  |  |  |  |                                             .map(|x| match x { | 
			
		
	
		
			
				
					|  |  |  |  |                                                 Ast::Symbol(s) => s.to_string(), | 
			
		
	
		
			
				
					|  |  |  |  |                                                 _ => panic!("Expected symbol! {:?}", x), | 
			
		
	
		
			
				
					|  |  |  |  |                                             } | 
			
		
	
		
			
				
					|  |  |  |  |                                         }).collect(); | 
			
		
	
		
			
				
					|  |  |  |  |                                             }) | 
			
		
	
		
			
				
					|  |  |  |  |                                             .collect(); | 
			
		
	
		
			
				
					|  |  |  |  |                                         // name_and_type is of the name:type format, like foo:f32
 | 
			
		
	
		
			
				
					|  |  |  |  |                                         let name: String = name_and_type.split(":").collect::<Vec<&str>>()[0].to_string(); | 
			
		
	
		
			
				
					|  |  |  |  |                                         let typ: String = name_and_type.split(":").collect::<Vec<&str>>()[1].to_string(); | 
			
		
	
		
			
				
					|  |  |  |  |                                         let name: String = | 
			
		
	
		
			
				
					|  |  |  |  |                                             name_and_type.split(":").collect::<Vec<&str>>()[0] | 
			
		
	
		
			
				
					|  |  |  |  |                                                 .to_string(); | 
			
		
	
		
			
				
					|  |  |  |  |                                         let typ: String = | 
			
		
	
		
			
				
					|  |  |  |  |                                             name_and_type.split(":").collect::<Vec<&str>>()[1] | 
			
		
	
		
			
				
					|  |  |  |  |                                                 .to_string(); | 
			
		
	
		
			
				
					|  |  |  |  |                                         let bind = match &list[2] { | 
			
		
	
		
			
				
					|  |  |  |  |                                             Ast::List(l) => l, | 
			
		
	
		
			
				
					|  |  |  |  |                                             _ => panic!("Expected list! {:?}", list[2]), | 
			
		
	
		
			
				
					|  |  |  |  |                                         }; | 
			
		
	
		
			
				
					|  |  |  |  |                                         let bind: Vec<String> = bind.iter().map(|x| { | 
			
		
	
		
			
				
					|  |  |  |  |                                             match x { | 
			
		
	
		
			
				
					|  |  |  |  |                                         let bind: Vec<String> = bind | 
			
		
	
		
			
				
					|  |  |  |  |                                             .iter() | 
			
		
	
		
			
				
					|  |  |  |  |                                             .map(|x| match x { | 
			
		
	
		
			
				
					|  |  |  |  |                                                 Ast::Symbol(s) => s.to_string(), | 
			
		
	
		
			
				
					|  |  |  |  |                                                 _ => panic!("Expected symbol! {:?}", x), | 
			
		
	
		
			
				
					|  |  |  |  |                                             } | 
			
		
	
		
			
				
					|  |  |  |  |                                         }).collect(); | 
			
		
	
		
			
				
					|  |  |  |  |                                             }) | 
			
		
	
		
			
				
					|  |  |  |  |                                             .collect(); | 
			
		
	
		
			
				
					|  |  |  |  |                                         let bind_name = match bind[0].as_str() { | 
			
		
	
		
			
				
					|  |  |  |  |                                             "BuiltIn" => Decoration::BuiltIn(BuiltinDecoration::FragCoord), | 
			
		
	
		
			
				
					|  |  |  |  |                                             "Location" => Decoration::Location(bind[1].parse::<u32>().unwrap()), | 
			
		
	
		
			
				
					|  |  |  |  |                                             "BuiltIn" => { | 
			
		
	
		
			
				
					|  |  |  |  |                                                 Decoration::BuiltIn(BuiltinDecoration::FragCoord) | 
			
		
	
		
			
				
					|  |  |  |  |                                             } | 
			
		
	
		
			
				
					|  |  |  |  |                                             "Location" => Decoration::Location( | 
			
		
	
		
			
				
					|  |  |  |  |                                                 bind[1].parse::<u32>().unwrap(), | 
			
		
	
		
			
				
					|  |  |  |  |                                             ), | 
			
		
	
		
			
				
					|  |  |  |  |                                             _ => panic!("Unknown bind! {:?}", bind), | 
			
		
	
		
			
				
					|  |  |  |  |                                         }; | 
			
		
	
		
			
				
					|  |  |  |  |                                         let mut exists = false; | 
			
		
	
	
		
			
				
					|  |  |  | @ -214,8 +224,12 @@ pub fn meta_compile(ast: &mut Ast) -> Module { | 
			
		
	
		
			
				
					|  |  |  |  |                                             Ast::Symbol(s) => s, | 
			
		
	
		
			
				
					|  |  |  |  |                                             _ => panic!("Expected symbol! {:?}", list[1]), | 
			
		
	
		
			
				
					|  |  |  |  |                                         }; | 
			
		
	
		
			
				
					|  |  |  |  |                                         let name: String = name_and_type.split(":").collect::<Vec<&str>>()[0].to_string(); | 
			
		
	
		
			
				
					|  |  |  |  |                                         let typ: String = name_and_type.split(":").collect::<Vec<&str>>()[1].to_string(); | 
			
		
	
		
			
				
					|  |  |  |  |                                         let name: String = | 
			
		
	
		
			
				
					|  |  |  |  |                                             name_and_type.split(":").collect::<Vec<&str>>()[0] | 
			
		
	
		
			
				
					|  |  |  |  |                                                 .to_string(); | 
			
		
	
		
			
				
					|  |  |  |  |                                         let typ: String = | 
			
		
	
		
			
				
					|  |  |  |  |                                             name_and_type.split(":").collect::<Vec<&str>>()[1] | 
			
		
	
		
			
				
					|  |  |  |  |                                                 .to_string(); | 
			
		
	
		
			
				
					|  |  |  |  |                                         let storage_class = match &list[2] { | 
			
		
	
		
			
				
					|  |  |  |  |                                             Ast::Symbol(s) => s, | 
			
		
	
		
			
				
					|  |  |  |  |                                             _ => panic!("Expected symbol! {:?}", list[2]), | 
			
		
	
	
		
			
				
					|  |  |  | @ -240,9 +254,12 @@ pub fn meta_compile(ast: &mut Ast) -> Module { | 
			
		
	
		
			
				
					|  |  |  |  |                                             }); | 
			
		
	
		
			
				
					|  |  |  |  |                                         } | 
			
		
	
		
			
				
					|  |  |  |  |                                         if exists { | 
			
		
	
		
			
				
					|  |  |  |  |                                             module.globals.iter_mut() | 
			
		
	
		
			
				
					|  |  |  |  |                                             module | 
			
		
	
		
			
				
					|  |  |  |  |                                                 .globals | 
			
		
	
		
			
				
					|  |  |  |  |                                                 .iter_mut() | 
			
		
	
		
			
				
					|  |  |  |  |                                                 .find(|x| x.name.as_str() == name.as_str()) | 
			
		
	
		
			
				
					|  |  |  |  |                                                 .unwrap().storage_class = storage_class.clone(); | 
			
		
	
		
			
				
					|  |  |  |  |                                                 .unwrap() | 
			
		
	
		
			
				
					|  |  |  |  |                                                 .storage_class = storage_class.clone(); | 
			
		
	
		
			
				
					|  |  |  |  |                                         } | 
			
		
	
		
			
				
					|  |  |  |  |                                     } | 
			
		
	
		
			
				
					|  |  |  |  |                                     "entry" => { | 
			
		
	
	
		
			
				
					|  |  |  | @ -262,22 +279,21 @@ pub fn meta_compile(ast: &mut Ast) -> Module { | 
			
		
	
		
			
				
					|  |  |  |  |                                             Ast::List(l) => l, | 
			
		
	
		
			
				
					|  |  |  |  |                                             _ => panic!("Expected list! {:?}", list[4]), | 
			
		
	
		
			
				
					|  |  |  |  |                                         }; | 
			
		
	
		
			
				
					|  |  |  |  |                                         let interface: Vec<String> = interface.iter().map(|x| { | 
			
		
	
		
			
				
					|  |  |  |  |                                             match x { | 
			
		
	
		
			
				
					|  |  |  |  |                                                 Ast::Symbol(s) => { 
 | 
			
		
	
		
			
				
					|  |  |  |  |                                                     s.to_string().replace(":", "") | 
			
		
	
		
			
				
					|  |  |  |  |                                                 }, | 
			
		
	
		
			
				
					|  |  |  |  |                                         let interface: Vec<String> = interface | 
			
		
	
		
			
				
					|  |  |  |  |                                             .iter() | 
			
		
	
		
			
				
					|  |  |  |  |                                             .map(|x| match x { | 
			
		
	
		
			
				
					|  |  |  |  |                                                 Ast::Symbol(s) => s.to_string().replace(":", ""), | 
			
		
	
		
			
				
					|  |  |  |  |                                                 _ => panic!("Expected symbol! {:?}", x), | 
			
		
	
		
			
				
					|  |  |  |  |                                             } | 
			
		
	
		
			
				
					|  |  |  |  |                                         }).collect(); | 
			
		
	
		
			
				
					|  |  |  |  |                                             }) | 
			
		
	
		
			
				
					|  |  |  |  |                                             .collect(); | 
			
		
	
		
			
				
					|  |  |  |  |                                         module.entry_points.push(EntryPoint { | 
			
		
	
		
			
				
					|  |  |  |  |                                             execution_model: ExecutionModel::Fragment, | 
			
		
	
		
			
				
					|  |  |  |  |                                             execution_mode: ExecutionMode::OriginUpperLeft, | 
			
		
	
		
			
				
					|  |  |  |  |                                             name: name.to_string(), | 
			
		
	
		
			
				
					|  |  |  |  |                                             interface: interface, | 
			
		
	
		
			
				
					|  |  |  |  |                                         }); | 
			
		
	
		
			
				
					|  |  |  |  |                                         assert_eq!(exec_model, "Fragment"); | 
			
		
	
		
			
				
					|  |  |  |  |                                         assert_eq!(exec_mode, "OriginUpperLeft"); | 
			
		
	
		
			
				
					|  |  |  |  |                                         assert_eq!(**exec_model, "Fragment"); | 
			
		
	
		
			
				
					|  |  |  |  |                                         assert_eq!(**exec_mode, "OriginUpperLeft"); | 
			
		
	
		
			
				
					|  |  |  |  |                                     } | 
			
		
	
		
			
				
					|  |  |  |  |                                     "fun" => { | 
			
		
	
		
			
				
					|  |  |  |  |                                         let name = match &list[1] { | 
			
		
	
	
		
			
				
					|  |  |  | @ -289,12 +305,23 @@ pub fn meta_compile(ast: &mut Ast) -> Module { | 
			
		
	
		
			
				
					|  |  |  |  |                                             _ => panic!("Expected symbol! {:?}", name), | 
			
		
	
		
			
				
					|  |  |  |  |                                         }; | 
			
		
	
		
			
				
					|  |  |  |  |                                         let body = list[2..].to_vec(); | 
			
		
	
		
			
				
					|  |  |  |  |                                         let location = if let (Some(s), Some(e)) = ( | 
			
		
	
		
			
				
					|  |  |  |  |                                             body.first().map(|a| a.location()).flatten(), | 
			
		
	
		
			
				
					|  |  |  |  |                                             body.last().map(|a| a.location()).flatten(), | 
			
		
	
		
			
				
					|  |  |  |  |                                         ) { | 
			
		
	
		
			
				
					|  |  |  |  |                                             Location::range(s, e) | 
			
		
	
		
			
				
					|  |  |  |  |                                         } else { | 
			
		
	
		
			
				
					|  |  |  |  |                                             Location::Char { line: 0, col: 0 } | 
			
		
	
		
			
				
					|  |  |  |  |                                         }; | 
			
		
	
		
			
				
					|  |  |  |  |                                         let fun = Function { | 
			
		
	
		
			
				
					|  |  |  |  |                                             name: name.to_string(), | 
			
		
	
		
			
				
					|  |  |  |  |                                             return_type: "void".to_string(), | 
			
		
	
		
			
				
					|  |  |  |  |                                             arguments: vec![], | 
			
		
	
		
			
				
					|  |  |  |  |                                             body: Some(vec![]), | 
			
		
	
		
			
				
					|  |  |  |  |                                             ast: Some(Ast::List(body)), | 
			
		
	
		
			
				
					|  |  |  |  |                                             ast: Some(Ast::List(Localised { | 
			
		
	
		
			
				
					|  |  |  |  |                                                 location, | 
			
		
	
		
			
				
					|  |  |  |  |                                                 item: body, | 
			
		
	
		
			
				
					|  |  |  |  |                                             })), | 
			
		
	
		
			
				
					|  |  |  |  |                                         }; | 
			
		
	
		
			
				
					|  |  |  |  |                                         module.functions.push(fun); | 
			
		
	
		
			
				
					|  |  |  |  |                                     } | 
			
		
	
	
		
			
				
					|  |  |  | @ -308,7 +335,8 @@ pub fn meta_compile(ast: &mut Ast) -> Module { | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |         _ => panic!("Non-root ast") | 
			
		
	
		
			
				
					|  |  |  |  |         _ => panic!("Non-root ast"), | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     module | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | 
 |