2025-03-15 19:37:03 +01:00
|
|
|
|
use {
|
2025-04-02 14:11:17 +02:00
|
|
|
|
crate::{c_gen_types::{encode_morph_type_to_symbol, encode_type_to_symbol, encode_type_to_value, get_c_repr_type}, morphism::LdmcPrimMorph, struct_layout::{get_type_size, LayoutType, ObjectSize, StructLayout}}, chumsky::{chain::Chain, primitive::Container}, laddertypes::{morphism::{Morphism, MorphismInstance}, morphism_sugared::{MorphismInstance2, SugaredMorphism, SugaredMorphismType}, parser::*, substitution_sugared::SugaredSubstitution, unparser::*, Substitution, SugaredEnumVariant, SugaredStructMember, SugaredTypeTerm, TypeDict, TypeTerm}, std::collections::HashMap
|
2025-03-15 19:37:03 +01:00
|
|
|
|
};
|
|
|
|
|
|
2025-04-01 18:23:18 +02:00
|
|
|
|
impl LdmcPrimMorph {
|
|
|
|
|
pub fn instantiated_symbol_name(&self, dict: &mut impl TypeDict, σ: &impl SugaredSubstitution) -> String {
|
|
|
|
|
let mut s = self.symbol.clone();
|
|
|
|
|
for (k_id,v) in self.type_args.iter() {
|
|
|
|
|
if let Some(val_trm) = σ.get(k_id) {
|
|
|
|
|
if let laddertypes::TypeID::Var(var_id) = k_id {
|
|
|
|
|
let name = dict.get_varname(*var_id).unwrap();
|
|
|
|
|
let val_str = encode_type_to_symbol(dict, &val_trm);
|
|
|
|
|
s.push_str(&format!("_{}_{}", name, val_str));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if let laddertypes::TypeID::Var(var_id) = k_id {
|
|
|
|
|
let k = dict.get_varname(*var_id).unwrap();
|
|
|
|
|
s.push_str(&format!("_{:?}_MISSING", k));
|
|
|
|
|
eprintln!("INCOMPLETE MORPHISM INSTANTIATION, missing type parameter {} ({})", k, var_id);
|
2025-03-15 19:37:03 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-04-01 18:23:18 +02:00
|
|
|
|
s
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn expected_c_type_signature(&self, dict: &mut impl TypeDict,
|
|
|
|
|
σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::SugaredTypeTerm>
|
|
|
|
|
) -> String {
|
|
|
|
|
format!("int {} ({} const * restrict src, {} * restrict dst);",
|
|
|
|
|
self.instantiated_symbol_name(dict, σ),
|
|
|
|
|
get_c_repr_type(dict, self.ty.src_type.clone(), true).expect("cant get c-repr type for src type"),
|
|
|
|
|
get_c_repr_type(dict, self.ty.dst_type.clone(), true).expect("cant get c-repr type for dst type"))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn generate_instantiation(&self, dict: &mut impl TypeDict, σ: &impl SugaredSubstitution) -> Option<String> {
|
|
|
|
|
let mut s = String::new();
|
2025-04-02 14:11:17 +02:00
|
|
|
|
let symbol = self.instantiated_symbol_name(dict, σ);
|
|
|
|
|
let src_c_symbol = encode_type_to_symbol(dict, &self.ty.strip_halo().src_type);
|
|
|
|
|
let dst_c_symbol = encode_type_to_symbol(dict, &self.ty.strip_halo().dst_type);
|
2025-04-01 18:23:18 +02:00
|
|
|
|
|
|
|
|
|
s.push_str(&format!(r#"
|
|
|
|
|
int {} ( {} const * restrict src, {} * restrict dst ) {{
|
|
|
|
|
"#,
|
2025-04-02 14:11:17 +02:00
|
|
|
|
symbol, src_c_symbol, dst_c_symbol,
|
2025-04-01 18:23:18 +02:00
|
|
|
|
));
|
|
|
|
|
s.push_str(&self.c_source);
|
|
|
|
|
s.push_str(&format!(r#"
|
|
|
|
|
return 0;
|
|
|
|
|
}}
|
|
|
|
|
"#));
|
|
|
|
|
Some(s)
|
2025-03-15 19:37:03 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2025-04-01 18:23:18 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub struct LdmcCTargetMorph {
|
|
|
|
|
includes: Vec< String >,
|
2025-04-02 14:11:17 +02:00
|
|
|
|
active_types: Vec< SugaredTypeTerm >,
|
2025-04-01 18:23:18 +02:00
|
|
|
|
active_instantiations: Vec< LdmcPrimMorph >,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl LdmcCTargetMorph {
|
|
|
|
|
pub fn new() -> Self {
|
|
|
|
|
LdmcCTargetMorph {
|
2025-04-02 14:11:17 +02:00
|
|
|
|
includes: vec![
|
|
|
|
|
"#include <stdint.h>".into(),
|
|
|
|
|
],
|
|
|
|
|
active_instantiations: Vec::new(),
|
|
|
|
|
active_types: Vec::new(),
|
2025-03-15 19:37:03 +01:00
|
|
|
|
}
|
2025-04-01 18:23:18 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn add_instantiation(
|
|
|
|
|
&mut self,
|
|
|
|
|
dict: &mut impl TypeDict,
|
|
|
|
|
morph: MorphismInstance2<LdmcPrimMorph>,
|
|
|
|
|
) -> Result<LdmcPrimMorph, ()> {
|
|
|
|
|
let new_inst = self.bake_morphism(dict, morph)?;
|
|
|
|
|
if ! self.active_instantiations.contains(&new_inst) {
|
|
|
|
|
self.active_instantiations.push(new_inst.clone());
|
2025-03-15 19:37:03 +01:00
|
|
|
|
}
|
2025-04-02 14:11:17 +02:00
|
|
|
|
|
|
|
|
|
let ty = new_inst.get_type().strip_halo();
|
|
|
|
|
if ! self.active_types.contains(&ty.src_type) {
|
|
|
|
|
self.active_types.push(ty.src_type);
|
|
|
|
|
}
|
|
|
|
|
if ! self.active_types.contains(&ty.dst_type) {
|
|
|
|
|
self.active_types.push(ty.dst_type);
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-01 18:23:18 +02:00
|
|
|
|
Ok(new_inst)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn into_c_source(self, dict: &mut impl TypeDict) -> String {
|
|
|
|
|
let mut source = String::new();
|
|
|
|
|
for inc in self.includes {
|
|
|
|
|
source.push_str(&inc);
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-02 14:11:17 +02:00
|
|
|
|
for ty in self.active_types {
|
|
|
|
|
source.push_str(&format!("
|
|
|
|
|
typedef {} {};
|
|
|
|
|
",
|
|
|
|
|
get_c_repr_type(dict, ty.clone(), false).expect("cant get c-repr type"),
|
|
|
|
|
encode_type_to_symbol(dict, &ty)));
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-01 18:23:18 +02:00
|
|
|
|
for m in self.active_instantiations {
|
|
|
|
|
source.push_str(&m.generate_instantiation(dict, &HashMap::new()).expect("cant create function"));
|
2025-03-15 19:37:03 +01:00
|
|
|
|
}
|
2025-04-01 18:23:18 +02:00
|
|
|
|
|
|
|
|
|
source
|
2025-03-15 19:37:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
2025-04-01 18:23:18 +02:00
|
|
|
|
pub fn bake_morphism(
|
|
|
|
|
&mut self,
|
|
|
|
|
dict: &mut impl laddertypes::TypeDict,
|
|
|
|
|
morph_inst: MorphismInstance2<LdmcPrimMorph>,
|
|
|
|
|
) -> Result<LdmcPrimMorph, ()> {
|
|
|
|
|
|
|
|
|
|
match &morph_inst {
|
|
|
|
|
MorphismInstance2::Primitive { ψ, σ, morph } => {
|
|
|
|
|
let mut c_source = String::new();
|
|
|
|
|
for (ty_id, kind) in morph.type_args.iter() {
|
|
|
|
|
if let Some(val) = σ.get(ty_id) {
|
|
|
|
|
let type_var_value =
|
|
|
|
|
if let Some(c_repr_type) = get_c_repr_type(dict, val.clone(), true) {
|
|
|
|
|
c_repr_type
|
|
|
|
|
} else {
|
|
|
|
|
encode_type_to_value(dict, &val)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
c_source.push_str(&format!(" #define {} {}\n", dict.get_typename(&ty_id).unwrap(), type_var_value));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
c_source.push_str(&morph.c_source);
|
|
|
|
|
for (ty_id, kind) in morph.type_args.iter() {
|
|
|
|
|
c_source.push_str(&format!("\n #undef {}", dict.get_typename(&ty_id).unwrap()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(LdmcPrimMorph{
|
|
|
|
|
symbol: morph.instantiated_symbol_name(dict, σ),
|
|
|
|
|
type_args: Vec::new(),
|
2025-04-02 14:11:17 +02:00
|
|
|
|
ty: morph_inst.get_haloless_type(),
|
2025-04-01 18:23:18 +02:00
|
|
|
|
c_source
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
MorphismInstance2::Chain { path } => {
|
2025-04-02 14:11:17 +02:00
|
|
|
|
let ty = morph_inst.get_type().strip_halo();
|
|
|
|
|
let symbol = encode_morph_type_to_symbol(dict, &morph_inst.get_haloless_type());
|
2025-04-01 18:23:18 +02:00
|
|
|
|
|
|
|
|
|
let mut c_source = String::new();
|
|
|
|
|
|
|
|
|
|
if path.len() > 1 {
|
|
|
|
|
c_source.push_str(r#"
|
|
|
|
|
uint8_t bufA[128];
|
|
|
|
|
uint8_t bufB[128];
|
|
|
|
|
"#);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i,morph) in path.iter().enumerate() {
|
|
|
|
|
if let Ok(inst) = self.add_instantiation(dict, morph.clone()) {
|
|
|
|
|
let morph_symbol = inst.instantiated_symbol_name(dict, &morph.get_subst());
|
|
|
|
|
|
2025-04-02 14:31:47 +02:00
|
|
|
|
let src_c_type = encode_type_to_symbol(dict, &inst.get_type().strip_halo().src_type);
|
|
|
|
|
let dst_c_type = encode_type_to_symbol(dict, &inst.get_type().strip_halo().dst_type);
|
2025-04-01 18:23:18 +02:00
|
|
|
|
|
|
|
|
|
let src_buf = if i == 0 { "src" } else if i%2 == 0 { "(void*)bufA" } else { "(void*)bufB" };
|
|
|
|
|
let dst_buf = if i+1 == path.len() { "dst" } else if i%2 == 0 { "(void*)bufB" } else { "(void*)bufA" };
|
|
|
|
|
|
|
|
|
|
c_source.push_str(&format!(r#"
|
|
|
|
|
{{
|
|
|
|
|
{} const * restrict src = {};
|
|
|
|
|
{} * restrict dst = {};
|
|
|
|
|
{} ( src, dst );
|
|
|
|
|
}}"#,
|
|
|
|
|
src_c_type, src_buf,
|
|
|
|
|
dst_c_type, dst_buf,
|
|
|
|
|
morph_symbol
|
|
|
|
|
));
|
|
|
|
|
} else {
|
|
|
|
|
eprintln!("failed to add instantiation of item morphism");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(LdmcPrimMorph {
|
|
|
|
|
symbol, type_args: Vec::new(), ty,
|
|
|
|
|
c_source
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
MorphismInstance2::MapSeq { ψ, seq_repr, item_morph } => {
|
|
|
|
|
let i = 0; // <--todo
|
2025-04-02 14:11:17 +02:00
|
|
|
|
self.add_instantiation(dict, item_morph.as_ref().clone()).expect("add instantiation");
|
2025-04-01 18:23:18 +02:00
|
|
|
|
if let Some(seq_repr) = seq_repr {
|
|
|
|
|
|
|
|
|
|
dict.add_varname("LengthType".into());
|
|
|
|
|
if let Ok(γ) = laddertypes::unification_sugared::unify(
|
|
|
|
|
&dict.parse("<LengthPrefix LengthType>").expect("parse type template").sugar(dict),
|
|
|
|
|
seq_repr.as_ref()
|
|
|
|
|
) {
|
|
|
|
|
let length_type = γ.get(&dict.get_typeid(&"LengthType".into()).expect("")).expect("cant get LengthType");
|
2025-04-02 14:11:17 +02:00
|
|
|
|
let ty = morph_inst.get_type().strip_halo();
|
|
|
|
|
let symbol = encode_morph_type_to_symbol(dict, &morph_inst.get_haloless_type());
|
|
|
|
|
let item_morph_symbol = encode_morph_type_to_symbol(dict, &item_morph.get_haloless_type());
|
2025-04-01 18:23:18 +02:00
|
|
|
|
|
|
|
|
|
let length_c_type = get_c_repr_type(dict, length_type.clone(), true).expect("cant c-repr type for array length");
|
2025-04-02 14:11:17 +02:00
|
|
|
|
let src_item_c_type = get_c_repr_type(dict, item_morph.get_haloless_type().src_type, true).expect("cant c-repr type for src item");
|
|
|
|
|
let dst_item_c_type = get_c_repr_type(dict, item_morph.get_haloless_type().dst_type, true).expect("cant c-repr type for dst item");
|
2025-04-02 14:31:47 +02:00
|
|
|
|
let src_c_type = encode_type_to_symbol(dict, &ty.src_type);
|
|
|
|
|
let dst_c_type = encode_type_to_symbol(dict, &ty.dst_type);
|
|
|
|
|
|
|
|
|
|
// todo: self.add_active_length_prefix_map()
|
2025-04-01 18:23:18 +02:00
|
|
|
|
|
|
|
|
|
let map_fn = format!("length_prefix_{}_array_map_{}_to_{}",
|
|
|
|
|
length_c_type, src_item_c_type, dst_item_c_type
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
let src_buf = if i%2 == 0 { "bufA" } else { "bufB" };
|
|
|
|
|
let dst_buf = if i%2 == 0 { "bufB" } else { "bufA" };
|
|
|
|
|
let c_source = format!(r#"
|
|
|
|
|
{{
|
|
|
|
|
{} const * restrict src = (void*) {};
|
|
|
|
|
{} * restrict dst = (void*) {};
|
|
|
|
|
{} ( {}, src, dst );
|
|
|
|
|
}}"#,
|
|
|
|
|
src_c_type, src_buf,
|
|
|
|
|
dst_c_type, dst_buf,
|
|
|
|
|
map_fn,
|
|
|
|
|
item_morph_symbol,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
Ok(LdmcPrimMorph{
|
|
|
|
|
symbol, type_args: Vec::new(), ty,
|
|
|
|
|
c_source
|
|
|
|
|
})
|
|
|
|
|
} else {
|
|
|
|
|
eprintln!("Error: Unknown Seq- Representation!!");
|
|
|
|
|
Err(())
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
eprintln!("Error: missing Seq- Representation!!");
|
|
|
|
|
Err(())
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
MorphismInstance2::MapStruct { ψ, struct_repr, member_morph } => {
|
2025-04-02 14:11:17 +02:00
|
|
|
|
let ty = morph_inst.get_type().strip_halo();
|
|
|
|
|
let symbol =encode_morph_type_to_symbol(dict, &morph_inst.get_haloless_type());
|
2025-04-01 18:23:18 +02:00
|
|
|
|
|
|
|
|
|
let mut c_source = String::new();
|
|
|
|
|
|
|
|
|
|
for (name, morph) in member_morph.iter() {
|
|
|
|
|
if let Ok(inst) = self.add_instantiation(dict, morph.clone()) {
|
2025-04-02 14:11:17 +02:00
|
|
|
|
let name = name.replace("-", "_").replace(".","_dot_");
|
2025-04-01 18:23:18 +02:00
|
|
|
|
c_source.push_str(
|
|
|
|
|
&format!("
|
|
|
|
|
{} ( &src->{}, &dst->{} );
|
|
|
|
|
",
|
|
|
|
|
inst.symbol,
|
|
|
|
|
name, name
|
|
|
|
|
));
|
|
|
|
|
} else {
|
|
|
|
|
eprintln!("failed to create morphism instantiation for struct member");
|
|
|
|
|
return Err(());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(LdmcPrimMorph{
|
|
|
|
|
symbol, type_args: Vec::new(), ty,
|
|
|
|
|
c_source
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
MorphismInstance2::MapEnum { ψ, enum_repr, variant_morph } => {
|
|
|
|
|
todo!();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-03-15 19:37:03 +01:00
|
|
|
|
}
|