Making variable-length vectors isn't too hard maybe
4 files changed, 53 insertions(+), 2 deletions(-)

M src/ast.rs
M src/compile/mod.rs
M src/compile/tests.rs
M src/verify.rs
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)>),