diff --git a/src/c_gen/gen_lib.rs b/src/c_gen/gen_lib.rs index f8858bb..95359cc 100644 --- a/src/c_gen/gen_lib.rs +++ b/src/c_gen/gen_lib.rs @@ -1,12 +1,14 @@ use { - super::types::get_c_repr_arg_type, crate::{c_gen::LdmcCTargetMorph, LdmcPrimMorph}, laddertypes::{morphism::MorphismInstance, parser::*, TypeDict}, std::collections::HashMap + super::types::get_c_repr_arg_type, crate::{c_gen::LdmcCTargetMorph, LdmcPrimMorph}, laddertypes::{morphism::MorphismInstance, parser::*, MorphismType, TypeDict}, std::collections::HashMap }; pub fn generate_lib( dict: &mut impl TypeDict, + include_blocks: Vec< String >, + include_dependencies: HashMap< MorphismType, usize >, morphisms: Vec< (String, MorphismInstance<LdmcPrimMorph>) > ) -> Result<String, ()> { - let mut target = LdmcCTargetMorph::new(); + let mut target = LdmcCTargetMorph::new( include_blocks, include_dependencies ); let mut wrappers = String::new(); for (name, morph) in morphisms { diff --git a/src/c_gen/morph/target_morph.rs b/src/c_gen/morph/target_morph.rs index fcb90fb..161d6fa 100644 --- a/src/c_gen/morph/target_morph.rs +++ b/src/c_gen/morph/target_morph.rs @@ -1,18 +1,20 @@ use { crate::{ c_gen::types::{ - encode_morph_type_to_symbol, get_c_repr_definition, get_c_repr_type, encode_type_to_value + encode_morph_type_to_symbol, encode_type_to_value, get_c_repr_definition, get_c_repr_kind, get_c_repr_type }, morphism::LdmcPrimMorph }, laddertypes::{ - parser::*, MorphismInstance, TypeDict, TypeTerm, Morphism + parser::*, Morphism, MorphismInstance, MorphismType, TypeDict, TypeTerm }, std::collections::HashMap }; pub struct LdmcCTargetMorph { - includes: Vec< String >, + include_blocks: Vec< String >, + include_dependencies: HashMap< MorphismType, usize >, + active_includes: Vec< usize >, active_types: Vec< TypeTerm >, active_instantiations: Vec< LdmcPrimMorph >, active_lenpfx_types: Vec< (TypeTerm, TypeTerm) >, @@ -21,19 +23,35 @@ pub struct LdmcCTargetMorph { } impl LdmcCTargetMorph { - pub fn new() -> Self { - LdmcCTargetMorph { - includes: vec![ - "#include <stdint.h>".into(), - "#include <array/length-prefix.h>".into(), - "#define FUSE(morph, src, dst) { int result = morph(src,dst); if(result) return result; }".into(), - ], + pub fn add_required_include_block(&mut self, block: String) { + let i = self.include_blocks.len(); + self.active_includes.push(i); + self.include_blocks.push(block); + } + + pub fn new( + include_blocks: Vec< String >, + include_dependencies: HashMap< MorphismType, usize > + ) -> Self { + let mut m = LdmcCTargetMorph { + include_blocks, + include_dependencies, + active_includes: Vec::new(), active_instantiations: Vec::new(), active_types: Vec::new(), active_lenpfx_types: Vec::new(), typedefs: Vec::new(), macro_calls: Vec::new() - } + }; + + m.add_required_include_block( + "/* default ldmc includes */ +#include <stdint.h> +#define FUSE(morph, src, dst) { int result = morph(src,dst); if(result) return result; } + +".into() + ); + m } pub fn add_type(&mut self, dict: &mut impl TypeDict, ty: TypeTerm) { @@ -106,15 +124,14 @@ impl LdmcCTargetMorph { pub fn into_c_source(mut self, dict: &mut impl TypeDict) -> String { let mut source = String::new(); - self.includes.dedup(); + self.active_includes.dedup(); + self.typedefs.dedup(); self.macro_calls.dedup(); - self.active_types.dedup(); - for inc in self.includes { - source.push_str(&inc); + for i in self.active_includes { + source.push_str( &self.include_blocks[i] ); source.push('\n'); } - source.push('\n'); for typedef in self.typedefs { @@ -146,6 +163,11 @@ impl LdmcCTargetMorph { match &morph_inst { MorphismInstance::Primitive { ψ, σ, morph } => { + if let Some(i) = self.include_dependencies.get(&morph.get_type()) { + self.active_includes.push(*i); + } + + let mut c_source = String::new(); for (ty_id, kind) in morph.type_args.iter() { if let laddertypes::TypeID::Var(var_id) = ty_id { diff --git a/src/main.rs b/src/main.rs index 5951618..8e8f40b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,15 +9,9 @@ use { crate::{ morphism::LdmcPrimMorph, parser::morphism_base_parser, - }, - laddertypes::{ - morphism::MorphismType, BimapTypeDict - }, parser::morphism_type_parser, - ariadne::{Color, Label, Report, ReportKind, Source}, - clap::Parser, - walkdir::WalkDir, - tiny_ansi::TinyAnsi, - std::{path::PathBuf, sync::{Arc, RwLock}, io::Write}, + }, ariadne::{Color, Label, Report, ReportKind, Source}, clap::Parser, laddertypes::{ + morphism::MorphismType, BimapTypeDict, Morphism + }, parser::morphism_type_parser, std::{io::Write, path::PathBuf, sync::{Arc, RwLock}}, tiny_ansi::TinyAnsi, walkdir::WalkDir }; #[derive(Parser, Debug)] @@ -66,6 +60,10 @@ fn main() { } // 1.2. read files + + let mut include_blocks = Vec::new(); + let mut include_dependencies = std::collections::HashMap::new(); + for mb_path in mb_paths { let src = std::fs::read_to_string(mb_path.clone()).expect("failed to read morphism base"); @@ -73,9 +71,16 @@ fn main() { let result = morphism_base_parser(type_dict.clone()).parse(src.clone()); match result { Ok((includes, morphisms)) => { - println!("{}",includes); eprintln!("[{}] parse ok.", mb_path.to_str().unwrap().bright_yellow()); + + let include_idx = include_blocks.len(); + + let mut includes_prefixed = format!("/* from `{}` */", mb_path.display()); + includes_prefixed.push_str(&includes); + include_blocks.push(includes_prefixed); + for m in morphisms { + include_dependencies.insert( m.get_type(), include_idx ); morphism_base.add_morphism(m); } } @@ -106,7 +111,7 @@ fn main() { } } - let c_source = crate::c_gen::gen_lib::generate_lib(&mut type_dict, instances).expect("failed to generate library"); + let c_source = crate::c_gen::gen_lib::generate_lib(&mut type_dict, include_blocks, include_dependencies, instances).expect("failed to generate library"); if let Some(out_path) = args.output { let mut file = std::fs::File::create(out_path).expect("failed to open output file"); file.write_all(c_source.as_bytes()).expect("failed to write output file");