From 2d897a6cc7fe0eb259597c242af132f49f31a73a Mon Sep 17 00:00:00 2001 From: Aria Date: Fri, 6 Oct 2023 15:49:05 +0100 Subject: add some docs --- primrose/src/generator.rs | 93 +++++++++++++++----------------------- primrose/src/lib_spec_processor.rs | 26 +++++++++-- 2 files changed, 59 insertions(+), 60 deletions(-) (limited to 'primrose') 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 { 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, ErrorMessage> { +/// Process the given file, returning code for all possible types +pub fn gen_outputs(filename: String, model_size: usize) -> Result, 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, + + /// 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 { 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 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, + /// The code define by the block + code: Vec, + /// Hoare triples for each operation op_infos: BTreeMap, + /// Provided operation names provided_ops: Vec, } +/// Extract a spec from a LIBSPEC block pub fn extract_lib_specs(src: String) -> Result { let mut result = Vec::::new(); let mut contents = src.trim(); @@ -193,7 +213,7 @@ pub fn extract_lib_specs(src: String) -> Result { } Ok(LibSpec { contents: contents.to_string(), - result, + code: result, op_infos, provided_ops, }) -- cgit v1.2.3