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::Error;
use std::io::ErrorKind;
use std::path::PathBuf; use std::path::PathBuf;
use structopt::StructOpt; use structopt::StructOpt;
@ -9,18 +10,33 @@ struct CommandLine {
#[structopt(short, long)] #[structopt(short, long)]
output_dir: PathBuf, output_dir: PathBuf,
#[structopt(long)] #[structopt(short, long)]
prefix: String, prefix: String,
#[structopt(long)] #[structopt(long)]
support_crate: Option<String>, support_crate: Option<String>,
#[structopt(long)]
module: Vec<String>,
input_glob: Vec<String>, input_glob: Vec<String>,
} }
fn main() -> Result<(), Error> { fn main() -> Result<(), Error> {
let args = CommandLine::from_args(); let args = CommandLine::from_args();
let mut config = CompilerConfig::new(args.output_dir, args.prefix); 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 { if let Some(c) = args.support_crate {
config.support_crate = c; config.support_crate = c;
} }

View File

@ -1,7 +1,9 @@
use preserves::value::{Map, IOValue}; use preserves::value::{Map, IOValue};
use crate::*;
use crate::syntax::block::Item; use crate::syntax::block::Item;
use crate::syntax::block::constructors::*; use crate::syntax::block::constructors::*;
use crate::gen::schema::*;
use super::CompilerConfig; use super::CompilerConfig;
use super::types; use super::types;
@ -49,15 +51,20 @@ impl<'m> ModuleContext<'m> {
self.functiondefs.push(i) self.functiondefs.push(i)
} }
pub fn render_ref(&self, mp: Vec<String>, n: String) -> Item { pub fn render_ref(&self, r: &Ref) -> Item {
if mp.len() == 0 { match self.config.module_aliases.get(&r.module.0) {
item(n) None =>
} else { if r.module.0.is_empty() {
let mut items = Vec::new(); item(r.name.to_owned())
items.push(item(self.config.fully_qualified_module_prefix.to_owned())); } else {
for p in mp { items.push(item(p)); } let mut items = Vec::new();
items.push(item(n)); items.push(item(self.config.fully_qualified_module_prefix.to_owned()));
item(name(items)) 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 unparsers;
pub mod codegen; pub mod codegen;
use crate::*;
use crate::gen::schema::*; use crate::gen::schema::*;
use crate::syntax::block::Formatter; use crate::syntax::block::Formatter;
use crate::syntax::block::constructors::*; use crate::syntax::block::constructors::*;
@ -33,6 +34,7 @@ pub struct CompilerConfig {
pub output_dir: PathBuf, pub output_dir: PathBuf,
pub fully_qualified_module_prefix: String, pub fully_qualified_module_prefix: String,
pub support_crate: String, pub support_crate: String,
pub module_aliases: Map<ModulePath, String>,
} }
impl CompilerConfig { impl CompilerConfig {
@ -45,6 +47,7 @@ impl CompilerConfig {
output_dir: output_dir, output_dir: output_dir,
fully_qualified_module_prefix: fully_qualified_module_prefix, fully_qualified_module_prefix: fully_qualified_module_prefix,
support_crate: "preserves_schema".to_owned(), 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())?; DirBuilder::new().recursive(true).create(output_path.parent().unwrap())?;
let mut m = context::ModuleContext::new(config); 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 { for (n, d) in &v.definitions.0 {
m.define_type(item(types::render_definition_type(&m, n, &types::definition_type(d)))); 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::Array(_)
| TField::Set(_) | TField::Set(_)
| TField::Map(_, _) => expr.to_owned(), | TField::Map(_, _) => expr.to_owned(),
TField::Ref(_, _) => TField::Ref(_) =>
if is_struct { if is_struct {
expr.to_owned() expr.to_owned()
} else { } else {
@ -173,8 +173,7 @@ fn simple_pattern_parser(
dest dest
}, },
SimplePattern::Ref(r) => { SimplePattern::Ref(r) => {
let Ref { module: ModulePath(module), name } = &**r; let tf = name![ctxt.m.render_ref(&**r), "try_from"];
let tf = name![ctxt.m.render_ref(module.clone(), name.to_owned()), "try_from"];
push_let(body, push_let(body,
item(dest.to_owned()), item(dest.to_owned()),
item(seq![tf, parens![src.to_owned()], "?"])); item(seq![tf, parens![src.to_owned()], "?"]));

View File

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

View File

@ -123,10 +123,13 @@ fn simple_pattern_unparser(
SimplePattern::Any => SimplePattern::Any =>
item(seq![src.as_ref().unwrap().to_owned(), ".clone()"]), item(seq![src.as_ref().unwrap().to_owned(), ".clone()"]),
SimplePattern::Atom { atom_kind: k } => { SimplePattern::Atom { atom_kind: k } => {
if let AtomKind::Symbol = &**k { match &**k {
item(seq!["preserves::value::Value::symbol(", src.as_ref().unwrap().to_owned(), ").wrap()"]) AtomKind::Symbol =>
} else { item(seq!["preserves::value::Value::symbol(", src.as_ref().unwrap().to_owned(), ").wrap()"]),
item(seq!["preserves::value::Value::from(", 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 { .. } => 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 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)] #[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone)]
pub enum AtomKind {Boolean, Float, Double, SignedInteger, String, ByteString, Symbol} pub enum AtomKind {Boolean, Float, Double, SignedInteger, String, ByteString, Symbol}