Passing through, making some notes
4 files changed, 56 insertions(+), 8 deletions(-)

M src/ast.rs
M src/compile/mod.rs
M src/lib.rs
M src/verify.rs
M src/ast.rs +7 -0
@@ 27,12 27,14 @@ impl From<&str> for Type {
     }
 }
 
+/// A parameter for a function.
 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
 pub struct Param {
     pub name: String,
     pub typ: Type,
 }
 
+/// A function declaration.
 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
 pub struct FunctionDecl {
     pub name: String,

          
@@ 41,12 43,14 @@ pub struct FunctionDecl {
     pub body: Vec<Expr>,
 }
 
+/// A structure declaration
 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
 pub struct StructureDecl {
     pub name: String,
     pub fields: Vec<(String, Type)>,
 }
 
+/// A declaration of some kind or another
 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
 pub enum Decl {
     /// Function definition

          
@@ 55,6 59,7 @@ pub enum Decl {
     Structure(StructureDecl),
 }
 
+/// A literal value.
 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, PartialOrd)]
 pub enum Lit {
     F32(f32),

          
@@ 159,6 164,8 @@ pub enum Pattern {
 pub type Exprs = Vec<Expr>;
 
 /// Expression that returns a value.
+///
+/// TODO: All of these need a span of some kind in the thing.
 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
 pub enum Expr {
     /// Unary operation

          
M src/compile/mod.rs +19 -7
@@ 98,9 98,11 @@ impl CContext {
     }
 
     /// Binds the variable to the current scope.
-    /// Will overwrite any previous binding.  That's fine.
+    /// Will overwrite any previous binding in this scope.  That's fine,
+    /// since there's no way to refer to a shadowed variable.
     ///
-    /// Panics if no scope.
+    /// # Panics
+    /// Panics if no scope exists
     pub fn bind_var(&mut self, name: &str, address: spirv::Word, typedef: spirv::Word) {
         self.symtable
             .last_mut()

          
@@ 108,8 110,13 @@ impl CContext {
             .insert(name.into(), VarBinding { address, typedef });
     }
 
-    /// Returns the Word bound to the given var name, or panics if not found.
-    /// All unknown vars should get caught by the validation step.
+    /// Returns the Word bound to the given var name
+    ///
+    /// # Panics
+    /// Panics if no scope exists.
+    ///
+    /// Panics if var name is not bound; all unknown vars should
+    /// get caught by the validation step.
     pub fn lookup_var(&self, name: &str) -> &VarBinding {
         assert!(!self.symtable.is_empty(), "No scope for variable lookup!");
         for scope in self.symtable.iter().rev() {

          
@@ 177,9 184,14 @@ impl CContext {
         }
     }
 
-    /// Panics if the type does not exist.
+    /// Gets the type with the given definition.
     ///
     /// TODO: Should this take a name and a VContext instead of a TypeDef?
+    /// mmmmmmmaybe.  Probably.  We probably do want name equality rather
+    /// than structural equality.
+    ///
+    /// # Panics
+    /// Panics if the type does not exist.
     pub fn get_type(&self, t: &verify::TypeDef) -> spirv::Word {
         *self.typetable.get(t).expect("Could not get type!")
     }

          
@@ 276,8 288,8 @@ impl CContext {
         }
     }
 
-    /// Returns the two Word's, the first holding the result of the expression,
-    /// the second holdin its type.
+    /// Returns two Word's, the first holding the result of the expression,
+    /// the second holding its type.
     pub fn compile_expr(
         &mut self,
         e: &ast::Expr,

          
M src/lib.rs +20 -1
@@ 1,4 1,5 @@ 
 use std::borrow::Cow;
+use std::fmt;
 
 use pest;
 use pest_derive::Parser;

          
@@ 32,6 33,21 @@ impl From<rspirv::mr::Error> for Error {
     }
 }
 
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match self {
+            Error::TypeMismatch(t1, t2) => {
+                write!(f, "Type mismatch: expected {:?}, got {:?}", t1, t2)
+            }
+            Error::Validation(v) => write!(f, "Validation failed: {}", v),
+            Error::SymbolExists(s) => write!(f, "Tried to redefine symbol: {}", s),
+            Error::CodegenError => write!(f, "Miscellanious codegen error of some kind"),
+        }
+    }
+}
+
+impl std::error::Error for Error {}
+
 /// TODO: Parser.
 pub fn parse(input: &str) -> Vec<ast::Decl> {
     use pest::Parser;

          
@@ 39,7 55,7 @@ pub fn parse(input: &str) -> Vec<ast::De
     for pair in parser {
         println!("Pair: {:?}", pair);
     }
-    vec![]
+    unimplemented!("No parser yet")
 }
 
 /// Well, SPIR-V is defined to be a list of u32 words, but its byte order is undefined,

          
@@ 50,6 66,7 @@ pub fn parse(input: &str) -> Vec<ast::De
 /// We COULD use unsafe to just cast the `&[u32]` to `&[u8]`, but that would be lame
 /// and platform-specific, so we do it RIGHT, copying the buffer in the process.
 /// Fite me.
+/// TODO: The `bytemuck` crate might make this better?
 pub fn words_to_bytes_le(words: &[u32]) -> Vec<u8> {
     /* Iterating over the [u8;4]'s is *problematic*,
     all the solutions I can come up with borrow it first

          
@@ 74,6 91,7 @@ pub fn compile(input: &str) -> Vec<u32> 
 
 #[cfg(test)]
 mod tests {
+    /*
     use super::*;
     use pest::Parser;
 

          
@@ 82,4 100,5 @@ mod tests {
         let input = "hello world";
         let _pairs = ChParser::parse(Rule::ident, input).unwrap();
     }
+    */
 }

          
M src/verify.rs +10 -0
@@ 64,16 64,26 @@ use crate::Error;
 /// has a particular type for vectors.  Hmm, for now
 /// let's just treat them as structs, it might change
 /// later.
+///
+/// The trick to vectors is really the layout, and
+/// the swizzling operators.  Both of these kiiiinda
+/// matter.  So we can either special case vectors
+/// as types, or special case any struct that
+/// could look like a vector.  Special casing
+/// vectors seems easier.
 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
 pub enum TypeDef {
     F32,
     Vec4F,
+    //RAR VecN(u8, TypeDef)
     Bool,
     Unit,
     Struct(Vec<(String, TypeDef)>),
     Function(Vec<TypeDef>, Box<TypeDef>),
 }
 
+//RAR pub type FunctionType = (Vec<TypeDef>, Box<TypeDef>)
+
 /// A function definition; the AST and whatever
 /// other information we care about that can get
 /// fed to the actual compiler-y bits.