forked from syndicate-lang/preserves
Module aliases and embedded pointer types
This commit is contained in:
parent
c3bc678a46
commit
d69787e5ee
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,16 +51,21 @@ 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 =>
|
||||||
|
if r.module.0.is_empty() {
|
||||||
|
item(r.name.to_owned())
|
||||||
} else {
|
} else {
|
||||||
let mut items = Vec::new();
|
let mut items = Vec::new();
|
||||||
items.push(item(self.config.fully_qualified_module_prefix.to_owned()));
|
items.push(item(self.config.fully_qualified_module_prefix.to_owned()));
|
||||||
for p in mp { items.push(item(p)); }
|
for p in &r.module.0 { items.push(item(p.to_owned())); }
|
||||||
items.push(item(n));
|
items.push(item(r.name.to_owned()));
|
||||||
item(name(items))
|
item(name(items))
|
||||||
}
|
}
|
||||||
|
Some(s) =>
|
||||||
|
item(name![s.to_owned(), r.name.to_owned()])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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))));
|
||||||
|
|
|
@ -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()], "?"]));
|
||||||
|
|
|
@ -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()],
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,9 +123,12 @@ 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()"]),
|
||||||
|
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()"])
|
item(seq!["preserves::value::Value::from(", src.as_ref().unwrap().to_owned(), ").wrap()"])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue