@@ -67,6 +67,54 @@ type tc_constraint = {
6767 r : FStarC_Range .t ;
6868}
6969
70+ let pattern_must_be_binder (p : pattern ) : binder =
71+ match p.pat with
72+ | PatConst Const_unit ->
73+ (* A unit pattern: `()`. Unsure if this is the right place to look
74+ for it. *)
75+ let x = gen p.prange in
76+ let u =
77+ unit_type p.prange
78+ (* mk_term (Const Const_unit) p.prange Expr *)
79+ in
80+ mk_binder (Annotated (x, u)) p.prange Expr None
81+
82+ | PatAscribed ({ pat = PatVar (x , aq , attrs )} , (t , _tac_opt )) ->
83+ mk_binder_with_attrs (Annotated (x, t)) p.prange Expr aq attrs
84+
85+ | PatVar (x , aq , attrs ) ->
86+ mk_binder_with_attrs (Variable x) p.prange Expr aq attrs
87+
88+ | PatAscribed ({ pat = PatWild (aq , attrs )} , (t , _tac_opt )) ->
89+ let x = gen p.prange in
90+ mk_binder_with_attrs (Annotated (x, t)) p.prange Expr aq attrs
91+
92+ | PatWild (aq , attrs ) ->
93+ let x = gen p.prange in
94+ mk_binder_with_attrs (Variable x) p.prange Expr aq attrs
95+
96+ | _ ->
97+ raise_error_text p.prange Fatal_SyntaxError
98+ (" Must be a simple binder: " ^ pat_to_string p)
99+
100+ (* For a multibinder like `(a b c : Type | eq, ord)`, this generates
101+ binders
102+ {| _ : eq a |} {| _ : ord a |}
103+ {| _ : eq b |} {| _ : ord b |}
104+ {| _ : eq c |} {| _ : ord c |}
105+ in that order.
106+ *)
107+ let expand_inline_constraints (cts : term list ) (xs : ident list ) : pattern list =
108+ List. concat_map (fun x ->
109+ List. concat_map (fun ct ->
110+ let r = ct.range in
111+ let x_t = mk_term (Var (lid_of_ids [x])) r Expr in
112+ let ct = mk_term (App (ct, x_t, Nothing )) r Expr in
113+ let id = gen r in
114+ [ mk_pattern (PatAscribed (mk_pattern (PatVar (id, Some TypeClassArg , [] )) r, (ct, None ))) r ]
115+ ) cts
116+ ) xs
117+
70118% }
71119
72120% token < string > STRING
@@ -510,7 +558,7 @@ letoperatorbinding:
510558 }
511559
512560letbinding:
513- | focus_opt= maybeFocus lid= lidentOrOperator lbp= nonempty_list(patternOrMultibinder ) ascr_opt= ascribeTyp? EQUALS tm= term
561+ | focus_opt= maybeFocus lid= lidentOrOperator lbp= nonempty_list(genBinder ) ascr_opt= ascribeTyp? EQUALS tm= term
514562 {
515563 let pat = mk_pattern (PatVar (lid, None , [] )) (rr $ loc(lid)) in
516564 let pat = mk_pattern (PatApp (pat, flatten lbp)) (rr2 $ loc(focus_opt) $ loc(lbp)) in
@@ -683,40 +731,75 @@ tuplePattern:
683731constructorPattern:
684732 | pat= constructorPattern COLON_COLON pats= constructorPattern
685733 { mk_pattern (consPat (rr $ loc(pats)) pat pats) (rr $ loc) }
686- | uid= quident args= nonempty_list(atomicPattern )
734+ | uid= quident args= nonempty_list(singleAtomicPattern )
687735 {
688736 let head_pat = mk_pattern (PatName uid) (rr $ loc(uid)) in
689737 mk_pattern (PatApp (head_pat, args)) (rr $ loc)
690738 }
691- | pat= atomicPattern
739+ | pat= singleAtomicPattern
692740 { pat }
693741
742+ singleAtomicPattern:
743+ | pats= atomicPattern
744+ {
745+ match pats with
746+ | [p] -> p
747+ | _ -> raise_error_text (rr $ loc) Fatal_SyntaxError " Syntax error: expected a single atomic pattern, not a list"
748+ }
749+
694750atomicPattern:
695- | DOT_DOT
751+ | a= atomicPatternNoLParen
752+ { [a] }
753+ | LPAREN
754+ pats= nonempty_list(tuplePattern)
755+ ann= genBinderAnnotation
756+ RPAREN
696757 {
697- mk_pattern PatRest (rr $ loc)
758+ let t_ann, ref_opt, tc_cts = ann in
759+ let t_pos = rr $ loc(ann) in
760+ (* let pats = List.flatten pats in *)
761+ let n = List. length pats in
762+ let bs : pattern list =
763+ List. mapi (fun idx pat ->
764+ (* let pat = mk_pattern (PatVar (x, aq, attrs)) pos in *)
765+ (* Only the last binder carries the refinement, if any. *)
766+ let ref_opt = if idx = Int. sub n 1 then ref_opt else None in
767+ (* ^ The - symbol resolves to F* addition. *)
768+ match t_ann with
769+ | Some ty ->
770+ mkRefinedPattern pat ty true ref_opt t_pos pat.prange
771+ | None -> pat
772+ ) pats
773+ in
774+ let rec pat_names bs =
775+ match bs with
776+ | [] -> []
777+ | b ::bs' ->
778+ match b.pat with
779+ | PatAscribed ({pat = PatVar (x, _, _)}, _)
780+ | PatVar (x , _ , _ ) -> x ::pat_names bs '
781+ | _ -> pat_names bs '
782+ in
783+ bs @ expand_inline_constraints tc_cts (pat_names bs )
698784 }
699- | LPAREN pat= tuplePattern COLON t= simpleArrow phi_opt= refineOpt RPAREN
785+
786+ atomicPatternNoLParen:
787+ | DOT_DOT
700788 {
701- let pos_t = rr2 $ loc(pat) $ loc(t) in
702- let pos = rr $ loc in
703- mkRefinedPattern pat t true phi_opt pos_t pos
789+ mk_pattern PatRest (rr $ loc)
704790 }
705791 | LBRACK pats= right_flexible_list(SEMICOLON , tuplePattern) RBRACK
706792 { mk_pattern (PatList pats) (rr2 $ loc($ 1 ) $ loc($ 3 )) }
707793 | LBRACE record_pat= right_flexible_list(SEMICOLON , fieldPattern) RBRACE
708794 { mk_pattern (PatRecord record_pat) (rr $ loc) }
709795 | LENS_PAREN_LEFT pat0= constructorPattern COMMA pats= separated_nonempty_list(COMMA , constructorPattern) LENS_PAREN_RIGHT
710796 { mk_pattern (PatTuple (pat0::pats, true )) (rr $ loc) }
711- | LPAREN pat= tuplePattern RPAREN { pat }
797+ // | LPAREN pat= tuplePattern RPAREN { pat }
712798 | LPAREN op= operator RPAREN
713799 { mk_pattern (PatOp op) (rr $ loc) }
714- | UNDERSCORE
715- { mk_pattern (PatWild (None , [] )) (rr $ loc) }
716- | HASH UNDERSCORE
717- { mk_pattern (PatWild (Some Implicit , [] )) (rr $ loc) }
718800 | c= constant
719801 { mk_pattern (PatConst c) (rr $ loc(c)) }
802+ (* I would not call this atomic. *)
720803 | tok= MINUS c= constant
721804 { let r = rr2 $ loc(tok) $ loc(c) in
722805 let c =
@@ -735,6 +818,10 @@ atomicPattern:
735818 {
736819 let (aqual, attrs), lid = qual_id in
737820 mk_pattern (PatVar (lid, aqual, attrs)) (rr $ loc(qual_id)) }
821+ | qual_id= aqualifiedWithAttrs(UNDERSCORE )
822+ {
823+ let (aqual, attrs), _ = qual_id in
824+ mk_pattern (PatWild (aqual, attrs)) (rr $ loc(qual_id)) }
738825 | uid= quident
739826 { mk_pattern (PatName uid) (rr $ loc(uid)) }
740827
@@ -751,83 +838,24 @@ tc_constraint:
751838 {id; t; r}
752839 }
753840
841+ (* Typeclass constraints: what appears inside a {| ... |}. They can
842+ be named or anonymous *)
754843tc_constraints:
755844 | constraints= right_flexible_nonempty_list(COMMA , tc_constraint) { constraints }
756-
757- (* (x : t) is already covered by atomicPattern *)
758- (* we do *NOT* allow _ in multibinder () since it creates reduce/reduce conflicts when*)
759- (* preprocessing to ocamlyacc/fsyacc (which is expected since the macro are expanded) *)
760- patternOrMultibinder:
761- | LBRACE_BAR constraints= tc_constraints BAR_RBRACE
762- {
763- let constraint_as_pat (c :tc_constraint ) =
764- let w = mk_pattern (PatVar (c.id, Some TypeClassArg , [] )) c.r in
765- let asc = (c.t, None ) in
766- mk_pattern (PatAscribed (w, asc)) c.r
767- in
768- List. map constraint_as_pat constraints
769- }
770-
771- | pat= atomicPattern { [pat] }
772- | LPAREN
773- qual_id0= aqualifiedWithAttrs(lident)
774- qual_ids= nonempty_list(aqualifiedWithAttrs(lident))
775- COLON
776- t= simpleArrow r= refineOpt
777- RPAREN
778- {
779- let pos = rr $ loc in
780- let t_pos = rr $ loc(t) in
781- let qual_ids = qual_id0 :: qual_ids in
782- let n = List .length qual_ids in
783- List .mapi (fun idx ((aq , attrs ), x ) ->
784- let pat = mk_pattern (PatVar (x , aq , attrs )) pos in
785- (* Only the last binder carries the refinement, if any. *)
786- let refine_opt = if idx = Int .sub n 1 then r else None in
787- (* ^ The - symbol resolves to F* addition. *)
788- mkRefinedPattern pat t true refine_opt t_pos pos
789- ) qual_ids
790- }
791-
792- binder:
793- | aqualifiedWithAttrs_lid= aqualifiedWithAttrs(lidentOrUnderscore)
794- {
795- let (q, attrs), lid = aqualifiedWithAttrs_lid in
796- mk_binder_with_attrs (Variable lid) (rr $ loc(aqualifiedWithAttrs_lid)) Type_level q attrs
797- }
845+
846+ (* Constraints on binders: like (#a : Type | deq) *)
847+ type_tc_constraints:
848+ | BAR constraints= right_flexible_nonempty_list(COMMA , tmEqNoRefinement) { constraints }
849+ | { [] }
798850
799851% public
800- multiBinder:
801- | LBRACE_BAR constraints= tc_constraints BAR_RBRACE
802- {
803- let constraint_as_binder (c :tc_constraint ) =
804- mk_binder (Annotated (c.id, c.t)) c.r Type_level (Some TypeClassArg )
805- in
806- List. map constraint_as_binder constraints
807- }
808-
809- | LPAREN qual_ids= nonempty_list(aqualifiedWithAttrs(lidentOrUnderscore)) COLON t= simpleArrow r= refineOpt RPAREN
810- {
811- let should_bind_var = match qual_ids with | [ _ ] -> true | _ -> false in
812- let n = List. length qual_ids in
813- List. mapi (fun idx ((q , attrs ), x ) ->
814- let refine_opt = if idx = Int. sub n 1 then r else None in
815- mkRefinedBinder x t true refine_opt (rr $ loc) q attrs
816- ) qual_ids
817- }
818-
819- | LPAREN_RPAREN
852+ binders:
853+ | bss= list (genBinder)
820854 {
821- let r = rr $ loc in
822- let unit_t = mk_term (Var (lid_of_ids [(mk_ident(" unit" , r))])) r Un in
823- [mk_binder (Annotated (gen r, unit_t)) r Un None ]
855+ let bs = flatten bss in
856+ List. map pattern_must_be_binder bs
824857 }
825858
826- | b= binder { [b] }
827-
828- % public
829- binders: bss= list (bs= multiBinder {bs}) { flatten bss }
830-
831859aqualifiedWithAttrs(X ):
832860 | aq= aqual attrs= binderAttributes x= X { (Some aq, attrs), x }
833861 | aq= aqual x= X { (Some aq, [] ), x }
@@ -1257,6 +1285,7 @@ simpleArrowDomain:
12571285
12581286(* Tm already accounts for ( term ), we need to add an explicit case for (#Tm), (#[@@@...]Tm) and ([@@@...]Tm) *)
12591287% inline tmArrowDomain(Tm ):
1288+ (* Replace all this for genBinder? *)
12601289 | LBRACE_BAR t= Tm BAR_RBRACE { ((Some TypeClassArg , [] ), t) }
12611290 | LPAREN q= aqual attrs_opt= ioption(binderAttributes) dom_tm= Tm RPAREN { (Some q, none_to_empty_list attrs_opt), dom_tm }
12621291 | LPAREN attrs= binderAttributes dom_tm= Tm RPAREN { (None , attrs), dom_tm }
@@ -1471,7 +1500,7 @@ trailingTerm:
14711500 { x }
14721501
14731502onlyTrailingTerm:
1474- | FUN pats= nonempty_list(patternOrMultibinder ) RARROW e= term
1503+ | FUN pats= nonempty_list(genBinder ) RARROW e= term
14751504 { mk_term (Abs (flatten pats, e)) (rr2 $ loc($ 1 ) $ loc(e)) Un }
14761505 | q= quantifier bs= binders DOT trigger= trigger e= term
14771506 {
@@ -1690,3 +1719,26 @@ reverse_left_flexible_nonempty_list(delim, X):
16901719% inline left_flexible_nonempty_list(delim, X ):
16911720 xs = reverse_left_flexible_nonempty_list(delim, X )
16921721 { List. rev xs }
1722+
1723+ genBinderAnnotation:
1724+ | { None , None , [] }
1725+ | COLON
1726+ t= simpleArrow
1727+ r= refineOpt
1728+ cts= type_tc_constraints
1729+ {
1730+ (Some t), r, cts
1731+ }
1732+
1733+ genBinder:
1734+ | LBRACE_BAR constraints= tc_constraints BAR_RBRACE
1735+ {
1736+ let constraint_as_pat (c :tc_constraint ) =
1737+ let w = mk_pattern (PatVar (c.id, Some TypeClassArg , [] )) c.r in
1738+ let asc = (c.t, None ) in
1739+ mk_pattern (PatAscribed (w, asc)) c.r
1740+ in
1741+ List. map constraint_as_pat constraints
1742+ }
1743+
1744+ | pats= atomicPattern { pats }
0 commit comments