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"
|
||||
laddertypes = { path = "../lib-laddertypes", features = ["pretty"] }
|
||||
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 morph;
|
||||
pub mod gen_main;
|
||||
pub mod gen_lib;
|
||||
|
||||
pub use {
|
||||
morph::target_morph::LdmcCTargetMorph
|
||||
|
|
78
src/main.rs
78
src/main.rs
|
@ -9,33 +9,66 @@ use {
|
|||
crate::{
|
||||
morphism::LdmcPrimMorph,
|
||||
parser::morphism_base_parser,
|
||||
},
|
||||
ariadne::{Color, Label, Report, ReportKind, Source},
|
||||
chumsky::prelude::*,
|
||||
laddertypes::{
|
||||
}, ariadne::{Color, Label, Report, ReportKind, Source}, chumsky::prelude::*, clap::{Parser, Subcommand}, laddertypes::{
|
||||
morphism::MorphismType,
|
||||
parser::ParseLadderType, BimapTypeDict
|
||||
},
|
||||
std::{sync::{Arc, RwLock}},
|
||||
tiny_ansi::TinyAnsi
|
||||
}, parser::morphism_type_parser, std::{path::PathBuf,
|
||||
sync::{Arc, RwLock}}, tiny_ansi::TinyAnsi,
|
||||
walkdir::WalkDir
|
||||
};
|
||||
|
||||
fn main() {
|
||||
let mut type_dict = Arc::new(RwLock::new(BimapTypeDict::new()));
|
||||
#[derive(Parser, Debug)]
|
||||
#[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 args = std::env::args().skip(1);
|
||||
let src_type_arg = args.next().expect("src type expected");
|
||||
let dst_type_arg = args.next().expect("dst type expected");
|
||||
// 1. load morphism base
|
||||
let mut mb_paths = args.morphism_base;
|
||||
|
||||
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");
|
||||
|
||||
use chumsky::Parser;
|
||||
let result = morphism_base_parser(type_dict.clone()).parse(src.clone());
|
||||
match result {
|
||||
Ok((includes, morphisms)) => {
|
||||
println!("{}",includes);
|
||||
eprintln!("[{}] parse ok.", mb_path.bright_yellow());
|
||||
eprintln!("[{}] parse ok.", mb_path.to_str().unwrap().bright_yellow());
|
||||
for m in morphisms {
|
||||
morphism_base.add_morphism(m);
|
||||
}
|
||||
|
@ -57,10 +90,17 @@ fn main() {
|
|||
}
|
||||
}
|
||||
|
||||
let src_type = type_dict.parse( src_type_arg.as_str() ).expect("");
|
||||
let dst_type = type_dict.parse( dst_type_arg.as_str() ).expect("");
|
||||
// 2. Generate Morphisms
|
||||
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 };
|
||||
let m = morphism_base.get_morphism_instance( &ty ).expect("failed to find morphism");
|
||||
println!("{}", crate::c_gen::gen_main::generate_main(&mut type_dict, m).expect("failed to generate main function"));
|
||||
println!("{}",
|
||||
crate::c_gen::gen_lib::generate_lib(&mut type_dict, instances).expect("failed to generate main function")
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use {
|
||||
crate::morphism::LdmcPrimMorph, chumsky::{
|
||||
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:
|
||||
|
@ -59,8 +59,8 @@ pub fn morphism_base_parser(
|
|||
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 dst_type = type_dict.parse_desugared(&dst_type.iter().collect::<String>()).expect("couldnt parse dst 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(&dst_type.iter().collect::<String>()).expect("couldnt parse dst type");
|
||||
|
||||
LdmcPrimMorph {
|
||||
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