Codegen: parameterize on a generated Context trait that contains external ctors/etors.
This commit is contained in:
@@ -1,8 +1,12 @@
|
|||||||
|
mod test;
|
||||||
|
|
||||||
pub fn get_input<C>(ctx: &mut C, x: u32) -> Option<(test::A,)> {
|
struct Context;
|
||||||
None
|
impl test::Context for Context {
|
||||||
|
fn get_input(&mut self, x: u32) -> Option<(test::A,)> {
|
||||||
|
Some((test::A::A1 { x: x + 1 },))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {
|
||||||
|
test::constructor_Lower(&mut Context, &test::A::A1 { x: 42 });
|
||||||
mod test;
|
}
|
||||||
|
|||||||
@@ -559,6 +559,7 @@ impl<'a> Codegen<'a> {
|
|||||||
let mut code = String::new();
|
let mut code = String::new();
|
||||||
|
|
||||||
self.generate_header(&mut code)?;
|
self.generate_header(&mut code)?;
|
||||||
|
self.generate_ctx_trait(&mut code)?;
|
||||||
self.generate_internal_types(&mut code)?;
|
self.generate_internal_types(&mut code)?;
|
||||||
self.generate_internal_term_constructors(&mut code)?;
|
self.generate_internal_term_constructors(&mut code)?;
|
||||||
self.generate_internal_term_extractors(&mut code)?;
|
self.generate_internal_term_extractors(&mut code)?;
|
||||||
@@ -576,11 +577,105 @@ impl<'a> Codegen<'a> {
|
|||||||
for file in &self.typeenv.filenames {
|
for file in &self.typeenv.filenames {
|
||||||
writeln!(code, "// - {}", file)?;
|
writeln!(code, "// - {}", file)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
writeln!(
|
writeln!(
|
||||||
code,
|
code,
|
||||||
"\nuse super::*; // Pulls in all external types and ctors/etors"
|
"\n#![allow(dead_code, unreachable_code, unused_imports, unused_variables, non_snake_case)]"
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
writeln!(code, "\nuse super::*; // Pulls in all external types.")?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_ctx_trait(&self, code: &mut dyn Write) -> Result<(), Error> {
|
||||||
|
writeln!(code, "")?;
|
||||||
|
writeln!(
|
||||||
|
code,
|
||||||
|
"/// Context during lowering: an implementation of this trait"
|
||||||
|
)?;
|
||||||
|
writeln!(
|
||||||
|
code,
|
||||||
|
"/// must be provided with all external constructors and extractors."
|
||||||
|
)?;
|
||||||
|
writeln!(
|
||||||
|
code,
|
||||||
|
"/// A mutable borrow is passed along through all lowering logic."
|
||||||
|
)?;
|
||||||
|
writeln!(code, "pub trait Context {{")?;
|
||||||
|
for term in &self.termenv.terms {
|
||||||
|
if let &TermKind::Regular {
|
||||||
|
extractor,
|
||||||
|
constructor,
|
||||||
|
..
|
||||||
|
} = &term.kind
|
||||||
|
{
|
||||||
|
if let Some((etor_name, infallible)) = extractor {
|
||||||
|
let etor_name = &self.typeenv.syms[etor_name.index()];
|
||||||
|
let arg_is_prim = match &self.typeenv.types[term.ret_ty.index()] {
|
||||||
|
&Type::Primitive(..) => true,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
let arg = format!(
|
||||||
|
"arg0: {}",
|
||||||
|
self.type_name(
|
||||||
|
term.ret_ty,
|
||||||
|
/* by_ref = */ if arg_is_prim { None } else { Some("&") }
|
||||||
|
),
|
||||||
|
);
|
||||||
|
let ret_tuple_tys = term
|
||||||
|
.arg_tys
|
||||||
|
.iter()
|
||||||
|
.map(|ty| {
|
||||||
|
self.type_name(*ty, /* by_ref = */ None)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
if infallible {
|
||||||
|
writeln!(
|
||||||
|
code,
|
||||||
|
" fn {}(&mut self, {}) -> ({},);",
|
||||||
|
etor_name,
|
||||||
|
arg,
|
||||||
|
ret_tuple_tys.join(", ")
|
||||||
|
)?;
|
||||||
|
} else {
|
||||||
|
writeln!(
|
||||||
|
code,
|
||||||
|
" fn {}(&mut self, {}) -> Option<({},)>;",
|
||||||
|
etor_name,
|
||||||
|
arg,
|
||||||
|
ret_tuple_tys.join(", ")
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(ctor_name) = constructor {
|
||||||
|
let ctor_name = &self.typeenv.syms[ctor_name.index()];
|
||||||
|
let args = term
|
||||||
|
.arg_tys
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, &arg_ty)| {
|
||||||
|
format!(
|
||||||
|
"arg{}: {}",
|
||||||
|
i,
|
||||||
|
self.type_name(arg_ty, /* by_ref = */ Some("&"))
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let ret = self.type_name(term.ret_ty, /* by_ref = */ None);
|
||||||
|
writeln!(
|
||||||
|
code,
|
||||||
|
"fn {}(&mut self, {}) -> Option<{}>;",
|
||||||
|
ctor_name,
|
||||||
|
args.join(", "),
|
||||||
|
ret,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeln!(code, "}}")?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -628,7 +723,7 @@ impl<'a> Codegen<'a> {
|
|||||||
&TermKind::Regular {
|
&TermKind::Regular {
|
||||||
constructor: Some(sym),
|
constructor: Some(sym),
|
||||||
..
|
..
|
||||||
} => self.typeenv.syms[sym.index()].clone(),
|
} => format!("C::{}", self.typeenv.syms[sym.index()]),
|
||||||
&TermKind::Regular {
|
&TermKind::Regular {
|
||||||
constructor: None, ..
|
constructor: None, ..
|
||||||
} => {
|
} => {
|
||||||
@@ -644,7 +739,7 @@ impl<'a> Codegen<'a> {
|
|||||||
&TermKind::Regular {
|
&TermKind::Regular {
|
||||||
extractor: Some((sym, infallible)),
|
extractor: Some((sym, infallible)),
|
||||||
..
|
..
|
||||||
} => (self.typeenv.syms[sym.index()].clone(), infallible),
|
} => (format!("C::{}", self.typeenv.syms[sym.index()]), infallible),
|
||||||
&TermKind::Regular {
|
&TermKind::Regular {
|
||||||
extractor: None, ..
|
extractor: None, ..
|
||||||
} => (
|
} => (
|
||||||
@@ -729,7 +824,7 @@ impl<'a> Codegen<'a> {
|
|||||||
)?;
|
)?;
|
||||||
writeln!(
|
writeln!(
|
||||||
code,
|
code,
|
||||||
"fn {}<C>(ctx: &mut C, {}) -> Option<{}> {{",
|
"pub fn {}<C: Context>(ctx: &mut C, {}) -> Option<{}> {{",
|
||||||
func_name,
|
func_name,
|
||||||
args.join(", "),
|
args.join(", "),
|
||||||
self.type_name(termdata.ret_ty, /* by_ref = */ None)
|
self.type_name(termdata.ret_ty, /* by_ref = */ None)
|
||||||
@@ -788,7 +883,7 @@ impl<'a> Codegen<'a> {
|
|||||||
)?;
|
)?;
|
||||||
writeln!(
|
writeln!(
|
||||||
code,
|
code,
|
||||||
"fn {}<C>(ctx: &mut C, {}) -> Option<({},)> {{",
|
"pub fn {}<C: Context>(ctx: &mut C, {}) -> Option<({},)> {{",
|
||||||
func_name,
|
func_name,
|
||||||
arg,
|
arg,
|
||||||
ret_tuple_tys.join(", "),
|
ret_tuple_tys.join(", "),
|
||||||
@@ -1114,7 +1209,7 @@ impl<'a> Codegen<'a> {
|
|||||||
// chain of if-lets.
|
// chain of if-lets.
|
||||||
let mut edges = edges.clone();
|
let mut edges = edges.clone();
|
||||||
edges.sort_by(|e1, e2| (-e1.range.0, &e1.symbol).cmp(&(-e2.range.0, &e2.symbol)));
|
edges.sort_by(|e1, e2| (-e1.range.0, &e1.symbol).cmp(&(-e2.range.0, &e2.symbol)));
|
||||||
|
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
while i < edges.len() {
|
while i < edges.len() {
|
||||||
let mut last = i;
|
let mut last = i;
|
||||||
|
|||||||
Reference in New Issue
Block a user