summaryrefslogtreecommitdiff
path: root/chomp-macro/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'chomp-macro/src/lib.rs')
-rw-r--r--chomp-macro/src/lib.rs42
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()
+}