diff --git a/src/compiler/backend/mod.rs b/src/compiler/backend/mod.rs index e896a23..a53e767 100644 --- a/src/compiler/backend/mod.rs +++ b/src/compiler/backend/mod.rs @@ -14,11 +14,13 @@ pub enum Type { Float(u32), Int(u32), Unsigned(u32), + Void, } impl fmt::Display for Type { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { + Type::Void => write!(f, "<>"), Type::Pointer(typ, storage_class) => match storage_class { StorageClass::Input => write!(f, "*{}i", typ), StorageClass::Output => write!(f, "*{}o", typ), @@ -42,6 +44,10 @@ pub fn parse_type(typ: &String) -> Type { let c = typ.chars().next().unwrap(); match c { + '<' => { + assert_eq!(typ.as_str(), "<>"); + Type::Void + } '*' => { let mut chars = typ.chars(); chars.next(); @@ -79,6 +85,9 @@ pub fn parse_type(typ: &String) -> Type { fn emit_type(typ: Type, ops: &mut Vec<(String, String)>) { match &typ { + Type::Void => { + ops.push(("%void".to_string(), "OpTypeVoid".to_string())); + } Type::Unsigned(size) => { ops.push(( format!("%u{}", size).to_string(), @@ -129,7 +138,13 @@ fn emit_type(typ: Type, ops: &mut Vec<(String, String)>) { } fn fix_name(name: &String) -> String { - format!("%{}", name.clone().replace("-", "_").replace("*", "p")) + format!( + "%{}", + name.clone() + .replace("-", "_") + .replace("*", "p") + .replace("<>", "void") + ) } fn has_id(name: String, ops: &Vec<(Option, Vec)>) -> bool { @@ -248,6 +263,24 @@ pub fn spirv_meta(module: Module) -> String { } } + for fun in module.functions { + let name = fix_name(&fun.name); + let return_type = fix_name(&fun.return_type); + let mut type_ops = Vec::new(); + emit_type(parse_type(&fun.return_type), &mut type_ops); + for op in type_ops { + if has_id(op.0.clone(), &ops) { + continue; + } + ops.push((Some(op.0), vec![op.1])); + } + // Push OpFunctionType + ops.push(( + Some(name.clone()), + vec!["OpTypeFunction".to_string(), return_type.clone()], + )); + } + for op in ops { if op.0.is_some() { write!(spirv_asm, "{} = ", op.0.unwrap()).unwrap(); diff --git a/src/compiler/backend/tests.rs b/src/compiler/backend/tests.rs index 4a90b07..2f0cce5 100644 --- a/src/compiler/backend/tests.rs +++ b/src/compiler/backend/tests.rs @@ -11,7 +11,7 @@ fn test_emit() { (dec frag-coord:*v4f32i Input) (dec out-color:*v4f32o Output) (entry main Fragment OriginUpperLeft (:frag-coord :out-color)) -(fun (main) :void +(fun (main) :<> (store-ptr (out-color) (v4f32i (/ (.xy (load-ptr frag-coord)) (v2f32 1920.0 1080.0)) diff --git a/src/compiler/meta_compile.rs b/src/compiler/meta_compile.rs index 7e8f937..d305239 100644 --- a/src/compiler/meta_compile.rs +++ b/src/compiler/meta_compile.rs @@ -181,7 +181,7 @@ pub fn compile_fun>( let mut name_it = name.into_iter(); let name = expect_symbol(name_it.next(), &name_loc)?; expect_empty(name_it, name_loc)?; - let _return_type = expect_one_of(&[":void"], expect_symbol(list.next(), &loc)?)?; + let _return_type = expect_one_of(&[":<>"], expect_symbol(list.next(), &loc)?)?; let return_type = _return_type.into_inner().replace(":", ""); let body = list.collect::>(); let location = if let (Some(s), Some(e)) = ( diff --git a/src/compiler/tests.rs b/src/compiler/tests.rs index cb47ba9..8064ea8 100644 --- a/src/compiler/tests.rs +++ b/src/compiler/tests.rs @@ -14,7 +14,7 @@ fn test_compile() { (dec frag-coord:*v4f32i Input) (dec out-color:*v4f32o Output) (entry main Fragment OriginUpperLeft (:frag-coord :out-color)) -(fun (main) :void +(fun (main) :<> (store-ptr (out-color) (v4f32i (/ (.xy (load-ptr frag-coord)) (v2f32 1920.0 1080.0)) @@ -49,7 +49,7 @@ fn test_compile() { ], functions: vec![Function { name: "main".to_string(), - return_type: "void".to_string(), + return_type: "<>".to_string(), arguments: vec![], body: Some(vec![]), ast: Some(Ast::List(Localised::dummy_location(vec![Ast::List( @@ -107,7 +107,7 @@ fn expected_symbol() { (dec frag-coord:*v4f32i Input) (dec out-color:*v4f32o Output) (entry main Fragment OriginUpperLeft (:frag-coord :out-color)) -(fun (main) :void +(fun (main) :<> (store-ptr (out-color) (v4f32i (/ (.xy (load-ptr frag-coord)) (v2f32 1920.0 1080.0)) diff --git a/src/parser/tests.rs b/src/parser/tests.rs index 2dff458..8e94147 100644 --- a/src/parser/tests.rs +++ b/src/parser/tests.rs @@ -43,7 +43,7 @@ fn test_parse() { (dec frag-coord:*v4f32i Input) (dec out-color:*v4f32o Output) (entry main Fragment OriginUpperLeft (:frag-coord :out-color)) -(fun (main) :void +(fun (main) :<> (store-ptr (out-color) (v4f32i (/ (.xy (load-ptr frag-coord)) (v2f32 1920.0 1080.0)) @@ -108,7 +108,7 @@ fn test_parse() { Ast::List(Localised::dummy_location(vec![Ast::Symbol( Localised::dummy_location("main".to_string()), )])), - Ast::Symbol(Localised::dummy_location(":void".to_string())), + Ast::Symbol(Localised::dummy_location(":<>".to_string())), Ast::List(Localised::dummy_location(vec![ Ast::Symbol(Localised::dummy_location("store-ptr".to_string())), Ast::List(Localised::dummy_location(vec![Ast::Symbol(