improve integration
* add command line parsing * read morphism base directory from environment * generate C library of multiple morphisms
This commit is contained in:
parent
923fe987dc
commit
27ea365755
6 changed files with 161 additions and 72 deletions
|
@ -8,3 +8,5 @@ chumsky = "0.9.0"
|
||||||
ariadne = "0.2"
|
ariadne = "0.2"
|
||||||
laddertypes = { path = "../lib-laddertypes", features = ["pretty"] }
|
laddertypes = { path = "../lib-laddertypes", features = ["pretty"] }
|
||||||
tiny-ansi = { version = "0.1.0" }
|
tiny-ansi = { version = "0.1.0" }
|
||||||
|
clap = { version = "4.5.37", features = ["derive"] }
|
||||||
|
walkdir = "2.5.0"
|
||||||
|
|
74
src/c_gen/gen_lib.rs
Normal file
74
src/c_gen/gen_lib.rs
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
use {
|
||||||
|
super::types::get_c_repr_arg_type, crate::{c_gen::LdmcCTargetMorph, LdmcPrimMorph}, laddertypes::{morphism::MorphismInstance, parser::*, TypeDict}, std::collections::HashMap
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn generate_lib(
|
||||||
|
dict: &mut impl TypeDict,
|
||||||
|
morphisms: Vec< (String, MorphismInstance<LdmcPrimMorph>) >
|
||||||
|
) -> Result<String, ()> {
|
||||||
|
let mut target = LdmcCTargetMorph::new();
|
||||||
|
let mut wrappers = String::new();
|
||||||
|
|
||||||
|
for (name, morph) in morphisms {
|
||||||
|
match target.add_instantiation(dict, morph) {
|
||||||
|
Ok(inst) => {
|
||||||
|
if name == "main" {
|
||||||
|
let mut c_source = String::new();
|
||||||
|
c_source.push_str(&format!(r#"
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int main() {{
|
||||||
|
uint8_t bufIn[4096];
|
||||||
|
uint8_t bufOut[4096];"#));
|
||||||
|
|
||||||
|
let (src_top, src_floor) = inst.ty.src_type.get_floor_type();
|
||||||
|
if src_floor == dict.parse_desugared("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict) {
|
||||||
|
c_source.push_str("scanf(\"%s\", bufIn);");
|
||||||
|
} else {
|
||||||
|
c_source.push_str("read(0, bufIn, sizeof(bufIn));");
|
||||||
|
}
|
||||||
|
|
||||||
|
c_source.push_str(&format!(r#"FUSE( {}, (void const*)bufIn, (void*)bufOut );"#, inst.instantiated_symbol_name(dict, &HashMap::new())));
|
||||||
|
|
||||||
|
if let Ok(ψ) = laddertypes::constraint_system::subtype_unify(
|
||||||
|
&inst.ty.src_type,
|
||||||
|
&dict.parse_desugared("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict)
|
||||||
|
) {
|
||||||
|
c_source.push_str("printf(\"%s\\n\", bufOut);");
|
||||||
|
} else {
|
||||||
|
c_source.push_str("write(1, bufOut, sizeof(bufOut));");
|
||||||
|
}
|
||||||
|
c_source.push_str("
|
||||||
|
return 0;
|
||||||
|
}");
|
||||||
|
wrappers.push_str(&c_source);
|
||||||
|
} else {
|
||||||
|
target.add_type(dict, inst.ty.src_type.clone());
|
||||||
|
target.add_type(dict, inst.ty.dst_type.clone());
|
||||||
|
|
||||||
|
wrappers.push_str(&format!("
|
||||||
|
int {} (
|
||||||
|
{} const * restrict src,
|
||||||
|
{} * restrict dst
|
||||||
|
) {{
|
||||||
|
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())
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_err) => {
|
||||||
|
eprintln!("failed to create morphism instatiation");
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut c_source = target.into_c_source(dict);
|
||||||
|
c_source.push_str(&wrappers);
|
||||||
|
|
||||||
|
Ok(c_source)
|
||||||
|
}
|
|
@ -1,49 +0,0 @@
|
||||||
use {
|
|
||||||
laddertypes::{TypeDict, morphism::MorphismInstance, parser::*},
|
|
||||||
crate::LdmcPrimMorph,
|
|
||||||
crate::c_gen::LdmcCTargetMorph,
|
|
||||||
std::collections::HashMap,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn generate_main(dict: &mut impl TypeDict, morph: MorphismInstance<LdmcPrimMorph>) -> Result<String, ()> {
|
|
||||||
let mut target = LdmcCTargetMorph::new();
|
|
||||||
let ty = morph.get_type();
|
|
||||||
match target.add_instantiation(dict, morph) {
|
|
||||||
Ok(inst) => {
|
|
||||||
let mut c_source = target.into_c_source(dict);
|
|
||||||
|
|
||||||
c_source.push_str(&format!(r#"
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
int main() {{
|
|
||||||
uint8_t bufIn[4096];
|
|
||||||
uint8_t bufOut[4096];"#));
|
|
||||||
|
|
||||||
let (src_top, src_floor) = ty.src_type.get_floor_type();
|
|
||||||
if src_floor == dict.parse_desugared("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict) {
|
|
||||||
c_source.push_str("scanf(\"%s\", bufIn);");
|
|
||||||
} else {
|
|
||||||
c_source.push_str("read(0, bufIn, sizeof(bufIn));");
|
|
||||||
}
|
|
||||||
|
|
||||||
c_source.push_str(&format!(r#"FUSE( {}, (void const*)bufIn, (void*)bufOut );"#, inst.instantiated_symbol_name(dict, &HashMap::new())));
|
|
||||||
|
|
||||||
if let Ok(ψ) = laddertypes::constraint_system::subtype_unify(
|
|
||||||
&ty.src_type,
|
|
||||||
&dict.parse_desugared("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict)
|
|
||||||
) {
|
|
||||||
c_source.push_str("printf(\"%s\\n\", bufOut);");
|
|
||||||
} else {
|
|
||||||
c_source.push_str("write(1, bufOut, sizeof(bufOut));");
|
|
||||||
}
|
|
||||||
c_source.push_str("
|
|
||||||
return 0;
|
|
||||||
}");
|
|
||||||
Ok(c_source)
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
eprintln!("failed to create morphism instatiation");
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
pub mod types;
|
pub mod types;
|
||||||
pub mod morph;
|
pub mod morph;
|
||||||
pub mod gen_main;
|
pub mod gen_lib;
|
||||||
|
|
||||||
pub use {
|
pub use {
|
||||||
morph::target_morph::LdmcCTargetMorph
|
morph::target_morph::LdmcCTargetMorph
|
||||||
|
|
78
src/main.rs
78
src/main.rs
|
@ -9,33 +9,66 @@ use {
|
||||||
crate::{
|
crate::{
|
||||||
morphism::LdmcPrimMorph,
|
morphism::LdmcPrimMorph,
|
||||||
parser::morphism_base_parser,
|
parser::morphism_base_parser,
|
||||||
},
|
}, ariadne::{Color, Label, Report, ReportKind, Source}, chumsky::prelude::*, clap::{Parser, Subcommand}, laddertypes::{
|
||||||
ariadne::{Color, Label, Report, ReportKind, Source},
|
|
||||||
chumsky::prelude::*,
|
|
||||||
laddertypes::{
|
|
||||||
morphism::MorphismType,
|
morphism::MorphismType,
|
||||||
parser::ParseLadderType, BimapTypeDict
|
parser::ParseLadderType, BimapTypeDict
|
||||||
},
|
}, parser::morphism_type_parser, std::{path::PathBuf,
|
||||||
std::{sync::{Arc, RwLock}},
|
sync::{Arc, RwLock}}, tiny_ansi::TinyAnsi,
|
||||||
tiny_ansi::TinyAnsi
|
walkdir::WalkDir
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() {
|
#[derive(Parser, Debug)]
|
||||||
let mut type_dict = Arc::new(RwLock::new(BimapTypeDict::new()));
|
#[command(version, about, long_about = None)]
|
||||||
|
struct Args {
|
||||||
|
#[arg(short='b', long)]
|
||||||
|
morphism_base: Vec<PathBuf>,
|
||||||
|
|
||||||
|
#[arg(short='m', long="morph")]
|
||||||
|
morphisms: Vec<String>
|
||||||
|
}
|
||||||
|
|
||||||
|
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 morphism_base = laddertypes::morphism_base::MorphismBase::<LdmcPrimMorph>::new();
|
||||||
|
|
||||||
let mut args = std::env::args().skip(1);
|
// 1. load morphism base
|
||||||
let src_type_arg = args.next().expect("src type expected");
|
let mut mb_paths = args.morphism_base;
|
||||||
let dst_type_arg = args.next().expect("dst type expected");
|
|
||||||
|
|
||||||
for mb_path in args {
|
// 1.1. pfade ermitteln
|
||||||
|
let env_var = "MORPHISM_BASE";
|
||||||
|
let suffix = ".morphism-base";
|
||||||
|
|
||||||
|
match std::env::var(env_var) {
|
||||||
|
Ok(path_str) => {
|
||||||
|
let path = std::path::Path::new(&path_str);
|
||||||
|
if path.is_dir() {
|
||||||
|
for entry in WalkDir::new(path)
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(Result::ok)
|
||||||
|
.filter(|e| e.path().is_file() && e.path().extension().map_or(false, |ext| ext == &suffix[1..]))
|
||||||
|
{
|
||||||
|
mb_paths.push(entry.path().into());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
eprintln!("morphism-base path is not a directory: {:?}", path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("failed to read environment variable {}: {}", env_var, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1.2. read files
|
||||||
|
for mb_path in mb_paths {
|
||||||
let src = std::fs::read_to_string(mb_path.clone()).expect("failed to read morphism base");
|
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(type_dict.clone()).parse(src.clone());
|
||||||
match result {
|
match result {
|
||||||
Ok((includes, morphisms)) => {
|
Ok((includes, morphisms)) => {
|
||||||
println!("{}",includes);
|
println!("{}",includes);
|
||||||
eprintln!("[{}] parse ok.", mb_path.bright_yellow());
|
eprintln!("[{}] parse ok.", mb_path.to_str().unwrap().bright_yellow());
|
||||||
for m in morphisms {
|
for m in morphisms {
|
||||||
morphism_base.add_morphism(m);
|
morphism_base.add_morphism(m);
|
||||||
}
|
}
|
||||||
|
@ -57,10 +90,17 @@ fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let src_type = type_dict.parse( src_type_arg.as_str() ).expect("");
|
// 2. Generate Morphisms
|
||||||
let dst_type = type_dict.parse( dst_type_arg.as_str() ).expect("");
|
let mut instances = Vec::new();
|
||||||
|
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 };
|
||||||
|
instances.push( (name, morphism_base.get_morphism_instance( &ty ).expect("failed to find morphism")) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let ty = MorphismType{ src_type, dst_type };
|
println!("{}",
|
||||||
let m = morphism_base.get_morphism_instance( &ty ).expect("failed to find morphism");
|
crate::c_gen::gen_lib::generate_lib(&mut type_dict, instances).expect("failed to generate main function")
|
||||||
println!("{}", crate::c_gen::gen_main::generate_main(&mut type_dict, m).expect("failed to generate main function"));
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use {
|
use {
|
||||||
crate::morphism::LdmcPrimMorph, chumsky::{
|
crate::morphism::LdmcPrimMorph, chumsky::{
|
||||||
prelude::*, text::*
|
prelude::*, text::*
|
||||||
}, laddertypes::{morphism::MorphismType, parser::*, BimapTypeDict, TypeDict}, std::sync::{Arc, RwLock}
|
}, laddertypes::{TypeTerm, morphism::MorphismType, parser::*, BimapTypeDict, TypeDict}, std::sync::{Arc, RwLock}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* morphism-base text format:
|
/* morphism-base text format:
|
||||||
|
@ -59,8 +59,8 @@ pub fn morphism_base_parser(
|
||||||
ty_args.push((var_id, kind));
|
ty_args.push((var_id, kind));
|
||||||
}
|
}
|
||||||
|
|
||||||
let src_type = type_dict.parse_desugared(&src_type.iter().collect::<String>()).expect("couldnt parse src type").sugar(&mut *type_dict);
|
let src_type = type_dict.parse(&src_type.iter().collect::<String>()).expect("couldnt parse src type");
|
||||||
let dst_type = type_dict.parse_desugared(&dst_type.iter().collect::<String>()).expect("couldnt parse dst type").sugar(&mut *type_dict);
|
let dst_type = type_dict.parse(&dst_type.iter().collect::<String>()).expect("couldnt parse dst type");
|
||||||
|
|
||||||
LdmcPrimMorph {
|
LdmcPrimMorph {
|
||||||
symbol,
|
symbol,
|
||||||
|
@ -76,3 +76,25 @@ pub fn morphism_base_parser(
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn morphism_type_parser(
|
||||||
|
mut type_dict: Arc<RwLock< BimapTypeDict >>
|
||||||
|
) -> impl Parser<char, (String, TypeTerm, TypeTerm), Error = Simple<char>> {
|
||||||
|
ident()
|
||||||
|
.padded()
|
||||||
|
.then(just(":").ignored())
|
||||||
|
.then(
|
||||||
|
take_until(just("-->").ignored())
|
||||||
|
)
|
||||||
|
.then(take_until(end()))
|
||||||
|
.map({
|
||||||
|
let type_dict = type_dict.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")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue