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