adapt to changes in lib-laddertypes

This commit is contained in:
Michael Sippel 2025-06-12 04:14:27 +02:00
parent 6897b5e274
commit 64e8b96c92
Signed by: senvas
GPG key ID: F96CF119C34B64A6
10 changed files with 196 additions and 196 deletions

View file

@ -1,9 +1,11 @@
use {
super::types::get_c_repr_arg_type, crate::{c_gen::LdmcCTargetMorph, LdmcPrimMorph}, laddertypes::{morphism::MorphismInstance, parser::*, MorphismType, TypeDict}, std::collections::HashMap
super::types::get_c_repr_arg_type, crate::{c_gen::LdmcCTargetMorph, LdmcPrimMorph},
laddertypes::{morphism::MorphismInstance, parser::*, Context, MorphismType, TypeDict},
std::{collections::HashMap, sync::{Arc, RwLock}}
};
pub fn generate_lib(
dict: &mut impl TypeDict,
mut ctx: Arc<RwLock<Context>>,
include_blocks: Vec< String >,
include_dependencies: HashMap< MorphismType, usize >,
morphisms: Vec< (String, MorphismInstance<LdmcPrimMorph>) >
@ -12,7 +14,7 @@ pub fn generate_lib(
let mut wrappers = String::new();
for (name, morph) in morphisms {
match target.add_instantiation(dict, morph) {
match target.add_instantiation(ctx.clone(), morph) {
Ok(inst) => {
if name == "main" {
let mut c_source = String::new();
@ -25,7 +27,7 @@ pub fn generate_lib(
if let Ok(_) = laddertypes::subtype_unify(
&inst.ty.src_type,
&dict.parse("<Seq~<ValueTerminated '\\n'> Char~Ascii~native.UInt8>").expect("")
&ctx.parse("<Seq~<ValueTerminated '\\n'> Char~Ascii~native.UInt8>").expect("")
) {
c_source.push_str("scanf(\"%s\", bufIn);\n");
} else {
@ -35,12 +37,12 @@ pub fn generate_lib(
c_source.push_str(
&format!(r#"FUSE( {}, (void const*)bufIn, (void*)bufOut );
"#,
inst.instantiated_symbol_name(dict, &HashMap::new()))
inst.instantiated_symbol_name(&ctx, &HashMap::new()))
);
if let Ok(ψ) = laddertypes::subtype_unify(
&inst.ty.dst_type,
&dict.parse("<Seq~<ValueTerminated 0> native.UInt8>").expect("")
&ctx.parse("<Seq~<ValueTerminated 0> native.UInt8>").expect("")
) {
c_source.push_str("printf(\"%s\\n\", bufOut);\n");
} else {
@ -51,8 +53,8 @@ pub fn generate_lib(
}");
wrappers.push_str(&c_source);
} else {
target.add_type(dict, inst.ty.src_type.clone());
target.add_type(dict, inst.ty.dst_type.clone());
target.add_type(ctx.clone(), inst.ty.src_type.clone());
target.add_type(ctx.clone(), inst.ty.dst_type.clone());
wrappers.push_str(&format!("
int {} (
@ -62,9 +64,9 @@ pub fn generate_lib(
return {}( (void*)src, (void*)dst );
}}
", name,
get_c_repr_arg_type(dict, &inst.ty.src_type),
get_c_repr_arg_type(dict, &inst.ty.dst_type),
inst.instantiated_symbol_name(dict, &HashMap::new())
get_c_repr_arg_type(ctx.clone(), &inst.ty.src_type),
get_c_repr_arg_type(ctx.clone(), &inst.ty.dst_type),
inst.instantiated_symbol_name(&ctx, &HashMap::new())
));
}
}
@ -75,7 +77,7 @@ pub fn generate_lib(
}
}
let mut c_source = target.into_c_source(dict);
let mut c_source = target.into_c_source(ctx);
c_source.push_str(&wrappers);
Ok(c_source)

View file

@ -9,57 +9,51 @@ use {
},
morphism::LdmcPrimMorph
},
laddertypes::{TypeDict, Substitution},
laddertypes::{Context, HashMapSubst, Substitution, TypeDict},
std::sync::{Arc, RwLock},
};
impl LdmcPrimMorph {
pub fn instantiated_symbol_name(&self, dict: &mut impl TypeDict, σ: &impl Substitution) -> String {
pub fn instantiated_symbol_name(&self, ctx: &Arc<RwLock<Context>>, σ: &impl Substitution) -> 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 {
for (var_id,v) in self.type_args.iter() {
if let Ok(val_trm) = σ.get(*var_id) {
//if self.get_type().strip_halo().src_type.contains_var(*var_id) ||
//self.get_type().strip_halo().dst_type.contains_var(*var_id) {
let name = dict.get_varname(*var_id).unwrap();
let val_str = get_c_repr_type(dict, &val_trm);
let name = ctx.get_varname(*var_id).unwrap();
let val_str = get_c_repr_type(ctx, &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);
}
let k = ctx.get_varname(*var_id).unwrap();
s.push_str(&format!("_{:?}_MISSING", k));
eprintln!("INCOMPLETE MORPHISM INSTANTIATION, missing type parameter {} ({})", k, var_id);
}
}
s
}
pub fn expected_c_type_signature(&self, dict: &mut impl TypeDict,
σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>
pub fn expected_c_type_signature(&self, ctx: Arc<RwLock<Context>>,
σ: &HashMapSubst
) -> String {
format!("int {} ({} const * restrict src, {} * restrict dst);",
self.instantiated_symbol_name(dict, σ),
get_c_repr_definition(dict, self.ty.src_type.clone(), true).expect("cant get c-repr type for src type"),
get_c_repr_definition(dict, self.ty.dst_type.clone(), true).expect("cant get c-repr type for dst type"))
self.instantiated_symbol_name(&ctx, σ),
get_c_repr_definition(ctx.clone(), self.ty.src_type.clone(), true).expect("cant get c-repr type for src type"),
get_c_repr_definition(ctx.clone(), 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 Substitution) -> Option<String> {
pub fn generate_instantiation(&self, mut ctx: Arc<RwLock<Context>>, σ: &impl Substitution) -> Option<String> {
let mut s = String::new();
let symbol = self.instantiated_symbol_name(dict, σ);
let symbol = self.instantiated_symbol_name(&ctx, σ);
eprintln!("generate instantiation:");
let ty = self.ty.clone();
eprintln!("full type: {} ----> {}", ty.src_type.pretty(dict, 0), ty.dst_type.pretty(dict,0));
let ty = ty.strip_halo().apply_subst(σ);
eprintln!("stripped type: {} ----> {}", ty.src_type.pretty(dict, 0), ty.dst_type.pretty(dict,0));
eprintln!("full type: {} ----> {}", ty.src_type.pretty(&mut ctx, 0), ty.dst_type.pretty(&mut ctx,0));
let ty = ty.strip_common_rungs().apply_subst(σ);
eprintln!("stripped type: {} ----> {}", ty.src_type.pretty(&mut ctx, 0), ty.dst_type.pretty(&mut ctx,0));
let src_c_symbol = get_c_repr_arg_type(dict, &ty.src_type);
let dst_c_symbol = get_c_repr_arg_type(dict, &ty.dst_type);
let src_c_symbol = get_c_repr_arg_type(ctx.clone(), &ty.src_type);
let dst_c_symbol = get_c_repr_arg_type(ctx.clone(), &ty.dst_type);
s.push_str(&format!(r#"
int {} ( {} const * restrict src, {} * restrict dst ) {{

View file

@ -6,8 +6,8 @@ use {
morphism::LdmcPrimMorph
},
laddertypes::{
parser::*, Morphism, MorphismInstance, MorphismType, Substitution, TypeDict, TypeID, TypeTerm
}, std::{collections::HashMap, ops::Deref}
parser::*, Context, HashMapSubst, LayeredContext, Morphism, MorphismInstance, MorphismType, Substitution, SubstitutionMut, TypeDict, TypeID, TypeKind, TypeTerm
}, std::{collections::HashMap, ops::Deref, sync::{Arc, RwLock}}
};
pub struct LdmcCTargetMorph {
@ -53,10 +53,10 @@ impl LdmcCTargetMorph {
m
}
pub fn add_type(&mut self, dict: &mut impl TypeDict, ty: TypeTerm) {
pub fn add_type(&mut self, mut ctx: Arc<RwLock<Context>>, ty: TypeTerm) {
let ty = ty.strip();
if ! self.active_types.contains(&ty) {
eprintln!("add type {}", ty.pretty(dict,0));
eprintln!("add type {}", ty.pretty(&mut ctx,0));
let (ht,ft) = ty.get_floor_type();
if ht.is_empty() {
@ -64,22 +64,23 @@ impl LdmcCTargetMorph {
match &ft {
TypeTerm::Seq { seq_repr, items } => {
let item_type = items.first().unwrap().clone();
self.add_type(dict, item_type.clone());
self.add_type(ctx.clone(), item_type.clone());
if let Some(seq_repr) = seq_repr {
dict.add_varname("LengthType".into());
let mut ctx = ctx.scope();
ctx.add_variable("LengthType", TypeKind::Type);
if let Ok(σ) =
laddertypes::constraint_system::unify(
seq_repr.as_ref(),
&dict.parse_desugared("<LengthPrefix LengthType>").expect("").sugar(dict)
&ctx.parse_desugared("<LengthPrefix LengthType>").expect("").sugar(&mut ctx)
)
{
let length_type = σ.get(&dict.get_typeid(&"LengthType".into()).expect("")).expect("cant get Length type");
self.add_type(dict, length_type.clone());
let length_type = σ.get(&ctx.get_varid("LengthType").expect("")).expect("cant get Length type");
self.add_type(ctx.clone(), length_type.clone());
self.macro_calls.push(
format!("DEFINE_LENGTH_PREFIX_ARRAY({}, {})\n",
get_c_repr_type(dict, &length_type),
get_c_repr_type(dict, &item_type)
get_c_repr_type(&ctx, &length_type),
get_c_repr_type(&ctx, &item_type)
)
);
}
@ -89,16 +90,16 @@ impl LdmcCTargetMorph {
}
self.active_types.push(ty.clone());
if let Some(type_def) = get_c_repr_definition(dict, ft, false) {
let type_name = get_c_repr_type(dict, &ty);
if let Some(type_def) = get_c_repr_definition(ctx.clone(), ft, false) {
let type_name = get_c_repr_type(&ctx, &ty);
self.typedefs.push(format!("typedef {} {};\n", type_def, type_name));
} else {
eprintln!("cant get c-repr type for type '{}'", ty.pretty(dict,0));
eprintln!("cant get c-repr type for type '{}'", ty.pretty(&mut ctx,0));
}
} else {
let type_name = get_c_repr_type(dict, &ty);
let type_def = get_c_repr_type(dict, &ft);
self.add_type(dict, ft);
let type_name = get_c_repr_type(&ctx, &ty);
let type_def = get_c_repr_type(&ctx, &ft);
self.add_type(ctx, ft);
self.typedefs.push(format!("typedef {} {};\n", type_def, type_name));
}
}
@ -106,23 +107,23 @@ impl LdmcCTargetMorph {
pub fn add_instantiation(
&mut self,
dict: &mut impl TypeDict,
ctx: Arc<RwLock<Context>>,
morph: MorphismInstance<LdmcPrimMorph>,
) -> Result<LdmcPrimMorph, ()> {
let mut σ = HashMap::new();
let new_inst = self.bake_morphism(dict, TypeTerm::unit(), &mut σ, morph)?;
let new_inst = self.bake_morphism(ctx.clone(), TypeTerm::unit(), &mut σ, morph)?;
if ! self.active_morphisms.contains(&new_inst) {
self.active_morphisms.push(new_inst.clone());
}
let ty = new_inst.get_type().strip_halo();
self.add_type(dict, ty.src_type);
self.add_type(dict, ty.dst_type);
let ty = new_inst.get_type().strip_common_rungs();
self.add_type(ctx.clone(), ty.src_type);
self.add_type(ctx, ty.dst_type);
Ok(new_inst)
}
pub fn into_c_source(mut self, dict: &mut impl TypeDict) -> String {
pub fn into_c_source(mut self, ctx: Arc<RwLock<Context>>) -> String {
let mut source = String::new();
self.active_headers.sort();
self.active_headers.dedup();
@ -149,20 +150,20 @@ impl LdmcCTargetMorph {
source.push('\n');
for m in self.active_morphisms {
source.push_str(&m.generate_instantiation(dict, &HashMap::new()).expect("cant create function"));
source.push_str(&m.generate_instantiation(ctx.clone(), &HashMap::new()).expect("cant create function"));
}
source
}
pub fn bake_morphism(
&mut self,
dict: &mut impl laddertypes::TypeDict,
ctx: Arc<RwLock<Context>>,
mut ψ: TypeTerm,
σ: &mut HashMap<TypeID, TypeTerm>,
σ: &mut HashMapSubst,
morph_inst: MorphismInstance<LdmcPrimMorph>,
) -> Result<LdmcPrimMorph, ()> {
let ty = morph_inst.get_type();
let symbol = encode_morph_type_to_symbol(dict, &ty);
let symbol = encode_morph_type_to_symbol(&ctx, &ty);
match &morph_inst {
MorphismInstance::Id { τ } => {
@ -170,17 +171,17 @@ impl LdmcCTargetMorph {
Ok(LdmcPrimMorph {
symbol,
type_args: Vec::new(),
ty: MorphismType { src_type: τ.clone(), dst_type: τ.clone() },
ty: MorphismType { bounds: Vec::new(), src_type: τ.clone(), dst_type: τ.clone() },
c_source: String::from("memcpy(dst, src, sizeof(*src));")
})
}
MorphismInstance::Sub { ψ:ψ1, m } => {
ψ = TypeTerm::Ladder(vec![ ψ1.clone(), ψ.clone() ]).normalize();
self.bake_morphism(dict, ψ, σ, m.deref().clone())
self.bake_morphism(ctx, ψ, σ, m.deref().clone())
}
MorphismInstance::Specialize { σ:σ1, m } => {
*σ = σ.clone().append(&σ1);
self.bake_morphism(dict, ψ, σ, m.deref().clone())
σ.append(&σ1);
self.bake_morphism(ctx, ψ, σ, m.deref().clone())
}
MorphismInstance::Primitive { m: morph } => {
if let Some(i) = self.header_dependencies.get(&morph.get_type()) {
@ -188,30 +189,26 @@ impl LdmcCTargetMorph {
}
let mut c_source = String::new();
for (ty_id, kind) in morph.type_args.iter() {
if let laddertypes::TypeID::Var(var_id) = ty_id {
if let Some(val) = σ.get(&ty_id) {
for (v, kind) in morph.type_args.iter() {
if let Some(val) = σ.get(v) {
let type_var_value =
if kind == "Type" {
get_c_repr_type(dict, val)
get_c_repr_type(&ctx, val)
} else {
encode_type_to_value(dict, val)
encode_type_to_value(&ctx, val)
};
c_source.push_str(&format!(" #define {} {}\n", dict.get_typename(&ty_id).unwrap(), type_var_value));
c_source.push_str(&format!(" #define {} {}\n", ctx.get_varname(*v).unwrap(), type_var_value));
}
}
}
c_source.push_str(&morph.c_source);
for (ty_id, kind) in morph.type_args.iter() {
if let laddertypes::TypeID::Var(var_id) = ty_id {
c_source.push_str(&format!("\n #undef {}", dict.get_typename(&ty_id).unwrap()));
}
for (v, kind) in morph.type_args.iter() {
c_source.push_str(&format!("\n #undef {}", ctx.get_varname(*v).unwrap()));
}
Ok(LdmcPrimMorph{
symbol: morph.instantiated_symbol_name(dict, σ),
symbol: morph.instantiated_symbol_name(&ctx, σ),
type_args: Vec::new(),
ty: morph_inst.get_type().apply_subst(σ).strip_halo(),
ty: morph_inst.get_type().apply_subst(σ).strip_common_rungs(),
c_source
})
},
@ -226,8 +223,8 @@ impl LdmcCTargetMorph {
}
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());
if let Ok(inst) = self.add_instantiation(ctx.clone(), morph.clone()) {
let morph_symbol = inst.instantiated_symbol_name(&ctx, &morph.get_subst());
let src_buf = if i == 0 { "(void*)src" } else if i%2 == 0 { "(void*)bufA" } else { "(void*)bufB" };
let dst_buf = if i+1 == path.len() { "(void*)dst" } else if i%2 == 0 { "(void*)bufB" } else { "(void*)bufA" };
@ -247,23 +244,24 @@ impl LdmcCTargetMorph {
})
}
MorphismInstance::MapSeq { seq_repr, item_morph } => {
if let Ok(item_morph_inst) = self.add_instantiation(dict, item_morph.as_ref().clone()) {
if let Ok(item_morph_inst) = self.add_instantiation(ctx.clone(), item_morph.as_ref().clone()) {
if let Some(seq_repr) = seq_repr {
dict.add_varname("Length".into());
dict.add_varname("LengthType".into());
dict.add_varname("TerminatorValue".into());
let mut ctx = ctx.scope();
ctx.add_variable("Length", TypeKind::ValueUInt);
ctx.add_variable("LengthType", TypeKind::Type);
ctx.add_variable("TerminatorValue", TypeKind::ValueUInt);
if let Ok(γ) = laddertypes::constraint_system::unify(
&dict.parse_desugared("<StaticLength Length>").expect("parse type template").sugar(dict),
&ctx.parse_desugared("<StaticLength Length>").expect("parse type template").sugar(&mut ctx),
seq_repr.as_ref()
) {
let length = γ.get(&dict.get_typeid(&"Length".into()).expect("")).expect("cant get Length");
let length = γ.get(&ctx.get_varid("Length").expect("")).expect("cant get Length");
match length {
TypeTerm::Num(l) => {
let item_morph_symbol = item_morph_inst.instantiated_symbol_name(dict, &HashMap::new());
let item_morph_symbol = item_morph_inst.instantiated_symbol_name(&ctx, &HashMap::new());
self.add_type( dict, morph_inst.get_type().strip_halo().src_type );
self.add_type( dict, morph_inst.get_type().strip_halo().dst_type );
self.add_type( ctx.clone(), morph_inst.get_type().strip_common_rungs().src_type );
self.add_type( ctx.clone(), morph_inst.get_type().strip_common_rungs().dst_type );
let c_source = format!(r#"
for( size_t i = 0; i < {}; ++i ) {{
@ -280,22 +278,22 @@ impl LdmcCTargetMorph {
})
}
_ => {
eprintln!("invalid length '{}'", length.pretty(dict, 0));
eprintln!("invalid length '{}'", length.pretty(&mut ctx, 0));
Err(())
}
}
}
else if let Ok(γ) = laddertypes::constraint_system::unify(
&dict.parse_desugared("<LengthPrefix LengthType>").expect("parse type template").sugar(dict),
&ctx.parse_desugared("<LengthPrefix LengthType>").expect("parse type template").sugar(&mut ctx),
seq_repr.as_ref()
) {
// todo: assert that length type is native.UIntX
//let length_type = γ.get(&dict.get_typeid(&"LengthType".into()).expect("")).expect("cant get LengthType");
let item_morph_symbol = item_morph_inst.instantiated_symbol_name(dict, &HashMap::new());
let item_morph_symbol = item_morph_inst.instantiated_symbol_name(&ctx, &HashMap::new());
self.add_type( dict, morph_inst.get_type().strip_halo().src_type );
self.add_type( dict, morph_inst.get_type().strip_halo().dst_type );
self.add_type( ctx.clone(), morph_inst.get_type().strip_common_rungs().src_type );
self.add_type( ctx.clone(), morph_inst.get_type().strip_common_rungs().dst_type );
let c_source = format!(r#"
for( size_t i = 0; i < src->len; ++i ) {{
@ -313,12 +311,12 @@ impl LdmcCTargetMorph {
}
else if let Ok(γ) = laddertypes::constraint_system::unify(
&dict.parse_desugared("<ValueTerminated TerminatorValue>").expect("parse type template").sugar(dict),
&ctx.parse_desugared("<ValueTerminated TerminatorValue>").expect("parse type template").sugar(&mut ctx),
seq_repr.as_ref()
) {
let terminator_value = γ.get(&dict.get_typeid(&"TerminatorValue".into()).expect("")).expect("cant get TerminatorValue");
let item_morph_symbol = item_morph_inst.instantiated_symbol_name(dict, &HashMap::new());
let terminator = encode_type_to_value(dict, terminator_value);
let terminator_value = γ.get(&ctx.get_varid("TerminatorValue").expect("")).expect("cant get TerminatorValue");
let item_morph_symbol = item_morph_inst.instantiated_symbol_name(&ctx, &HashMap::new());
let terminator = encode_type_to_value(&ctx, terminator_value);
let c_source = format!(r#"
while( *src != {} ) {{
@ -357,11 +355,11 @@ impl LdmcCTargetMorph {
let mut c_source = String::new();
for (name, morph) in member_morph.iter() {
if let Ok(inst) = self.add_instantiation(dict, morph.clone()) {
if let Ok(inst) = self.add_instantiation(ctx.clone(), morph.clone()) {
let name = name.replace("-", "_").replace(".","_dot_");
c_source.push_str(
&format!("
FUSE( {}, &src->{}, &dst->{} );",
FUSE( {}, (void*)&src->{}, (void*)&dst->{} );",
inst.symbol,
name, name
));

View file

@ -1,9 +1,11 @@
use {
crate::struct_layout::LayoutType,
chumsky::chain::Chain, laddertypes::{morphism::MorphismType,
parser::*,
substitution::Substitution,
unparser::*, EnumVariant, StructMember, TypeTerm, TypeDict}
laddertypes::{
morphism::MorphismType, parser::*, unparser::*,
Context, EnumVariant, LayeredContext, StructMember,
TypeDict, TypeID, TypeKind, TypeTerm
},
std::sync::{Arc, RwLock}
};
/*
@ -17,22 +19,22 @@ pub fn get_c_repr_kind(kind: String) -> Option<String> {
/* for a given ladder type `t`, get the corresponding C type
*/
pub fn get_c_repr_definition(dict: &mut impl TypeDict, t: TypeTerm, skip_pointer: bool) -> Option<String> {
pub fn get_c_repr_definition(mut ctx: Arc<RwLock<Context>>, t: TypeTerm, skip_pointer: bool) -> Option<String> {
match t {
TypeTerm::TypeID(tyid) => {
if tyid == dict.get_typeid_creat("native.UInt8") {
TypeTerm::Id(tyid) => {
if TypeID::Fun(tyid) == ctx.get_typeid_creat("native.UInt8") {
Some("uint8_t".into())
} else if tyid == dict.get_typeid_creat("native.UInt16") {
} else if TypeID::Fun(tyid) == ctx.get_typeid_creat("native.UInt16") {
Some("uint16_t".into())
} else if tyid == dict.get_typeid_creat("native.UInt32") {
} else if TypeID::Fun(tyid) == ctx.get_typeid_creat("native.UInt32") {
Some("uint32_t".into())
} else if tyid == dict.get_typeid_creat("native.UInt64") {
} else if TypeID::Fun(tyid) == ctx.get_typeid_creat("native.UInt64") {
Some("uint64_t".into())
} else if tyid == dict.get_typeid_creat("native.Address") {
} else if TypeID::Fun(tyid) == ctx.get_typeid_creat("native.Address") {
Some("void*".into())
} else if tyid == dict.get_typeid_creat("native.Float32") {
} else if TypeID::Fun(tyid) == ctx.get_typeid_creat("native.Float32") {
Some("float".into())
} else if tyid == dict.get_typeid_creat("native.Float64") {
} else if TypeID::Fun(tyid) == ctx.get_typeid_creat("native.Float64") {
Some("double".into())
} else {
None
@ -42,19 +44,21 @@ pub fn get_c_repr_definition(dict: &mut impl TypeDict, t: TypeTerm, skip_pointer
TypeTerm::Seq{ seq_repr, items } => {
if let Some(seq_repr) = seq_repr {
let item_type = items.first().expect("no item type specified!").clone();
let item_c_type : String = get_c_repr_type(dict, &item_type);
let item_c_type : String = get_c_repr_type(&mut ctx, &item_type);
dict.add_varname("Length".into()); // Kind: Num
dict.add_varname("LengthType".into()); // Kind: Type
dict.add_varname("TermValue".into()); // Kind: Value of Type ItemType
let ctx = ctx.scope();
ctx.add_variable("Length", TypeKind::ValueUInt);
ctx.add_variable("LengthType", TypeKind::Type);
ctx.add_variable("TermValue", TypeKind::ValueUInt); // Kind: Value of Type ItemType
if let Ok((ψ, σ)) = laddertypes::constraint_system::subtype_unify(
seq_repr.as_ref(),
&dict.parse_desugared("<StaticLength Length>").expect("parse template type").sugar(dict)
&ctx.clone().parse_desugared("<StaticLength Length>").expect("parse template type").sugar(&mut ctx.clone())
) {
let length = match
σ.get(
&dict.get_typeid(&"Length".into()).expect("no Length ID")
&ctx.get_varid("Length").expect("no Length ID")
).expect("no length specified!")
{
TypeTerm::Num(l) => l,
@ -67,19 +71,19 @@ pub fn get_c_repr_definition(dict: &mut impl TypeDict, t: TypeTerm, skip_pointer
}
else if let Ok((ψ, σ)) = laddertypes::constraint_system::subtype_unify(
seq_repr.as_ref(),
&dict.parse_desugared("<LengthPrefix LengthType>").expect("parse template type").sugar(dict)
&ctx.clone().parse_desugared("<LengthPrefix LengthType>").expect("parse template type").sugar(&mut ctx.clone())
) {
let length_type = σ.get(
&dict.get_typeid(&"LengthType".into()).expect("no LengthType ID")
&ctx.get_varid("LengthType").expect("no LengthType ID")
).expect("no length type specified");
let length_c_type = get_c_repr_type(dict, &length_type);
let length_c_type = get_c_repr_type(&ctx, &length_type);
Some(format!("struct {{ {} len; {} items[]; }} ", length_c_type, item_c_type))
}
else if let Ok((ψ, σ)) = laddertypes::constraint_system::subtype_unify(
seq_repr.as_ref(),
&dict.parse_desugared("<ValueTerminated TermValue>").expect("parse template type").sugar(dict)
&ctx.clone().parse_desugared("<ValueTerminated TermValue>").expect("parse template type").sugar(&mut ctx.clone())
) {
if skip_pointer {
Some(item_c_type)
@ -89,7 +93,7 @@ pub fn get_c_repr_definition(dict: &mut impl TypeDict, t: TypeTerm, skip_pointer
}
else if let Ok((ψ, σ)) = laddertypes::constraint_system::subtype_unify(
seq_repr.as_ref(),
&dict.parse_desugared("MsbCont").expect("parse template type").sugar(dict)
&ctx.clone().parse_desugared("MsbCont").expect("parse template type").sugar(&mut ctx.clone())
) {
if skip_pointer {
Some(item_c_type)
@ -98,7 +102,7 @@ pub fn get_c_repr_definition(dict: &mut impl TypeDict, t: TypeTerm, skip_pointer
}
}
else {
eprintln!("can't get C-repr for sequence type `{}`!", seq_repr.pretty(dict, 0));
eprintln!("can't get C-repr for sequence type `{}`!", seq_repr.pretty(&mut ctx.clone(), 0));
None
}
} else {
@ -110,8 +114,8 @@ pub fn get_c_repr_definition(dict: &mut impl TypeDict, t: TypeTerm, skip_pointer
TypeTerm::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") {
let sr = sr.desugar(&mut ctx);
match LayoutType::parse(&mut ctx, &sr).expect("layout type") {
LayoutType::Aligned => "",
LayoutType::Packed => "__attribute((packed))__"
}
@ -120,7 +124,7 @@ pub fn get_c_repr_definition(dict: &mut impl TypeDict, t: TypeTerm, skip_pointer
let mut c_type = format!("struct {} {{\n", c_struct_attribute);
for StructMember{ symbol, ty } in members {
let field_c_type = get_c_repr_definition(dict, ty, false).expect("");
let field_c_type = get_c_repr_definition(ctx.clone(), ty, false).expect("");
c_type.push_str(&format!(" {} {};\n",
field_c_type,
symbol.replace("-", "_").replace(".","_dot_")
@ -154,7 +158,7 @@ struct {{
");
for EnumVariant{ symbol, ty } in variants {
let variant_c_type = get_c_repr_definition(dict, ty, false).expect("cant get C-Repr type for variant");
let variant_c_type = get_c_repr_definition(ctx.clone(), ty, false).expect("cant get C-Repr type for variant");
c_type.push_str(&format!(
" {} {};\n", variant_c_type, symbol.replace("-", "_").replace(".","_dot_")
));
@ -169,7 +173,7 @@ struct {{
TypeTerm::Ladder(rungs) => {
if let Some(t) = rungs.last() {
get_c_repr_definition(dict, t.clone(), false)
get_c_repr_definition(ctx, t.clone(), false)
} else {
None
}
@ -179,10 +183,10 @@ struct {{
}
}
pub fn get_c_repr_type(dict: &mut impl TypeDict, t: &laddertypes::TypeTerm)-> String {
pub fn get_c_repr_type(parent: &Arc<RwLock<Context>>, t: &laddertypes::TypeTerm)-> String {
let t = t.clone().strip();
match t.desugar(dict) {
match t.desugar(&mut parent.clone()) {
laddertypes::DesugaredTypeTerm::Char(c) => {
match c {
'.' => format!("_dot_"),
@ -195,7 +199,7 @@ pub fn get_c_repr_type(dict: &mut impl TypeDict, t: &laddertypes::TypeTerm)-> St
format!("{}", n)
}
laddertypes::DesugaredTypeTerm::TypeID(ty_id) => {
if let Some(name) = dict.get_typename(&ty_id) {
if let Some(name) = parent.get_name(ty_id.clone()) {
name
.replace("-", "_")
.replace(".", "")
@ -208,8 +212,8 @@ pub fn get_c_repr_type(dict: &mut impl TypeDict, t: &laddertypes::TypeTerm)-> St
let mut s = String::new();
s.push('_');
for r in rs {
let r = r.sugar(dict);
s.push_str(&get_c_repr_type(dict, &r));
let r = r.sugar(&mut parent.clone());
s.push_str(&get_c_repr_type(parent, &r));
s.push('_');
}
s
@ -217,41 +221,41 @@ pub fn get_c_repr_type(dict: &mut impl TypeDict, t: &laddertypes::TypeTerm)-> St
}
}
pub fn get_c_repr_arg_type(dict: &mut impl TypeDict, t: &laddertypes::TypeTerm)-> String {
pub fn get_c_repr_arg_type(mut ctx: Arc<RwLock<Context>>, t: &laddertypes::TypeTerm)-> String {
let t = t.clone().strip().get_floor_type().1;
dict.add_varname("TerminatorValue".into());
ctx.add_variable("TerminatorValue", TypeKind::ValueUInt);
match &t {
TypeTerm::Seq { seq_repr, items } => {
if let Some(seq_repr) = seq_repr.as_ref() {
if let Ok(ψ) = laddertypes::constraint_system::subtype_unify(
seq_repr,
&dict.parse_desugared("<ValueTerminated TerminatorValue>").expect("").sugar(dict)
&ctx.parse_desugared("<ValueTerminated TerminatorValue>").expect("").sugar(&mut ctx.clone())
) {
return get_c_repr_type(dict, &items[0].clone().strip().get_floor_type().1);
return get_c_repr_type(&ctx, &items[0].clone().strip().get_floor_type().1);
}
else if let Ok(ψ) = laddertypes::constraint_system::subtype_unify(
seq_repr,
&dict.parse_desugared("MsbCont").expect("").sugar(dict)
&ctx.parse_desugared("MsbCont").expect("").sugar(&mut ctx.clone())
) {
return get_c_repr_type(dict, &items[0].clone().strip().get_floor_type().1);
return get_c_repr_type(&ctx, &items[0].clone().strip().get_floor_type().1);
}
}
}
_ => {}
}
get_c_repr_type(dict, &t)
get_c_repr_type(&ctx, &t)
}
pub fn encode_morph_type_to_symbol(dict: &mut impl TypeDict, t: &MorphismType) -> String {
pub fn encode_morph_type_to_symbol(ctx: &Arc<RwLock<Context>>, t: &MorphismType) -> String {
format!(
"morph__{}___TO__{}",
get_c_repr_type(dict, &t.strip_halo().src_type),
get_c_repr_type(dict, &t.strip_halo().dst_type)
get_c_repr_type(ctx, &t.strip_common_rungs().src_type),
get_c_repr_type(ctx, &t.strip_common_rungs().dst_type)
)
}
pub fn encode_type_to_value(dict: &mut impl TypeDict, t: &laddertypes::TypeTerm) -> String {
let t = t.clone().desugar(dict);
dict.unparse(&t)
pub fn encode_type_to_value(ctx: &Arc<RwLock<Context>>, t: &laddertypes::TypeTerm) -> String {
let t = t.clone().desugar(&mut ctx.clone());
ctx.unparse(&t)
}

View file

@ -13,7 +13,7 @@ use {
viz::{MorphbaseVisualizationPane, Visualization},
},
ariadne::{Color, Label, Report, ReportKind, Source}, clap::Parser, laddertypes::{
morphism::MorphismType, morphism_graph::MorphismGraph, BimapTypeDict, Morphism
morphism::*, BimapTypeDict, Context, Morphism
},
parser::morphism_type_parser, std::{io::Write, path::PathBuf, str::FromStr, sync::{Arc, RwLock}},
tiny_ansi::TinyAnsi,
@ -38,8 +38,8 @@ struct Args {
fn main() {
let args = Args::parse();
let mut type_dict = Arc::new(RwLock::new(BimapTypeDict::new()));
let mut morphism_base = laddertypes::morphism_base::MorphismBase::<LdmcPrimMorph>::new();
let mut ctx = Context::new();
let mut morphism_base = laddertypes::morphism::base::MorphismBase::<LdmcPrimMorph>::new();
// 1. load morphism base
let mut mb_paths = args.morphism_base;
@ -87,7 +87,7 @@ fn main() {
let src = std::fs::read_to_string(mb_path.clone()).expect("failed to read morphism base");
use chumsky::Parser;
let result = morphism_base_parser(type_dict.clone()).parse(src.clone());
let result = morphism_base_parser(ctx.clone()).parse(src.clone());
match result {
Ok((includes, morphisms)) => {
eprintln!("[{}] parse ok.", mb_path.to_str().unwrap().bright_yellow());
@ -123,7 +123,7 @@ fn main() {
}
eprintln!("done loading");
morphbase_pane.build_svg(&mut type_dict);
morphbase_pane.build_svg(&mut ctx);
viz.add_pane( morphbase_pane );
// 2. Generate Morphisms
@ -131,16 +131,16 @@ fn main() {
let mut morph_graph = MorphismGraph::new(morphism_base);
for morph_decl in args.morphisms.iter() {
use chumsky::Parser;
if let Ok((name, src_type, dst_type)) = morphism_type_parser(type_dict.clone()).parse(morph_decl.as_str()) {
let ty = MorphismType{ src_type, dst_type };
let morph_inst = morph_graph.search( ty, &mut type_dict ).expect("failed to find morphism");
if let Ok((name, src_type, dst_type)) = morphism_type_parser(ctx.clone()).parse(morph_decl.as_str()) {
let ty = MorphismType{ bounds: vec![], src_type, dst_type };
let morph_inst = morph_graph.search( ty, &mut ctx ).expect("failed to find morphism");
viz.add_module(name.clone());
viz.add_morph_inst(name.clone(), morph_inst.clone(), &mut type_dict);
viz.add_morph_inst(name.clone(), morph_inst.clone(), &mut ctx);
instances.push( (name, morph_inst) );
}
}
let c_source = crate::c_gen::gen_lib::generate_lib(&mut type_dict, include_blocks, include_dependencies, instances).expect("failed to generate library");
let c_source = crate::c_gen::gen_lib::generate_lib(ctx.clone(), include_blocks, include_dependencies, instances).expect("failed to generate library");
if let Some(out_path) = args.output {
let mut file = std::fs::File::create(out_path).expect("failed to open output file");
file.write_all(c_source.as_bytes()).expect("failed to write output file");
@ -149,7 +149,7 @@ fn main() {
}
if let Some(html_path) = args.html {
let html_src = viz.into_html(&mut type_dict, vec![
let html_src = viz.into_html(&mut ctx, vec![
PathBuf::from_str("file:///home/micha/projects/syntaxAlchemist/ldmc/example-layout.csv").unwrap()
]);
let mut output = std::fs::File::create(html_path).expect("couldnt open file");

View file

@ -4,7 +4,7 @@ use laddertypes::morphism::{Morphism, MorphismType};
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct LdmcPrimMorph {
pub symbol: String,
pub type_args: Vec<(laddertypes::TypeID, String)>,
pub type_args: Vec<(u64, String)>,
pub ty: MorphismType,
pub c_source: String
}

View file

@ -1,11 +1,12 @@
use {
crate::morphism::LdmcPrimMorph, chumsky::{
prelude::*, text::*
}, laddertypes::{TypeTerm, morphism::MorphismType, parser::*, BimapTypeDict, TypeDict}, std::sync::{Arc, RwLock}
}, laddertypes::{morphism::MorphismType, parser::*, BimapTypeDict, Context, LayeredContext, TypeDict, TypeKind, TypeTerm}, std::sync::{Arc, RwLock}
};
/* morphism-base text format:
* NAME '(' [TYPE-ARG-NAME ':' KIND] ')'
* NAME '(' [TYPE-ARG-NAME ':' Kind] ')'
* where
* SRC-TYPE
* '-->' DST-TYPE
* ```
@ -13,7 +14,7 @@ use {
* ```
*/
pub fn morphism_base_parser(
type_dict: Arc<RwLock< BimapTypeDict >>
root_ctx: Arc<RwLock< Context >>
) -> impl Parser<char, (String, Vec<LdmcPrimMorph>), Error = Simple<char>> {
just("```")
@ -51,21 +52,22 @@ pub fn morphism_base_parser(
.map(
move |((((symbol, type_args), (src_type, _)), (dst_type, _)), (c_source, _))| {
let c_source = c_source.iter().collect();
let mut type_dict = type_dict.write().unwrap();
let mut ctx = root_ctx.scope();
let type_args : Vec<_> = type_args.into_iter().map(|(v,k)| (v,k.into_iter().collect())).collect();
let mut ty_args = Vec::new();
for (var, kind) in type_args.into_iter() {
let var_id = type_dict.add_varname(var.clone());
ty_args.push((var_id, kind));
for (var, bound) in type_args.into_iter() {
let var_id = ctx.add_variable(var.as_str(), TypeKind::Type);
ty_args.push((var_id, bound));
}
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 = ctx.parse(&src_type.iter().collect::<String>()).expect("couldnt parse src type");
let dst_type = ctx.parse(&dst_type.iter().collect::<String>()).expect("couldnt parse dst type");
LdmcPrimMorph {
symbol,
type_args: ty_args,
ty: MorphismType{
bounds: Vec::new(),
src_type,
dst_type
},
@ -78,7 +80,7 @@ pub fn morphism_base_parser(
}
pub fn morphism_type_parser(
mut type_dict: Arc<RwLock< BimapTypeDict >>
ctx: Arc<RwLock< Context >>
) -> impl Parser<char, (String, TypeTerm, TypeTerm), Error = Simple<char>> {
ident()
.padded()
@ -88,12 +90,12 @@ pub fn morphism_type_parser(
)
.then(take_until(end()))
.map({
let type_dict = type_dict.clone();
let ctx = ctx.clone();
move |((name, src_type), dst_type)| {
(
name.0,
type_dict.clone().parse(&src_type.0.iter().collect::<String>()).expect("parse type"),
type_dict.clone().parse(&dst_type.0.iter().collect::<String>()).expect("parse type")
ctx.clone().parse(&src_type.0.iter().collect::<String>()).expect("parse type"),
ctx.clone().parse(&dst_type.0.iter().collect::<String>()).expect("parse type")
)
}
})

View file

@ -1,6 +1,6 @@
use laddertypes::{parser::*, StructMember, TypeTerm, TypeDict, DesugaredTypeTerm};
use laddertypes::{parser::*, DesugaredTypeTerm, StructMember, TypeDict, TypeID, TypeTerm};
#[derive(Clone, Copy, Debug)]
pub enum ObjectSize {
@ -47,14 +47,14 @@ impl std::ops::Mul for ObjectSize {
pub fn get_type_size( dict: &mut impl TypeDict, ty: TypeTerm ) -> ObjectSize {
match &ty {
TypeTerm::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) }
TypeTerm::Id(tyid) => {
if TypeID::Fun(*tyid) == dict.get_typeid_creat("native.UInt8") { ObjectSize::Static(1) }
else if TypeID::Fun(*tyid) == dict.get_typeid_creat("native.UInt16") { ObjectSize::Static(2) }
else if TypeID::Fun(*tyid) == dict.get_typeid_creat("native.UInt32") { ObjectSize::Static(4) }
else if TypeID::Fun(*tyid) == dict.get_typeid_creat("native.UInt64") { ObjectSize::Static(8) }
else if TypeID::Fun(*tyid) == dict.get_typeid_creat("native.Address") { ObjectSize::Static(8) }
else if TypeID::Fun(*tyid) == dict.get_typeid_creat("native.Float32") { ObjectSize::Static(4) }
else if TypeID::Fun(*tyid) == dict.get_typeid_creat("native.Float64") { ObjectSize::Static(8) }
else {
ObjectSize::Unknown
}
@ -79,7 +79,7 @@ pub fn get_type_size( dict: &mut impl TypeDict, ty: TypeTerm ) -> ObjectSize {
&seq_repr.clone(),
&dict.parse("<StaticLength Length>").expect("")
) {
if let Some(TypeTerm::Num(len)) = σ.get(&dict.get_typeid(&"Length".into()).expect("")) {
if let Some(TypeTerm::Num(len)) = σ.get(&dict.get_varid("Length").expect("")) {
ObjectSize::Static(*len as u64) * get_type_size(dict, items.first().unwrap().clone())
} else {
ObjectSize::Unknown

View file

@ -103,7 +103,7 @@ impl MorphinstVizPane {
svg.push_str(r##"</g>"##);
for e in edges.iter() {
svg.push_str(&format!(r##"
<line class="arrow arrow2" data-source="{}" data-target="{}" />
@ -260,10 +260,10 @@ impl Layout {
}
MorphismInstance::Sub { ψ:ψ1, m } => {
self.add_morph_inst(nodes, edges, m, dict, subnames);
}
MorphismInstance::Specialize { σ, m } => {
self.add_morph_inst(nodes, edges, m, dict, subnames);
}
MorphismInstance::Primitive { m: morph } => {
subnames.push( morph.symbol.clone() );

View file

@ -15,15 +15,15 @@ pub fn unparse_type_to_svg(
<tspan class="value">{}</tspan>
"##, n)
}
TypeTerm::TypeID(TypeID::Fun(fun_id)) => {
TypeTerm::Id(id) => {
format!(r##"
<tspan class="type">{}</tspan>
"##, dict.get_typename(&TypeID::Fun(*fun_id)).unwrap())
"##, dict.get_typename(*id).unwrap_or("?".into()))
}
TypeTerm::TypeID(TypeID::Var(var_id)) => {
TypeTerm::Var(var_id) => {
format!(r##"
<tspan class="typevar">{}</tspan>
"##, dict.get_typename(&TypeID::Var(*var_id)).unwrap())
"##, dict.get_varname(*var_id).unwrap_or("?".into()))
}
TypeTerm::Spec(args) => {
let mut s = String::new();