@@ -5,17 +5,18 @@ use std::sync::Mutex;
5
5
6
6
use ascent_base:: util:: update;
7
7
use derive_syn_parse:: Parse ;
8
- use itertools:: Itertools ;
8
+ use itertools:: { Either , Itertools } ;
9
9
use proc_macro2:: { Span , TokenStream } ;
10
10
use quote:: ToTokens ;
11
11
use syn:: parse:: { Parse , ParseStream , Parser } ;
12
12
use syn:: punctuated:: Punctuated ;
13
13
use syn:: spanned:: Spanned ;
14
14
use syn:: {
15
- Attribute , Error , Expr , ExprMacro , Generics , Ident , ImplGenerics , Pat , Result , Token , Type , TypeGenerics ,
15
+ Attribute , Error , Expr , ExprMacro , Generics , Ident , ImplGenerics , Pat , Path , Result , Token , Type , TypeGenerics ,
16
16
Visibility , WhereClause , braced, parenthesized, parse2,
17
17
} ;
18
18
19
+ use crate :: AscentMacroKind ;
19
20
use crate :: syn_utils:: {
20
21
expr_get_vars, expr_visit_free_vars_mut, expr_visit_idents_in_macros_mut, pattern_get_vars, pattern_visit_vars_mut,
21
22
token_stream_idents, token_stream_replace_ident,
@@ -45,13 +46,13 @@ mod kw {
45
46
pub struct LongLeftArrow ( Token ! [ <] , Token ! [ -] , Token ! [ -] ) ;
46
47
#[ allow( unused) ]
47
48
impl LongLeftArrow {
48
- pub fn span ( & self ) -> Span {
49
- join_spans ( [ self . 0 . span , self . 1 . span , self . 2 . span ] )
50
- }
49
+ pub fn span ( & self ) -> Span { join_spans ( [ self . 0 . span , self . 1 . span , self . 2 . span ] ) }
51
50
}
52
51
syn:: custom_keyword!( agg) ;
53
52
syn:: custom_keyword!( ident) ;
54
53
syn:: custom_keyword!( expr) ;
54
+
55
+ syn:: custom_keyword!( include_source) ;
55
56
}
56
57
57
58
#[ derive( Clone , Debug ) ]
@@ -117,7 +118,7 @@ fn parse_generics_with_where_clause(input: ParseStream) -> Result<Generics> {
117
118
Ok ( res)
118
119
}
119
120
120
- // #[derive(Clone)]
121
+ #[ derive( PartialEq , Eq , Clone ) ]
121
122
pub struct RelationNode {
122
123
pub attrs : Vec < Attribute > ,
123
124
pub name : Ident ,
@@ -126,6 +127,7 @@ pub struct RelationNode {
126
127
pub _semi_colon : Token ! [ ; ] ,
127
128
pub is_lattice : bool ,
128
129
}
130
+
129
131
impl Parse for RelationNode {
130
132
fn parse ( input : ParseStream ) -> Result < Self > {
131
133
let is_lattice = input. peek ( kw:: lattice) ;
@@ -549,6 +551,18 @@ pub struct MacroDefNode {
549
551
body : TokenStream ,
550
552
}
551
553
554
+ #[ derive( Parse ) ]
555
+ pub struct IncludeSourceNode {
556
+ pub include_source_kw : kw:: include_source ,
557
+ _bang : Token ! [ !] ,
558
+ #[ paren]
559
+ _arg_paren : syn:: token:: Paren ,
560
+ #[ inside( _arg_paren) ]
561
+ #[ call( syn:: Path :: parse_mod_style) ]
562
+ path : syn:: Path ,
563
+ _semi : Token ! [ ; ] ,
564
+ }
565
+
552
566
// #[derive(Clone)]
553
567
pub ( crate ) struct AscentProgram {
554
568
pub rules : Vec < RuleNode > ,
@@ -558,40 +572,85 @@ pub(crate) struct AscentProgram {
558
572
pub macros : Vec < MacroDefNode > ,
559
573
}
560
574
561
- impl Parse for AscentProgram {
562
- fn parse ( input : ParseStream ) -> Result < Self > {
563
- let attributes = Attribute :: parse_inner ( input) ?;
564
- let mut struct_attrs = Attribute :: parse_outer ( input) ?;
565
- let signatures = if input. peek ( Token ! [ pub ] ) || input. peek ( Token ! [ struct ] ) {
566
- let mut signatures = Signatures :: parse ( input) ?;
567
- signatures. declaration . attrs = std:: mem:: take ( & mut struct_attrs) ;
568
- Some ( signatures)
575
+ /// The output that should be emitted when an `include_source!()` is encountered
576
+ pub ( crate ) struct IncludeSourceMacroCall {
577
+ /// the encountered `include_source!()`
578
+ pub include_node : IncludeSourceNode ,
579
+ pub before_tokens : TokenStream ,
580
+ pub after_tokens : TokenStream ,
581
+ pub ascent_macro_name : Path ,
582
+ }
583
+
584
+ impl IncludeSourceMacroCall {
585
+ /// The output that should be emitted
586
+ pub fn macro_call_output ( & self ) -> TokenStream {
587
+ let Self { include_node, before_tokens, after_tokens, ascent_macro_name } = self ;
588
+ let include_macro_callback = & include_node. path ;
589
+ quote_spanned ! { include_macro_callback. span( ) =>
590
+ #include_macro_callback! { { #ascent_macro_name} , { #before_tokens} , { #after_tokens} }
591
+ }
592
+ }
593
+ }
594
+
595
+ pub ( crate ) fn parse_ascent_program (
596
+ input : ParseStream , ascent_macro_name : Path ,
597
+ ) -> Result < Either < AscentProgram , IncludeSourceMacroCall > > {
598
+ let input_clone = input. cursor ( ) ;
599
+ let attributes = Attribute :: parse_inner ( input) ?;
600
+ let mut struct_attrs = Attribute :: parse_outer ( input) ?;
601
+ let signatures = if input. peek ( Token ! [ pub ] ) || input. peek ( Token ! [ struct ] ) {
602
+ let mut signatures = Signatures :: parse ( input) ?;
603
+ signatures. declaration . attrs = std:: mem:: take ( & mut struct_attrs) ;
604
+ Some ( signatures)
605
+ } else {
606
+ None
607
+ } ;
608
+ let mut rules = vec ! [ ] ;
609
+ let mut relations = vec ! [ ] ;
610
+ let mut macros = vec ! [ ] ;
611
+ while !input. is_empty ( ) {
612
+ let attrs =
613
+ if !struct_attrs. is_empty ( ) { std:: mem:: take ( & mut struct_attrs) } else { Attribute :: parse_outer ( input) ? } ;
614
+ if input. peek ( kw:: relation) || input. peek ( kw:: lattice) {
615
+ let mut relation_node = RelationNode :: parse ( input) ?;
616
+ relation_node. attrs = attrs;
617
+ relations. push ( relation_node) ;
618
+ } else if input. peek ( Token ! [ macro] ) {
619
+ if !attrs. is_empty ( ) {
620
+ return Err ( Error :: new ( attrs[ 0 ] . span ( ) , "unexpected attribute(s)" ) ) ;
621
+ }
622
+ macros. push ( MacroDefNode :: parse ( input) ?) ;
623
+ } else if input. peek ( kw:: include_source) {
624
+ if !attrs. is_empty ( ) {
625
+ return Err ( Error :: new ( attrs[ 0 ] . span ( ) , "unexpected attribute(s)" ) ) ;
626
+ }
627
+ let before_tokens = input_clone
628
+ . token_stream ( )
629
+ . into_iter ( )
630
+ . take_while ( |tt| !spans_eq ( & tt. span ( ) , & input. span ( ) ) )
631
+ . collect :: < TokenStream > ( ) ;
632
+ let include_node = IncludeSourceNode :: parse ( input) ?;
633
+ let after_tokens: TokenStream = input. parse ( ) ?;
634
+ let include_source_macro_call =
635
+ IncludeSourceMacroCall { include_node, before_tokens, after_tokens, ascent_macro_name } ;
636
+ return Ok ( Either :: Right ( include_source_macro_call) ) ;
569
637
} else {
570
- None
571
- } ;
572
- let mut rules = vec ! [ ] ;
573
- let mut relations = vec ! [ ] ;
574
- let mut macros = vec ! [ ] ;
575
- while !input. is_empty ( ) {
576
- let attrs =
577
- if !struct_attrs. is_empty ( ) { std:: mem:: take ( & mut struct_attrs) } else { Attribute :: parse_outer ( input) ? } ;
578
- if input. peek ( kw:: relation) || input. peek ( kw:: lattice) {
579
- let mut relation_node = RelationNode :: parse ( input) ?;
580
- relation_node. attrs = attrs;
581
- relations. push ( relation_node) ;
582
- } else if input. peek ( Token ! [ macro] ) {
583
- if !attrs. is_empty ( ) {
584
- return Err ( Error :: new ( attrs[ 0 ] . span ( ) , "unexpected attribute(s)" ) ) ;
585
- }
586
- macros. push ( MacroDefNode :: parse ( input) ?) ;
587
- } else {
588
- if !attrs. is_empty ( ) {
589
- return Err ( Error :: new ( attrs[ 0 ] . span ( ) , "unexpected attribute(s)" ) ) ;
590
- }
591
- rules. push ( RuleNode :: parse ( input) ?) ;
638
+ if !attrs. is_empty ( ) {
639
+ return Err ( Error :: new ( attrs[ 0 ] . span ( ) , "unexpected attribute(s)" ) ) ;
592
640
}
641
+ rules. push ( RuleNode :: parse ( input) ?) ;
642
+ }
643
+ }
644
+ Ok ( Either :: Left ( AscentProgram { rules, relations, signatures, attributes, macros } ) )
645
+ }
646
+
647
+ impl Parse for AscentProgram {
648
+ fn parse ( input : ParseStream ) -> Result < Self > {
649
+ match parse_ascent_program ( input, AscentMacroKind :: default ( ) . macro_path ( Span :: call_site ( ) ) ) ? {
650
+ Either :: Left ( parsed) => Ok ( parsed) ,
651
+ Either :: Right ( include) =>
652
+ Err ( Error :: new ( include. include_node . include_source_kw . span ( ) , "Encountered `include_source!`" ) ) ,
593
653
}
594
- Ok ( AscentProgram { rules, relations, signatures, attributes, macros } )
595
654
}
596
655
}
597
656
0 commit comments