Compiler plugins (hardcoded to begin with)

This commit is contained in:
Tony Garnock-Jones 2021-08-12 15:23:37 -04:00
parent ea75dc8f59
commit eafc22fb1c
7 changed files with 600 additions and 536 deletions

View File

@ -28,7 +28,7 @@ pub struct ModuleContext<'m> {
pub literals: Map<_Any, String>,
pub typedefs: Vec<Item>,
pub functiondefs: Vec<Item>,
pub mode: ModuleContextMode,
pub mode: Option<ModuleContextMode>,
}
pub struct FunctionContext<'a, 'm> {
@ -62,7 +62,7 @@ impl<'m> ModuleContext<'m> {
literals: Map::new(),
typedefs: Vec::new(),
functiondefs: Vec::new(),
mode: ModuleContextMode::TargetIOValue,
mode: None,
}
}
@ -105,15 +105,19 @@ impl<'m> ModuleContext<'m> {
}
}
pub fn mode(&self) -> ModuleContextMode {
self.mode.expect("defined ModuleContextMode")
}
pub fn target(&self) -> &'static str {
match self.mode {
match self.mode() {
ModuleContextMode::TargetIOValue => "preserves::value::IOValue",
ModuleContextMode::TargetAny => "_Any",
}
}
pub fn target_prefix(&self) -> &'static str {
match self.mode {
match self.mode() {
ModuleContextMode::TargetIOValue => "_io_",
ModuleContextMode::TargetAny => "_any_",
}

View File

@ -28,6 +28,15 @@ use std::path::PathBuf;
pub type ModulePath = Vec<String>;
pub trait Plugin {
fn generate(
&mut self,
module_ctxt: &mut context::ModuleContext,
definition_name: &str,
definition: &Definition,
);
}
#[derive(Debug)]
pub struct CompilerConfig {
pub bundle: Map<ModulePath, Schema>,
@ -135,16 +144,24 @@ pub fn compile(config: &CompilerConfig) -> io::Result<()> {
let modes = modes; // rebind as non-mutable
let mut plugins: Vec<Box<dyn Plugin>> = vec![
Box::new(types::TypePlugin),
Box::new(readers::ReaderPlugin),
Box::new(parsers::ParserPlugin),
Box::new(unparsers::UnparserPlugin),
];
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(seq!["impl preserves::value::Domain for ",
names::render_constructor(n), " {}"]));
for mode in &modes {
m.mode = *mode;
parsers::gen_definition_parser(&mut m, n, d);
unparsers::gen_definition_unparser(&mut m, n, d);
for plugin in plugins.iter_mut() {
plugin.generate(&mut m, n, d);
}
readers::gen_definition_reader(&mut m, n, d);
for mode in &modes {
m.mode = Some(*mode);
for plugin in plugins.iter_mut() {
plugin.generate(&mut m, n, d);
}
}
m.mode = None;
}
//---------------------------------------------------------------------------
@ -162,7 +179,7 @@ pub fn compile(config: &CompilerConfig) -> io::Result<()> {
lines.push("".to_owned());
for mode in &modes {
m.mode = *mode;
m.mode = Some(*mode);
lines.push(format!("mod {} {{", m.target_prefix()));
lines.push(" use super::_Any;".to_owned());
lines.push(format!(" use {}::support as _support;", &config.support_crate));
@ -180,6 +197,7 @@ pub fn compile(config: &CompilerConfig) -> io::Result<()> {
lines.push("}".to_owned());
lines.push("".to_owned());
}
m.mode = None;
for i in m.typedefs {
lines.push(Formatter::to_string(i));

View File

@ -7,6 +7,16 @@ use super::context::{ModuleContextMode, ModuleContext, FunctionContext};
use super::names;
use super::types::*;
pub struct ParserPlugin;
impl compiler::Plugin for ParserPlugin {
fn generate(&mut self, module_ctxt: &mut ModuleContext, definition_name: &str, definition: &Definition) {
if module_ctxt.mode.is_some() {
gen_definition_parser(module_ctxt, definition_name, definition)
}
}
}
pub fn gen_definition_parser(m: &mut ModuleContext, n: &str, d: &Definition) {
m.define_function(
n,
@ -107,7 +117,7 @@ fn simple_pattern_parser(
let dest = ctxt.gentempname();
match p {
SimplePattern::Any => {
match ctxt.m.mode {
match ctxt.m.mode() {
ModuleContextMode::TargetIOValue =>
ctxt.define_atom(body, &dest, item(seq!["_support::decode_embedded", parens![src.to_owned()], "?"])),
ModuleContextMode::TargetAny =>
@ -129,7 +139,7 @@ fn simple_pattern_parser(
dest
},
SimplePattern::Embedded { .. } => {
match ctxt.m.mode {
match ctxt.m.mode() {
ModuleContextMode::TargetIOValue =>
ctxt.define_atom(body, &dest, item(seq![
"std::sync::Arc::new(_Dom::try_from",

View File

@ -14,6 +14,16 @@ use super::context::{ModuleContext, FunctionContext};
use super::names;
use super::types::*;
pub struct ReaderPlugin;
impl compiler::Plugin for ReaderPlugin {
fn generate(&mut self, module_ctxt: &mut ModuleContext, definition_name: &str, definition: &Definition) {
if module_ctxt.mode.is_none() {
gen_definition_reader(module_ctxt, definition_name, definition)
}
}
}
#[derive(Clone)]
struct BoundaryTracker {
tracker_name: String,

View File

@ -31,6 +31,18 @@ pub enum TField {
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub struct TRecord(pub Vec<(String, TField)>);
pub struct TypePlugin;
impl compiler::Plugin for TypePlugin {
fn generate(&mut self, m: &mut ModuleContext, n: &str, d: &Definition) {
if m.mode.is_none() {
m.define_type(item(render_definition_type(m, n, &definition_type(d))));
m.define_type(item(seq![
"impl preserves::value::Domain for ", names::render_constructor(n), " {}"]));
}
}
}
pub fn definition_type(d: &Definition) -> TDefinition {
match d {
Definition::Or { pattern_0, pattern_1, pattern_n } =>

View File

@ -10,6 +10,16 @@ use super::context::{ModuleContextMode, ModuleContext, FunctionContext};
use super::names;
use super::types::*;
pub struct UnparserPlugin;
impl compiler::Plugin for UnparserPlugin {
fn generate(&mut self, module_ctxt: &mut ModuleContext, definition_name: &str, definition: &Definition) {
if module_ctxt.mode.is_some() {
gen_definition_unparser(module_ctxt, definition_name, definition)
}
}
}
type ValueSource = Option<String>;
#[derive(Clone)]
@ -121,7 +131,7 @@ fn simple_pattern_unparser(
let src = &vc.src;
match p {
SimplePattern::Any => {
match ctxt.m.mode {
match ctxt.m.mode() {
ModuleContextMode::TargetIOValue =>
item(seq!["_support::encode_embedded", parens![src.as_ref().unwrap().to_owned()]]),
ModuleContextMode::TargetAny =>
@ -139,7 +149,7 @@ fn simple_pattern_unparser(
}
}
SimplePattern::Embedded { .. } => {
match ctxt.m.mode {
match ctxt.m.mode() {
ModuleContextMode::TargetIOValue =>
item(seq!["preserves::value::Value::Embedded(preserves::value::IOValue::from(&**", src.as_ref().unwrap().to_owned(), ")).wrap()"]),
ModuleContextMode::TargetAny =>

File diff suppressed because it is too large Load Diff