From 4ecf63c54dabeda8acd5d4d8b4b9b3cc519a3de2 Mon Sep 17 00:00:00 2001 From: greg Date: Fri, 19 Oct 2018 02:36:23 -0700 Subject: [PATCH] Okay the proc_macro is actually doing something At the cost of breaking code --- schala-lang/codegen/Cargo.toml | 2 +- schala-lang/codegen/src/lib.rs | 29 +++++++++++++++++++++++++++-- schala-lang/language/Cargo.toml | 1 + schala-lang/language/src/lib.rs | 3 +++ schala-lang/language/src/parsing.rs | 10 ++++++---- 5 files changed, 38 insertions(+), 7 deletions(-) diff --git a/schala-lang/codegen/Cargo.toml b/schala-lang/codegen/Cargo.toml index 9a54126..74a26cb 100644 --- a/schala-lang/codegen/Cargo.toml +++ b/schala-lang/codegen/Cargo.toml @@ -8,5 +8,5 @@ edition = "2018" proc-macro = true [dependencies] -syn = { version = "0.15.6", features = ["full", "extra-traits"] } +syn = { version = "0.15.12", features = ["full", "extra-traits", "fold"] } quote = "0.6.8" diff --git a/schala-lang/codegen/src/lib.rs b/schala-lang/codegen/src/lib.rs index 3e7003c..3c1a597 100644 --- a/schala-lang/codegen/src/lib.rs +++ b/schala-lang/codegen/src/lib.rs @@ -1,11 +1,36 @@ +#![feature(box_patterns)] extern crate proc_macro; #[macro_use] extern crate quote; +#[macro_use] extern crate syn; use self::proc_macro::TokenStream; +use self::syn::fold::Fold; + +struct RecursiveDescentFn { +} + +impl Fold for RecursiveDescentFn { + fn fold_item_fn(&mut self, mut i: syn::ItemFn) -> syn::ItemFn { + let box block = i.block; + let mut stmts = block.stmts; + let new_item: syn::Stmt = parse_quote! { + println!("FROM PROC MACRO"); + }; + let mut new_stmts = vec![new_item]; + new_stmts.append(&mut stmts); + let new_block = syn::Block { brace_token: block.brace_token, stmts: new_stmts }; + i.block = Box::new(new_block); + i + } +} #[proc_macro_attribute] -pub fn parser_function(attr: TokenStream, item: TokenStream) -> TokenStream { - item +pub fn recursive_descent_method(attr: TokenStream, item: TokenStream) -> TokenStream { + + let input: syn::ItemFn = parse_macro_input!(item as syn::ItemFn); + let mut folder = RecursiveDescentFn {}; + let output = folder.fold_item_fn(input); + TokenStream::from(quote!(#output)) } diff --git a/schala-lang/language/Cargo.toml b/schala-lang/language/Cargo.toml index 0259869..373d1e9 100644 --- a/schala-lang/language/Cargo.toml +++ b/schala-lang/language/Cargo.toml @@ -9,5 +9,6 @@ take_mut = "0.1.3" maplit = "*" lazy_static = "0.2.8" +codegen = { path = "../codegen" } schala-repl = { path = "../../schala-repl" } schala-repl-codegen = { path = "../../schala-repl-codegen" } diff --git a/schala-lang/language/src/lib.rs b/schala-lang/language/src/lib.rs index 6a0c2a1..906339e 100644 --- a/schala-lang/language/src/lib.rs +++ b/schala-lang/language/src/lib.rs @@ -1,4 +1,5 @@ #![feature(trace_macros)] +#![feature(custom_attribute)] #![feature(unrestricted_attribute_tokens)] #![feature(slice_patterns, box_patterns, box_syntax)] extern crate itertools; @@ -10,6 +11,8 @@ extern crate maplit; extern crate schala_repl; #[macro_use] extern crate schala_repl_codegen; +#[macro_use] +extern crate codegen; use std::cell::RefCell; use std::rc::Rc; diff --git a/schala-lang/language/src/parsing.rs b/schala-lang/language/src/parsing.rs index f057183..1828d93 100644 --- a/schala-lang/language/src/parsing.rs +++ b/schala-lang/language/src/parsing.rs @@ -789,7 +789,8 @@ impl Parser { }) }); - parse_method!(signed_number_literal(&mut self) -> ParseResult { + #[recursive_descent_method] + fn signed_number_literal(&mut self) -> ParseResult { let neg = match self.peek() { Operator(ref op) if **op == "-" => { self.next(); @@ -799,7 +800,7 @@ impl Parser { }; let Expression(expr_type, _) = self.number_literal()?; Ok(Pattern::Literal(PatternLiteral::NumPattern { neg, num: expr_type })) - }); + } parse_method!(record_pattern_entry(&mut self) -> ParseResult<(Rc, Pattern)> { let name = self.identifier()?; @@ -913,12 +914,13 @@ impl Parser { } }); - parse_method!(number_literal(&mut self) -> ParseResult { + #[recursive_descent_method] + fn number_literal(&mut self) -> ParseResult { match self.peek() { HexLiteral(_) | BinNumberSigil => self.int_literal(), _ => self.float_literal(), } - }); + } parse_method!(int_literal(&mut self) -> ParseResult { use self::ExpressionType::*;