Code maid stuff

pull/5/head
Avery 3 weeks ago
parent 9db2b68e7b
commit 3713c418d8
Signed by untrusted user: Avery
GPG Key ID: 4E53F4CB69B2CC8D

@ -1,11 +1,12 @@
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
use crate::compiler::{Instruction, Module}; use crate::compiler::{
AddressingModel, BuiltinDecoration, Decoration, ExecutionMode, ExecutionModel, Instruction,
MemoryModel, Module, StorageClass,
};
use std::fmt; use std::fmt;
use super::StorageClass;
use crate::parser::Ast; use crate::parser::Ast;
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
@ -43,48 +44,43 @@ pub fn parse_type(typ: &String) -> Type {
// So, *v4f32i is a pointer to a vector of 4 floats, with the storage class Input. // So, *v4f32i is a pointer to a vector of 4 floats, with the storage class Input.
// *v4f32o is a pointer to a vector of 4 floats, with the storage class Output. // *v4f32o is a pointer to a vector of 4 floats, with the storage class Output.
let c = typ.chars().next().unwrap(); let mut chars = typ.chars();
match c { match chars.next() {
'<' => { Some('<') => {
assert_eq!(typ.as_str(), "<>"); assert_eq!(typ.as_str(), "<>");
Type::Void Type::Void
} }
'*' => { Some('*') => {
let mut chars = typ.chars(); let mut typ = chars.collect::<String>();
chars.next(); let storage_class = match typ.pop() {
let typ = chars.collect::<String>(); Some('i') => StorageClass::Input,
let storage_class = match typ.chars().last().unwrap() { Some('o') => StorageClass::Output,
'i' => StorageClass::Input,
'o' => StorageClass::Output,
_ => panic!("Invalid storage class"), _ => panic!("Invalid storage class"),
}; };
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' => { Some('v') => {
let mut chars = typ.chars(); let size = chars.next().map(|s| s.to_digit(10)).flatten().unwrap();
chars.next();
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' => { Some('f') => {
let size = typ.chars().skip(1).collect::<String>().parse().unwrap(); let size = chars.collect::<String>().parse().unwrap();
Type::Float(size) Type::Float(size)
} }
's' => { Some('s') => {
let size = typ.chars().skip(1).collect::<String>().parse().unwrap(); let size = chars.collect::<String>().parse().unwrap();
Type::Int(size) Type::Int(size)
} }
'u' => { Some('u') => {
let size = typ.chars().skip(1).collect::<String>().parse().unwrap(); let size = chars.collect::<String>().parse().unwrap();
Type::Unsigned(size) Type::Unsigned(size)
} }
_ => panic!("Invalid type"), _ => panic!("Invalid 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::Void => { Type::Void => {
ops.push(("%void".to_string(), "OpTypeVoid".to_string())); ops.push(("%void".to_string(), "OpTypeVoid".to_string()));
@ -108,18 +104,14 @@ fn emit_type(typ: Type, ops: &mut Vec<(String, String)>) {
)); ));
} }
Type::Vector(in_typ, size) => { Type::Vector(in_typ, size) => {
emit_type(*in_typ.clone(), ops); emit_type(in_typ, ops);
ops.push(( ops.push((
fix_name(&typ.to_string()), fix_name(&typ.to_string()),
format!( format!("OpTypeVector {} {}", fix_name(&in_typ.to_string()), size),
"OpTypeVector {} {}",
fix_name(&in_typ.clone().to_string()),
size
),
)) ))
} }
Type::Pointer(in_typ, storage_class) => { Type::Pointer(in_typ, storage_class) => {
emit_type(*in_typ.clone(), ops); emit_type(in_typ, ops);
let typ_id = fix_name(&typ.to_string()); 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",
@ -138,23 +130,19 @@ fn emit_type(typ: Type, ops: &mut Vec<(String, String)>) {
} }
} }
fn fix_name(name: &String) -> String { fn fix_name(name: &str) -> String {
format!( format!(
"%{}", "%{}",
name.clone() name.replace("-", "_")
.replace("-", "_")
.replace("*", "p") .replace("*", "p")
.replace("<>", "void") .replace("<>", "void")
) )
} }
fn has_id<T>(name: String, ops: &Vec<(Option<String>, T)>) -> bool { fn has_id<T>(name: &str, ops: &Vec<(Option<String>, T)>) -> bool {
for op in ops { ops.iter()
if op.0.is_some() && op.0.clone().unwrap() == name { .find(|op| op.0.as_ref().map(|s| *s == name).unwrap_or(false))
return true; .is_some()
}
}
false
} }
pub fn spirv_meta(module: &mut Module) -> Vec<(Option<String>, Vec<String>)> { pub fn spirv_meta(module: &mut Module) -> Vec<(Option<String>, Vec<String>)> {
@ -170,15 +158,15 @@ pub fn spirv_meta(module: &mut Module) -> Vec<(Option<String>, Vec<String>)> {
} }
let memory_model_address = match module.memory_model.addressing_model { let memory_model_address = match module.memory_model.addressing_model {
crate::compiler::AddressingModel::Logical => "Logical", AddressingModel::Logical => "Logical",
crate::compiler::AddressingModel::Physical32 => "Physical32", AddressingModel::Physical32 => "Physical32",
crate::compiler::AddressingModel::Physical64 => "Physical64", AddressingModel::Physical64 => "Physical64",
crate::compiler::AddressingModel::PhysicalStorageBuffer64 => "PhysicalStorageBuffer64", AddressingModel::PhysicalStorageBuffer64 => "PhysicalStorageBuffer64",
}; };
let memory_model_model = match module.memory_model.memory_model { let memory_model_model = match module.memory_model.memory_model {
crate::compiler::MemoryModel::Simple => "Simple", MemoryModel::Simple => "Simple",
crate::compiler::MemoryModel::GLSL450 => "GLSL450", MemoryModel::GLSL450 => "GLSL450",
crate::compiler::MemoryModel::OpenCL => "OpenCL", MemoryModel::OpenCL => "OpenCL",
_ => todo!(), _ => todo!(),
}; };
ops.push(( ops.push((
@ -192,8 +180,8 @@ pub fn spirv_meta(module: &mut Module) -> Vec<(Option<String>, Vec<String>)> {
for entry in module.entry_points.clone() { for entry in module.entry_points.clone() {
let exec_model = match entry.execution_model { let exec_model = match entry.execution_model {
crate::compiler::ExecutionModel::Fragment => "Fragment", ExecutionModel::Fragment => "Fragment",
crate::compiler::ExecutionModel::Vertex => "Vertex", ExecutionModel::Vertex => "Vertex",
}; };
let name = entry.name; let name = entry.name;
let interface: Vec<String> = entry let interface: Vec<String> = entry
@ -202,7 +190,7 @@ pub fn spirv_meta(module: &mut Module) -> Vec<(Option<String>, Vec<String>)> {
.map(|i| fix_name(&i.to_string())) .map(|i| fix_name(&i.to_string()))
.collect(); .collect();
let exec_mode = match entry.execution_mode { let exec_mode = match entry.execution_mode {
crate::compiler::ExecutionMode::OriginUpperLeft => "OriginUpperLeft", ExecutionMode::OriginUpperLeft => "OriginUpperLeft",
}; };
ops.push(( ops.push((
None, None,
@ -226,16 +214,16 @@ pub fn spirv_meta(module: &mut Module) -> Vec<(Option<String>, Vec<String>)> {
for global in module.globals.clone() { for global in module.globals.clone() {
let name = fix_name(&global.name); let name = fix_name(&global.name);
let _typ = global.typ; let typ = global.typ;
let storage_class = match global.storage_class { let storage_class = match global.storage_class {
crate::compiler::StorageClass::Input => "Input", StorageClass::Input => "Input",
crate::compiler::StorageClass::Output => "Output", StorageClass::Output => "Output",
crate::compiler::StorageClass::Undefined => panic!("Bound a non-declared variable"), StorageClass::Undefined => panic!("Bound a non-declared variable"),
}; };
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) { if has_id(&op.0, &ops) {
continue; continue;
} }
ops.push((Some(op.0), vec![op.1])); ops.push((Some(op.0), vec![op.1]));
@ -244,17 +232,17 @@ pub fn spirv_meta(module: &mut Module) -> Vec<(Option<String>, Vec<String>)> {
Some(name.clone()), Some(name.clone()),
vec![ vec![
"OpVariable".to_string(), "OpVariable".to_string(),
fix_name(&_typ), fix_name(&typ),
storage_class.to_string(), 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 {
crate::compiler::Decoration::Location(loc) => format!("Location {}", loc), Decoration::Location(loc) => format!("Location {}", loc),
crate::compiler::Decoration::BuiltIn(builtin) => { Decoration::BuiltIn(builtin) => {
let builtin = match builtin { let builtin = match builtin {
crate::compiler::BuiltinDecoration::FragCoord => "FragCoord", BuiltinDecoration::FragCoord => "FragCoord",
}; };
format!("BuiltIn {}", builtin) format!("BuiltIn {}", builtin)
} }
@ -267,29 +255,26 @@ pub fn spirv_meta(module: &mut Module) -> Vec<(Option<String>, Vec<String>)> {
let name = fix_name(&format!("l_{}", fun.name)); let name = fix_name(&format!("l_{}", fun.name));
let return_type = fix_name(&fun.return_type); let return_type = fix_name(&fun.return_type);
let mut type_ops = Vec::new(); let mut type_ops = Vec::new();
emit_type(parse_type(&fun.return_type), &mut type_ops); emit_type(&parse_type(&fun.return_type), &mut type_ops);
for op in type_ops { for op in type_ops {
if has_id(op.0.clone(), &ops) { if has_id(&op.0, &ops) {
continue; continue;
} }
ops.push((Some(op.0), vec![op.1])); ops.push((Some(op.0), vec![op.1]));
} }
ops.push(( // Push OpFunctionType
Some(name.clone()), ops.push((Some(name), vec!["OpTypeFunction".to_string(), return_type]));
vec!["OpTypeFunction".to_string(), return_type.clone()],
));
} }
// for op in ops { // for op in ops {
// if op.0.is_some() { // if let Some(op0) = op.0 {
// write!(spirv_asm, "{} = ", op.0.unwrap()).unwrap(); // write!(spirv_asm, "{} = ", op0).unwrap();
// } // }
// for arg in op.1 { // for arg in op.1 {
// write!(spirv_asm, "{} ", arg).unwrap(); // write!(spirv_asm, "{} ", arg).unwrap();
// } // }
// writeln!(spirv_asm).unwrap(); // writeln!(spirv_asm).unwrap();
// } // }
// spirv_asm
ops ops
} }
@ -370,8 +355,7 @@ pub fn compile_ast_ssa(
out: &mut Vec<(Option<String>, String)>, out: &mut Vec<(Option<String>, String)>,
) { ) {
match ast.clone().list() { match ast.clone().list() {
Some(l) => { Some(mut lst) => {
let mut lst = l.clone();
assert!(!lst.is_empty()); assert!(!lst.is_empty());
let fun = lst.remove(0); let fun = lst.remove(0);
assert!(true); // no safe remove, thanks Rust assert!(true); // no safe remove, thanks Rust
@ -421,9 +405,7 @@ pub fn compile_ast_ssa(
} }
} }
None => { None => {
let sym = ast.clone().symbol(); let sym = ast.symbol().unwrap();
assert!(sym.is_some());
let sym = sym.unwrap();
match match_number(&sym) { match match_number(&sym) {
Number::Int(i) => { Number::Int(i) => {
let key = format!("i32_{}", i); let key = format!("i32_{}", i);
@ -500,14 +482,14 @@ pub fn compile_fun_ssa(module: &mut Module, ops: &Vec<(Option<String>, String)>)
let mut out_pre = vec![]; let mut out_pre = vec![];
for t in &types { for t in &types {
let typ = parse_type(t); let typ = parse_type(t);
if has_id(fix_name(&typ.to_string()), ops) { if has_id(&fix_name(&typ.to_string()), ops) {
continue; continue;
} }
if has_id(fix_name(&typ.to_string()), &out_pre) { if has_id(&fix_name(&typ.to_string()), &out_pre) {
continue; continue;
} }
let mut type_ops = vec![]; let mut type_ops = vec![];
emit_type(typ, &mut type_ops); emit_type(&typ, &mut type_ops);
for type_op in type_ops { for type_op in type_ops {
out_pre.push((Some(type_op.0), type_op.1)); out_pre.push((Some(type_op.0), type_op.1));
} }

@ -194,7 +194,7 @@ pub fn compile_fun<I: Iterator<Item = Ast>>(
}; };
let fun = Function { let fun = Function {
name: name.to_string(), name: name.to_string(),
return_type: return_type, return_type,
arguments: vec![], arguments: vec![],
body: Some(vec![]), body: Some(vec![]),
ast: Some(Ast::List(Localised { ast: Some(Ast::List(Localised {

Loading…
Cancel
Save