@@ -33,6 +33,57 @@ impl<T> AnnotFormula<T> {
3333 }
3434}
3535
36+ /// A path in an annotation.
37+ #[ derive( Debug , Clone ) ]
38+ pub struct AnnotPath {
39+ pub segments : Vec < AnnotPathSegment > ,
40+ }
41+
42+ impl AnnotPath {
43+ pub fn to_datatype_ctor < V > ( & self , ctor_args : Vec < chc:: Term < V > > ) -> ( chc:: Term < V > , chc:: Sort ) {
44+ let mut segments = self . segments . clone ( ) ;
45+
46+ let ctor = segments. pop ( ) . unwrap ( ) ;
47+ if !ctor. generic_args . is_empty ( ) {
48+ unimplemented ! ( "generic arguments in datatype constructor" ) ;
49+ }
50+ let Some ( ty_last_segment) = segments. last_mut ( ) else {
51+ unimplemented ! ( "single segment path" ) ;
52+ } ;
53+ let generic_args: Vec < _ > = ty_last_segment. generic_args . drain ( ..) . collect ( ) ;
54+ let ty_path_idents: Vec < _ > = segments
55+ . into_iter ( )
56+ . map ( |segment| {
57+ if !segment. generic_args . is_empty ( ) {
58+ unimplemented ! ( "generic arguments in datatype constructor" ) ;
59+ }
60+ segment. ident . to_string ( )
61+ } )
62+ . collect ( ) ;
63+ // see refine::datatype_symbol
64+ let d_sym = chc:: DatatypeSymbol :: new ( ty_path_idents. join ( "." ) ) ;
65+ let v_sym = chc:: DatatypeSymbol :: new ( format ! ( "{}.{}" , d_sym, ctor. ident. as_str( ) ) ) ;
66+ let term = chc:: Term :: datatype_ctor ( d_sym. clone ( ) , generic_args. clone ( ) , v_sym, ctor_args) ;
67+ let sort = chc:: Sort :: datatype ( d_sym, generic_args) ;
68+ ( term, sort)
69+ }
70+
71+ pub fn single_segment_ident ( & self ) -> Option < & Ident > {
72+ if self . segments . len ( ) == 1 && self . segments [ 0 ] . generic_args . is_empty ( ) {
73+ Some ( & self . segments [ 0 ] . ident )
74+ } else {
75+ None
76+ }
77+ }
78+ }
79+
80+ /// A segment of a path in an annotation.
81+ #[ derive( Debug , Clone ) ]
82+ pub struct AnnotPathSegment {
83+ pub ident : Ident ,
84+ pub generic_args : Vec < chc:: Sort > ,
85+ }
86+
3687/// A trait for resolving variables in annotations to their logical representation and their sorts.
3788pub trait Resolver {
3889 type Output ;
@@ -298,6 +349,84 @@ where
298349 }
299350 }
300351
352+ fn parse_path_tail ( & mut self , head : Ident ) -> Result < AnnotPath > {
353+ let mut segments: Vec < AnnotPathSegment > = Vec :: new ( ) ;
354+ segments. push ( AnnotPathSegment {
355+ ident : head,
356+ generic_args : Vec :: new ( ) ,
357+ } ) ;
358+ while let Some ( Token {
359+ kind : TokenKind :: ModSep ,
360+ ..
361+ } ) = self . look_ahead_token ( 0 )
362+ {
363+ self . consume ( ) ;
364+ match self . next_token ( "ident or <" ) ? {
365+ t @ Token {
366+ kind : TokenKind :: Lt ,
367+ ..
368+ } => {
369+ if segments. is_empty ( ) {
370+ return Err ( ParseAttrError :: unexpected_token (
371+ "path segment before <" ,
372+ t. clone ( ) ,
373+ ) ) ;
374+ }
375+ let mut generic_args = Vec :: new ( ) ;
376+ loop {
377+ let sort = self . parse_sort ( ) ?;
378+ generic_args. push ( sort) ;
379+ match self . next_token ( ", or >" ) ? {
380+ Token {
381+ kind : TokenKind :: Comma ,
382+ ..
383+ } => { }
384+ Token {
385+ kind : TokenKind :: Gt ,
386+ ..
387+ } => break ,
388+ t => return Err ( ParseAttrError :: unexpected_token ( ", or >" , t. clone ( ) ) ) ,
389+ }
390+ }
391+ segments. last_mut ( ) . unwrap ( ) . generic_args = generic_args;
392+ }
393+ t @ Token {
394+ kind : TokenKind :: Ident ( _, _) ,
395+ ..
396+ } => {
397+ let ( ident, _) = t. ident ( ) . unwrap ( ) ;
398+ segments. push ( AnnotPathSegment {
399+ ident,
400+ generic_args : Vec :: new ( ) ,
401+ } ) ;
402+ }
403+ t => return Err ( ParseAttrError :: unexpected_token ( "ident or <" , t. clone ( ) ) ) ,
404+ }
405+ }
406+ Ok ( AnnotPath { segments } )
407+ }
408+
409+ fn parse_datatype_ctor_args ( & mut self ) -> Result < Vec < chc:: Term < T :: Output > > > {
410+ let mut terms = Vec :: new ( ) ;
411+ loop {
412+ let formula_or_term = self . parse_formula_or_term ( ) ?;
413+ let ( t, _) = formula_or_term. into_term ( ) . ok_or_else ( || {
414+ ParseAttrError :: unexpected_formula ( "in datatype constructor arguments" )
415+ } ) ?;
416+ terms. push ( t) ;
417+ if let Some ( Token {
418+ kind : TokenKind :: Comma ,
419+ ..
420+ } ) = self . look_ahead_token ( 0 )
421+ {
422+ self . consume ( ) ;
423+ } else {
424+ break ;
425+ }
426+ }
427+ Ok ( terms)
428+ }
429+
301430 fn parse_atom ( & mut self ) -> Result < FormulaOrTerm < T :: Output > > {
302431 let tt = self . next_token_tree ( "term or formula" ) ?. clone ( ) ;
303432
@@ -317,21 +446,43 @@ where
317446 } ;
318447
319448 let formula_or_term = if let Some ( ( ident, _) ) = t. ident ( ) {
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- }
331- _ => {
332- let ( v, sort) = self . resolve ( ident) ?;
333- FormulaOrTerm :: Term ( chc:: Term :: var ( v) , sort)
449+ let path = self . parse_path_tail ( ident) ?;
450+ if let Some ( ident) = path. single_segment_ident ( ) {
451+ match (
452+ ident. as_str ( ) ,
453+ self . formula_existentials . get ( ident. name . as_str ( ) ) ,
454+ ) {
455+ ( "true" , _) => FormulaOrTerm :: Formula ( chc:: Formula :: top ( ) ) ,
456+ ( "false" , _) => FormulaOrTerm :: Formula ( chc:: Formula :: bottom ( ) ) ,
457+ ( _, Some ( sort) ) => {
458+ let var =
459+ chc:: Term :: FormulaExistentialVar ( sort. clone ( ) , ident. name . to_string ( ) ) ;
460+ FormulaOrTerm :: Term ( var, sort. clone ( ) )
461+ }
462+ _ => {
463+ let ( v, sort) = self . resolve ( * ident) ?;
464+ FormulaOrTerm :: Term ( chc:: Term :: var ( v) , sort)
465+ }
334466 }
467+ } else {
468+ let next_tt = self
469+ . next_token_tree ( "arguments for datatype constructor" ) ?
470+ . clone ( ) ;
471+ let TokenTree :: Delimited ( _, _, Delimiter :: Parenthesis , s) = next_tt else {
472+ return Err ( ParseAttrError :: unexpected_token_tree (
473+ "arguments for datatype constructor" ,
474+ next_tt. clone ( ) ,
475+ ) ) ;
476+ } ;
477+ let mut parser = Parser {
478+ resolver : self . boxed_resolver ( ) ,
479+ cursor : s. trees ( ) ,
480+ formula_existentials : self . formula_existentials . clone ( ) ,
481+ } ;
482+ let args = parser. parse_datatype_ctor_args ( ) ?;
483+ parser. end_of_input ( ) ?;
484+ let ( term, sort) = path. to_datatype_ctor ( args) ;
485+ FormulaOrTerm :: Term ( term, sort)
335486 }
336487 } else {
337488 match t. kind {
0 commit comments