M src/ast.rs +15 -0
@@ 64,6 64,7 @@ pub enum Decl {
pub enum Lit {
F32(f32),
Vec4F(f32, f32, f32, f32),
+ VecN(Vec<f32>),
Bool(bool),
Unit,
}
@@ 73,6 74,10 @@ impl Lit {
match self {
Lit::F32(_) => Type("F32".into()),
Lit::Vec4F(_, _, _, _) => Type("Vec4F".into()),
+ Lit::VecN(v) => {
+ let name = format!("Vec{}", v.len());
+ Type(name)
+ }
Lit::Bool(_) => Type("Bool".into()),
Lit::Unit => Type("()".into()),
}
@@ 109,6 114,16 @@ impl std::hash::Hash for Lit {
f_bits.hash(state)
}
}
+ Lit::VecN(v) => {
+ for f in v.as_slice() {
+ let f_bits = if f.is_nan() {
+ std::f32::NAN.to_bits()
+ } else {
+ f.to_bits()
+ };
+ f_bits.hash(state)
+ }
+ }
Lit::Bool(b) => b.hash(state),
Lit::Unit => ().hash(state),
}
M src/compile/mod.rs +29 -1
@@ 75,6 75,9 @@ impl CContext {
use verify::TypeDef;
s.add_type(&TypeDef::F32);
s.add_type(&TypeDef::Vec4F);
+ s.add_type(&TypeDef::VecN(2));
+ s.add_type(&TypeDef::VecN(3));
+ s.add_type(&TypeDef::VecN(4));
// Struct4<f32>
s.add_type(&TypeDef::Struct(vec![
("x".into(), TypeDef::F32),
@@ 145,7 148,7 @@ impl CContext {
// causes borrowing issues. :|
let type_float = self.get_type(&verify::TypeDef::F32);
let type_bool = self.get_type(&verify::TypeDef::Bool);
- let type_vec4f = self.get_type(&verify::TypeDef::Vec4F);
+ let type_vec4f = self.get_type(&verify::TypeDef::VecN(4));
//let type_unit = self.get_type(&verify::TypeDef::Unit);
let consts = &mut self.consts;
@@ 173,6 176,18 @@ impl CContext {
];
self.b.constant_composite(type_vec4f, &components)
}
+ ast::Lit::VecN(v) => {
+ assert!(
+ v.len() < (std::u32::MAX as usize),
+ "u w0t m8? can't happen"
+ );
+ let type_vec = self.get_type(&verify::TypeDef::VecN(v.len() as u32));
+ let components: Vec<_> = v
+ .iter()
+ .map(|n| self.define_const(ast::Lit::F32(*n)))
+ .collect();
+ self.b.constant_composite(type_vec, &components)
+ }
// TODO: This is WRONG WRONG WRONG but
// I'm not entirely sure how to make it right
// yet. Unit is not actually a value, so.
@@ 233,6 248,19 @@ impl CContext {
vec_type_word
}
}
+ TypeDef::VecN(n) => {
+ assert!(*n <= 4, "Vector of length {}, really? Try <= 4", n);
+ if let Some(val) = self.typetable.get(typedef) {
+ // VecN for that N already exists
+ *val
+ } else {
+ // Currently all vectors are vectors of F32
+ let f_type_word = self.add_type(&verify::TypeDef::F32);
+ let vec_type_word = self.b.type_vector(f_type_word, *n);
+ self.typetable.insert(typedef.clone(), vec_type_word);
+ vec_type_word
+ }
+ }
TypeDef::Bool => {
let b = &mut self.b;
*self
M src/compile/tests.rs +7 -0
@@ 36,8 36,15 @@ fn validate_module_header(asm: &str) ->
while p.peek().unwrap().contains("OpName ") {
p.next();
}
+ while p.peek().unwrap().contains("OpDecorate ") {
+ p.next();
+ }
// Skip built-in types
assert!(p.next().unwrap().contains("%1 = OpTypeFloat 32"));
+ assert!(p.next().unwrap().contains("%1 = OpTypeVector %1 4"));
+ assert!(p.next().unwrap().contains("%1 = OpTypeVector %1 2"));
+ assert!(p.next().unwrap().contains("%1 = OpTypeVector %1 3"));
+ assert!(p.next().unwrap().contains("%1 = OpTypeVector %1 4"));
assert!(p.next().unwrap().contains("%2 = OpTypeStruct %1 %1 %1 %1"));
assert!(p.next().unwrap().contains("%3 = OpTypeFunction %1 %1"));
assert!(p.next().unwrap().contains("%4 = OpTypeBool"));
M src/verify.rs +2 -1
@@ 75,7 75,8 @@ use crate::Error;
pub enum TypeDef {
F32,
Vec4F,
- //RAR VecN(u8, TypeDef)
+ /// For now vec's only contain f32's
+ VecN(u32),
Bool,
Unit,
Struct(Vec<(String, TypeDef)>),