diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ast.ml | 1 | ||||
| -rw-r--r-- | src/ast_util.ml | 5 | ||||
| -rw-r--r-- | src/ast_util.mli | 2 | ||||
| -rw-r--r-- | src/initial_check.ml | 1 | ||||
| -rw-r--r-- | src/lexer2.mll | 4 | ||||
| -rw-r--r-- | src/parse_ast.ml | 1 | ||||
| -rw-r--r-- | src/parser2.mly | 11 | ||||
| -rw-r--r-- | src/type_check.ml | 20 |
8 files changed, 42 insertions, 3 deletions
@@ -260,6 +260,7 @@ type | P_as of 'a pat * id (* named pattern *) | P_typ of typ * 'a pat (* typed pattern *) | P_id of id (* identifier *) + | P_var of kid (* bind identifier and type variable *) | P_app of id * ('a pat) list (* union constructor pattern *) | P_record of ('a fpat) list * bool (* struct pattern *) | P_vector of ('a pat) list (* vector pattern *) diff --git a/src/ast_util.ml b/src/ast_util.ml index 0c6461d1..ddd83429 100644 --- a/src/ast_util.ml +++ b/src/ast_util.ml @@ -112,6 +112,7 @@ and map_pat_annot_aux f = function | P_as (pat, id) -> P_as (map_pat_annot f pat, id) | P_typ (typ, pat) -> P_typ (typ, map_pat_annot f pat) | P_id id -> P_id id + | P_var kid -> P_var kid | P_app (id, pats) -> P_app (id, List.map (map_pat_annot f) pats) | P_record (fpats, b) -> P_record (List.map (map_fpat_annot f) fpats, b) | P_tup pats -> P_tup (List.map (map_pat_annot f) pats) @@ -145,6 +146,9 @@ let string_of_id = function | Id_aux (Id v, _) -> v | Id_aux (DeIid v, _) -> "(deinfix " ^ v ^ ")" +let id_of_kid = function + | Kid_aux (Var v, l) -> Id_aux (Id (String.sub v 1 (String.length v - 1)), l) + let string_of_kid = function | Kid_aux (Var v, _) -> v @@ -313,6 +317,7 @@ and string_of_pat (P_aux (pat, l)) = | P_lit lit -> string_of_lit lit | P_wild -> "_" | P_id v -> string_of_id v + | P_var kid -> string_of_kid kid | P_typ (typ, pat) -> "(" ^ string_of_typ typ ^ ") " ^ string_of_pat pat | P_tup pats -> "(" ^ string_of_list ", " string_of_pat pats ^ ")" | P_app (f, pats) -> string_of_id f ^ "(" ^ string_of_list ", " string_of_pat pats ^ ")" diff --git a/src/ast_util.mli b/src/ast_util.mli index ae340839..94f3f0cc 100644 --- a/src/ast_util.mli +++ b/src/ast_util.mli @@ -86,6 +86,8 @@ val string_of_index_range : index_range -> string val id_of_fundef : 'a fundef -> id +val id_of_kid : kid -> id + module Id : sig type t = id val compare : id -> id -> int diff --git a/src/initial_check.ml b/src/initial_check.ml index 357ed100..e5717389 100644 --- a/src/initial_check.ml +++ b/src/initial_check.ml @@ -415,6 +415,7 @@ let rec to_ast_pat (k_env : kind Envmap.t) (def_ord : order) (Parse_ast.P_aux(pa | Parse_ast.P_as(pat,id) -> P_as(to_ast_pat k_env def_ord pat,to_ast_id id) | Parse_ast.P_typ(typ,pat) -> P_typ(to_ast_typ k_env def_ord typ,to_ast_pat k_env def_ord pat) | Parse_ast.P_id(id) -> P_id(to_ast_id id) + | Parse_ast.P_var kid -> P_var (to_ast_var kid) | Parse_ast.P_app(id,pats) -> if pats = [] then P_id (to_ast_id id) diff --git a/src/lexer2.mll b/src/lexer2.mll index 4f4a8be2..f5350ea8 100644 --- a/src/lexer2.mll +++ b/src/lexer2.mll @@ -192,7 +192,6 @@ rule token = parse token lexbuf } | "&" { (Amp(r"&")) } | "@" { (At "@") } - | "|" { Bar } | "2" ws "^" { TwoCaret } | "^" { (Caret(r"^")) } | ":" { Colon(r ":") } @@ -207,6 +206,9 @@ rule token = parse | ";" { Semi } | "*" { (Star(r"*")) } | "_" { Under } + | "{|" { LcurlyBar } + | "|}" { RcurlyBar } + | "|" { Bar } | "{" { Lcurly } | "}" { Rcurly } | "()" { Unit(r"()") } diff --git a/src/parse_ast.ml b/src/parse_ast.ml index 54feaf29..3951ab51 100644 --- a/src/parse_ast.ml +++ b/src/parse_ast.ml @@ -234,6 +234,7 @@ pat_aux = (* Pattern *) | P_as of pat * id (* named pattern *) | P_typ of atyp * pat (* typed pattern *) | P_id of id (* identifier *) + | P_var of kid | P_app of id * (pat) list (* union constructor pattern *) | P_record of (fpat) list * bool (* struct pattern *) | P_vector of (pat) list (* vector pattern *) diff --git a/src/parser2.mly b/src/parser2.mly index 9ce947be..bde542e0 100644 --- a/src/parser2.mly +++ b/src/parser2.mly @@ -133,7 +133,7 @@ let rec desugar_rchain chain s e = %token Div_ Mod ModUnderS Quot Rem QuotUnderS %token Bar Comma Dot Eof Minus Semi Under DotDot -%token Lcurly Rcurly Lparen Rparen Lsquare Rsquare +%token Lcurly Rcurly Lparen Rparen Lsquare Rsquare LcurlyBar RcurlyBar %token BarBar BarSquare BarBarSquare ColonEq ColonGt ColonSquare %token MinusGt LtBar LtColon SquareBar SquareBarBar @@ -484,6 +484,11 @@ atomic_typ: { $2 } | Lparen typ Comma typ_list Rparen { mk_typ (ATyp_tup ($2 :: $4)) $startpos $endpos } + | LcurlyBar num_list RcurlyBar + { let v = mk_kid "n" $startpos $endpos in + let atom_id = mk_id (Id "atom") $startpos $endpos in + let atom_of_v = mk_typ (ATyp_app (atom_id, [mk_typ (ATyp_var v) $startpos $endpos])) $startpos $endpos in + mk_typ (ATyp_exist ([v], NC_aux (NC_nat_set_bounded (v, $2), loc $startpos($2) $endpos($2)), atom_of_v)) $startpos $endpos } | Lcurly kid_list Dot typ Rcurly { mk_typ (ATyp_exist ($2, NC_aux (NC_true, loc $startpos $endpos), $4)) $startpos $endpos } | Lcurly kid_list Comma nc Dot typ Rcurly @@ -603,6 +608,10 @@ atomic_pat: { mk_pat (P_lit $1) $startpos $endpos } | id { mk_pat (P_id $1) $startpos $endpos } + | kid + { mk_pat (P_var $1) $startpos $endpos } + | tydecl typ + { mk_pat (P_typ ($2, mk_pat (P_var $1) $startpos $endpos($1))) $startpos $endpos } | id Lparen pat_list Rparen { mk_pat (P_app ($1, $3)) $startpos $endpos } | pat Colon typ diff --git a/src/type_check.ml b/src/type_check.ml index 8a7983ce..ec0b4a58 100644 --- a/src/type_check.ml +++ b/src/type_check.ml @@ -811,7 +811,7 @@ end = struct then typ_error (kid_loc kid) ("Kind identifier " ^ string_of_kid kid ^ " is already bound") else begin - typ_debug ("Adding kind identifier binding " ^ string_of_kid kid ^ " :: " ^ string_of_base_kind_aux k); + typ_print ("Adding kind identifier " ^ string_of_kid kid ^ " :: " ^ string_of_base_kind_aux k); { env with typ_vars = KBindings.add kid k env.typ_vars } end @@ -2064,6 +2064,23 @@ and bind_pat env (P_aux (pat_aux, (l, ())) as pat) (Typ_aux (typ_aux, _) as typ) | Unification_error (l, m) -> typ_error l ("Unification error when pattern matching against union constructor: " ^ m) end end + | P_var kid -> + begin + let v = id_of_kid kid in + match Env.lookup_id v env with + | Local (Immutable, _) | Unbound -> + begin + match destruct_exist env typ with + | Some ([kid'], nc, typ) -> + let env = Env.add_typ_var kid BK_nat env in + let env = Env.add_constraint (nc_subst_nexp kid' (Nexp_var kid) nc) env in + let env = Env.add_local v (Immutable, typ_subst_nexp kid' (Nexp_var kid) typ) env in + annot_pat (P_var kid) typ, env + | Some _ -> typ_error l ("Cannot bind type variable pattern against multiple argument existential") + | None _ -> typ_error l ("Cannot bind type variable against non existential type") + end + | _ -> typ_error l ("Bad type identifer pattern: " ^ string_of_pat pat) + end | P_wild -> annot_pat P_wild typ, env | P_cons (hd_pat, tl_pat) -> begin @@ -2829,6 +2846,7 @@ and propagate_pat_effect_aux = function let p_pat = propagate_pat_effect pat in P_typ (typ, p_pat), effect_of_pat p_pat | P_id id -> P_id id, no_effect + | P_var kid -> P_var kid, no_effect | P_app (id, pats) -> let p_pats = List.map propagate_pat_effect pats in P_app (id, p_pats), collect_effects_pat p_pats |
