Well the compiler command-line program works now!

Just can't, you know, get anything useful as input.
4 files changed, 65 insertions(+), 2 deletions(-)

M src/compile/mod.rs
M src/lib.rs
M src/main.rs
M src/parser.pest
M src/compile/mod.rs +7 -0
@@ 662,6 662,13 @@ impl CContext {
         }
         */
     }
+
+    /// Returns the generated output instructions.
+    /// Consumes self.
+    pub fn output(self) -> Vec<u32> {
+        use rspirv::binary::Assemble;
+        self.b.module().assemble()
+    }
 }
 
 pub fn compile(ctx: &verify::VContext) -> Result<CContext, crate::Error> {

          
M src/lib.rs +48 -0
@@ 32,6 32,54 @@ impl From<rspirv::mr::Error> for Error {
     }
 }
 
+/// TODO: Parser.
+pub fn parse(input: &str) -> Vec<ast::Decl> {
+    use pest::Parser;
+    let parser = ChParser::parse(Rule::program, input).expect("Could not parse program!");
+    for pair in parser {
+        println!("Pair: {:?}", pair);
+    }
+    vec![]
+}
+
+/// Well, SPIR-V is defined to be a list of u32 words, but its byte order is undefined,
+/// and we need a slice of bytes to write to a file.  So, this is just a convenient
+/// converter function that encodes it in little-endian format.  Since in practice all
+/// systems that matter are little-endian anyway.
+///
+/// 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.
+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
+    when I want to move it.  Oh well, we do it the dumb way.
+     */
+    /*
+    words
+        .iter()
+        .copied()
+        .flat_map(|word| word.to_le_bytes().into_iter())
+        .cloned()
+        .collect()
+     */
+    let mut res = Vec::with_capacity(words.len() * 4);
+    for word in words {
+        let bytes = word.to_le_bytes();
+        res.extend(&bytes[..]);
+    }
+    res
+}
+
+/// Top-level driver function that goes from a source string to
+/// SPIR-V output.  Currently panics on error.
+pub fn compile(input: &str) -> Vec<u32> {
+    let ast = parse(input);
+    let ctx = verify::verify(ast).expect("Verification failed");
+    let cc = compile::compile(&ctx).expect("Compilation failed!");
+    cc.output()
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;

          
M src/main.rs +7 -1
@@ 1,3 1,4 @@ 
+use chrysanthemum as c;
 use structopt::StructOpt;
 
 use std::fs;

          
@@ 15,7 16,12 @@ struct Opt {
 
 fn main() {
     let opt = Opt::from_args();
-    let contents = fs::read_to_string(opt.input).expect("Could not read input file");
+    let contents = fs::read_to_string(&opt.input).expect("Could not read input file");
+
+    let output = c::compile(&contents);
+    let output_bytes = c::words_to_bytes_le(&output);
+
     let mut output_path = opt.input.clone();
     output_path.set_extension("spv");
+    fs::write(output_path, output_bytes).expect("Could not write to output file");
 }

          
M src/parser.pest +3 -1
@@ 1,4 1,6 @@ 
 alpha = { 'a'..'z' | 'A'..'Z' }
 digit = { '0'..'9' }
 
-ident = { (alpha | digit)+ }
  No newline at end of file
+ident = { (alpha | digit)+ }
+
+program = { ident }
  No newline at end of file