diff options
author | Greg Brown <gmb60@cam.ac.uk> | 2021-01-09 14:31:02 +0000 |
---|---|---|
committer | Greg Brown <gmb60@cam.ac.uk> | 2021-01-09 14:31:02 +0000 |
commit | 0d01692c97ea8ca6fc4b229e5b9678cb252bceda (patch) | |
tree | 6c5ed07740b814f50dddbc6afaefc21c11dc3440 /chomp-macro/src/lib.rs | |
parent | 487ce4fe0fa081f58d790d7d6417bf7d2659197c (diff) |
Introduce chomp as a procedural macro.
Add a bunch of tests.
Fix chomp and chewed so autochomp compiles.
Diffstat (limited to 'chomp-macro/src/lib.rs')
-rw-r--r-- | chomp-macro/src/lib.rs | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/chomp-macro/src/lib.rs b/chomp-macro/src/lib.rs new file mode 100644 index 0000000..d58bbdc --- /dev/null +++ b/chomp-macro/src/lib.rs @@ -0,0 +1,42 @@ +use chomp::{ + chomp::{ + check::{InlineCalls, TypeCheck}, + context::Context, + visit::Visitable, + }, + lower::{rust::RustBackend, Backend, GenerateCode}, + nibble::cst::File, +}; +use proc_macro::{Span, TokenStream}; +use syn::Error; + +#[proc_macro] +pub fn nibble(item: TokenStream) -> TokenStream { + syn::parse(item) + .and_then(|nibble: File| { + nibble + .convert() + .ok_or_else(|| todo!()) + }) + .and_then(|(funs, goal)| { + funs.into_iter() + .try_rfold(goal, |goal, function| { + goal.fold(&mut InlineCalls::new(function)) + }) + .map_err(Error::from) + }) + .and_then(|expr| { + let mut context = Context::default(); + expr.fold(&mut TypeCheck { + context: &mut context, + }) + .map_err(Error::from) + }) + .map(|typed| { + let mut backend = RustBackend::default(); + let id = typed.gen(&mut backend); + backend.emit_code(id) + }) + .unwrap_or_else(Error::into_compile_error) + .into() +} |