manage include blocks & only output required blocks once

This commit is contained in:
Michael Sippel 2025-05-10 16:27:56 +02:00
parent efa584dfb5
commit 4a705241fe
Signed by: senvas
GPG key ID: F96CF119C34B64A6
3 changed files with 58 additions and 29 deletions

View file

@ -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 {

View file

@ -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 {

View file

@ -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");