Fixed type generation

pull/3/head
itycodes 3 weeks ago
parent 3d5369cc36
commit 5f041f491a

@ -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 *<t>i or *<t>o, for the storage class // pointers have the format *<t>i or *<t>o, for the storage class
// floats have the format f<size>, so f32, f64... // floats have the format f<size>, so f32, f64...
// ints have the format s<size>, so s32, s64... // ints have the format s<size>, so s32, s64...
@ -54,14 +54,14 @@ pub fn parse_type(typ: String) -> Type {
_ => panic!("Invalid storage class"), _ => panic!("Invalid storage class"),
}; };
let typ = typ.chars().take(typ.len() - 1).collect::<String>(); let typ = typ.chars().take(typ.len() - 1).collect::<String>();
Type::Pointer(Box::new(parse_type(typ)), storage_class) Type::Pointer(Box::new(parse_type(&typ)), storage_class)
}, },
'v' => { 'v' => {
let mut chars = typ.chars(); let mut chars = typ.chars();
chars.next(); chars.next();
let size = chars.next().unwrap().to_digit(10).unwrap(); let size = chars.next().unwrap().to_digit(10).unwrap();
let typ = chars.collect::<String>(); let typ = chars.collect::<String>();
Type::Vector(Box::new(parse_type(typ)), size) Type::Vector(Box::new(parse_type(&typ)), size)
}, },
'f' => { 'f' => {
let size = typ.chars().skip(1).collect::<String>().parse().unwrap(); let size = typ.chars().skip(1).collect::<String>().parse().unwrap();
@ -81,7 +81,7 @@ pub fn parse_type(typ: String) -> Type {
} }
fn emit_type(typ: Type, ops: &mut Vec<(String, String)>) { fn emit_type(typ: Type, ops: &mut Vec<(String, String)>) {
match typ { match &typ {
Type::Unsigned(size) => { Type::Unsigned(size) => {
ops.push((format!("%u{}", size).to_string(), format!("OpTypeInt {}", 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) => { Type::Float(size) => {
ops.push((format!("%f{}", size).to_string(), format!("OpTypeFloat {}", size))); ops.push((format!("%f{}", size).to_string(), format!("OpTypeFloat {}", size)));
}, },
Type::Vector(typ, size) => { Type::Vector(in_typ, size) => {
emit_type(*typ.clone(), ops); emit_type(*in_typ.clone(), ops);
let typ_id = format!("%{}", *typ.clone()); ops.push((fix_name(&typ.to_string()), format!("OpTypeVector {} {}", fix_name(&in_typ.clone().to_string()), size)))
ops.push((format!("%v{}{}", typ_id, size).to_string(), format!("OpTypeVector {} {}", typ_id, size)))
}, },
Type::Pointer(typ, storage_class) => { Type::Pointer(in_typ, storage_class) => {
emit_type(*typ.clone(), ops); emit_type(*in_typ.clone(), ops);
let typ_id = format!("%{}", *typ.clone()); let typ_id = fix_name(&typ.to_string());
let storage_class = match storage_class { let storage_class = match storage_class {
StorageClass::Input => "Input", StorageClass::Input => "Input",
StorageClass::Output => "Output", StorageClass::Output => "Output",
StorageClass::Undefined => panic!("Bound a non-declared variable"), 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 { fn fix_name(name: &String) -> String {
format!("%{}", name.clone().replace("-", "_")) format!("%{}", name.clone().replace("-", "_").replace("*", "p"))
}
fn has_id(name: String, ops: &Vec<(Option<String>, Vec<String>)>) -> 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 { 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::Output => "Output",
crate::compiler::StorageClass::Undefined => panic!("Bound a non-declared variable"), crate::compiler::StorageClass::Undefined => panic!("Bound a non-declared variable"),
}; };
let typ_id = format!("%{}", _typ);
let mut type_ops = Vec::new(); 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 { for op in type_ops {
if has_id(op.0.clone(), &ops) {
continue;
}
ops.push((Some(op.0), vec![op.1])); 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 { for dec in global.decorations {
// Decorations have the format Location 0, or Builtin FragCoord // Decorations have the format Location 0, or Builtin FragCoord
let dec = match dec { let dec = match dec {

@ -28,12 +28,12 @@ fn test_emit() {
fn test_type_parse() { fn test_type_parse() {
use crate::compiler::backend::*; use crate::compiler::backend::*;
use Type::*; 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)); 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)); 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)); Vector(Box::new(Float(32)), 2));
assert_eq!(parse_type("f32".to_string()), Float(32)); assert_eq!(parse_type(&"f32".to_string()), Float(32));
assert_eq!(parse_type("s32".to_string()), Int(32)); assert_eq!(parse_type(&"s32".to_string()), Int(32));
} }
Loading…
Cancel
Save