@@ -12,6 +12,7 @@ use rustc_ast::token::{BinOpToken, Delimiter, LitKind, Token, TokenKind};
1212use rustc_ast:: tokenstream:: { RefTokenTreeCursor , Spacing , TokenStream , TokenTree } ;
1313use rustc_index:: IndexVec ;
1414use rustc_span:: symbol:: Ident ;
15+ use std:: collections:: HashMap ;
1516
1617use crate :: chc;
1718use crate :: pretty:: PrettyDisplayExt as _;
@@ -185,6 +186,7 @@ impl<T> FormulaOrTerm<T> {
185186struct Parser < ' a , T > {
186187 resolver : T ,
187188 cursor : RefTokenTreeCursor < ' a > ,
189+ formula_existentials : HashMap < String , chc:: Sort > ,
188190}
189191
190192impl < ' a , T > Parser < ' a , T >
@@ -232,6 +234,15 @@ where
232234 }
233235 }
234236
237+ fn expect_next_ident ( & mut self ) -> Result < Ident > {
238+ let t = self . next_token ( "ident" ) ?;
239+ if let Some ( ( ident, _) ) = t. ident ( ) {
240+ Ok ( ident)
241+ } else {
242+ Err ( ParseAttrError :: unexpected_token ( "ident" , t. clone ( ) ) )
243+ }
244+ }
245+
235246 fn consume ( & mut self ) {
236247 self . cursor . next ( ) . unwrap ( ) ;
237248 }
@@ -296,6 +307,7 @@ where
296307 let mut parser = Parser {
297308 resolver : self . boxed_resolver ( ) ,
298309 cursor : s. trees ( ) ,
310+ formula_existentials : self . formula_existentials . clone ( ) ,
299311 } ;
300312 let formula_or_term = parser. parse_formula_or_term_or_tuple ( ) ?;
301313 parser. end_of_input ( ) ?;
@@ -305,9 +317,17 @@ where
305317 } ;
306318
307319 let formula_or_term = if let Some ( ( ident, _) ) = t. ident ( ) {
308- match ident. as_str ( ) {
309- "true" => FormulaOrTerm :: Formula ( chc:: Formula :: top ( ) ) ,
310- "false" => FormulaOrTerm :: Formula ( chc:: Formula :: bottom ( ) ) ,
320+ match (
321+ ident. as_str ( ) ,
322+ self . formula_existentials . get ( ident. name . as_str ( ) ) ,
323+ ) {
324+ ( "true" , _) => FormulaOrTerm :: Formula ( chc:: Formula :: top ( ) ) ,
325+ ( "false" , _) => FormulaOrTerm :: Formula ( chc:: Formula :: bottom ( ) ) ,
326+ ( _, Some ( sort) ) => {
327+ let var =
328+ chc:: Term :: FormulaExistentialVar ( sort. clone ( ) , ident. name . to_string ( ) ) ;
329+ FormulaOrTerm :: Term ( var, sort. clone ( ) )
330+ }
311331 _ => {
312332 let ( v, sort) = self . resolve ( ident) ?;
313333 FormulaOrTerm :: Term ( chc:: Term :: var ( v) , sort)
@@ -575,8 +595,102 @@ where
575595 Ok ( formula_or_term)
576596 }
577597
598+ fn parse_exists ( & mut self ) -> Result < FormulaOrTerm < T :: Output > > {
599+ match self . look_ahead_token ( 0 ) {
600+ Some ( Token {
601+ kind : TokenKind :: Ident ( sym, _) ,
602+ ..
603+ } ) if sym. as_str ( ) == "exists" => {
604+ self . consume ( ) ;
605+ let mut vars = Vec :: new ( ) ;
606+ loop {
607+ let ident = self . expect_next_ident ( ) ?;
608+ self . expect_next_token ( TokenKind :: Colon , ":" ) ?;
609+ let sort = self . parse_sort ( ) ?;
610+ vars. push ( ( ident. name . to_string ( ) , sort) ) ;
611+ match self . next_token ( ". or ," ) ? {
612+ Token {
613+ kind : TokenKind :: Comma ,
614+ ..
615+ } => { }
616+ Token {
617+ kind : TokenKind :: Dot ,
618+ ..
619+ } => break ,
620+ t => return Err ( ParseAttrError :: unexpected_token ( "., or ," , t. clone ( ) ) ) ,
621+ }
622+ }
623+ self . formula_existentials . extend ( vars. iter ( ) . cloned ( ) ) ;
624+ let formula = self
625+ . parse_formula_or_term ( ) ?
626+ . into_formula ( )
627+ . ok_or_else ( || ParseAttrError :: unexpected_term ( "in exists formula" ) ) ?;
628+ for ( name, _) in & vars {
629+ self . formula_existentials . remove ( name) ;
630+ }
631+ return Ok ( FormulaOrTerm :: Formula ( chc:: Formula :: exists ( vars, formula) ) ) ;
632+ }
633+ _ => self . parse_binop_5 ( ) ,
634+ }
635+ }
636+
578637 fn parse_formula_or_term ( & mut self ) -> Result < FormulaOrTerm < T :: Output > > {
579- self . parse_binop_5 ( )
638+ self . parse_exists ( )
639+ }
640+
641+ fn parse_sort ( & mut self ) -> Result < chc:: Sort > {
642+ let tt = self . next_token_tree ( "sort" ) ?. clone ( ) ;
643+ match tt {
644+ TokenTree :: Token (
645+ Token {
646+ kind : TokenKind :: Ident ( sym, _) ,
647+ ..
648+ } ,
649+ _,
650+ ) => {
651+ let sort = match sym. as_str ( ) {
652+ "bool" => chc:: Sort :: bool ( ) ,
653+ "int" => chc:: Sort :: int ( ) ,
654+ "string" => unimplemented ! ( ) ,
655+ "null" => chc:: Sort :: null ( ) ,
656+ "fn" => unimplemented ! ( ) ,
657+ _ => unimplemented ! ( ) ,
658+ } ;
659+ Ok ( sort)
660+ }
661+ //TokenTree::Token(
662+ // Token {
663+ // kind: TokenKind::Gt,
664+ // ..
665+ // },
666+ // _,
667+ //) => {
668+ //}
669+ TokenTree :: Delimited ( _, _, Delimiter :: Parenthesis , ts) => {
670+ let mut parser = Parser {
671+ resolver : self . boxed_resolver ( ) ,
672+ cursor : ts. trees ( ) ,
673+ formula_existentials : self . formula_existentials . clone ( ) ,
674+ } ;
675+ let mut sorts = Vec :: new ( ) ;
676+ loop {
677+ sorts. push ( parser. parse_sort ( ) ?) ;
678+ match parser. look_ahead_token ( 0 ) {
679+ Some ( Token {
680+ kind : TokenKind :: Comma ,
681+ ..
682+ } ) => {
683+ parser. consume ( ) ;
684+ }
685+ None => break ,
686+ Some ( t) => return Err ( ParseAttrError :: unexpected_token ( "," , t. clone ( ) ) ) ,
687+ }
688+ }
689+ parser. end_of_input ( ) ?;
690+ Ok ( chc:: Sort :: tuple ( sorts) . into ( ) )
691+ }
692+ t => Err ( ParseAttrError :: unexpected_token_tree ( "sort" , t. clone ( ) ) ) ,
693+ }
580694 }
581695
582696 fn parse_ty ( & mut self ) -> Result < rty:: Type < T :: Output > > {
@@ -662,6 +776,7 @@ where
662776 let mut parser = Parser {
663777 resolver : self . boxed_resolver ( ) ,
664778 cursor : ts. trees ( ) ,
779+ formula_existentials : self . formula_existentials . clone ( ) ,
665780 } ;
666781 let mut rtys = Vec :: new ( ) ;
667782 loop {
@@ -697,6 +812,7 @@ where
697812 let mut parser = Parser {
698813 resolver : self . boxed_resolver ( ) ,
699814 cursor : ts. trees ( ) ,
815+ formula_existentials : self . formula_existentials . clone ( ) ,
700816 } ;
701817 let self_ident = if matches ! (
702818 parser. look_ahead_token( 1 ) ,
@@ -720,6 +836,7 @@ where
720836 let mut parser = Parser {
721837 resolver : RefinementResolver :: new ( self . boxed_resolver ( ) ) ,
722838 cursor : parser. cursor ,
839+ formula_existentials : self . formula_existentials . clone ( ) ,
723840 } ;
724841 if let Some ( self_ident) = self_ident {
725842 parser. resolver . set_self ( self_ident, ty. to_sort ( ) ) ;
@@ -859,6 +976,7 @@ where
859976 let mut parser = Parser {
860977 resolver : & self . resolver ,
861978 cursor : ts. trees ( ) ,
979+ formula_existentials : Default :: default ( ) ,
862980 } ;
863981 let rty = parser. parse_rty ( ) ?;
864982 parser. end_of_input ( ) ?;
@@ -869,6 +987,7 @@ where
869987 let mut parser = Parser {
870988 resolver : & self . resolver ,
871989 cursor : ts. trees ( ) ,
990+ formula_existentials : Default :: default ( ) ,
872991 } ;
873992 let formula = parser. parse_annot_formula ( ) ?;
874993 parser. end_of_input ( ) ?;
0 commit comments