summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ast.ml4
-rw-r--r--src/type_check_new.ml33
-rw-r--r--test/typecheck/fail/default_order.sail6
-rw-r--r--test/typecheck/pass/default_order.sail1
4 files changed, 39 insertions, 5 deletions
diff --git a/src/ast.ml b/src/ast.ml
index 476c40b7..c21bd225 100644
--- a/src/ast.ml
+++ b/src/ast.ml
@@ -470,7 +470,7 @@ type
type
-'a default_spec_aux = (* Default kinding or typing assumption *)
+default_spec_aux = (* Default kinding or typing assumption *)
DT_kind of base_kind * kid
| DT_order of order
| DT_typ of typschm * id
@@ -526,7 +526,7 @@ type
type
'a default_spec =
- DT_aux of 'a default_spec_aux * l
+ DT_aux of default_spec_aux * l
type
diff --git a/src/type_check_new.ml b/src/type_check_new.ml
index 175586ed..5dedd777 100644
--- a/src/type_check_new.ml
+++ b/src/type_check_new.ml
@@ -250,6 +250,9 @@ module Env : sig
val add_ret_typ : typ -> t -> t
val add_typ_synonym : id -> (typ_arg list -> typ) -> t -> t
val get_typ_synonym : id -> t -> typ_arg list -> typ
+ val get_default_order : t -> order
+ val set_default_order_inc : t -> t
+ val set_default_order_dec : t -> t
val fresh_kid : t -> kid
val expand_synonyms : t -> typ -> typ
val empty : t
@@ -260,6 +263,7 @@ end = struct
typ_vars : base_kind_aux KBindings.t;
typ_synonyms : (typ_arg list -> typ) Bindings.t;
constraints : n_constraint list;
+ default_order : order option;
ret_typ : typ option
}
@@ -269,6 +273,7 @@ end = struct
typ_vars = KBindings.empty;
typ_synonyms = Bindings.empty;
constraints = [];
+ default_order = None;
ret_typ = None;
}
@@ -383,6 +388,19 @@ end = struct
| Typ_arg_typ typ -> Typ_arg_aux (Typ_arg_typ (expand_synonyms env typ), l)
| arg -> Typ_arg_aux (arg, l)
+ let get_default_order env =
+ match env.default_order with
+ | None -> typ_error Parse_ast.Unknown ("No default order has been set")
+ | Some ord -> ord
+
+ let set_default_order o env =
+ match env.default_order with
+ | None -> { env with default_order = Some (Ord_aux (o, Parse_ast.Unknown)) }
+ | Some _ -> typ_error Parse_ast.Unknown ("Cannot change default order once already set")
+
+ let set_default_order_inc = set_default_order Ord_inc
+ let set_default_order_dec = set_default_order Ord_dec
+
end
type tannot = (Env.t * typ) option
@@ -753,7 +771,7 @@ let rec bind_pat env (P_aux (pat_aux, (l, _)) as pat) (Typ_aux (typ_aux, _) as t
| P_lit lit ->
begin
let lit_typ = infer_lit env lit in
- subtyp l env lit_typ typ;
+ subtyp l env lit_typ typ; (* CHECK: is the the correct way round? *)
annot_pat (P_lit lit) typ, env
end
| _ -> typ_error l ("Unhandled pat " ^ string_of_pat pat)
@@ -958,7 +976,7 @@ let check_fundef env (FD_aux (FD_function (recopt, tannotopt, effectopt, funcls)
(* Checking a val spec simply adds the type as a binding in the
context. We have to destructure the various kinds of val specs, but
- the difference is irrelvant for the typechecker. *)
+ the difference is irrelevant for the typechecker. *)
let check_val_spec env (VS_aux (vs, (l, _))) =
let (id, quants, typ) = match vs with
| VS_val_spec (TypSchm_aux (TypSchm_ts (quants, typ), _), id) -> (id, quants, typ)
@@ -966,6 +984,15 @@ let check_val_spec env (VS_aux (vs, (l, _))) =
| VS_extern_spec (TypSchm_aux (TypSchm_ts (quants, typ), _), id, _) -> (id, quants, typ) in
DEF_spec (VS_aux (vs, (l, None))), Env.add_val_spec id (quants, typ) env
+let check_default env (DT_aux (ds, l)) =
+ match ds with
+ | DT_kind _ -> DEF_default (DT_aux (ds,l)), env
+ | DT_order (Ord_aux (Ord_inc, _)) -> DEF_default (DT_aux (ds, l)), Env.set_default_order_inc env
+ | DT_order (Ord_aux (Ord_dec, _)) -> DEF_default (DT_aux (ds, l)), Env.set_default_order_dec env
+ | DT_order (Ord_aux (Ord_var _, _)) -> typ_error l "Cannot have variable default order"
+ (* This branch allows us to write something like: default forall Nat 'n. [|'n|] name... what does this even mean?! *)
+ | DT_typ (typschm, id) -> typ_error l ("Unsupported default construct")
+
let rec check_def env def =
let cd_err () = raise (Reporting_basic.err_unreachable Parse_ast.Unknown "Unimplemented Case") in
match def with
@@ -974,7 +1001,7 @@ let rec check_def env def =
| DEF_fundef fdef -> check_fundef env fdef, env
| DEF_val letdef -> cd_err ()
| DEF_spec vs -> check_val_spec env vs
- | DEF_default default -> cd_err ()
+ | DEF_default default -> check_default env default
| DEF_reg_dec(DEC_aux(DEC_reg(typ,id), (l,annot))) -> cd_err ()
| DEF_reg_dec(DEC_aux(DEC_alias(id,aspec), (l,annot))) -> cd_err ()
| DEF_reg_dec(DEC_aux(DEC_typ_alias(typ,id,aspec),(l,tannot))) -> cd_err ()
diff --git a/test/typecheck/fail/default_order.sail b/test/typecheck/fail/default_order.sail
new file mode 100644
index 00000000..8de5cc46
--- /dev/null
+++ b/test/typecheck/fail/default_order.sail
@@ -0,0 +1,6 @@
+(* Could make an argument for why this should be ok, but allowing
+default order to change could have unintended consequences if we arn't
+careful, so it seems safer to just forbid it *)
+
+default Order dec
+default Order inc
diff --git a/test/typecheck/pass/default_order.sail b/test/typecheck/pass/default_order.sail
new file mode 100644
index 00000000..a283b221
--- /dev/null
+++ b/test/typecheck/pass/default_order.sail
@@ -0,0 +1 @@
+default Order dec