summaryrefslogtreecommitdiff
path: root/language/l2.ott
diff options
context:
space:
mode:
authorJon French2017-07-21 20:33:31 +0100
committerJon French2017-07-24 18:24:05 +0100
commitaa08c004b613d11b4e3d6b8909c06eec5cee5b86 (patch)
tree3ddedbb8699cf1291c24c5f2290e113750d241cc /language/l2.ott
parente609a9ead0505ffcf824177d211d43d685b7c08f (diff)
move value type definitions to ott, and introduce new E_internal_value ast node for passing around encapsulated evaluated values; change Interp.to_exp to now just wrap values in this node
Diffstat (limited to 'language/l2.ott')
-rw-r--r--language/l2.ott432
1 files changed, 431 insertions, 1 deletions
diff --git a/language/l2.ott b/language/l2.ott
index 803472a8..c78c66f8 100644
--- a/language/l2.ott
+++ b/language/l2.ott
@@ -10,6 +10,11 @@ metavar num,numZero,numOne ::=
{{ lem integer }}
{{ com Numeric literals }}
+metavar nat ::=
+ {{ phantom }}
+ {{ lex numeric }}
+ {{ lem nat }}
+
metavar hex ::=
{{ phantom }}
{{ lex numeric }}
@@ -47,6 +52,8 @@ type 'a annot = l * 'a
embed
{{ lem
+open import Pervasives
+open import Pervasives_extra
open import Map
open import Maybe
open import Set_extra
@@ -545,12 +552,405 @@ P_app <= P_app
P_app <= P_as
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Machinery for typing rules %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+embed
+{{ lem
+
+let rec remove_one i l =
+ match l with
+ | [] -> []
+ | i2::l2 -> if i2 = i then l2 else i2::(remove_one i l2)
+end
+
+let rec remove_from l l2 =
+ match l2 with
+ | [] -> l
+ | i::l2' -> remove_from (remove_one i l) l2'
+end
+
+let disjoint s1 s2 = Set.null (s1 inter s2)
+
+let rec disjoint_all sets =
+ match sets with
+ | [] -> true
+ | s1::[] -> true
+ | s1::s2::sets -> (disjoint s1 s2) && (disjoint_all (s2::sets))
+end
+}}
+
+
+grammar
+
+k :: 'Ki_' ::=
+{{ com Internal kinds }}
+ | K_Typ :: :: typ
+ | K_Nat :: :: nat
+ | K_Ord :: :: ord
+ | K_Efct :: :: efct
+ | K_Lam ( k0 .. kn -> k' ) :: :: ctor
+ | K_infer :: :: infer {{ com Representing an unknown kind, inferred by context }}
+
+t , u :: 'T_' ::=
+{{ com Internal types }}
+ | x :: :: id
+ | ' x :: :: var
+ | t1 -> t2 effect :: :: fn
+ | ( t1 , .... , tn ) :: :: tup
+ | x < t_args > :: :: app
+ | t |-> t1 :: :: abbrev
+ | register < t_arg > :: S :: reg_app {{ ichlo T_app "register" [[t_arg]] }}
+ | range < ne ne' > :: S :: range_app {{ ichlo T_app "range" [[ [ ne ; ne' ] ]] }}
+ | atom < ne > :: S :: atom_app {{ ichlo T_app "atom" [ [[ne]] ] }}
+ | vector < ne ne' order t > :: S :: vector_app {{ ichlo T_app "vector" [[ [ ne; ne'; ord; t ] ]] }}
+ | list < t > :: S :: list_app {{ ichlo T_app "list" [[t]] }}
+ | reg < t > :: S :: box_app {{ ichlo T_app "reg" [[t]] }}
+ | implicit < ne > :: S :: implicit_app {{ ichlo T_app "implicit" [[ne]] }}
+ | bit :: S :: bit_typ {{ ichlo T_id "bit" }}
+ | string :: S :: string_typ {{ ichlo T_id "string" }}
+ | unit :: S :: unit_typ {{ ichlo T_id "unit" }}
+ | t [ t_arg1 / tid1 .. t_argn / tidn ] :: M :: subst {{ ichlo "todo" }}
+
+optx :: '' ::= {{ phantom }} {{ lem maybe string }} {{ ocaml string option }}
+ | x :: :: optx_x
+ {{ lem (Just [[x]]) }} {{ ocaml (Some [[x]]) }}
+ | :: :: optx_none
+ {{ lem Nothing }} {{ ocaml None }}
+
+
+tag :: 'Tag_' ::=
+{{ com Data indicating where the identifier arises and thus information necessary in compilation }}
+ | None :: :: empty
+ | Intro :: :: intro {{ com Denotes an assignment and lexp that introduces a binding }}
+ | Set :: :: set {{ com Denotes an expression that mutates a local variable }}
+ | Tuple :: :: tuple_assign {{ com Denotes an assignment with a tuple lexp }}
+ | Global :: :: global {{ com Globally let-bound or enumeration based value/variable }}
+ | Ctor :: :: ctor {{ com Data constructor from a type union }}
+ | Extern optx :: :: extern {{ com External function, specied only with a val statement }}
+ | Default :: :: default {{ com Type has come from default declaration, identifier may not be bound locally }}
+ | Spec :: :: spec
+ | Enum num :: :: enum
+ | Alias :: :: alias
+ | Unknown_path optx :: :: unknown {{ com Tag to distinguish an unknown path from a non-analysis non deterministic path}}
+
+ne :: 'Ne_' ::=
+ {{ com internal numeric expressions }}
+ | x :: :: id
+ | ' x :: :: var
+ | num :: :: const
+ | infinity :: :: inf
+ | ne1 * ne2 :: :: mult
+ | ne1 + ... + nen :: :: add
+ | ne1 - ne2 :: :: minus
+ | 2 ** ne :: :: exp
+ | ( - ne ) :: :: unary
+ | zero :: S :: zero
+ {{ ichlo (Ne_const 0) }}
+ | one :: S :: one
+ {{ ichlo (Ne_const 1) }}
+ | bitlength ( bin ) :: M :: cbin
+ {{ ocaml (asssert false) }}
+ {{ hol ARB }}
+ {{ lem (blength [[bin]]) }}
+ | bitlength ( hex ) :: M :: chex
+ {{ ocaml (assert false) }}
+ {{ hol ARB }}
+ {{ lem (hlength [[hex]]) }}
+ | count ( num0 ... numi ) :: M :: length {{ichlo "todo" }}
+ | length ( pat1 ... patn ) :: M :: cpat
+ {{ ocaml (assert false) }}
+ {{ hol ARB }}
+ {{ lem (Ne_const (List.length [[pat1...patn]])) }}
+ | length ( exp1 ... expn ) :: M :: cexp
+ {{ hol ARB }}
+ {{ ocaml (assert false) }}
+ {{ lem (Ne_const (List.length [[exp1...expn]])) }}
+
+ t_arg :: 't_arg_' ::=
+ {{ com Argument to type constructors }}
+ | t :: :: typ
+ | ne :: :: nexp
+ | effect :: :: effect
+ | order :: :: order
+ | fresh :: M :: freshvar {{ ichlo T_arg (T_var "fresh") }}
+
+ t_args :: '' ::= {{ lem list t_arg }}
+ {{ com Arguments to type constructors }}
+ | t_arg1 ... t_argn :: :: T_args
+
+ nec :: 'Nec_' ::=
+ {{ com Numeric expression constraints }}
+ | ne <= ne' :: :: lteq
+ | ne = ne' :: :: eq
+ | ne >= ne' :: :: gteq
+ | ' x 'IN' { num1 , ... , numn } :: :: in
+ | nec0 .. necn -> nec'0 ... nec'm :: :: cond
+ | nec0 ... necn :: :: branch
+
+S_N {{ tex {\Sigma^{\textsc{N} } } }} :: '' ::= {{ phantom }}
+ {{ hol nec list }}
+ {{ lem list nec }}
+ {{ com nexp constraint lists }}
+ | { nec1 , .. , necn } :: :: Sn_concrete
+ {{ hol [[nec1 .. necn]] }}
+ {{ lem [[nec1 .. necn]] }}
+ | S_N1 u+ .. u+ S_Nn :: M :: SN_union
+ {{ hol (FOLDR FUNION FEMPTY [[S_N1..S_Nn]]) }}
+ {{ lem (List.foldr (++) [] [[S_N1..S_Nn]]) }}
+ {{ ocaml (assert false) }}
+ | consistent_increase ne1 ne'1 ... nen ne'n :: M :: SN_increasing
+ {{ com Generates constraints from pairs of constraints, where the first of each pair is always larger than the sum of the previous pair }}
+ {{ ocaml (assert false) }}
+ {{ ichl todo }}
+ | consistent_decrease ne1 ne'1 ... nen ne'n :: M :: SN_decreasing
+ {{ com Generates constraints from pairs of constraints, where the first of each pair is always smaller than the difference of the previous pair }}
+ {{ ocaml assert false }}
+ {{ ichl todo }}
+ | resolve ( S_N ) :: :: resolution
+ {{ lem [[S_N]] (* Write constraint solver *) }}
+
+
+ E_d {{ tex {\ottnt{E}^{\textsc{d} } } }} :: 'E_d_' ::= {{ phantom }}
+ {{ lem definition_env }}
+ {{ com Environments storing top level information, such as defined abbreviations, records, enumerations, and kinds }}
+ | < E_k , E_a , E_r , E_e > :: :: base
+ {{ hol arb }}
+ {{ lem (Denv [[E_k]] [[E_r]] [[E_e]]) }}
+ | empty :: :: empty
+ {{ hol arb }}
+ {{ lem DenvEmp }}
+ | E_d u+ E_d' :: :: union
+ {{ hol arb }}
+ {{ lem (denv_union [[E_d]] [[E_d']]) }}
+
+ kinf :: 'kinf_' ::=
+ {{ com Whether a kind is default or from a local binding }}
+ | k :: :: k
+ | k default :: :: def
+
+ tid :: 'tid_' ::=
+ {{ com A type identifier or type variable }}
+ | id :: :: id
+ | kid :: :: var
+
+ E_k {{ tex {\ottnt{E}^{\textsc{k} } } }} :: 'E_k_' ::= {{ phantom }}
+ {{ hol (tid-> kinf) }}
+ {{ lem (map tid kinf) }}
+ {{ com Kind environments }}
+ | { tid1 |-> kinf1 , .. , tidn |-> kinfn } :: :: concrete
+ {{ hol (FOLDR (\(k1,k2) E. E |+ (k1,k2)) FEMPTY [[tid1 kinf1 .. tidn kinfn]]) }}
+ {{ lem (List.foldr (fun (x,v) m -> Map.insert x v m) Map.empty [[tid1 kinf1 .. tidn kinfn]]) }}
+ | E_k1 u+ .. u+ E_kn :: M :: union
+ {{ com In a unioning kinf, {k default} u {k} results in {k} (i.e. the default is locally forgotten) }}
+ {{ hol (FOLDR FUNION FEMPTY [[E_k1..E_kn]]) }}
+ {{ lem (List.foldr (union) Map.empty [[E_k1..E_kn]]) }}
+ {{ ocaml (assert false) }}
+ | E_k u- E_k1 .. E_kn :: M :: multi_set_minus
+ {{ hol arb }}
+ {{ lem (Map.fromList (remove_from (Set_extra.toList (Map.toSet [[E_k]]))
+ (Set_extra.toList (Map.toSet (List.foldr (union) Map.empty [[E_k1..E_kn]]))))) }}
+ {{ ocaml assert false }}
+
+ tinf :: 'tinf_' ::=
+ {{ com Type variables, type, and constraints, bound to an identifier }}
+ | t :: :: typ
+ | E_k , S_N , tag , t :: :: quant_typ
+
+tinflist :: 'tinfs_' ::=
+ {{ com In place so that a list of tinfs can be referred to without the dot form }}
+ | empty :: :: empty
+ | tinf1 ... tinfn :: :: ls
+
+conformsto :: 'conformsto_' ::=
+ {{ com how much conformance does overloading need }}
+ | full :: :: full
+ | parm :: :: parm
+
+widenvec :: 'widenvec_' ::=
+ | vectors :: :: widen
+ | none :: :: dont
+ | _ :: :: dontcare
+
+widennum :: 'widennum_' ::=
+ | nums :: :: widen
+ | none :: :: dont
+ | _ :: :: dontcare
+
+widening :: 'widening_' ::=
+ {{ com Should we widen vector start locations, should we widen atoms and ranges }}
+ | ( widennum , widenvec ) :: :: w
+
+ E_a {{ tex \ottnt{E}^{\textsc{a} } }} :: 'E_a_' ::= {{ phantom }}
+ {{ hol tid |-> tinf}}
+ {{ lem map tid tinf }}
+ | { tid1 |-> tinf1 , .. , tidn |-> tinfn } :: :: concrete
+ | E_a1 u+ .. u+ E_an :: :: union
+
+ field_typs :: 'FT_' ::= {{ phantom }}
+ {{ lem list (id * t) }}
+ {{ com Record fields }}
+ | id1 : t1 , .. , idn : tn :: :: fields
+ {{ lem [[id1 t1..idn tn]] }}
+
+ E_r {{ tex \ottnt{E}^{\textsc{r} } }} :: 'E_r_' ::= {{ phantom }}
+ {{ hol (id*t) |-> tinf) }}
+ {{ lem map (list (id*t)) tinf }}
+ {{ com Record environments }}
+ | { { field_typs1 } |-> tinf1 , .. , { field_typsn } |-> tinfn } :: :: concrete
+ {{ hol (FOLDR (\x E. E |+ x) FEMPTY) }}
+ {{ lem (List.foldr (fun (x,f) m -> Map.insert x f m) Map.empty [[field_typs1 tinf1..field_typsn tinfn]]) }}
+ | E_r1 u+ .. u+ E_rn :: M :: union
+ {{ hol (FOLDR FUNION FEMPTY [[E_r1..E_rn]]) }}
+ {{ lem (List.foldr (union) Map.empty [[E_r1..E_rn]]) }}
+ {{ ocaml (assert false) }}
+
+ enumerate_map :: '' ::= {{ phantom }}
+ {{ lem (list (nat*id)) }}
+ | { num1 |-> id1 ... numn |-> idn } :: :: enum_map
+ {{ lem [[num1 id1...numn idn]] }}
+
+ E_e {{ tex \ottnt{E}^{\textsc{e} } }} :: 'E_e_' ::= {{ phantom }}
+ {{ lem (map t (list (nat*id))) }}
+ {{ com Enumeration environments }}
+ | { t1 |-> enumerate_map1 , .. , tn |-> enumerate_mapn } :: :: base
+ {{ lem (List.foldr (fun (x,f) m -> Map.insert x f m) Map.empty [[t1 enumerate_map1..tn enumerate_mapn]]) }}
+ | E_e1 u+ .. u+ E_en :: :: union
+ {{ lem (List.foldr (union) Map.empty [[E_e1..E_en]]) }}
+
+
+embed
+{{ lem
+ type definition_env =
+ | DenvEmp
+ | Denv of (map tid kinf) * (map (list (id*t)) tinf) * (map t (list (nat*id)))
+
+}}
+
+grammar
+
+ E_t {{ tex {\ottnt{E}^{\textsc{t} } } }} :: 'E_t_' ::= {{ phantom }}
+ {{ hol (id |-> tinf) }}
+ {{ lem map id tinf }}
+ {{ com Type environments }}
+ | { id1 |-> tinf1 , .. , idn |-> tinfn } :: :: base
+ {{ hol (FOLDR (\x E. E |+ x) FEMPTY [[id1 tinf1 .. idn tinfn]]) }}
+ {{ lem (List.foldr (fun (x,f) m -> Map.insert x f m) Map.empty [[id1 tinf1 .. idn tinfn]]) }}
+ | { id |-> overload tinf conformsto : tinf1 , ... , tinfn } :: :: overload
+ | ( E_t1 u+ .... u+ E_tn ) :: M :: union
+ {{ hol (FOLDR FUNION FEMPTY [[E_t1....E_tn]]) }}
+ {{ lem (List.foldr (union) Map.empty [[E_t1....E_tn]]) }}
+ {{ ocaml (assert false) }}
+ | u+ E_t1 .. E_tn :: M :: multi_union
+ {{ hol arb }}
+ {{ lem (List.foldr (union) Map.empty [[E_t1..E_tn]]) }}
+ {{ ocaml assert false }}
+ | E_t u- id1 .. idn :: M :: multi_set_minus
+ {{ hol arb }}
+ {{ lem (Map.fromList (remove_from (Set_extra.toList (Map.toSet [[E_t]]))
+ (Set_extra.toList (Map.toSet (List.foldr (union) Map.empty [[id1..idn]]))))) }}
+ {{ ocaml assert false }}
+ | ( E_t1 inter .... inter E_tn ) :: M :: intersect
+ {{ hol arb }}
+ {{ lem (List.foldr (fun a b -> (Map.fromList (Set_extra.toList ((Map.toSet a) inter (Map.toSet b))))) Map.empty [[E_t1....E_tn]]) }}
+ {{ ocaml (assert false) }}
+ | inter E_t1 .. E_tn :: M :: multi_inter
+ {{ hol arb }}
+ {{ lem (List.foldr (fun a b -> (Map.fromList (Set_extra.toList ((Map.toSet a) inter (Map.toSet b))))) Map.empty [[E_t1..E_tn]]) }}
+ {{ ocaml assert false }}
+
+
+ts :: ts_ ::= {{ phantom }}
+ {{ lem list t }}
+ | t1 , .. , tn :: :: lst
+
+embed
+{{ lem
+let blength (bit) = Ne_const 8
+let hlength (bit) = Ne_const 8
+
+ type env =
+ | EnvEmp
+ | Env of (map id tinf) * definition_env
+
+ type inf =
+ | Iemp
+ | Inf of (list nec) * effect
+
+ val denv_union : definition_env -> definition_env -> definition_env
+ let denv_union de1 de2 =
+ match (de1,de2) with
+ | (DenvEmp,de2) -> de2
+ | (de1,DenvEmp) -> de1
+ | ((Denv ke1 re1 ee1),(Denv ke2 re2 ee2)) ->
+ Denv (ke1 union ke2) (re1 union re2) (ee1 union ee2)
+ end
+
+ val env_union : env -> env -> env
+ let env_union e1 e2 =
+ match (e1,e2) with
+ | (EnvEmp,e2) -> e2
+ | (e1,EnvEmp) -> e1
+ | ((Env te1 de1),(Env te2 de2)) ->
+ Env (te1 union te2) (denv_union de1 de2)
+ end
+
+let inf_union i1 i2 =
+ match (i1,i2) with
+ | (Iemp,i2) -> i2
+ | (i1,Iemp) -> i1
+ | (Inf n1 e1,Inf n2 e2) -> (Inf (n1++n2) (effect_union e1 e2))
+ end
+
+let fresh_kid denv = Var "x" (*TODO When strings can be manipulated, this should actually build a fresh string*)
+
+}}
+
+grammar
+
+ E :: '' ::=
+ {{ hol ((string,env_body) fmaptree) }}
+ {{ lem env }}
+ {{ com Definition environment and lexical environment }}
+ | < E_t , E_d > :: :: E
+ {{ hol arb }}
+ {{ lem (Env [[E_t]] [[E_d]]) }}
+ | empty :: M :: E_empty
+ {{ hol arb }}
+ {{ lem EnvEmp }}
+ {{ ocaml assert false }}
+ | E u+ E' :: :: E_union
+ {{ lem (env_union [[E]] [[E']]) }}
+
+ I :: '' ::= {{ lem inf }}
+ {{ com Information given by type checking an expression }}
+ | < S_N , effect > :: :: I
+ {{ lem (Inf [[S_N]] [[effect]]) }}
+ | Ie :: :: Iempty {{ com Empty constraints, effect }} {{ tex {\ottnt{I}_{\epsilon} } }}
+ {{ lem Iemp }}
+ | ( I1 u+ I2 ) :: :: singleunion {{ tex [[I1]] [[u+]] [[I2]] }}
+ | I1 u+ .. u+ In :: :: Iunion {{ com Unions the constraints and effect }}
+ {{ lem (List.foldr inf_union Iemp [[I1..In]]) }}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Expressions %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+embed
+{{ lem
+
+type tannot = maybe (t * tag * list nec * effect * effect)
+}}
grammar
+tannot :: '' ::=
+ {{ phantom }}
+ {{ ocaml tannot }}
+ {{ lem tannot }}
+
+
exp :: 'E_' ::=
{{ com expression }}
@@ -689,7 +1089,37 @@ exp :: 'E_' ::=
| let lexp = exp in exp' :: I :: internal_let {{ com This is an internal node for compilation that demonstrates the scope of a local mutable variable }}
| let pat = exp in exp' :: I :: internal_plet {{ com This is an internal node, used to distinguised some introduced lets during processing from original ones }}
| return_int ( exp ) :: I :: internal_return {{ com For internal use to embed into monad definition }}
-
+ | value :: I :: internal_value {{ com For internal use in interpreter to wrap pre-evaluated values when returning an action }}
+
+i_direction :: 'I' ::=
+ | IInc :: :: Inc
+ | IDec :: :: Dec
+
+ctor_kind :: 'C_' ::=
+ | C_Enum nat :: :: Enum
+ | C_Union :: :: Union
+
+reg_form :: 'Form_' ::=
+ | Reg id tannot i_direction :: :: Reg
+ | SubReg id reg_form index_range :: :: SubReg
+
+reg_form_set :: '' ::= {{ phantom }} {{ lem set reg_form }}
+
+alias_spec_tannot :: '' ::= {{ phantom }} {{ lem alias_spec tannot }} {{ ocaml tannot alias_spec }}
+
+value :: 'V_' ::= {{ com interpreter evaluated value }}
+ | Boxref nat t :: :: boxref
+ | Lit lit :: :: lit
+ | Tuple ( value1 , ... , valuen ) :: :: tuple
+ | List ( value1 , ... , valuen ) :: :: list
+ | Vector nat i_direction ( value1 , ... , valuen ) :: :: vector
+ | Vector_sparse nat' nat'' i_direction ( nat1 value1 , ... , natn valuen ) value' :: :: vector_sparse
+ | Record t ( id1 value1 , ... , idn valuen ) :: :: record
+ | V_ctor id t ctor_kind value1 :: :: ctor
+ | Unknown :: :: unknown
+ | Register reg_form :: :: register
+ | Register_alias alias_spec_tannot tannot :: :: register_alias
+ | Track value reg_form_set :: :: track
lexp :: 'LEXP_' ::= {{ com lvalue expression }}
{{ aux _ annot }} {{ auxparam 'a }}