Module aliases and embedded pointer types

This commit is contained in:
Tony Garnock-Jones 2021-06-29 23:19:22 +02:00
parent c3bc678a46
commit d69787e5ee
7 changed files with 57 additions and 27 deletions

View File

@ -1,4 +1,5 @@
use std::io::Error;
use std::io::ErrorKind;
use std::path::PathBuf;
use structopt::StructOpt;
@ -9,18 +10,33 @@ struct CommandLine {
#[structopt(short, long)]
output_dir: PathBuf,
#[structopt(long)]
#[structopt(short, long)]
prefix: String,
#[structopt(long)]
support_crate: Option<String>,
#[structopt(long)]
module: Vec<String>,
input_glob: Vec<String>,
}
fn main() -> Result<(), Error> {
let args = CommandLine::from_args();
let mut config = CompilerConfig::new(args.output_dir, args.prefix);
for alias in args.module {
let (modulepath_str, target) = {
let pieces: Vec<&str> = alias.split('=').collect();
if pieces.len() != 2 {
return Err(Error::new(ErrorKind::InvalidData,
format!("Invalid module alias: {:?}", alias)));
}
(pieces[0], pieces[1])
};
let modulepath: Vec<String> = modulepath_str.split('.').map(str::to_owned).collect();
config.module_aliases.insert(modulepath, target.to_owned());
}
if let Some(c) = args.support_crate {
config.support_crate = c;
}

View File

@ -1,7 +1,9 @@
use preserves::value::{Map, IOValue};
use crate::*;
use crate::syntax::block::Item;
use crate::syntax::block::constructors::*;
use crate::gen::schema::*;
use super::CompilerConfig;
use super::types;
@ -49,15 +51,20 @@ impl<'m> ModuleContext<'m> {
self.functiondefs.push(i)
}
pub fn render_ref(&self, mp: Vec<String>, n: String) -> Item {
if mp.len() == 0 {
item(n)
} else {
let mut items = Vec::new();
items.push(item(self.config.fully_qualified_module_prefix.to_owned()));
for p in mp { items.push(item(p)); }
items.push(item(n));
item(name(items))
pub fn render_ref(&self, r: &Ref) -> Item {
match self.config.module_aliases.get(&r.module.0) {
None =>
if r.module.0.is_empty() {
item(r.name.to_owned())
} else {
let mut items = Vec::new();
items.push(item(self.config.fully_qualified_module_prefix.to_owned()));
for p in &r.module.0 { items.push(item(p.to_owned())); }
items.push(item(r.name.to_owned()));
item(name(items))
}
Some(s) =>
item(name![s.to_owned(), r.name.to_owned()])
}
}
}

View File

@ -5,6 +5,7 @@ pub mod parsers;
pub mod unparsers;
pub mod codegen;
use crate::*;
use crate::gen::schema::*;
use crate::syntax::block::Formatter;
use crate::syntax::block::constructors::*;
@ -33,6 +34,7 @@ pub struct CompilerConfig {
pub output_dir: PathBuf,
pub fully_qualified_module_prefix: String,
pub support_crate: String,
pub module_aliases: Map<ModulePath, String>,
}
impl CompilerConfig {
@ -45,6 +47,7 @@ impl CompilerConfig {
output_dir: output_dir,
fully_qualified_module_prefix: fully_qualified_module_prefix,
support_crate: "preserves_schema".to_owned(),
module_aliases: Map::new(),
}
}
@ -96,7 +99,10 @@ pub fn compile(config: &CompilerConfig) -> Result<(), std::io::Error> {
DirBuilder::new().recursive(true).create(output_path.parent().unwrap())?;
let mut m = context::ModuleContext::new(config);
// TODO: embedded type
m.define_type(item(seq!["pub type _Ptr = ", match &v.embedded_type {
EmbeddedTypeName::False => item("preserves::value::IOValue".to_owned()),
EmbeddedTypeName::Ref(r) => m.render_ref(&**r),
}, ";"]));
for (n, d) in &v.definitions.0 {
m.define_type(item(types::render_definition_type(&m, n, &types::definition_type(d))));

View File

@ -85,7 +85,7 @@ fn store_wrap(is_struct: bool, ty: &TField, expr: &str) -> String {
| TField::Array(_)
| TField::Set(_)
| TField::Map(_, _) => expr.to_owned(),
TField::Ref(_, _) =>
TField::Ref(_) =>
if is_struct {
expr.to_owned()
} else {
@ -173,8 +173,7 @@ fn simple_pattern_parser(
dest
},
SimplePattern::Ref(r) => {
let Ref { module: ModulePath(module), name } = &**r;
let tf = name![ctxt.m.render_ref(module.clone(), name.to_owned()), "try_from"];
let tf = name![ctxt.m.render_ref(&**r), "try_from"];
push_let(body,
item(dest.to_owned()),
item(seq![tf, parens![src.to_owned()], "?"]));

View File

@ -24,7 +24,7 @@ pub enum TField {
Array(Box<TField>),
Set(Box<TField>),
Map(Box<TField>, Box<TField>),
Ref(Vec<String>, String),
Ref(Ref),
Base(String),
}
@ -140,16 +140,13 @@ pub fn field_type(p: &SimplePattern) -> TField {
AtomKind::ByteString => TField::Base("std::vec::Vec<u8>".to_owned()),
AtomKind::Symbol => TField::Base("std::string::String".to_owned()),
},
SimplePattern::Embedded { .. } => TField::Base("_ptr".to_owned()),
SimplePattern::Embedded { .. } => TField::Base("_Ptr".to_owned()),
SimplePattern::Lit { .. } => TField::Unit,
SimplePattern::Seqof { pattern: t } => TField::Array(Box::new(field_type(t))),
SimplePattern::Setof { pattern: t } => TField::Set(Box::new(field_type(t))),
SimplePattern::Dictof { key: k, value: v } =>
TField::Map(Box::new(field_type(k)), Box::new(field_type(v))),
SimplePattern::Ref(r) => {
let Ref { module: ModulePath(mp), name: n } = &**r;
TField::Ref(mp.clone(), n.to_owned())
}
SimplePattern::Ref(r) => TField::Ref((**r).clone()),
}
}
@ -165,11 +162,11 @@ pub fn render_field_type(
TField::Map(k, v) => seq!["preserves::value::Map",
anglebrackets![render_field_type(ctxt, false, k),
render_field_type(ctxt, false, v)]],
TField::Ref(mp, n) =>
TField::Ref(r) =>
if box_needed {
seq!["std::boxed::Box", anglebrackets![ctxt.render_ref(mp.clone(), n.to_owned())]]
seq!["std::boxed::Box", anglebrackets![ctxt.render_ref(r)]]
} else {
seq![ctxt.render_ref(mp.clone(), n.to_owned())]
seq![ctxt.render_ref(r)]
},
TField::Base(n) => seq![n.to_owned()],
}

View File

@ -123,10 +123,13 @@ fn simple_pattern_unparser(
SimplePattern::Any =>
item(seq![src.as_ref().unwrap().to_owned(), ".clone()"]),
SimplePattern::Atom { atom_kind: k } => {
if let AtomKind::Symbol = &**k {
item(seq!["preserves::value::Value::symbol(", src.as_ref().unwrap().to_owned(), ").wrap()"])
} else {
item(seq!["preserves::value::Value::from(", src.as_ref().unwrap().to_owned(), ").wrap()"])
match &**k {
AtomKind::Symbol =>
item(seq!["preserves::value::Value::symbol(", src.as_ref().unwrap().to_owned(), ").wrap()"]),
AtomKind::ByteString =>
item(seq!["preserves::value::Value::ByteString(", src.as_ref().unwrap().to_owned(), ".clone()).wrap()"]),
_ =>
item(seq!["preserves::value::Value::from(", src.as_ref().unwrap().to_owned(), ").wrap()"])
}
}
SimplePattern::Embedded { .. } =>

View File

@ -36,6 +36,8 @@ lazy_static! {
pub static ref LIT20: preserves::value::IOValue = /* version */ preserves::value::packed::from_bytes(&vec![179, 7, 118, 101, 114, 115, 105, 111, 110]).unwrap();
}
pub type _Ptr = preserves::value::IOValue;
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone)]
pub enum AtomKind {Boolean, Float, Double, SignedInteger, String, ByteString, Symbol}