Support xrefs in schema compiler; offer Arc for languages
This commit is contained in:
parent
acbc1c5fe5
commit
7f387d6d71
|
@ -12,7 +12,7 @@ fn main() -> Result<(), Error> {
|
|||
let mut c = CompilerConfig::new(gen_dir, "crate::schemas".to_owned());
|
||||
|
||||
let inputs = expand_inputs(&vec!["path.bin".to_owned()])?;
|
||||
c.load_schemas_and_bundles(&inputs)?;
|
||||
c.load_schemas_and_bundles(&inputs, &vec![])?;
|
||||
|
||||
compile(&c)
|
||||
}
|
||||
|
|
|
@ -19,6 +19,9 @@ struct CommandLine {
|
|||
#[structopt(long)]
|
||||
module: Vec<String>,
|
||||
|
||||
#[structopt(long)]
|
||||
xref: Vec<String>,
|
||||
|
||||
input_glob: Vec<String>,
|
||||
}
|
||||
|
||||
|
@ -40,6 +43,8 @@ fn main() -> Result<(), Error> {
|
|||
if let Some(c) = args.support_crate {
|
||||
config.support_crate = c;
|
||||
}
|
||||
config.load_schemas_and_bundles(&expand_inputs(&args.input_glob)?)?;
|
||||
config.load_schemas_and_bundles(
|
||||
&expand_inputs(&args.input_glob)?,
|
||||
&expand_inputs(&args.xref)?)?;
|
||||
compile(&config)
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ use preserves::value::Value;
|
|||
use super::CompilerConfig;
|
||||
use super::names;
|
||||
use super::types;
|
||||
use super::types::Purpose;
|
||||
|
||||
pub struct BundleContext<'b> {
|
||||
pub config: &'b CompilerConfig,
|
||||
|
@ -82,8 +83,9 @@ impl<'b> BundleContext<'b> {
|
|||
"_Value"
|
||||
}
|
||||
|
||||
pub fn lookup_definition(&self, r: &Ref) -> Option<&Definition> {
|
||||
self.config.bundle.get(&r.module.0).and_then(|s| s.definitions.0.get(&r.name))
|
||||
pub fn lookup_definition(&self, r: &Ref) -> Option<(&Definition, Purpose)> {
|
||||
self.config.bundle.get(&r.module.0).and_then(
|
||||
|s| s.0.definitions.0.get(&r.name).map(|d| (d, s.1)))
|
||||
}
|
||||
|
||||
pub fn type_for_name(&self, r: &Ref) -> Option<&types::TDefinition> {
|
||||
|
@ -229,7 +231,7 @@ impl<'a, 'm, 'b> FunctionContext<'a, 'm, 'b> {
|
|||
pub fn new(m: &'a mut ModuleContext<'m, 'b>, error_context: &str) -> Self {
|
||||
FunctionContext {
|
||||
error_context: error_context.to_owned(),
|
||||
m: m,
|
||||
m,
|
||||
temp_counter: 0,
|
||||
captures: Vec::new(),
|
||||
capture_mode: CaptureMode::Definite,
|
||||
|
@ -238,8 +240,8 @@ impl<'a, 'm, 'b> FunctionContext<'a, 'm, 'b> {
|
|||
|
||||
pub fn capture(&mut self, field_name: String, ty: types::TField, source_expr: String) {
|
||||
self.captures.push(Capture {
|
||||
field_name: field_name,
|
||||
ty: ty,
|
||||
field_name,
|
||||
ty,
|
||||
source_expr: match self.capture_mode {
|
||||
CaptureMode::Definite =>
|
||||
source_expr,
|
||||
|
|
|
@ -8,6 +8,7 @@ pub mod unparsers;
|
|||
|
||||
use crate::*;
|
||||
use crate::compiler::context::*;
|
||||
use crate::compiler::types::Purpose;
|
||||
use crate::gen::Language;
|
||||
use crate::gen::schema;
|
||||
use crate::gen::schema::*;
|
||||
|
@ -97,7 +98,7 @@ impl ExternalModule {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct CompilerConfig {
|
||||
pub bundle: Map<ModulePath, Schema>,
|
||||
pub bundle: Map<ModulePath, (Schema, Purpose)>,
|
||||
pub output_dir: PathBuf,
|
||||
pub fully_qualified_module_prefix: String,
|
||||
pub support_crate: String,
|
||||
|
@ -105,7 +106,21 @@ pub struct CompilerConfig {
|
|||
pub plugins: Vec<Box<dyn Plugin>>,
|
||||
}
|
||||
|
||||
pub fn load_schema_or_bundle(bundle: &mut Map<ModulePath, Schema>, i: &PathBuf) -> io::Result<()> {
|
||||
pub fn load_schema_or_bundle_with_purpose(
|
||||
bundle: &mut Map<ModulePath, (Schema, Purpose)>,
|
||||
i: &PathBuf,
|
||||
purpose: Purpose,
|
||||
) -> io::Result<()> {
|
||||
let mut inserted = Map::<ModulePath, Schema>::new();
|
||||
load_schema_or_bundle(&mut inserted, i)?;
|
||||
for (k, v) in inserted.into_iter() { bundle.insert(k, (v, purpose)); }
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn load_schema_or_bundle(
|
||||
bundle: &mut Map<ModulePath, Schema>,
|
||||
i: &PathBuf,
|
||||
) -> io::Result<()> {
|
||||
let mut f = File::open(&i)?;
|
||||
let mut src = IOBinarySource::new(&mut f);
|
||||
let mut reader = src.packed_iovalues();
|
||||
|
@ -139,8 +154,8 @@ impl CompilerConfig {
|
|||
) -> Self {
|
||||
CompilerConfig {
|
||||
bundle: Map::new(),
|
||||
output_dir: output_dir,
|
||||
fully_qualified_module_prefix: fully_qualified_module_prefix,
|
||||
output_dir,
|
||||
fully_qualified_module_prefix,
|
||||
support_crate: "preserves_schema".to_owned(),
|
||||
external_modules: Map::new(),
|
||||
plugins: vec![
|
||||
|
@ -159,9 +174,12 @@ impl CompilerConfig {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn load_schemas_and_bundles(&mut self, inputs: &Vec<PathBuf>) -> io::Result<()> {
|
||||
pub fn load_schemas_and_bundles(&mut self, inputs: &Vec<PathBuf>, xrefs: &Vec<PathBuf>) -> io::Result<()> {
|
||||
for i in inputs {
|
||||
load_schema_or_bundle(&mut self.bundle, i)?;
|
||||
load_schema_or_bundle_with_purpose(&mut self.bundle, i, Purpose::Codegen)?;
|
||||
}
|
||||
for i in xrefs {
|
||||
load_schema_or_bundle_with_purpose(&mut self.bundle, i, Purpose::Xref)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -169,8 +187,8 @@ impl CompilerConfig {
|
|||
fn build_type_cache(&self) -> Map<Ref, types::TDefinition> {
|
||||
self.bundle.iter().flat_map(|(modpath, s)| {
|
||||
let modpath = ModulePath(modpath.clone());
|
||||
s.definitions.0.iter().map(move |(name, def)| {
|
||||
let ty = types::definition_type(&modpath, name, def);
|
||||
s.0.definitions.0.iter().map(move |(name, def)| {
|
||||
let ty = types::definition_type(&modpath, s.1, name, def);
|
||||
(ty.self_ref.clone(), ty)
|
||||
})
|
||||
}).collect()
|
||||
|
@ -237,7 +255,11 @@ impl Schema {
|
|||
pub fn compile(config: &CompilerConfig) -> io::Result<()> {
|
||||
let mut b = BundleContext::new(config);
|
||||
|
||||
for (k, v) in config.bundle.iter() {
|
||||
for (k, (v, module_purpose)) in config.bundle.iter() {
|
||||
if *module_purpose != Purpose::Codegen {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut output_path = config.output_dir.clone();
|
||||
output_path.extend(k);
|
||||
let module_name = output_path.file_stem().unwrap().to_str().unwrap().to_owned();
|
||||
|
@ -300,7 +322,10 @@ pub fn compile(config: &CompilerConfig) -> io::Result<()> {
|
|||
mod_rs.extend(vec!["mod.rs"]);
|
||||
let mut lines = Vec::new();
|
||||
|
||||
for modpath in config.bundle.keys() {
|
||||
for (modpath, (_, module_purpose)) in config.bundle.iter() {
|
||||
if *module_purpose != Purpose::Codegen {
|
||||
continue;
|
||||
}
|
||||
lines.push(format!("pub mod {};", names::render_modname(modpath.last().unwrap())));
|
||||
}
|
||||
lines.push("".to_owned());
|
||||
|
|
|
@ -22,7 +22,7 @@ impl compiler::Plugin for ParserPlugin {
|
|||
}
|
||||
|
||||
pub fn gen_definition_parser(m: &mut ModuleContext, n: &str, d: &Definition) {
|
||||
let ty = definition_type(&m.module_path, n, d);
|
||||
let ty = definition_type(&m.module_path, Purpose::Codegen, n, d);
|
||||
|
||||
m.define_function(
|
||||
n,
|
||||
|
|
|
@ -78,7 +78,7 @@ impl BoundaryTracker {
|
|||
}
|
||||
|
||||
pub fn gen_definition_reader(m: &mut ModuleContext, n: &str, d: &Definition) {
|
||||
let ty = definition_type(&m.module_path, n, d);
|
||||
let ty = definition_type(&m.module_path, Purpose::Codegen, n, d);
|
||||
|
||||
m.define_function(
|
||||
n,
|
||||
|
|
|
@ -11,8 +11,15 @@ use super::context::ModuleContextMode;
|
|||
use super::context::RefRenderStyle;
|
||||
use super::names;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord)]
|
||||
pub enum Purpose {
|
||||
Codegen,
|
||||
Xref,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
pub struct TDefinition {
|
||||
pub purpose: Purpose,
|
||||
pub self_ref: Ref,
|
||||
pub body: TDefinitionBody,
|
||||
}
|
||||
|
@ -60,7 +67,7 @@ impl compiler::Plugin for TypePlugin {
|
|||
|
||||
fn generate_definition(&self, m: &mut ModuleContext, n: &str, d: &Definition) {
|
||||
if let ModuleContextMode::TargetGeneric = m.mode {
|
||||
let ty = definition_type(&m.module_path, n, d);
|
||||
let ty = definition_type(&m.module_path, Purpose::Codegen, n, d);
|
||||
m.define_type(item(ty.render(m, n)));
|
||||
m.define_type(item(seq![
|
||||
"impl", ty.generic_decl(m), " preserves::value::Domain for ",
|
||||
|
@ -69,8 +76,9 @@ impl compiler::Plugin for TypePlugin {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn definition_type(module: &ModulePath, n: &str, d: &Definition) -> TDefinition {
|
||||
pub fn definition_type(module: &ModulePath, purpose: Purpose, n: &str, d: &Definition) -> TDefinition {
|
||||
TDefinition {
|
||||
purpose,
|
||||
self_ref: Ref { module: module.clone(), name: n.to_owned() },
|
||||
body: match d {
|
||||
Definition::Or { pattern_0, pattern_1, pattern_n } =>
|
||||
|
@ -229,8 +237,8 @@ impl TField {
|
|||
r,
|
||||
|ctxt, r| ctxt.type_for_name(r),
|
||||
|s, t| match t {
|
||||
Some(ty) => ty._language_types(s, ts),
|
||||
None => {
|
||||
Some(ty) if ty.purpose == Purpose::Codegen => ty._language_types(s, ts),
|
||||
Some(_) | None => {
|
||||
let xmts = &s.context.config.external_modules.get(&r.module.0).unwrap()
|
||||
.rust_language_types;
|
||||
if let Some(f) = xmts.definitions.get(&r.name).or(xmts.fallback.as_ref()) {
|
||||
|
|
|
@ -53,15 +53,15 @@ struct ValueContext {
|
|||
}
|
||||
|
||||
fn normal_none(is_struct: bool) -> ValueContext {
|
||||
ValueContext { src: None, sink: ValueSink::Normal, is_struct: is_struct }
|
||||
ValueContext { src: None, sink: ValueSink::Normal, is_struct }
|
||||
}
|
||||
|
||||
fn normal_src(src: String, is_struct: bool) -> ValueContext {
|
||||
ValueContext { src: Some(src), sink: ValueSink::Normal, is_struct: is_struct }
|
||||
ValueContext { src: Some(src), sink: ValueSink::Normal, is_struct }
|
||||
}
|
||||
|
||||
pub fn gen_definition_unparser(m: &mut ModuleContext, n: &str, d: &Definition) {
|
||||
let ty = definition_type(&m.module_path, n, d);
|
||||
let ty = definition_type(&m.module_path, Purpose::Codegen, n, d);
|
||||
|
||||
m.define_function(
|
||||
n,
|
||||
|
@ -234,7 +234,7 @@ fn pattern_unparser(
|
|||
sink: ValueSink::Fields(Rc::new(Cell::new(Some(FieldsSink {
|
||||
finish: item(seq![rtmp.clone(), ".finish().wrap()"]),
|
||||
vec_expr: item(seq![rtmp.clone(), ".fields_vec_mut()"]),
|
||||
body: body,
|
||||
body,
|
||||
})))),
|
||||
is_struct: vc.is_struct,
|
||||
})
|
||||
|
@ -285,7 +285,7 @@ fn sequenceify<'a>(
|
|||
finish: item(seq![
|
||||
"preserves::value::Value::Sequence", parens![rtmp.clone()], ".wrap()"]),
|
||||
vec_expr: item(rtmp),
|
||||
body: body,
|
||||
body,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,9 +70,16 @@ macro_rules! define_language {
|
|||
mod $fname {
|
||||
use super::*;
|
||||
lazy_static::lazy_static! {
|
||||
pub static ref GLOBAL_LANG: $lang<$default_value> = $lang {
|
||||
$($field: std::sync::Arc::new($($type)::*::default())),*
|
||||
};
|
||||
pub static ref GLOBAL_LANG: std::sync::Arc<$lang<$default_value>> =
|
||||
std::sync::Arc::new($lang {
|
||||
$($field: std::sync::Arc::new($($type)::*::default())),*
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl $lang<$default_value> {
|
||||
pub fn arc() -> &'static std::sync::Arc<$lang<$default_value>> {
|
||||
&*$fname::GLOBAL_LANG
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue