wip struct morphisms
This commit is contained in:
parent
1869176bb7
commit
21bb33193a
4 changed files with 496 additions and 39 deletions
133
src/c_gen.rs
133
src/c_gen.rs
|
@ -1,6 +1,6 @@
|
|||
use {
|
||||
laddertypes::{TypeDict, TypeTerm, parser::*, unparser::*, morphism::{Morphism, MorphismInstance}},
|
||||
crate::morphism::{LdmcPrimCMorphism, LdmcMorphism}
|
||||
crate::{morphism::{LdmcMorphism, LdmcPrimCMorphism}, struct_layout::{get_type_size, ObjectSize, StructLayout}},
|
||||
laddertypes::{morphism::{Morphism, MorphismInstance}, parser::*, unparser::*, TypeDict, TypeTerm},
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -85,7 +85,23 @@ pub fn get_c_repr_type(dict: &mut impl TypeDict, t: laddertypes::TypeTerm, skip_
|
|||
}
|
||||
}
|
||||
else {
|
||||
None
|
||||
|
||||
if let Some(layout) = StructLayout::parse(dict, t.clone()) {
|
||||
let mut c_type = String::from("struct {\n");
|
||||
|
||||
for (field_name, field_type) in layout.members.iter() {
|
||||
let field_c_type = get_c_repr_type(dict, field_type.clone(), false).expect("");
|
||||
c_type.push_str(&format!(" {} {};\n",
|
||||
field_c_type,
|
||||
field_name
|
||||
));
|
||||
}
|
||||
|
||||
c_type.push_str("}");
|
||||
Some(c_type)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -205,14 +221,17 @@ morph {}
|
|||
---> {},
|
||||
subst σ = {:?},
|
||||
halo Ψ = {}
|
||||
*/"#,
|
||||
*/
|
||||
{}
|
||||
"#,
|
||||
type_dict.unparse(&morph_inst.get_type().dst_type.param_normalize().decurry()),
|
||||
type_dict.unparse(&morph_inst.m.get_type().src_type),
|
||||
type_dict.unparse(&morph_inst.m.get_type().dst_type),
|
||||
morph_inst.σ,
|
||||
type_dict.unparse(&morph_inst.halo),
|
||||
morph_inst.m.generate_call(type_dict, &morph_inst.σ, i)
|
||||
);
|
||||
morph_inst.m.generate_call(type_dict, &morph_inst.σ, i);
|
||||
|
||||
i += 1;
|
||||
}
|
||||
|
||||
|
@ -322,7 +341,42 @@ int {} ( {} const * restrict src, {} * restrict dst ) {{
|
|||
}
|
||||
|
||||
impl LdmcMorphism {
|
||||
pub fn generate_call(&self, dict: &mut impl TypeDict, σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>, i: u64) {
|
||||
pub fn into_prim_c_morphism(self, dict: &mut impl laddertypes::TypeDict, symbol: String, σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>) -> LdmcPrimCMorphism {
|
||||
|
||||
let src_type = self.get_type().src_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone();
|
||||
let dst_type = self.get_type().dst_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone();
|
||||
|
||||
let src_c_type = get_c_repr_type(dict, src_type.clone(), true).expect("cant get c-repr type for src type");
|
||||
let dst_c_type = get_c_repr_type(dict, dst_type.clone(), true).expect("cant get c-repr type for src type");
|
||||
|
||||
let c_source =
|
||||
format!("
|
||||
typedef {} {}_src_t;
|
||||
|
||||
typedef {} {}_dst_t;
|
||||
|
||||
int {} ( {}_src_t const * restrict src, {}_dst_t * restrict dst )
|
||||
{{
|
||||
{}
|
||||
return 0;
|
||||
}}
|
||||
",
|
||||
src_c_type, symbol,
|
||||
dst_c_type, symbol,
|
||||
symbol, symbol, symbol,
|
||||
self.generate_call(dict, σ, 0)
|
||||
);
|
||||
|
||||
LdmcPrimCMorphism {
|
||||
symbol,
|
||||
type_args: Vec::new(),
|
||||
src_type,
|
||||
dst_type,
|
||||
c_source
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_call(&self, dict: &mut impl TypeDict, σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>, i: u64) -> String {
|
||||
match self {
|
||||
LdmcMorphism::Primitive(prim_morph) => {
|
||||
let src_c_type = get_c_repr_type(dict, prim_morph.src_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone(), true).expect("cant get c-repr type for src type");
|
||||
|
@ -331,17 +385,16 @@ impl LdmcMorphism {
|
|||
let src_buf = if i%2 == 0 { "bufA" } else { "bufB" };
|
||||
let dst_buf = if i%2 == 0 { "bufB" } else { "bufA" };
|
||||
|
||||
println!(r#"
|
||||
{}
|
||||
format!(r#"
|
||||
{{
|
||||
{} const * restrict src = (void*) {};
|
||||
{} * restrict dst = (void*) {};
|
||||
{} ( src, dst );
|
||||
{}"#,
|
||||
'{',
|
||||
}}"#,
|
||||
src_c_type, src_buf,
|
||||
dst_c_type, dst_buf,
|
||||
prim_morph.instantiated_symbol_name(dict, σ),
|
||||
'}');
|
||||
)
|
||||
}
|
||||
LdmcMorphism::LengthPrefixMap { length_prefix_type, item_morph } => {
|
||||
let src_type = self.get_type().src_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone();
|
||||
|
@ -383,18 +436,17 @@ impl LdmcMorphism {
|
|||
|
||||
let src_buf = if i%2 == 0 { "bufA" } else { "bufB" };
|
||||
let dst_buf = if i%2 == 0 { "bufB" } else { "bufA" };
|
||||
println!(r#"
|
||||
{}
|
||||
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.instantiated_symbol_name(dict, σ),
|
||||
'}');
|
||||
)
|
||||
}
|
||||
LdmcMorphism::ValueDelimMap { delim, item_morph } => {
|
||||
let src_c_type = get_c_repr_type(dict, item_morph.src_type.clone(), false).expect("cant get c-repr type for src type");
|
||||
|
@ -402,17 +454,54 @@ impl LdmcMorphism {
|
|||
|
||||
let src_buf = if i%2 == 0 { "bufA" } else { "bufB" };
|
||||
let dst_buf = if i%2 == 0 { "bufB" } else { "bufA" };
|
||||
println!(r#"
|
||||
{}
|
||||
format!(r#"
|
||||
{{
|
||||
{} const * restrict src = (void*) {};
|
||||
{} * restrict dst = (void*) {};
|
||||
value_delim_array_map_8_to_64( {}, src, dst );
|
||||
{}"#,
|
||||
'{',
|
||||
}}"#,
|
||||
src_c_type, src_buf,
|
||||
dst_c_type, dst_buf,
|
||||
item_morph.instantiated_symbol_name(dict, σ),
|
||||
'}');
|
||||
item_morph.instantiated_symbol_name(dict, σ)
|
||||
)
|
||||
},
|
||||
|
||||
LdmcMorphism::StructMap { src_struct, dst_struct, member_morphisms } => {
|
||||
let mut output = String::new();
|
||||
for member_morph in member_morphisms.iter() {
|
||||
if let Some(m) = member_morph.item_morph.as_ref() {
|
||||
//let src_c_type = get_c_repr_type(dict, m.src_type.clone(), false).expect("cant get c-repr type for field member");
|
||||
//let dst_c_type = get_c_repr_type(dict, m.dst_type.clone(), false).expect("cant get c-repr type for field member");
|
||||
|
||||
output.push_str(&format!(" {} ( &src->{}, &dst->{} );\n",
|
||||
m.instantiated_symbol_name(dict, σ),
|
||||
member_morph.field_name,
|
||||
member_morph.field_name
|
||||
));
|
||||
} else {
|
||||
let mut field_type = None;
|
||||
for (field_name, ft) in src_struct.members.iter() {
|
||||
if field_name == &member_morph.field_name {
|
||||
field_type = Some(ft);
|
||||
}
|
||||
}
|
||||
|
||||
let field_type = field_type.expect("cant get field member type");
|
||||
//if let Some(field_c_type) = get_c_repr_type(dict, field_type.clone(), false).expect("cat get c-repr type for field member");
|
||||
|
||||
match get_type_size(dict, field_type.clone()) {
|
||||
ObjectSize::Static(size) => {
|
||||
output.push_str(&format!(" memcpy( &dst->{}, &src->{}, sizeof(dst->{}) );\n",
|
||||
member_morph.field_name, member_morph.field_name, member_morph.field_name
|
||||
));
|
||||
}
|
||||
_ => {
|
||||
eprintln!("cant assign field of unknown size!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
output
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
119
src/main.rs
119
src/main.rs
|
@ -3,29 +3,25 @@
|
|||
mod morphism;
|
||||
mod parser;
|
||||
mod c_gen;
|
||||
mod struct_layout;
|
||||
|
||||
use {
|
||||
ariadne::{Color, Label, Report, ReportKind, Source},
|
||||
chumsky::prelude::*,
|
||||
laddertypes::{
|
||||
parser::ParseLadderType, BimapTypeDict, MorphismType
|
||||
},
|
||||
std::sync::{Arc, RwLock},
|
||||
tiny_ansi::TinyAnsi,
|
||||
|
||||
|
||||
crate::{
|
||||
morphism::LdmcMorphism,
|
||||
parser::morphism_base_parser,
|
||||
}
|
||||
}, ariadne::{Color, Label, Report, ReportKind, Source}, chumsky::prelude::*, laddertypes::{
|
||||
parser::ParseLadderType, unparser::*, BimapTypeDict, MorphismType, TypeDict
|
||||
}, std::{collections::HashMap, sync::{Arc, RwLock}}, tiny_ansi::TinyAnsi
|
||||
};
|
||||
|
||||
fn main() {
|
||||
let mut type_dict = Arc::new(RwLock::new(BimapTypeDict::new()));
|
||||
let mut morphism_base = laddertypes::MorphismBase::<LdmcMorphism>::new(vec![
|
||||
|
||||
let mut morphism_base = laddertypes::morphism_base::MorphismBase::<LdmcMorphism>::new(vec![
|
||||
//type_dict.parse("Seq~MsbCont").expect(""),
|
||||
//type_dict.parse("Seq~<ValueTerminated '\\0'>").expect(""),
|
||||
type_dict.parse("Seq~<LengthPrefix native.UInt64>").expect("")
|
||||
type_dict.parse("Seq~<LengthPrefix native.UInt64>").expect(""),
|
||||
type_dict.parse("Struct").expect("")
|
||||
]);
|
||||
|
||||
let mut args = std::env::args().skip(1);
|
||||
|
@ -60,14 +56,105 @@ fn main() {
|
|||
}
|
||||
}
|
||||
|
||||
let mut γ = HashMap::new();
|
||||
γ.insert(
|
||||
type_dict.get_typeid_creat(&"Byte".into()),
|
||||
type_dict.parse("<Seq~<StaticLength 8> Bit>").expect("parse")
|
||||
.apply_substitution(&|k| γ.get(k).cloned())
|
||||
.clone()
|
||||
);
|
||||
γ.insert(
|
||||
type_dict.get_typeid_creat(&"x86.UInt8".into()),
|
||||
type_dict.parse("ℤ_2^8 ~ <PosInt 2 BigEndian> ~ <Seq~<StaticLength 8> <Digit 2> ~ Bit>").expect("parse")
|
||||
.apply_substitution(&|k| γ.get(k).cloned())
|
||||
.clone()
|
||||
);
|
||||
γ.insert(
|
||||
type_dict.get_typeid_creat(&"x86.UInt16".into()),
|
||||
type_dict.parse("ℤ_2^16 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 2> <Digit 256> ~ x86.UInt8 >").expect("parse")
|
||||
.apply_substitution(&|k| γ.get(k).cloned())
|
||||
.clone()
|
||||
);
|
||||
γ.insert(
|
||||
type_dict.get_typeid_creat(&"x86.UInt32".into()),
|
||||
type_dict.parse("ℤ_2^32 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 4> <Digit 256> ~ x86.UInt8 >").expect("parse")
|
||||
.apply_substitution(&|k| γ.get(k).cloned())
|
||||
.clone()
|
||||
);
|
||||
γ.insert(
|
||||
type_dict.get_typeid_creat(&"x86.UInt64".into()),
|
||||
type_dict.parse("ℤ_2^64 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 8> <Digit 256> ~ x86.UInt8 >").expect("parse")
|
||||
.apply_substitution(&|k| γ.get(k).cloned())
|
||||
.clone()
|
||||
);
|
||||
γ.insert(
|
||||
type_dict.get_typeid_creat(&"x86.Float".into()),
|
||||
type_dict.parse("ℝ ~ IEEE-754.Float32 ~ <Seq~<StaticLength 4> Byte>").expect("parse")
|
||||
.apply_substitution(&|k| γ.get(k).cloned())
|
||||
.clone()
|
||||
);
|
||||
|
||||
let struct_type1 = type_dict.parse("
|
||||
<Struct
|
||||
<Struct.Field online-since TimePoint ~ <TimeSince UnixEpoch> ~ Duration ~ Seconds ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt64 >
|
||||
<Struct.Field battery-capacity Energy ~ Wh ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt64 >
|
||||
<Struct.Field battery-charge Energy ~ Wh ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt64 >
|
||||
<Struct.Field min-sampling-period Duration ~ Seconds ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt32 >
|
||||
<Struct.Field cur-sampling-period Duration ~ Seconds ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt32 >
|
||||
<Struct.Field max-chunk-size ℕ ~ native.UInt32 >
|
||||
<Struct.Field cur-chunk-size ℕ ~ native.UInt32 >
|
||||
<Struct.Field n-chunks-capacity ℕ ~ native.UInt32 >
|
||||
<Struct.Field n-full-data-chunks ℕ ~ native.UInt32 >
|
||||
<Struct.Field n-empty-data-chunks ℕ ~ native.UInt32 >
|
||||
>
|
||||
").expect("parse struct type");
|
||||
|
||||
eprintln!("{}
|
||||
",
|
||||
struct_type1.clone().sugar(&mut type_dict).pretty(&type_dict, 0)
|
||||
);
|
||||
|
||||
for m in morphism_base.enum_morphisms( &struct_type1 ) {
|
||||
eprintln!("{:?} -> {:?}",
|
||||
type_dict.read().unwrap().unparse(&m.get_type().src_type),
|
||||
type_dict.read().unwrap().unparse(&m.get_type().dst_type)
|
||||
);
|
||||
}
|
||||
return;
|
||||
|
||||
let struct_type2 = type_dict.parse("
|
||||
<Struct
|
||||
|
||||
<Struct.Field battery-charge Energy ~ Wh ~ ℝ ~ native.Double >
|
||||
<Struct.Field battery-capacity Energy ~ Wh ~ ℝ ~ native.Double >
|
||||
<Struct.Field min-sampling-period Duration ~ Seconds ~ ℝ ~ native.Double >
|
||||
<Struct.Field cur-sampling-period Duration ~ Seconds ~ ℝ ~ native.Double >
|
||||
<Struct.Field max-chunk-size ℕ ~ native.UInt32 >
|
||||
<Struct.Field cur-chunk-size ℕ ~ native.UInt32 >
|
||||
<Struct.Field n-chunks-capacity ℕ ~ native.UInt32 >
|
||||
<Struct.Field n-full-data-chunks ℕ ~ native.UInt32 >
|
||||
<Struct.Field n-empty-data-chunks ℕ ~ native.UInt32 >
|
||||
|
||||
<Struct.Field online-since TimePoint ~ <TimeSince UnixEpoch> ~ Duration ~ Seconds ~ ℝ ~ native.Double >
|
||||
>
|
||||
").expect("parse struct type");
|
||||
|
||||
let m = LdmcMorphism::new_struct_map(&mut type_dict, &morphism_base, struct_type1, struct_type2);
|
||||
|
||||
println!("{}",
|
||||
m.into_prim_c_morphism(&mut type_dict, "morph_my_struct".into(), &HashMap::new())
|
||||
.c_source
|
||||
);
|
||||
return;
|
||||
let src_type = type_dict.parse( src_type_arg.as_str() ).expect("");
|
||||
let dst_type = type_dict.parse( dst_type_arg.as_str() ).expect("");
|
||||
|
||||
let path = morphism_base.find_morphism_path(MorphismType {
|
||||
src_type: src_type.clone(),
|
||||
dst_type: dst_type.clone(),
|
||||
});
|
||||
let path = laddertypes::morphism_path::ShortestPathProblem::new(
|
||||
&morphism_base,
|
||||
MorphismType {
|
||||
src_type: src_type.clone(),
|
||||
dst_type: dst_type.clone(),
|
||||
}).solve();
|
||||
|
||||
match path {
|
||||
Some(path) => {
|
||||
|
|
116
src/morphism.rs
116
src/morphism.rs
|
@ -1,5 +1,6 @@
|
|||
|
||||
use laddertypes::morphism::Morphism;
|
||||
use laddertypes::{morphism::Morphism, morphism_base::MorphismBase};
|
||||
use crate::{c_gen::encode_type_to_symbol, struct_layout::StructLayout};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct LdmcPrimCMorphism {
|
||||
|
@ -10,9 +11,18 @@ pub struct LdmcPrimCMorphism {
|
|||
pub c_source: String
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct StructFieldMorphism {
|
||||
pub field_name: String,
|
||||
pub item_morph: Option<Box<LdmcPrimCMorphism>>,
|
||||
pub src_offset: u64,
|
||||
pub dst_offset: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum LdmcMorphism {
|
||||
Primitive( LdmcPrimCMorphism ),
|
||||
//Chain(Vec< LdmcPrimCMorphism >),
|
||||
LengthPrefixMap{
|
||||
length_prefix_type: laddertypes::TypeTerm,
|
||||
item_morph: Box<LdmcPrimCMorphism>
|
||||
|
@ -20,6 +30,104 @@ pub enum LdmcMorphism {
|
|||
ValueDelimMap{
|
||||
delim: u64,
|
||||
item_morph: Box<LdmcPrimCMorphism>
|
||||
},
|
||||
StructMap{
|
||||
src_struct: StructLayout,
|
||||
dst_struct: StructLayout,
|
||||
member_morphisms: Vec<StructFieldMorphism>
|
||||
}
|
||||
}
|
||||
|
||||
impl LdmcMorphism {
|
||||
/*
|
||||
pub fn into_prim_c_morphism(self, dict: &mut impl laddertypes::TypeDict, symbol: String) -> LdmcPrimCMorphism {
|
||||
|
||||
let src_c_type = ;
|
||||
let dst_c_type = ;
|
||||
|
||||
let c_source =
|
||||
format!("
|
||||
int {} ( {} const * restrict src, {} * restrict dst ) {{
|
||||
{}
|
||||
return 0;
|
||||
}}
|
||||
",
|
||||
symbol, src_c_type, dst_c_type,
|
||||
self.generate_call(dict, &std::collections::HashMap::new(), 0)
|
||||
);
|
||||
|
||||
LdmcPrimCMorphism {
|
||||
symbol,
|
||||
type_args: Vec::new(),
|
||||
src_type,
|
||||
dst_type,
|
||||
c_source
|
||||
}
|
||||
}
|
||||
*/
|
||||
pub fn new_struct_map(
|
||||
dict: &mut impl laddertypes::TypeDict,
|
||||
morph_base: &MorphismBase<LdmcMorphism>,
|
||||
src: laddertypes::TypeTerm,
|
||||
dst: laddertypes::TypeTerm,
|
||||
) -> Self {
|
||||
let src_struct = StructLayout::parse(dict, src).expect("cant parse src struct layout");
|
||||
let dst_struct = StructLayout::parse(dict, dst).expect("cant parse dst struct layout");
|
||||
|
||||
let mut member_morphisms = Vec::new();
|
||||
|
||||
for (field_name, dst_type) in dst_struct.members.iter() {
|
||||
let mut src_type = None;
|
||||
for (src_name, st) in src_struct.members.iter() {
|
||||
if src_name == field_name {
|
||||
src_type = Some(st.clone());
|
||||
}
|
||||
}
|
||||
let src_type = src_type.expect(&format!("cant find member {} in src struct", field_name));
|
||||
|
||||
if src_type == *dst_type {
|
||||
member_morphisms.push(
|
||||
StructFieldMorphism {
|
||||
field_name: field_name.to_string(),
|
||||
item_morph: None,
|
||||
src_offset: src_struct.get_offset( field_name ),
|
||||
dst_offset: dst_struct.get_offset( field_name ),
|
||||
}
|
||||
);
|
||||
} else {
|
||||
match morph_base.find_morphism(
|
||||
&laddertypes::MorphismType {
|
||||
src_type: src_type.clone(),
|
||||
dst_type: dst_type.clone()
|
||||
},
|
||||
dict
|
||||
) {
|
||||
Some(item_morph) => {
|
||||
let morph_symb = format!("morph_{}_to_{}",
|
||||
encode_type_to_symbol(dict, &src_type),
|
||||
encode_type_to_symbol(dict, &dst_type)
|
||||
);
|
||||
member_morphisms.push(
|
||||
StructFieldMorphism {
|
||||
field_name: field_name.to_string(),
|
||||
item_morph: Some(Box::new(item_morph.m.into_prim_c_morphism(dict, morph_symb, &item_morph.σ))),
|
||||
src_offset: src_struct.get_offset( field_name ),
|
||||
dst_offset: dst_struct.get_offset( field_name ),
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
None => {
|
||||
eprintln!("cant map field {}", field_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LdmcMorphism::StructMap {
|
||||
src_struct, dst_struct,
|
||||
member_morphisms
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,6 +155,12 @@ impl Morphism for LdmcMorphism {
|
|||
src_type: laddertypes::TypeTerm::App(vec![ value_delim_type.clone(), item_morph.src_type.clone() ]),
|
||||
dst_type: laddertypes::TypeTerm::App(vec![ value_delim_type.clone(), item_morph.dst_type.clone() ]),
|
||||
}
|
||||
},
|
||||
LdmcMorphism::StructMap { src_struct, dst_struct, member_morphisms } => {
|
||||
laddertypes::MorphismType {
|
||||
src_type: src_struct.get_type(),
|
||||
dst_type: dst_struct.get_type()
|
||||
}
|
||||
}
|
||||
}.normalize()
|
||||
}
|
||||
|
|
167
src/struct_layout.rs
Normal file
167
src/struct_layout.rs
Normal file
|
@ -0,0 +1,167 @@
|
|||
|
||||
use laddertypes::{parser::*, unparser::*, SugaredStructMember, SugaredTypeTerm, TypeDict, TypeTerm};
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum ObjectSize {
|
||||
Static(u64),
|
||||
Dynamic(/* function to get size at runtime */),
|
||||
Unknown
|
||||
}
|
||||
|
||||
|
||||
pub fn get_type_size( dict: &mut impl TypeDict, ty: TypeTerm ) -> ObjectSize {
|
||||
let ty = ty.clone().get_lnf_vec().last().unwrap().clone();
|
||||
|
||||
if ty == dict.parse("native.UInt8").expect("") {
|
||||
return ObjectSize::Static(1);
|
||||
}
|
||||
if ty == dict.parse("native.UInt16").expect("") {
|
||||
return ObjectSize::Static(2);
|
||||
}
|
||||
if ty == dict.parse("native.UInt32").expect("") ||
|
||||
ty == dict.parse("native.Float").expect("") {
|
||||
return ObjectSize::Static(4);
|
||||
}
|
||||
if ty == dict.parse("native.UInt64").expect("") ||
|
||||
ty == dict.parse("native.Double").expect("") {
|
||||
return ObjectSize::Static(8);
|
||||
}
|
||||
|
||||
if let Some(layout) = StructLayout::parse( dict, ty ) {
|
||||
return layout.get_size();
|
||||
}
|
||||
|
||||
ObjectSize::Unknown
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
enum LayoutType {
|
||||
Natural,
|
||||
Packed
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct StructLayout {
|
||||
ty: laddertypes::TypeTerm,
|
||||
item_type: laddertypes::TypeTerm,
|
||||
pub members: Vec< (String, laddertypes::TypeTerm) >,
|
||||
offsets: std::collections::HashMap< String, u64 >,
|
||||
size: ObjectSize
|
||||
}
|
||||
|
||||
impl StructLayout {
|
||||
pub fn get_type(&self) -> TypeTerm {
|
||||
self.ty.clone()
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> ObjectSize {
|
||||
self.size
|
||||
}
|
||||
|
||||
pub fn get_offset(&self, name: &String) -> u64 {
|
||||
*self.offsets.get(name).expect("")
|
||||
}
|
||||
|
||||
pub fn calculate_offsets(&mut self, dict: &mut impl TypeDict) {
|
||||
let layout_type = LayoutType::Natural;
|
||||
let mut offset = 0;
|
||||
|
||||
for (field_name, field_type) in self.members.iter() {
|
||||
//let field_c_type = crate::c_gen::get_c_repr_type(dict, field_type.clone(), true).expect("cant get c-repr for struct field");
|
||||
match get_type_size( dict, field_type.clone() ) {
|
||||
ObjectSize::Static(field_size) => {
|
||||
if layout_type == LayoutType::Natural {
|
||||
// add padding to natural alignment
|
||||
if offset % field_size > 0 {
|
||||
offset = field_size * ((offset / field_size)+1);
|
||||
}
|
||||
}
|
||||
|
||||
// take offset
|
||||
self.offsets.insert(field_name.clone(), offset);
|
||||
|
||||
// advance by current size
|
||||
offset += field_size;
|
||||
}
|
||||
ObjectSize::Dynamic() => {
|
||||
eprintln!("dynamically sized Field in struct!");
|
||||
self.offsets.insert(field_name.clone(), offset);
|
||||
self.size = ObjectSize::Dynamic();
|
||||
return;
|
||||
}
|
||||
ObjectSize::Unknown => {
|
||||
eprintln!("unknown field size!");
|
||||
self.offsets.insert(field_name.clone(), offset);
|
||||
self.size = ObjectSize::Unknown;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match self.size {
|
||||
ObjectSize::Dynamic() => {
|
||||
|
||||
}
|
||||
_ => {
|
||||
self.size = ObjectSize::Static(offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_members(&self, dict: &mut impl TypeDict, prefix: &str, base_ptr: &str) {
|
||||
let mut offset = 0;
|
||||
|
||||
for (field_name, field_type) in self.members.iter() {
|
||||
let field_c_type = crate::c_gen::get_c_repr_type(dict, field_type.clone(), true).expect("cant get c-repr for struct field");
|
||||
let offset = self.get_offset(field_name);
|
||||
println!(" {} * restrict {}_{} = {} + {};",
|
||||
field_c_type, prefix, field_name, base_ptr, offset
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse(dict: &mut impl TypeDict, struct_type: TypeTerm) -> Option <Self> {
|
||||
match struct_type.sugar(dict) {
|
||||
SugaredTypeTerm::Struct(sugared_members) => {
|
||||
let mut members = Vec::new();
|
||||
let mut item_type = dict.parse("Byte").expect("");
|
||||
|
||||
for SugaredStructMember{ symbol, ty } in sugared_members {
|
||||
members.push((symbol, ty.desugar(dict)));
|
||||
}
|
||||
|
||||
let mut sl = StructLayout {
|
||||
ty: TypeTerm::unit(),
|
||||
item_type,
|
||||
members,
|
||||
offsets: std::collections::HashMap::new(),
|
||||
size: ObjectSize::Unknown
|
||||
};
|
||||
|
||||
sl.calculate_offsets(dict);
|
||||
sl.calculate_type(dict);
|
||||
|
||||
Some(sl)
|
||||
}
|
||||
|
||||
_ => {
|
||||
eprintln!("not a struct");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn calculate_type(&mut self, dict: &mut impl TypeDict) {
|
||||
self.ty =
|
||||
SugaredTypeTerm::Struct(
|
||||
self.members
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(|(symbol,ty)|
|
||||
SugaredStructMember{ symbol, ty:ty.sugar(dict) })
|
||||
.collect()
|
||||
)
|
||||
.desugar(dict);
|
||||
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue