aboutsummaryrefslogtreecommitdiff
path: root/primrose
diff options
context:
space:
mode:
authorAria <me@aria.rip>2023-10-06 15:49:05 +0100
committerAria <me@aria.rip>2023-10-06 15:49:05 +0100
commit2d897a6cc7fe0eb259597c242af132f49f31a73a (patch)
tree951e3c2e694df9ef2ce6347225a093e581142f9a /primrose
parent0bd7ba9534b69051dd157237907a19a43059d136 (diff)
add some docs
Diffstat (limited to 'primrose')
-rw-r--r--primrose/src/generator.rs93
-rw-r--r--primrose/src/lib_spec_processor.rs26
2 files changed, 59 insertions, 60 deletions
diff --git a/primrose/src/generator.rs b/primrose/src/generator.rs
index 465fca2..b76a947 100644
--- a/primrose/src/generator.rs
+++ b/primrose/src/generator.rs
@@ -85,7 +85,7 @@ pub fn process_bound_decl(ctx: &InforMap) -> Result<String, ErrorMessage> {
Ok(code)
}
-// Generate the code ro replace the container delcaration in property specification
+/// Generate the code to replace the container declaration in property specification
pub fn process_con_decl(
ctx: &InforMap,
prop_specs: &PropSpecs,
@@ -307,70 +307,47 @@ fn library_spec_lookup(
Ok(structs)
}
-pub fn process_src(filename: String, model_size: usize) -> Result<Vec<String>, ErrorMessage> {
+/// Process the given file, returning code for all possible types
+pub fn gen_outputs(filename: String, model_size: usize) -> Result<Vec<String>, ErrorMessage> {
setup_dirs();
println!("Ready...");
let f = readfile(filename);
- match spec::prog(&f) {
- Ok(blocks) => {
- let mut tc = TypeChecker::new();
- match tc.check_prog(blocks.clone()) {
- // type checking
- Ok(_) => {
- // type checking ok
- // run analyser
- let mut analyser = Analyser::new();
- match analyser.analyse_prog(blocks.clone(), model_size) {
- Ok(_) => {
- let mut gen_code = Vec::new();
- // let mut result = String::new();
- // generate con types according to the information in con decl
- match process_bound_decl(analyser.get_ctx()) {
- Ok(code) => {
- let bound = code.clone();
- match process_con_decl(
- analyser.get_ctx(),
- analyser.get_prop_specs(),
- ) {
- Ok(gen_con_code) => {
- for code in gen_con_code.iter() {
- let mut result = bound.clone();
- result = CODEGEN.to_string()
- + IMPORT
- + &result
- + &code
- + CODEGENEND;
- // generate rust source code
- let code_blocks: Vec<&Block> = blocks
- .iter()
- .filter(|block| block.is_code_block())
- .collect();
- for block in code_blocks.iter() {
- result =
- result + &process_block(block.to_owned());
- }
- gen_code.push(result);
- }
- Ok(gen_code)
- }
- Err(e) => Err(e),
- }
- }
- Err(e) => Err(e),
- }
- }
- Err(e) => Err(e),
- }
- }
- Err(e) => Err(e),
- }
+
+ let blocks = spec::prog(&f).map_err(|_| "Error, invalid source code.".to_string())?;
+
+ // Type Checking
+ let mut tc = TypeChecker::new();
+ tc.check_prog(blocks.clone())?;
+
+ // Run Analysis
+ let mut analyser = Analyser::new();
+ analyser.analyse_prog(blocks.clone(), model_size)?;
+
+ let code = process_bound_decl(analyser.get_ctx())?;
+
+ // generate con types according to the information in con decl
+ let mut gen_code = Vec::new();
+ let gen_con_code = process_con_decl(analyser.get_ctx(), analyser.get_prop_specs())?;
+ for generated_code in gen_con_code.iter() {
+ let mut result = code.clone();
+ result = CODEGEN.to_string() + IMPORT + &result + &generated_code + CODEGENEND;
+ // generate rust source code
+ let code_blocks: Vec<&Block> = blocks
+ .iter()
+ .filter(|block| block.is_code_block())
+ .collect();
+ for block in code_blocks.iter() {
+ result = result + &process_block(block.to_owned());
}
- _ => Err("Error, invalid source code.".to_string()),
+ gen_code.push(result);
}
+
+ Ok(gen_code)
}
+/// Read input from the filename, calculate all valid implementations, and output them to seperate files in output_path
pub fn run(input: String, output_path: String, model_size: usize) -> Result<(), Error> {
- match process_src(input, model_size) {
+ match gen_outputs(input, model_size) {
Ok(gen_code) => {
let mut i = 0;
while i < gen_code.len() {
@@ -385,6 +362,8 @@ pub fn run(input: String, output_path: String, model_size: usize) -> Result<(),
}
}
+/// Mark all parts of the code so everything is between either CODE and CODEEND
+/// or SPEC and SPECEND
fn mark_src_blocks(src: String) -> String {
let mut trimed_src = src.trim();
let mut result = String::new();
diff --git a/primrose/src/lib_spec_processor.rs b/primrose/src/lib_spec_processor.rs
index 8f288db..6a60cf6 100644
--- a/primrose/src/lib_spec_processor.rs
+++ b/primrose/src/lib_spec_processor.rs
@@ -1,3 +1,5 @@
+//! Process library files and extracts library specifications
+
use std::collections::btree_map::Iter;
use std::collections::BTreeMap;
use std::collections::HashMap;
@@ -38,15 +40,28 @@ fn has_pragma_spec(src: &str) -> bool {
src.contains(LIBSPEC)
}
+/// Specifications extracted from a library file
pub struct LibraryFileSpec {
+ /// Name of the specification
spec_name: String,
+
+ /// Name of the specified structs
struct_name: String,
+
+ /// All specification code defined
specs: Vec<String>,
+
+ /// The provided rosette module name
provide: String,
+
+ /// The bounds of each operation
interface_provide_map: Bounds,
+
+ /// The provided operations
provided_ops: ProvidedOps,
}
+/// Read a library file and parse the spec
pub fn read_lib_file(filename: String) -> Result<LibraryFileSpec, ErrorMessage> {
let contents = fs::read_to_string(filename).expect("Something went wrong reading the file");
let trimed_contents = contents.trim().to_string();
@@ -94,7 +109,7 @@ pub fn read_lib_file(filename: String) -> Result<LibraryFileSpec, ErrorMessage>
match lib_specs {
Ok(LibSpec {
contents,
- mut result,
+ code: mut result,
op_infos,
provided_ops: mut ops,
}) => {
@@ -159,12 +174,17 @@ pub fn generate_provide(
}
pub struct LibSpec {
+ /// The contents of the LIBSPEC block
contents: String,
- result: Vec<String>,
+ /// The code define by the block
+ code: Vec<String>,
+ /// Hoare triples for each operation
op_infos: BTreeMap<String, (String, String, String)>,
+ /// Provided operation names
provided_ops: Vec<String>,
}
+/// Extract a spec from a LIBSPEC block
pub fn extract_lib_specs(src: String) -> Result<LibSpec, ErrorMessage> {
let mut result = Vec::<String>::new();
let mut contents = src.trim();
@@ -193,7 +213,7 @@ pub fn extract_lib_specs(src: String) -> Result<LibSpec, ErrorMessage> {
}
Ok(LibSpec {
contents: contents.to_string(),
- result,
+ code: result,
op_infos,
provided_ops,
})