flp_compiler/
lib.rs

1//! # The Official Floorplan Compiler Crate
2//!
3//! This module interfaces with the Haskell implementation of the
4//! Floorplan compiler, providing official support for compiling
5//! Floorplan specifications into Rust code directly from the
6//! cargo toolchain.
7//!
8//! In order to use this crate, you must have the `flp` executable
9//! on your `$PATH` when developing a Floorplan-based memory manager.
10//!
11//! In order to compile directly from the cargo toolchain, include a
12//! `build.rs` in your project root similar to the following:
13//! 
14//! ```rust,ignore
15//! extern crate flp_compiler as flpc;
16//!
17//! fn main() {
18//!    flpc::Build::new()
19//!        .src("src/heap/layout.flp")
20//!        .dest("src/heap/layout.rs")
21//!        .compile();
22//! }
23//! ```
24//!
25//! For information on acquiring the Floorplan compiler itself,
26//! go see the [GitHub project here][github-project].
27//!
28//! [github-project]: https://github.com/RedlineResearch/floorplan
29use std::process::*;
30use std::io::Write;
31
32/// A build configuration.
33#[derive(Clone, Debug)]
34pub struct Build {
35    src: Option<String>,
36    dest: Option<String>,
37}
38
39/// A very basic implementation of a binding to an external compiler, supporting
40/// specification of input and output files.
41impl Build {
42
43    /// Construct a new build configuration with default values, which will fail to compile
44    /// by default.
45    pub fn new() -> Build {
46        Build {
47            src: None,
48            dest: None,
49        }
50    }
51
52    /// Set the source `.flp` to be compiled.
53    pub fn src(&mut self, s: &str) -> &mut Build {
54        self.src = Some(s.to_string());
55        self
56    }
57
58    /// Set the destination `.rs` file to generate the output library into.
59    pub fn dest(&mut self, d: &str) -> &mut Build {
60        self.dest = Some(d.to_string());
61        self
62    }
63
64    /// Run the compiler on the current build configuration, failing miserably on error.
65    pub fn compile(&mut self) {
66        if let Err(e) = self.try_compile() {
67            fail(&e);
68        }
69    }
70
71    /// Attempt to run the compiler on the current build configuration, politely
72    /// returning an error message if the compiler fails.
73    pub fn try_compile(&mut self) -> Result<(), String> {
74        let src = self.src.clone().unwrap();
75        let dest = self.dest.clone().unwrap();
76        Command::new("flp")
77                .args(&[src, dest])
78                .output()
79                .expect("Floorplan failed to run.");
80        Ok(())
81    }
82
83}
84
85fn fail(s: &str) -> ! {
86    let _ = writeln!(std::io::stderr(), "\nError: {}\n\n", s);
87    std::process::exit(1);
88}
89