wip struct morphisms
This commit is contained in:
parent
d98afc294d
commit
583892f10d
6 changed files with 774 additions and 564 deletions
628
src/c_gen.rs
628
src/c_gen.rs
|
@ -1,158 +1,286 @@
|
|||
use {
|
||||
crate::{morphism::{LdmcMorphism, LdmcPrimCMorphism}, struct_layout::{get_type_size, ObjectSize, StructLayout}},
|
||||
laddertypes::{morphism::{Morphism, MorphismInstance}, parser::*, unparser::*, TypeDict, TypeTerm},
|
||||
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, SugaredMorphismType}, parser::*, substitution_sugared::SugaredSubstitution, unparser::*, Substitution, SugaredEnumVariant, SugaredStructMember, SugaredTypeTerm, TypeDict, TypeTerm}, std::collections::HashMap
|
||||
};
|
||||
|
||||
/*
|
||||
*/
|
||||
pub fn get_c_repr_kind(kind: String) -> Option<String> {
|
||||
match kind.as_str() {
|
||||
"ℤ" => Some("uint64_t".into()),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
/* for a given ladder type `t`, get the corresponding C type
|
||||
*/
|
||||
pub fn get_c_repr_type(dict: &mut impl TypeDict, t: laddertypes::TypeTerm, skip_pointer: bool) -> Option<String> {
|
||||
let lnf = t.normalize().decurry().get_lnf_vec();
|
||||
|
||||
match lnf.last() {
|
||||
Some(t) => {
|
||||
if t == &dict.parse("Byte").expect("parse")
|
||||
|| t == &dict.parse("native.UInt8").expect("parse")
|
||||
|| t == &dict.parse("<StaticLength 8 Bit>").expect("parse")
|
||||
{
|
||||
Some("uint8_t".into())
|
||||
} else if t == &dict.parse("native.UInt16").expect("parse") {
|
||||
Some("uint16_t".into())
|
||||
} else if t == &dict.parse("native.UInt32").expect("parse") {
|
||||
Some("uint32_t".into())
|
||||
} else if t == &dict.parse("native.UInt64").expect("parse") {
|
||||
Some("uint64_t".into())
|
||||
} else if t == &dict.parse("native.Float").expect("parse") {
|
||||
Some("float".into())
|
||||
} else if t == &dict.parse("native.Double").expect("parse") {
|
||||
Some("double".into())
|
||||
|
||||
|
||||
|
||||
|
||||
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 {
|
||||
match t {
|
||||
laddertypes::TypeTerm::App(args) => {
|
||||
if args[0] == laddertypes::TypeTerm::TypeID(dict.get_typeid(&"LengthPrefix".into()).unwrap())
|
||||
{
|
||||
let length_c_type : String = get_c_repr_type(dict, args[1].clone(), false)?;
|
||||
let item_c_type : String = get_c_repr_type(dict, args[2].clone(), false)?;
|
||||
|
||||
match length_c_type.as_str() {
|
||||
"uint8_t" |
|
||||
"uint16_t" |
|
||||
"uint32_t" |
|
||||
"uint64_t" => {}
|
||||
_ => {
|
||||
eprintln!("invalid length type!");
|
||||
return None;
|
||||
}
|
||||
}
|
||||
match item_c_type.as_str() {
|
||||
"uint8_t" |
|
||||
"uint16_t" |
|
||||
"uint32_t" |
|
||||
"uint64_t" => {}
|
||||
_ => {
|
||||
eprintln!("invalid item type!");
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
Some(format!("LengthPrefix_{}_Array_{}", length_c_type, item_c_type))
|
||||
}
|
||||
else if args[0] == laddertypes::TypeTerm::TypeID(dict.get_typeid(&"ValueTerminated".into()).unwrap())
|
||||
{
|
||||
let _delim_val = args[1].clone();
|
||||
let c_type = get_c_repr_type(dict, args[2].clone(), false)?;
|
||||
if skip_pointer {
|
||||
Some(c_type)
|
||||
} else {
|
||||
Some(format!("{} *", c_type))
|
||||
}
|
||||
}
|
||||
else if args[0] == laddertypes::TypeTerm::TypeID(dict.get_typeid(&"MsbCont".into()).unwrap())
|
||||
{
|
||||
let c_type = get_c_repr_type(dict, args[1].clone(), false)?;
|
||||
if skip_pointer {
|
||||
Some(c_type)
|
||||
} else {
|
||||
Some(format!("{} *", c_type))
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_ => None
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
None => None
|
||||
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();
|
||||
let src_type = self.ty.src_type.clone().apply_subst(σ).clone();
|
||||
let dst_type = self.ty.dst_type.clone().apply_subst(σ).clone();
|
||||
|
||||
let symbol = encode_morph_type_to_symbol(dict, &self.ty);
|
||||
let src_c_symbol = encode_type_to_symbol(dict, &self.ty.src_type);
|
||||
let dst_c_symbol = encode_type_to_symbol(dict, &self.ty.dst_type);
|
||||
|
||||
let src_c_type = get_c_repr_type(dict, self.ty.src_type.clone(), true).expect("cant get c-repr type for src type");
|
||||
let dst_c_type = get_c_repr_type(dict, self.ty.dst_type.clone(), true).expect("cant get c-repr type for src type");
|
||||
|
||||
s.push_str(&format!(r#"
|
||||
int {} ( {} const * restrict src, {} * restrict dst ) {{
|
||||
"#,
|
||||
self.instantiated_symbol_name(dict, σ),
|
||||
get_c_repr_type(dict, src_type, true).expect("cant get c-repr-type"),
|
||||
get_c_repr_type(dict, dst_type, true).expect("cant get c-repr-type"),
|
||||
));
|
||||
s.push_str(&self.c_source);
|
||||
s.push_str(&format!(r#"
|
||||
return 0;
|
||||
}}
|
||||
"#));
|
||||
Some(s)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn encode_type_to_symbol(dict: &mut impl TypeDict, t: &laddertypes::TypeTerm)-> String {
|
||||
match t {
|
||||
laddertypes::TypeTerm::Char(c) => {
|
||||
match c {
|
||||
'.' => format!("_dot_"),
|
||||
_ =>
|
||||
format!("{}", (*c as u64))
|
||||
}
|
||||
},
|
||||
laddertypes::TypeTerm::Num(n) => {
|
||||
format!("{}", n)
|
||||
|
||||
|
||||
|
||||
pub struct LdmcCTargetMorph {
|
||||
includes: Vec< String >,
|
||||
active_instantiations: Vec< LdmcPrimMorph >,
|
||||
}
|
||||
|
||||
impl LdmcCTargetMorph {
|
||||
pub fn new() -> Self {
|
||||
LdmcCTargetMorph {
|
||||
includes: Vec::new(),
|
||||
active_instantiations: Vec::new()
|
||||
}
|
||||
laddertypes::TypeTerm::TypeID(ty_id) => {
|
||||
if let Some(name) = dict.get_typename(ty_id) {
|
||||
format!("{}", name.replace(".", "_dot_"))
|
||||
} else {
|
||||
format!("")
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
laddertypes::TypeTerm::Ladder(rs) |
|
||||
laddertypes::TypeTerm::App(rs) => {
|
||||
let mut s = String::new();
|
||||
for r in rs {
|
||||
s.push('_');
|
||||
s.push_str(&encode_type_to_symbol(dict, r));
|
||||
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);
|
||||
}
|
||||
|
||||
for m in self.active_instantiations {
|
||||
source.push_str(&m.generate_instantiation(dict, &HashMap::new()).expect("cant create function"));
|
||||
}
|
||||
|
||||
source
|
||||
}
|
||||
|
||||
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) {
|
||||
eprintln!("val = {}", val.pretty(dict, 0));
|
||||
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(),
|
||||
ty: morph_inst.get_type(),
|
||||
c_source
|
||||
})
|
||||
},
|
||||
MorphismInstance2::Chain { path } => {
|
||||
let ty = morph_inst.get_type();
|
||||
let symbol = encode_morph_type_to_symbol(dict, &ty);
|
||||
|
||||
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());
|
||||
|
||||
let src_c_type = get_c_repr_type(dict, ty.src_type.clone(), true).expect("cant get c-repr type for src type");
|
||||
let dst_c_type = get_c_repr_type(dict, ty.dst_type.clone(), true).expect("cant get c-repr type for dst type");
|
||||
|
||||
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
|
||||
self.add_instantiation(dict, item_morph.as_ref().clone());
|
||||
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");
|
||||
let ty = morph_inst.get_type();
|
||||
let symbol = encode_morph_type_to_symbol(dict, &ty);
|
||||
let item_morph_symbol = encode_morph_type_to_symbol(dict, &item_morph.get_type());
|
||||
|
||||
let length_c_type = get_c_repr_type(dict, length_type.clone(), true).expect("cant c-repr type for array length");
|
||||
let src_item_c_type = get_c_repr_type(dict, item_morph.get_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_type().dst_type, true).expect("cant c-repr type for dst item");
|
||||
let src_c_type = get_c_repr_type(dict, ty.src_type.clone(), true).expect("cant get c-repr type for src type");
|
||||
let dst_c_type = get_c_repr_type(dict, ty.dst_type.clone(), true).expect("cant get c-repr type for dst type");
|
||||
|
||||
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 } => {
|
||||
let ty = morph_inst.get_type();
|
||||
let symbol =encode_morph_type_to_symbol(dict, &ty);
|
||||
|
||||
let mut c_source = String::new();
|
||||
|
||||
for (name, morph) in member_morph.iter() {
|
||||
if let Ok(inst) = self.add_instantiation(dict, morph.clone()) {
|
||||
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!();
|
||||
}
|
||||
s
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encode_type_to_value(dict: &mut impl TypeDict, t: &laddertypes::TypeTerm) -> String {
|
||||
dict.unparse(t)
|
||||
}
|
||||
|
||||
|
||||
pub fn generate_main(type_dict: &mut impl TypeDict, path: Vec<MorphismInstance<LdmcMorphism>>, src_type: TypeTerm, dst_type: TypeTerm) {
|
||||
/*
|
||||
pub fn generate_main(
|
||||
type_dict: &mut impl TypeDict,
|
||||
morph: MorphismInstance2<LdmcPrimMorph>,
|
||||
src_type: TypeTerm, dst_type: TypeTerm
|
||||
) {
|
||||
let mut i = 0;
|
||||
|
||||
|
||||
|
||||
/* todo: collect include files from morphism base */
|
||||
println!(r#"
|
||||
#include <stdio.h>
|
||||
|
@ -271,238 +399,4 @@ return 0;
|
|||
|
||||
eprintln!("Success: generated C code");
|
||||
}
|
||||
|
||||
impl LdmcPrimCMorphism {
|
||||
pub fn instantiated_symbol_name(&self, dict: &mut impl TypeDict,
|
||||
σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>) -> 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 {} ({})", k, var_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
s
|
||||
}
|
||||
|
||||
pub fn expected_c_type_signature(&self, dict: &mut impl TypeDict,
|
||||
σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>) -> String {
|
||||
format!("int {} ({} const * restrict src, {} * restrict dst);",
|
||||
self.instantiated_symbol_name(dict, σ),
|
||||
get_c_repr_type(dict, self.src_type.clone(), true).expect("cant get c-repr type for src type"),
|
||||
get_c_repr_type(dict, self.dst_type.clone(), true).expect("cant get c-repr type for dst type"))
|
||||
}
|
||||
|
||||
pub fn generate_instantiation(&self, dict: &mut impl TypeDict, σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>) -> Option<String> {
|
||||
let mut s = String::new();
|
||||
|
||||
s.push_str(&format!(r#"
|
||||
int {} ( {} const * restrict src, {} * restrict dst ) {{
|
||||
"#,
|
||||
self.instantiated_symbol_name(dict, &σ),
|
||||
get_c_repr_type(dict, self.src_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone(), true).expect("cant get c-repr-type"),
|
||||
get_c_repr_type(dict, self.dst_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone(), true).expect("cant get c-repr-type"),
|
||||
));
|
||||
for (ty_id, kind) in self.type_args.iter() {
|
||||
if let Some(val) = σ.get(ty_id) {
|
||||
eprintln!("val = {}", dict.unparse(&val));
|
||||
|
||||
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)
|
||||
};
|
||||
|
||||
s.push_str(&format!(" #define {} {}\n", dict.get_typename(&ty_id).unwrap(), type_var_value));
|
||||
}
|
||||
}
|
||||
|
||||
s.push_str(&self.c_source);
|
||||
|
||||
for (ty_id, kind) in self.type_args.iter() {
|
||||
s.push_str(&format!("\n #undef {}", dict.get_typename(&ty_id).unwrap()));
|
||||
}
|
||||
|
||||
s.push_str(&format!(r#"
|
||||
}}
|
||||
"#));
|
||||
Some(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl LdmcMorphism {
|
||||
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");
|
||||
let dst_c_type = get_c_repr_type(dict, prim_morph.dst_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone(), true).expect("cant get c-repr type for dst type");
|
||||
|
||||
let src_buf = if i%2 == 0 { "bufA" } else { "bufB" };
|
||||
let dst_buf = if i%2 == 0 { "bufB" } else { "bufA" };
|
||||
|
||||
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();
|
||||
let dst_type = self.get_type().dst_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone();
|
||||
|
||||
eprintln!("length prefix type ={:?}", length_prefix_type);
|
||||
eprintln!("src_type ={:?}", src_type);
|
||||
eprintln!("dst_type = {:?}", dst_type);
|
||||
|
||||
dict.add_varname("S".into());
|
||||
|
||||
let γ_src = laddertypes::unify(
|
||||
&dict.parse("<Seq~<LengthPrefix S> T>").expect("parse template"),
|
||||
&src_type
|
||||
).expect("cant get src item type");
|
||||
|
||||
let γ_dst = laddertypes::unify(
|
||||
&dict.parse("<Seq~<LengthPrefix S> T>").expect("parse template"),
|
||||
&dst_type
|
||||
).expect("cant get dst item type");
|
||||
|
||||
let src_length_type = γ_src.get(&dict.get_typeid(&"S".into()).unwrap()).expect("cant get src-length type").clone();
|
||||
let dst_length_type = γ_src.get(&dict.get_typeid(&"S".into()).unwrap()).expect("cant get dst-length type").clone();
|
||||
|
||||
let length_type = src_length_type;
|
||||
|
||||
let src_item_type = γ_src.get(&dict.get_typeid(&"T".into()).unwrap()).expect("cant get src-item type").clone();
|
||||
let dst_item_type = γ_dst.get(&dict.get_typeid(&"T".into()).unwrap()).expect("cant get src-item type").clone();
|
||||
|
||||
let length_c_type = get_c_repr_type(dict, length_type, true).expect("cant c-repr type for array length");
|
||||
let src_item_c_type = get_c_repr_type(dict, src_item_type, true).expect("cant c-repr type for src item");
|
||||
let dst_item_c_type = get_c_repr_type(dict, dst_item_type, true).expect("cant c-repr type for dst item");
|
||||
let src_c_type = get_c_repr_type(dict, src_type, true).expect("cant get c-repr type for src type");
|
||||
let dst_c_type = get_c_repr_type(dict, dst_type, true).expect("cant get c-repr type for dst type");
|
||||
|
||||
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" };
|
||||
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");
|
||||
let dst_c_type = get_c_repr_type(dict, item_morph.dst_type.clone(), false).expect("cant get c-repr type for dst type");
|
||||
|
||||
let src_buf = if i%2 == 0 { "bufA" } else { "bufB" };
|
||||
let dst_buf = if i%2 == 0 { "bufB" } else { "bufA" };
|
||||
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, σ)
|
||||
)
|
||||
},
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
240
src/c_gen_types.rs
Normal file
240
src/c_gen_types.rs
Normal file
|
@ -0,0 +1,240 @@
|
|||
use {
|
||||
crate::{morphism::LdmcPrimMorph, struct_layout::{get_type_size, LayoutType, ObjectSize, StructLayout}}, chumsky::chain::Chain, laddertypes::{morphism::{Morphism, MorphismInstance}, morphism_sugared::{MorphismInstance2, SugaredMorphismType}, parser::*, substitution_sugared::SugaredSubstitution, unparser::*, Substitution, SugaredEnumVariant, SugaredStructMember, SugaredTypeTerm, TypeDict, TypeTerm}
|
||||
};
|
||||
|
||||
/*
|
||||
*/
|
||||
pub fn get_c_repr_kind(kind: String) -> Option<String> {
|
||||
match kind.as_str() {
|
||||
"ℤ" => Some("uint64_t".into()),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
/* for a given ladder type `t`, get the corresponding C type
|
||||
*/
|
||||
pub fn get_c_repr_type(dict: &mut impl TypeDict, t: SugaredTypeTerm, skip_pointer: bool) -> Option<String> {
|
||||
eprintln!("get c repr of {}", t.pretty(dict,0));
|
||||
|
||||
match t.get_floor_type().1.strip() {
|
||||
SugaredTypeTerm::TypeID(tyid) => {
|
||||
if tyid == dict.get_typeid_creat("native.UInt8") {
|
||||
Some("uint8_t".into())
|
||||
} else if tyid == dict.get_typeid_creat("native.UInt16") {
|
||||
Some("uint16_t".into())
|
||||
} else if tyid == dict.get_typeid_creat("native.UInt32") {
|
||||
Some("uint32_t".into())
|
||||
} else if tyid == dict.get_typeid_creat("native.UInt64") {
|
||||
Some("uint64_t".into())
|
||||
} else if tyid == dict.get_typeid_creat("native.Address") {
|
||||
Some("void*".into())
|
||||
} else if tyid == dict.get_typeid_creat("native.Float32") {
|
||||
Some("float".into())
|
||||
} else if tyid == dict.get_typeid_creat("native.Float64") {
|
||||
Some("double".into())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
SugaredTypeTerm::Seq{ seq_repr, items } => {
|
||||
if let Some(sr_sugar) = seq_repr {
|
||||
let sr = sr_sugar.desugar(dict);
|
||||
|
||||
let item_type = items.first().expect("no item type specified!").clone();
|
||||
let item_c_type : String = get_c_repr_type(dict, item_type, false).expect("cant get item type representation");
|
||||
|
||||
dict.add_varname("Length".into()); // Kind: Num
|
||||
dict.add_varname("LengthType".into()); // Kind: Type
|
||||
dict.add_varname("TermValue".into()); // Kind: Value of Type ItemType
|
||||
|
||||
if let Ok(σ) = laddertypes::unify(
|
||||
&sr,
|
||||
&dict.parse("<StaticLength Length>").expect("parse")
|
||||
) {
|
||||
let length = match
|
||||
σ.get(
|
||||
&dict.get_typeid(&"Length".into()).expect("no Length ID")
|
||||
).expect("no length specified!")
|
||||
{
|
||||
TypeTerm::Num(l) => l,
|
||||
_ => {
|
||||
eprintln!("invalid Length!");
|
||||
return None;
|
||||
}
|
||||
};
|
||||
Some(format!("{}[{}]", item_c_type, length))
|
||||
}
|
||||
else if let Ok(σ) = laddertypes::unify(
|
||||
&sr,
|
||||
&dict.parse("<LengthPrefix LengthType>").expect("parse")
|
||||
) {
|
||||
let length_type = σ.get(
|
||||
&dict.get_typeid(&"LengthType".into()).expect("no LengthType ID")
|
||||
).expect("no length type specified")
|
||||
.clone()
|
||||
.sugar(dict);
|
||||
let length_c_type : String = get_c_repr_type(dict, length_type, false).expect("cant get length type representation");
|
||||
|
||||
match length_c_type.as_str() {
|
||||
"uint8_t" |
|
||||
"uint16_t" |
|
||||
"uint32_t" |
|
||||
"uint64_t" => {}
|
||||
s => {
|
||||
eprintln!("invalid length type '{}' !", s);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
match item_c_type.as_str() {
|
||||
"uint8_t" |
|
||||
"uint16_t" |
|
||||
"uint32_t" |
|
||||
"uint64_t" |
|
||||
"void*" => {}
|
||||
s => {
|
||||
eprintln!("invalid item type '{}'!", s);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
Some(format!("LengthPrefix_{}_Array_{}", length_c_type, item_c_type))
|
||||
}
|
||||
else if let Ok(σ) = laddertypes::unify(
|
||||
&sr,
|
||||
&dict.parse("<ValueTerminated TermValue>").expect("")
|
||||
) {
|
||||
if skip_pointer {
|
||||
Some(item_c_type)
|
||||
} else {
|
||||
Some(format!("{} *", item_c_type))
|
||||
}
|
||||
}
|
||||
else {
|
||||
eprintln!("can't get C-repr for sequence type `{}`!", dict.unparse(&sr));
|
||||
None
|
||||
}
|
||||
} else {
|
||||
eprintln!("no sequence-representation type specified!");
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
SugaredTypeTerm::Struct{ struct_repr, members } => {
|
||||
let c_struct_attribute =
|
||||
if let Some(sr) = struct_repr {
|
||||
let sr = sr.desugar(dict);
|
||||
match LayoutType::parse(dict, &sr).expect("layout type") {
|
||||
LayoutType::Aligned => "",
|
||||
LayoutType::Packed => "__attribute((packed))__"
|
||||
}
|
||||
} else {""};
|
||||
|
||||
let mut c_type = format!("struct {} {{\n", c_struct_attribute);
|
||||
|
||||
for SugaredStructMember{ symbol, ty } in members {
|
||||
let field_c_type = get_c_repr_type(dict, ty, false).expect("");
|
||||
c_type.push_str(&format!(" {} {};\n",
|
||||
field_c_type,
|
||||
symbol
|
||||
));
|
||||
}
|
||||
|
||||
c_type.push_str("}");
|
||||
Some(c_type)
|
||||
}
|
||||
|
||||
SugaredTypeTerm::Enum { enum_repr, variants } => {
|
||||
let mut c_type = format!("
|
||||
struct {{
|
||||
enum {{
|
||||
");
|
||||
|
||||
for (i, SugaredEnumVariant{ symbol, ty }) in variants.iter().enumerate() {
|
||||
c_type.push_str(&format!(
|
||||
" {} = {}", symbol.to_uppercase(), i
|
||||
));
|
||||
|
||||
if i+1 < variants.len() {
|
||||
c_type.push_str(",\n");
|
||||
}
|
||||
}
|
||||
|
||||
c_type.push_str("
|
||||
} tag;
|
||||
|
||||
union {
|
||||
");
|
||||
|
||||
for SugaredEnumVariant{ symbol, ty } in variants {
|
||||
let variant_c_type = get_c_repr_type(dict, ty, false).expect("cant get C-Repr type for variant");
|
||||
c_type.push_str(&format!(
|
||||
" {} {};\n", variant_c_type, symbol
|
||||
));
|
||||
}
|
||||
|
||||
c_type.push_str("
|
||||
};
|
||||
}");
|
||||
|
||||
Some(c_type)
|
||||
}
|
||||
|
||||
SugaredTypeTerm::Ladder(rungs) => {
|
||||
if let Some(t) = rungs.last() {
|
||||
get_c_repr_type(dict, t.clone(), false)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
_ => { None }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encode_type_to_symbol(dict: &mut impl TypeDict, t: &laddertypes::SugaredTypeTerm)-> String {
|
||||
let t = t.clone().desugar(dict);
|
||||
match t {
|
||||
laddertypes::TypeTerm::Char(c) => {
|
||||
match c {
|
||||
'.' => format!("_dot_"),
|
||||
_ =>
|
||||
format!("{}", (c as u64))
|
||||
}
|
||||
},
|
||||
laddertypes::TypeTerm::Num(n) => {
|
||||
format!("{}", n)
|
||||
}
|
||||
laddertypes::TypeTerm::TypeID(ty_id) => {
|
||||
if let Some(name) = dict.get_typename(&ty_id) {
|
||||
format!("{}", name.replace(".", "_dot_"))
|
||||
} else {
|
||||
format!("")
|
||||
}
|
||||
}
|
||||
laddertypes::TypeTerm::Ladder(rs) |
|
||||
laddertypes::TypeTerm::App(rs) => {
|
||||
let mut s = String::new();
|
||||
for r in rs {
|
||||
s.push('_');
|
||||
|
||||
let r = r.sugar(dict);
|
||||
s.push_str(&encode_type_to_symbol(dict, &r));
|
||||
}
|
||||
s
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encode_morph_type_to_symbol(dict: &mut impl TypeDict, t: &SugaredMorphismType) -> String {
|
||||
format!(
|
||||
"morph_{}__to_{}",
|
||||
encode_type_to_symbol(dict, &t.src_type),
|
||||
encode_type_to_symbol(dict, &t.dst_type)
|
||||
)
|
||||
}
|
||||
|
||||
pub fn encode_type_to_value(dict: &mut impl TypeDict, t: &laddertypes::SugaredTypeTerm) -> String {
|
||||
let t = t.clone().desugar(dict);
|
||||
dict.unparse(&t)
|
||||
}
|
143
src/main.rs
143
src/main.rs
|
@ -3,26 +3,22 @@
|
|||
mod morphism;
|
||||
mod parser;
|
||||
mod c_gen;
|
||||
mod c_gen_types;
|
||||
mod struct_layout;
|
||||
|
||||
use {
|
||||
crate::{
|
||||
morphism::LdmcMorphism,
|
||||
morphism::LdmcPrimMorph,
|
||||
parser::morphism_base_parser,
|
||||
}, ariadne::{Color, Label, Report, ReportKind, Source}, chumsky::prelude::*, laddertypes::{
|
||||
parser::ParseLadderType, unparser::*, BimapTypeDict, MorphismType, TypeDict
|
||||
}, ariadne::{Color, Label, Report, ReportKind, Source}, c_gen::LdmcCTargetMorph, chumsky::prelude::*, laddertypes::{
|
||||
morphism_path_sugared::SugaredShortestPathProblem, morphism_sugared::{MorphismInstance2, SugaredMorphism, SugaredMorphismType}, parser::ParseLadderType, unparser::*, BimapTypeDict, MorphismType, SugaredTypeTerm, 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::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("Struct").expect("")
|
||||
]);
|
||||
let mut morphism_base = laddertypes::morphism_base_sugared::SugaredMorphismBase::<LdmcPrimMorph>::new();
|
||||
|
||||
let mut args = std::env::args().skip(1);
|
||||
let src_type_arg = args.next().expect("src type expected");
|
||||
|
@ -36,7 +32,7 @@ fn main() {
|
|||
eprintln!("[{}] parse ok.", mb_path.bright_yellow());
|
||||
println!("{}", includes);
|
||||
for m in morphisms {
|
||||
morphism_base.add_morphism(LdmcMorphism::Primitive(m));
|
||||
morphism_base.add_morphism(m);
|
||||
}
|
||||
}
|
||||
Err(errs) => {
|
||||
|
@ -58,86 +54,103 @@ fn main() {
|
|||
|
||||
let mut γ = HashMap::new();
|
||||
γ.insert(
|
||||
type_dict.get_typeid_creat(&"Byte".into()),
|
||||
type_dict.get_typeid_creat(&"Byte"),
|
||||
type_dict.parse("<Seq~<StaticLength 8> Bit>").expect("parse")
|
||||
.apply_substitution(&|k| γ.get(k).cloned())
|
||||
.apply_subst(&γ)
|
||||
.clone()
|
||||
);
|
||||
γ.insert(
|
||||
type_dict.get_typeid_creat(&"x86.UInt8".into()),
|
||||
type_dict.get_typeid_creat(&"x86.UInt8"),
|
||||
type_dict.parse("ℤ_2^8 ~ <PosInt 2 BigEndian> ~ <Seq~<StaticLength 8> <Digit 2> ~ Bit>").expect("parse")
|
||||
.apply_substitution(&|k| γ.get(k).cloned())
|
||||
.apply_subst(&γ)
|
||||
.clone()
|
||||
);
|
||||
γ.insert(
|
||||
type_dict.get_typeid_creat(&"x86.UInt16".into()),
|
||||
type_dict.get_typeid_creat(&"x86.UInt16"),
|
||||
type_dict.parse("ℤ_2^16 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 2> <Digit 256> ~ x86.UInt8 >").expect("parse")
|
||||
.apply_substitution(&|k| γ.get(k).cloned())
|
||||
.apply_subst(&γ)
|
||||
.clone()
|
||||
);
|
||||
γ.insert(
|
||||
type_dict.get_typeid_creat(&"x86.UInt32".into()),
|
||||
type_dict.get_typeid_creat(&"x86.UInt32"),
|
||||
type_dict.parse("ℤ_2^32 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 4> <Digit 256> ~ x86.UInt8 >").expect("parse")
|
||||
.apply_substitution(&|k| γ.get(k).cloned())
|
||||
.clone()
|
||||
.apply_subst(&γ).clone()
|
||||
);
|
||||
γ.insert(
|
||||
type_dict.get_typeid_creat(&"x86.UInt64".into()),
|
||||
type_dict.get_typeid_creat(&"x86.UInt64"),
|
||||
type_dict.parse("ℤ_2^64 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 8> <Digit 256> ~ x86.UInt8 >").expect("parse")
|
||||
.apply_substitution(&|k| γ.get(k).cloned())
|
||||
.clone()
|
||||
.apply_subst(&γ).clone()
|
||||
);
|
||||
γ.insert(
|
||||
type_dict.get_typeid_creat(&"x86.Float".into()),
|
||||
type_dict.get_typeid_creat(&"x86.Float32"),
|
||||
type_dict.parse("ℝ ~ IEEE-754.Float32 ~ <Seq~<StaticLength 4> Byte>").expect("parse")
|
||||
.apply_substitution(&|k| γ.get(k).cloned())
|
||||
.clone()
|
||||
.apply_subst(&γ).clone()
|
||||
);
|
||||
γ.insert(
|
||||
type_dict.get_typeid_creat(&"x86.Float64"),
|
||||
type_dict.parse("ℝ ~ IEEE-754.Float64 ~ <Seq~<StaticLength 4> Byte>").expect("parse")
|
||||
.apply_subst(&γ).clone()
|
||||
);
|
||||
|
||||
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 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 >
|
||||
<Struct ~ Aligned
|
||||
<online-since TimePoint ~ <TimeSince UnixEpoch> ~ Duration ~ Seconds ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt64 >
|
||||
<capacity Energy ~ Wh ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt64 >
|
||||
<battery-charge Energy ~ Wh ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt64 >
|
||||
<min-sampling-period Duration ~ Seconds ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt32 >
|
||||
<cur-sampling-period Duration ~ Seconds ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt32 >
|
||||
<max-chunk-size ℕ ~ native.UInt32 >
|
||||
<cur-chunk-size ℕ ~ native.UInt32 >
|
||||
<n-chunks-capacity ℕ ~ native.UInt32 >
|
||||
<n-full-data-chunks ℕ ~ native.UInt32 >
|
||||
<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 >
|
||||
<Struct ~ Packed
|
||||
<battery-charge Energy ~ Wh ~ ℝ ~ native.Double >
|
||||
<battery-capacity Energy ~ Wh ~ ℝ ~ native.Double >
|
||||
<min-sampling-period Duration ~ Seconds ~ ℝ ~ native.Double >
|
||||
<cur-sampling-period Duration ~ Seconds ~ ℝ ~ native.Double >
|
||||
<max-chunk-size ℕ ~ native.UInt32 >
|
||||
<cur-chunk-size ℕ ~ native.UInt32 >
|
||||
<n-chunks-capacity ℕ ~ native.UInt32 >
|
||||
<n-full-data-chunks ℕ ~ native.UInt32 >
|
||||
<n-empty-data-chunks ℕ ~ native.UInt32 >
|
||||
<online-since TimePoint ~ <TimeSince UnixEpoch> ~ Duration ~ Seconds ~ ℝ ~ native.Double >
|
||||
>
|
||||
").expect("parse struct type");
|
||||
*/
|
||||
|
||||
/*
|
||||
let struct_type1 = type_dict.parse("
|
||||
RGB~<Struct
|
||||
<red ℝ ~ <QuantizedLinear 0 1 255> ~ ℕ ~ native.UInt8>
|
||||
<green ℝ ~ <QuantizedLinear 0 1 255> ~ ℕ ~ native.UInt8>
|
||||
<blue ℝ ~ <QuantizedLinear 0 1 255> ~ ℕ ~ native.UInt8>
|
||||
>
|
||||
").expect("parse");
|
||||
|
||||
let struct_type2 = type_dict.parse("
|
||||
RGB~<Struct
|
||||
<red ℝ ~ native.Float64>
|
||||
<green ℝ ~ native.Float64>
|
||||
<blue ℝ ~ native.Float64>
|
||||
>
|
||||
").expect("parse");
|
||||
*/
|
||||
|
||||
let ty = SugaredMorphismType{ src_type: src_type.sugar(&mut type_dict), dst_type: dst_type.sugar(&mut type_dict) };
|
||||
let mut target = LdmcCTargetMorph::new();
|
||||
target.add_instantiation(&mut type_dict, morphism_base.get_morphism_instance( &ty ).expect("cant get instance"));
|
||||
println!("{}", target.into_c_source(&mut type_dict));
|
||||
/*
|
||||
return;
|
||||
|
||||
let m = LdmcMorphism::new_struct_map(&mut type_dict, &morphism_base, struct_type1, struct_type2);
|
||||
|
||||
|
@ -145,10 +158,9 @@ fn main() {
|
|||
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("");
|
||||
|
||||
|
||||
return;
|
||||
let path = laddertypes::morphism_path::ShortestPathProblem::new(
|
||||
&morphism_base,
|
||||
MorphismType {
|
||||
|
@ -165,4 +177,5 @@ return;
|
|||
std::process::exit(-1);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -1,44 +1,16 @@
|
|||
|
||||
use laddertypes::{morphism::Morphism, morphism_base::MorphismBase};
|
||||
use crate::{c_gen::encode_type_to_symbol, struct_layout::StructLayout};
|
||||
use laddertypes::{morphism::Morphism, morphism_base::MorphismBase, morphism_path::ShortestPathProblem, morphism_sugared::{SugaredMorphism, SugaredMorphismType}, SugaredStructMember};
|
||||
use crate::{c_gen_types::encode_type_to_symbol, struct_layout::StructLayout};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct LdmcPrimCMorphism {
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct LdmcPrimMorph {
|
||||
pub symbol: String,
|
||||
pub type_args: Vec<(laddertypes::TypeID, String)>,
|
||||
pub src_type: laddertypes::TypeTerm,
|
||||
pub dst_type: laddertypes::TypeTerm,
|
||||
pub ty: SugaredMorphismType,
|
||||
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>
|
||||
},
|
||||
ValueDelimMap{
|
||||
delim: u64,
|
||||
item_morph: Box<LdmcPrimCMorphism>
|
||||
},
|
||||
StructMap{
|
||||
src_struct: StructLayout,
|
||||
dst_struct: StructLayout,
|
||||
member_morphisms: Vec<StructFieldMorphism>
|
||||
}
|
||||
}
|
||||
|
||||
impl LdmcMorphism {
|
||||
impl LdmcPrimMorph {
|
||||
/*
|
||||
pub fn into_prim_c_morphism(self, dict: &mut impl laddertypes::TypeDict, symbol: String) -> LdmcPrimCMorphism {
|
||||
|
||||
|
@ -65,20 +37,22 @@ impl LdmcMorphism {
|
|||
}
|
||||
}
|
||||
*/
|
||||
/*
|
||||
|
||||
pub fn new_struct_map(
|
||||
dict: &mut impl laddertypes::TypeDict,
|
||||
morph_base: &MorphismBase<LdmcMorphism>,
|
||||
morph_base: &MorphismBase<LdmcPrimMorph>,
|
||||
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 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() {
|
||||
for SugaredStructMember{ symbol: field_name, ty: dst_type } in dst_struct.members.iter() {
|
||||
let mut src_type = None;
|
||||
for (src_name, st) in src_struct.members.iter() {
|
||||
for SugaredStructMember{ symbol: src_name, ty: st } in src_struct.members.iter() {
|
||||
if src_name == field_name {
|
||||
src_type = Some(st.clone());
|
||||
}
|
||||
|
@ -95,14 +69,19 @@ impl LdmcMorphism {
|
|||
}
|
||||
);
|
||||
} else {
|
||||
match morph_base.find_morphism(
|
||||
&laddertypes::MorphismType {
|
||||
src_type: src_type.clone(),
|
||||
dst_type: dst_type.clone()
|
||||
},
|
||||
dict
|
||||
) {
|
||||
Some(item_morph) => {
|
||||
match ShortestPathProblem::new(
|
||||
&morph_base,
|
||||
laddertypes::MorphismType {
|
||||
src_type: src_type.clone().desugar(dict),
|
||||
dst_type: dst_type.clone().desugar(dict)
|
||||
}
|
||||
).solve()
|
||||
{
|
||||
Some(path) => {
|
||||
|
||||
let src_type = src_type.clone().desugar(dict);
|
||||
let dst_type = dst_type.clone().desugar(dict);
|
||||
|
||||
let morph_symb = format!("morph_{}_to_{}",
|
||||
encode_type_to_symbol(dict, &src_type),
|
||||
encode_type_to_symbol(dict, &dst_type)
|
||||
|
@ -110,7 +89,7 @@ impl LdmcMorphism {
|
|||
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.σ))),
|
||||
item_morph: None,//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 ),
|
||||
}
|
||||
|
@ -124,13 +103,20 @@ impl LdmcMorphism {
|
|||
}
|
||||
}
|
||||
|
||||
LdmcMorphism::StructMap {
|
||||
LdmcPrimMorph::StructMap {
|
||||
src_struct, dst_struct,
|
||||
member_morphisms
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
impl SugaredMorphism for LdmcPrimMorph {
|
||||
fn get_type(&self) -> SugaredMorphismType {
|
||||
self.ty.clone()
|
||||
}
|
||||
}
|
||||
/*
|
||||
impl Morphism for LdmcMorphism {
|
||||
fn weight(&self) -> u64 {
|
||||
1
|
||||
|
@ -188,3 +174,4 @@ impl Morphism for LdmcMorphism {
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
use {
|
||||
chumsky::{
|
||||
crate::morphism::LdmcPrimMorph, chumsky::{
|
||||
prelude::*, text::*
|
||||
},
|
||||
std::sync::{Arc, RwLock},
|
||||
|
||||
laddertypes::{TypeDict, BimapTypeDict, parser::*},
|
||||
crate::morphism::LdmcPrimCMorphism
|
||||
}, laddertypes::{morphism_sugared::SugaredMorphismType, parser::*, BimapTypeDict, TypeDict}, std::sync::{Arc, RwLock}
|
||||
};
|
||||
|
||||
/* morphism-base text format:
|
||||
|
@ -18,7 +14,7 @@ use {
|
|||
*/
|
||||
pub fn morphism_base_parser(
|
||||
type_dict: Arc<RwLock< BimapTypeDict >>
|
||||
) -> impl Parser<char, (String, Vec<LdmcPrimCMorphism>), Error = Simple<char>> {
|
||||
) -> impl Parser<char, (String, Vec<LdmcPrimMorph>), Error = Simple<char>> {
|
||||
|
||||
just("```")
|
||||
.then(take_until(just("```")))
|
||||
|
@ -63,14 +59,16 @@ pub fn morphism_base_parser(
|
|||
ty_args.push((var_id, kind));
|
||||
}
|
||||
|
||||
let src_type = type_dict.parse(&src_type.iter().collect::<String>()).expect("couldnt parse src type");
|
||||
let dst_type = type_dict.parse(&dst_type.iter().collect::<String>()).expect("couldnt parse dst type");
|
||||
let src_type = type_dict.parse(&src_type.iter().collect::<String>()).expect("couldnt parse src type").sugar(&mut *type_dict);
|
||||
let dst_type = type_dict.parse(&dst_type.iter().collect::<String>()).expect("couldnt parse dst type").sugar(&mut *type_dict);
|
||||
|
||||
LdmcPrimCMorphism {
|
||||
LdmcPrimMorph {
|
||||
symbol,
|
||||
type_args: ty_args,
|
||||
src_type,
|
||||
dst_type,
|
||||
ty: SugaredMorphismType{
|
||||
src_type,
|
||||
dst_type
|
||||
},
|
||||
c_source
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
|
||||
use std::ops::Deref;
|
||||
|
||||
use laddertypes::{parser::*, unparser::*, SugaredStructMember, SugaredTypeTerm, TypeDict, TypeTerm};
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
|
@ -8,43 +10,137 @@ pub enum ObjectSize {
|
|||
Unknown
|
||||
}
|
||||
|
||||
impl std::ops::Add for ObjectSize {
|
||||
type Output = Self;
|
||||
|
||||
pub fn get_type_size( dict: &mut impl TypeDict, ty: TypeTerm ) -> ObjectSize {
|
||||
let ty = ty.clone().get_lnf_vec().last().unwrap().clone();
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
match (self, rhs) {
|
||||
(ObjectSize::Unknown, _) |
|
||||
(_, ObjectSize::Unknown)
|
||||
=> ObjectSize::Unknown,
|
||||
|
||||
if ty == dict.parse("native.UInt8").expect("") {
|
||||
return ObjectSize::Static(1);
|
||||
(ObjectSize::Dynamic(), _) |
|
||||
(_, ObjectSize::Dynamic())
|
||||
=> ObjectSize::Dynamic(),
|
||||
|
||||
(ObjectSize::Static(s1), ObjectSize::Static(s2)) => ObjectSize::Static(s1 + s2),
|
||||
}
|
||||
}
|
||||
if ty == dict.parse("native.UInt16").expect("") {
|
||||
return ObjectSize::Static(2);
|
||||
}
|
||||
|
||||
impl std::ops::Mul for ObjectSize {
|
||||
type Output = Self;
|
||||
|
||||
fn mul(self, rhs: Self) -> Self {
|
||||
match (self, rhs) {
|
||||
(ObjectSize::Unknown, _) |
|
||||
(_, ObjectSize::Unknown)
|
||||
=> ObjectSize::Unknown,
|
||||
|
||||
(ObjectSize::Dynamic(), _) |
|
||||
(_, ObjectSize::Dynamic())
|
||||
=> ObjectSize::Dynamic(),
|
||||
|
||||
(ObjectSize::Static(s1), ObjectSize::Static(s2)) => ObjectSize::Static(s1 * s2),
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
pub fn get_type_size( dict: &mut impl TypeDict, ty: SugaredTypeTerm ) -> ObjectSize {
|
||||
match &ty {
|
||||
SugaredTypeTerm::TypeID(tyid) => {
|
||||
if tyid == &dict.get_typeid_creat("native.UInt8") { ObjectSize::Static(1) }
|
||||
else if tyid == &dict.get_typeid_creat("native.UInt16") { ObjectSize::Static(2) }
|
||||
else if tyid == &dict.get_typeid_creat("native.UInt32") { ObjectSize::Static(4) }
|
||||
else if tyid == &dict.get_typeid_creat("native.UInt64") { ObjectSize::Static(8) }
|
||||
else if tyid == &dict.get_typeid_creat("native.Address") { ObjectSize::Static(8) }
|
||||
else if tyid == &dict.get_typeid_creat("native.Float32") { ObjectSize::Static(4) }
|
||||
else if tyid == &dict.get_typeid_creat("native.Float64") { ObjectSize::Static(8) }
|
||||
else {
|
||||
ObjectSize::Unknown
|
||||
}
|
||||
},
|
||||
|
||||
SugaredTypeTerm::Ladder(rungs) => {
|
||||
get_type_size(dict, rungs.last().unwrap().clone() )
|
||||
}
|
||||
|
||||
SugaredTypeTerm::Struct { struct_repr, members } => {
|
||||
let layout = StructLayout::parse_sugared(dict, ty).expect("invalid struct");
|
||||
layout.get_size()
|
||||
}
|
||||
|
||||
SugaredTypeTerm::Seq { seq_repr, items } => {
|
||||
if let Some(seq_repr) = seq_repr {
|
||||
dict.add_typename("Length".into());
|
||||
dict.add_typename("LengthType".into());
|
||||
dict.add_typename("TerminatorValue".into());
|
||||
|
||||
if let Ok(σ) = laddertypes::unify(
|
||||
&seq_repr.clone().desugar(dict),
|
||||
&dict.parse("<StaticLength Length>").expect("")
|
||||
) {
|
||||
if let Some(TypeTerm::Num(len)) = σ.get(&dict.get_typeid(&"Length".into()).expect("")) {
|
||||
ObjectSize::Static(*len as u64) * get_type_size(dict, items.first().unwrap().clone())
|
||||
} else {
|
||||
ObjectSize::Unknown
|
||||
}
|
||||
}
|
||||
else if let Ok(σ) = laddertypes::unify(
|
||||
&seq_repr.clone().desugar(dict),
|
||||
&dict.parse("<LengthPrefix LengthType>").expect("")
|
||||
) {
|
||||
ObjectSize::Dynamic()
|
||||
}
|
||||
else if let Ok(σ) = laddertypes::unify(
|
||||
&seq_repr.clone().desugar(dict),
|
||||
&dict.parse("<ValueTerminated TerminatorValue>").expect("")
|
||||
) {
|
||||
ObjectSize::Dynamic()
|
||||
}
|
||||
else {
|
||||
ObjectSize::Unknown
|
||||
}
|
||||
} else {
|
||||
ObjectSize::Unknown
|
||||
}
|
||||
}
|
||||
|
||||
_ => ObjectSize::Unknown
|
||||
}
|
||||
|
||||
if let Some(layout) = StructLayout::parse( dict, ty ) {
|
||||
return layout.get_size();
|
||||
}
|
||||
|
||||
ObjectSize::Unknown
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
enum LayoutType {
|
||||
Natural,
|
||||
pub enum LayoutType {
|
||||
Aligned,
|
||||
Packed
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
impl LayoutType {
|
||||
pub fn parse( dict: &mut impl TypeDict, ty: &TypeTerm ) -> Option< LayoutType > {
|
||||
if ty == &dict.parse("Aligned").expect("parse") {
|
||||
Some(LayoutType::Aligned)
|
||||
} else if ty == &dict.parse("Packed").expect("parse") {
|
||||
Some(LayoutType::Packed)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unparse(&self, dict: &mut impl TypeDict) -> TypeTerm {
|
||||
match self {
|
||||
LayoutType::Aligned => dict.parse("Aligned").unwrap(),
|
||||
LayoutType::Packed => dict.parse("Packed").unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct StructLayout {
|
||||
ty: laddertypes::TypeTerm,
|
||||
item_type: laddertypes::TypeTerm,
|
||||
pub members: Vec< (String, laddertypes::TypeTerm) >,
|
||||
pub ty: laddertypes::TypeTerm,
|
||||
pub layout: LayoutType,
|
||||
pub members: Vec< SugaredStructMember >,
|
||||
offsets: std::collections::HashMap< String, u64 >,
|
||||
size: ObjectSize
|
||||
}
|
||||
|
@ -62,18 +158,22 @@ impl StructLayout {
|
|||
*self.offsets.get(name).expect("")
|
||||
}
|
||||
|
||||
pub fn calculate_offsets(&mut self, dict: &mut impl TypeDict) {
|
||||
let layout_type = LayoutType::Natural;
|
||||
pub fn init_offsets(&mut self, dict: &mut impl TypeDict) {
|
||||
let mut offset = 0;
|
||||
|
||||
for (field_name, field_type) in self.members.iter() {
|
||||
for SugaredStructMember{symbol: field_name, ty: 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);
|
||||
match self.layout {
|
||||
LayoutType::Aligned => {
|
||||
// add padding to get natural alignment of current member
|
||||
if offset % field_size > 0 {
|
||||
offset = field_size * ((offset / field_size)+1);
|
||||
}
|
||||
}
|
||||
LayoutType::Packed => {
|
||||
// no padding
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,7 +190,7 @@ impl StructLayout {
|
|||
return;
|
||||
}
|
||||
ObjectSize::Unknown => {
|
||||
eprintln!("unknown field size!");
|
||||
eprintln!("Struct member `{}` has unknown size!", field_name);
|
||||
self.offsets.insert(field_name.clone(), offset);
|
||||
self.size = ObjectSize::Unknown;
|
||||
return;
|
||||
|
@ -108,38 +208,30 @@ impl StructLayout {
|
|||
}
|
||||
}
|
||||
|
||||
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> {
|
||||
let st = struct_type.clone().strip().param_normalize().sugar(dict);
|
||||
Self::parse_sugared(dict, st)
|
||||
}
|
||||
|
||||
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)));
|
||||
}
|
||||
|
||||
pub fn parse_sugared(dict: &mut impl TypeDict, st: SugaredTypeTerm) -> Option <Self> {
|
||||
eprintln!("{}", st.pretty(dict, 0));
|
||||
match st.clone() {
|
||||
SugaredTypeTerm::Struct{ struct_repr, members } => {
|
||||
let mut sl = StructLayout {
|
||||
ty: TypeTerm::unit(),
|
||||
item_type,
|
||||
ty: st.desugar(dict),
|
||||
layout: if let Some(sr) = struct_repr {
|
||||
let sr = sr.desugar(dict);
|
||||
LayoutType::parse( dict, &sr ).expect("invalid struct layout type")
|
||||
} else {
|
||||
eprintln!("choose default struct repr");
|
||||
LayoutType::Aligned
|
||||
},
|
||||
|
||||
members,
|
||||
offsets: std::collections::HashMap::new(),
|
||||
size: ObjectSize::Unknown
|
||||
};
|
||||
|
||||
sl.calculate_offsets(dict);
|
||||
sl.calculate_type(dict);
|
||||
sl.init_offsets(dict);
|
||||
|
||||
Some(sl)
|
||||
}
|
||||
|
@ -150,18 +242,4 @@ impl StructLayout {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
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