ModuleContextMode::TargetIOValue, ModuleContextMode::TargetAny

This commit is contained in:
Tony Garnock-Jones 2021-07-02 07:48:52 +02:00
parent 8cafcbcaf1
commit 23943f8b14
5 changed files with 1015 additions and 177 deletions

View File

@ -15,11 +15,18 @@ use super::CompilerConfig;
use super::names;
use super::types;
#[derive(Clone, Copy)]
pub enum ModuleContextMode {
TargetIOValue,
TargetAny,
}
pub struct ModuleContext<'m> {
pub config: &'m CompilerConfig,
pub literals: Map<_Any, String>,
pub typedefs: Vec<Item>,
pub functiondefs: Vec<Item>,
pub mode: ModuleContextMode,
}
pub struct FunctionContext<'a, 'm> {
@ -45,6 +52,7 @@ impl<'m> ModuleContext<'m> {
literals: Map::new(),
typedefs: Vec::new(),
functiondefs: Vec::new(),
mode: ModuleContextMode::TargetIOValue,
}
}
@ -58,7 +66,7 @@ impl<'m> ModuleContext<'m> {
_ => prefix
};
let next_id = next_id.to_case(Case::UpperSnake);
"&*".to_owned() + self.literals.entry(v.clone()).or_insert(next_id)
"&*".to_owned() + self.target_prefix() + "::" + self.literals.entry(v.clone()).or_insert(next_id)
}
pub fn define_type(&mut self, i: Item) {
@ -86,6 +94,20 @@ impl<'m> ModuleContext<'m> {
item(name![s.to_owned(), r.name.to_owned()])
}
}
pub fn target(&self) -> &'static str {
match self.mode {
ModuleContextMode::TargetIOValue => "preserves::value::IOValue",
ModuleContextMode::TargetAny => "_Any",
}
}
pub fn target_prefix(&self) -> &'static str {
match self.mode {
ModuleContextMode::TargetIOValue => "_io_",
ModuleContextMode::TargetAny => "_any_",
}
}
}
impl<'a, 'm> FunctionContext<'a, 'm> {

View File

@ -92,6 +92,9 @@ pub fn expand_inputs(globs: &Vec<String>) -> Result<Vec<PathBuf>, Error> {
}
pub fn compile(config: &CompilerConfig) -> Result<(), std::io::Error> {
let modes: Vec<context::ModuleContextMode> =
vec![context::ModuleContextMode::TargetIOValue, context::ModuleContextMode::TargetAny];
for (k, v) in config.bundle.iter() {
let mut output_path = config.output_dir.clone();
output_path.extend(k);
@ -109,8 +112,11 @@ pub fn compile(config: &CompilerConfig) -> Result<(), std::io::Error> {
for (n, d) in &v.definitions.0 {
m.define_type(item(types::render_definition_type(&m, n, &types::definition_type(d))));
parsers::gen_definition_parser(&mut m, n, d);
unparsers::gen_definition_unparser(&mut m, n, d);
for mode in &modes {
m.mode = *mode;
parsers::gen_definition_parser(&mut m, n, d);
unparsers::gen_definition_unparser(&mut m, n, d);
}
}
//---------------------------------------------------------------------------
@ -126,16 +132,28 @@ pub fn compile(config: &CompilerConfig) -> Result<(), std::io::Error> {
lines.push(format!("use {}::support as _support;", &config.support_crate));
lines.push("".to_owned());
lines.push("_support::lazy_static! {".to_owned());
for (value, name) in m.literals {
let bs = preserves::value::PackedWriter::encode(&value.to_io_value()).unwrap();
lines.push(format!(" pub static ref {}: preserves::value::IOValue = /* {:?} */ preserves::value::packed::from_bytes(&vec!{:?}).unwrap();",
name,
value,
bs));
for mode in &modes {
m.mode = *mode;
lines.push(format!("mod {} {{", m.target_prefix()));
lines.push(" use super::_Any;".to_owned());
lines.push(" use preserves::value::NestedValue;".to_owned());
lines.push(" use preserves::value::packed::from_bytes;".to_owned());
lines.push(format!(" use {}::support as _support;", &config.support_crate));
lines.push(" _support::lazy_static! {".to_owned());
for (value, name) in &m.literals {
let bs = preserves::value::PackedWriter::encode(&value.to_io_value()).unwrap();
lines.push(format!(
" pub static ref {}: {} = /* {:?} */ {}::from_io_value(&from_bytes(&vec!{:?}).unwrap()).unwrap();",
name,
m.target(),
value,
m.target(),
bs));
}
lines.push(" }".to_owned());
lines.push("}".to_owned());
lines.push("".to_owned());
}
lines.push("}".to_owned());
lines.push("".to_owned());
for i in m.typedefs {
lines.push(Formatter::to_string(i));

View File

@ -4,7 +4,7 @@ use crate::syntax::block::Item;
use crate::syntax::block::constructors::*;
use super::codegen::*;
use super::context::{ModuleContext, FunctionContext};
use super::context::{ModuleContextMode, ModuleContext, FunctionContext};
use super::names;
use super::types::*;
@ -18,7 +18,8 @@ pub fn gen_definition_parser(m: &mut ModuleContext, n: &str, d: &Definition) {
let mut ps = vec![&**pattern_0, &**pattern_1];
ps.extend(pattern_n);
for NamedAlternative { variant_label: name, pattern: pat } in ps {
let fname = seq!["_parse_", names::render_fieldname(n), "_", names::render_fieldname(name)];
let fname = seq![ctxt.m.target_prefix(), "parse_",
names::render_fieldname(n), "_", names::render_fieldname(name)];
let ctorname = item(name![names::render_constructor(n), names::render_constructor(name)]);
ctxt.m.define_function(
|mut ctxt| {
@ -26,7 +27,7 @@ pub fn gen_definition_parser(m: &mut ModuleContext, n: &str, d: &Definition) {
let dest = pattern_parser(&mut ctxt, pat, "value", None, &mut body);
let dest = dest.as_ref().map(String::as_str);
construct(&ctxt, ctorname, false, &pattern_type(pat), dest, &mut body);
item(seq!["fn ", fname.clone(), "(value: &preserves::value::IOValue) -> ",
item(seq!["fn ", fname.clone(), "(value: &", ctxt.m.target(), ") -> ",
"std::result::Result<", names::render_constructor(n), ", _support::ParseError> ",
block(body)])
});
@ -49,10 +50,10 @@ pub fn gen_definition_parser(m: &mut ModuleContext, n: &str, d: &Definition) {
}
}
item(seq!["impl std::convert::TryFrom", anglebrackets!["preserves::value::IOValue"], " for ",
item(seq!["impl std::convert::TryFrom", anglebrackets![ctxt.m.target()], " for ",
names::render_constructor(n), " ", block![
seq!["type Error = _support::ParseError;"],
seq!["fn try_from(value: preserves::value::IOValue) -> ",
seq!["fn try_from(value: ", ctxt.m.target(), ") -> ",
"std::result::Result<Self, Self::Error> ",
block(body)]]])
});
@ -105,7 +106,12 @@ fn simple_pattern_parser(
let dest = ctxt.gentempname();
match p {
SimplePattern::Any => {
push_let(body, item(dest.to_owned()), item(seq!["_Any::from_io_value", parens![src.to_owned()], "?"]));
match ctxt.m.mode {
ModuleContextMode::TargetIOValue =>
push_let(body, item(dest.to_owned()), item(seq!["_Any::from_io_value", parens![src.to_owned()], "?"])),
ModuleContextMode::TargetAny =>
push_let(body, item(dest.to_owned()), item(src.to_owned())),
}
dest
},
SimplePattern::Atom { atom_kind: k } => {
@ -122,10 +128,16 @@ fn simple_pattern_parser(
dest
},
SimplePattern::Embedded { .. } => {
push_let(body, item(dest.to_owned()), item(seq![
"_Ptr::from_preserves",
parens![seq![src.to_owned(), ".value().to_embedded()?", ".clone()"]],
"?"]));
match ctxt.m.mode {
ModuleContextMode::TargetIOValue =>
push_let(body, item(dest.to_owned()), item(seq![
"_Ptr::from_preserves",
parens![seq![src.to_owned(), ".value().to_embedded()?", ".clone()"]],
"?"])),
ModuleContextMode::TargetAny =>
push_let(body, item(dest.to_owned()), item(seq![
parens![seq![src.to_owned(), ".value().to_embedded()?"]]])),
}
dest
},
SimplePattern::Lit { value } => {

View File

@ -7,7 +7,7 @@ use std::cell::Cell;
use std::rc::Rc;
use super::codegen::*;
use super::context::{ModuleContext, FunctionContext};
use super::context::{ModuleContextMode, ModuleContext, FunctionContext};
use super::names;
use super::types::*;
@ -82,7 +82,7 @@ pub fn gen_definition_unparser(m: &mut ModuleContext, n: &str, d: &Definition) {
}
item(seq!["impl std::convert::From", anglebrackets![seq!["&", names::render_constructor(n)]],
" for preserves::value::IOValue ", block![
" for ", ctxt.m.target(), " ", block![
seq!["fn from(value: &", names::render_constructor(n), ") -> Self ",
block(body)]]])
});
@ -120,8 +120,14 @@ fn simple_pattern_unparser(
) -> Item {
let src = &vc.src;
match p {
SimplePattern::Any =>
item(seq![src.as_ref().unwrap().to_owned(), ".to_io_value()"]),
SimplePattern::Any => {
match ctxt.m.mode {
ModuleContextMode::TargetIOValue =>
item(seq![src.as_ref().unwrap().to_owned(), ".to_io_value()"]),
ModuleContextMode::TargetAny =>
item(seq![src.as_ref().unwrap().to_owned(), ".clone()"]),
}
}
SimplePattern::Atom { atom_kind: k } => {
match &**k {
AtomKind::Symbol =>
@ -132,8 +138,14 @@ fn simple_pattern_unparser(
item(seq!["preserves::value::Value::from(", src.as_ref().unwrap().to_owned(), ").wrap()"])
}
}
SimplePattern::Embedded { .. } =>
item(seq!["preserves::value::Value::Domain(", src.as_ref().unwrap().to_owned(), ".as_preserves()).wrap()"]),
SimplePattern::Embedded { .. } => {
match ctxt.m.mode {
ModuleContextMode::TargetIOValue =>
item(seq!["preserves::value::Value::Domain(", src.as_ref().unwrap().to_owned(), ".as_preserves()).wrap()"]),
ModuleContextMode::TargetAny =>
item(seq!["preserves::value::Value::Domain(", src.as_ref().unwrap().to_owned(), ").wrap()"]),
}
}
SimplePattern::Lit { value } =>
item(seq![parens![ctxt.m.define_literal(value)], ".clone()"]),
SimplePattern::Seqof { pattern } => {
@ -166,7 +178,7 @@ fn simple_pattern_unparser(
").collect()).wrap()"])
}
SimplePattern::Ref(_r) =>
item(seq!["preserves::value::IOValue::from(", src.as_ref().unwrap().to_owned(),
item(seq![ctxt.m.target(), "::from(", src.as_ref().unwrap().to_owned(),
if vc.is_struct { "" } else { ".as_ref()" },
")"]),
}

File diff suppressed because it is too large Load Diff