diff options
| author | Jon French | 2017-07-21 20:33:31 +0100 |
|---|---|---|
| committer | Jon French | 2017-07-24 18:24:05 +0100 |
| commit | aa08c004b613d11b4e3d6b8909c06eec5cee5b86 (patch) | |
| tree | 3ddedbb8699cf1291c24c5f2290e113750d241cc /language/l2.ott | |
| parent | e609a9ead0505ffcf824177d211d43d685b7c08f (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.ott | 432 |
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 }} |
