From 5f041f491a74264d1b5039b7c106ac029e982e44 Mon Sep 17 00:00:00 2001 From: itycodes Date: Thu, 6 Mar 2025 11:38:58 +0100 Subject: [PATCH] Fixed type generation --- src/compiler/backend/mod.rs | 42 ++++++++++++++++++++++------------- src/compiler/backend/tests.rs | 10 ++++----- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/compiler/backend/mod.rs b/src/compiler/backend/mod.rs index 74193c5..e88ceed 100644 --- a/src/compiler/backend/mod.rs +++ b/src/compiler/backend/mod.rs @@ -34,7 +34,7 @@ impl fmt::Display for Type { } } -pub fn parse_type(typ: String) -> Type { +pub fn parse_type(typ: &String) -> Type { // pointers have the format *i or *o, for the storage class // floats have the format f, so f32, f64... // ints have the format s, so s32, s64... @@ -54,14 +54,14 @@ pub fn parse_type(typ: String) -> Type { _ => panic!("Invalid storage class"), }; let typ = typ.chars().take(typ.len() - 1).collect::(); - Type::Pointer(Box::new(parse_type(typ)), storage_class) + Type::Pointer(Box::new(parse_type(&typ)), storage_class) }, 'v' => { let mut chars = typ.chars(); chars.next(); let size = chars.next().unwrap().to_digit(10).unwrap(); let typ = chars.collect::(); - Type::Vector(Box::new(parse_type(typ)), size) + Type::Vector(Box::new(parse_type(&typ)), size) }, 'f' => { let size = typ.chars().skip(1).collect::().parse().unwrap(); @@ -81,7 +81,7 @@ pub fn parse_type(typ: String) -> Type { } fn emit_type(typ: Type, ops: &mut Vec<(String, String)>) { - match typ { + match &typ { Type::Unsigned(size) => { ops.push((format!("%u{}", size).to_string(), format!("OpTypeInt {}", size))); }, @@ -91,26 +91,34 @@ fn emit_type(typ: Type, ops: &mut Vec<(String, String)>) { Type::Float(size) => { ops.push((format!("%f{}", size).to_string(), format!("OpTypeFloat {}", size))); }, - Type::Vector(typ, size) => { - emit_type(*typ.clone(), ops); - let typ_id = format!("%{}", *typ.clone()); - ops.push((format!("%v{}{}", typ_id, size).to_string(), format!("OpTypeVector {} {}", typ_id, size))) + Type::Vector(in_typ, size) => { + emit_type(*in_typ.clone(), ops); + ops.push((fix_name(&typ.to_string()), format!("OpTypeVector {} {}", fix_name(&in_typ.clone().to_string()), size))) }, - Type::Pointer(typ, storage_class) => { - emit_type(*typ.clone(), ops); - let typ_id = format!("%{}", *typ.clone()); + Type::Pointer(in_typ, storage_class) => { + emit_type(*in_typ.clone(), ops); + let typ_id = fix_name(&typ.to_string()); let storage_class = match storage_class { StorageClass::Input => "Input", StorageClass::Output => "Output", StorageClass::Undefined => panic!("Bound a non-declared variable"), }; - ops.push((format!("%{}{}", typ_id, storage_class).to_string(), format!("OpTypePointer {} {}", storage_class, typ_id))) + ops.push((typ_id, format!("OpTypePointer {} {}", storage_class, fix_name(&in_typ.to_string())))) }, } } fn fix_name(name: &String) -> String { - format!("%{}", name.clone().replace("-", "_")) + format!("%{}", name.clone().replace("-", "_").replace("*", "p")) +} + +fn has_id(name: String, ops: &Vec<(Option, Vec)>) -> bool { + for op in ops { + if op.0.is_some() && op.0.clone().unwrap() == name { + return true; + } + } + false } pub fn spirv_meta(module: Module) -> String { @@ -162,13 +170,15 @@ pub fn spirv_meta(module: Module) -> String { crate::compiler::StorageClass::Output => "Output", crate::compiler::StorageClass::Undefined => panic!("Bound a non-declared variable"), }; - let typ_id = format!("%{}", _typ); let mut type_ops = Vec::new(); - emit_type(parse_type(_typ), &mut type_ops); + emit_type(parse_type(&_typ), &mut type_ops); for op in type_ops { + if has_id(op.0.clone(), &ops) { + continue; + } ops.push((Some(op.0), vec![op.1])); } - ops.push((Some(name.clone()), vec!["OpVariable".to_string(), typ_id.to_string(), storage_class.to_string()])); + ops.push((Some(name.clone()), vec!["OpVariable".to_string(), fix_name(&_typ), storage_class.to_string()])); for dec in global.decorations { // Decorations have the format Location 0, or Builtin FragCoord let dec = match dec { diff --git a/src/compiler/backend/tests.rs b/src/compiler/backend/tests.rs index e84c06b..0f21e2f 100644 --- a/src/compiler/backend/tests.rs +++ b/src/compiler/backend/tests.rs @@ -28,12 +28,12 @@ fn test_emit() { fn test_type_parse() { use crate::compiler::backend::*; use Type::*; - assert_eq!(parse_type("*v4f32i".to_string()), + assert_eq!(parse_type(&"*v4f32i".to_string()), Pointer(Box::new(Vector(Box::new(Float(32)), 4)), StorageClass::Input)); - assert_eq!(parse_type("*v4f32o".to_string()), + assert_eq!(parse_type(&"*v4f32o".to_string()), Pointer(Box::new(Vector(Box::new(Float(32)), 4)), StorageClass::Output)); - assert_eq!(parse_type("v2f32".to_string()), + assert_eq!(parse_type(&"v2f32".to_string()), Vector(Box::new(Float(32)), 2)); - assert_eq!(parse_type("f32".to_string()), Float(32)); - assert_eq!(parse_type("s32".to_string()), Int(32)); + assert_eq!(parse_type(&"f32".to_string()), Float(32)); + assert_eq!(parse_type(&"s32".to_string()), Int(32)); } \ No newline at end of file