diff --git a/interpreter/binary/decode.ml b/interpreter/binary/decode.ml index 433b092ed9..f817ff2606 100644 --- a/interpreter/binary/decode.ml +++ b/interpreter/binary/decode.ml @@ -920,6 +920,7 @@ let rec instr s = | 0xebl -> f32x4_pmax | 0xecl -> f64x2_abs | 0xedl -> f64x2_neg + | 0xeel as n -> illegal s pos (I32.to_int_u n) | 0xefl -> f64x2_sqrt | 0xf0l -> f64x2_add | 0xf1l -> f64x2_sub diff --git a/specification/wasm-3.0/6.1-text.values.spectec b/specification/wasm-3.0/6.1-text.values.spectec index 9965f70c73..09b6bbd2ea 100644 --- a/specification/wasm-3.0/6.1-text.values.spectec +++ b/specification/wasm-3.0/6.1-text.values.spectec @@ -153,7 +153,7 @@ syntax I = idctxt def $concat_idctxt(idctxt*) : idctxt hint(show (++) %) def $concat_idctxt(eps) = {} -def $concat_idctxt(I I') = I ++ $concat_idctxt(I'*) +def $concat_idctxt(I I'*) = I ++ $concat_idctxt(I'*) relation Idctxt_ok: |- idctxt : OK diff --git a/specification/wasm-3.0/6.3-text.modules.spectec b/specification/wasm-3.0/6.4-text.modules.spectec similarity index 98% rename from specification/wasm-3.0/6.3-text.modules.spectec rename to specification/wasm-3.0/6.4-text.modules.spectec index 48e877ad89..3dac9343b6 100644 --- a/specification/wasm-3.0/6.3-text.modules.spectec +++ b/specification/wasm-3.0/6.4-text.modules.spectec @@ -56,7 +56,7 @@ grammar Tlocal_(I)/plain : (local*, idctxt) = | ... grammar Tlocal_(I)/abbrev : (local*, idctxt) = - ... | "(" "local" t:Tvaltype_(I)* ")" == ("(" "local" t:Tvaltype_(I) ")")* + ... | "(" "local" Tvaltype_(I)* ")" == ("(" "local" Tvaltype_(I) ")")* ;; Data segments @@ -97,8 +97,8 @@ grammar Telem_(I)/plain : (elem, idctxt) = | ... grammar Telem_(I)/abbrev : (elem, idctxt) = ... - | "(" "elem" e':Toffset_(I) Tlist(Tfuncidx_(I)) ")" == - "(" "elem" e':Toffset_(I) "func" Tlist(Tfuncidx_(I)) ")" + | "(" "elem" Toffset_(I) Tlist(Tfuncidx_(I)) ")" == + "(" "elem" Toffset_(I) "func" Tlist(Tfuncidx_(I)) ")" grammar Telemlist_(I)/plain : (reftype, expr*) = | rt:Treftype_(I) e*:Tlist(Texpr_(I)) => (rt, e*) diff --git a/spectec/doc/Language.md b/spectec/doc/Language.md index b26cee6e9f..24fd7b6ceb 100644 --- a/spectec/doc/Language.md +++ b/spectec/doc/Language.md @@ -1547,7 +1547,7 @@ params ::= ("(" param*"," ")")? param ::= (varid ":") typ "syntax" synid - "grammar" gramid ":" typ + "grammar" gramid params ":" typ "def" "$" defid params ":" typ def ::= diff --git a/spectec/src/al/al_util.ml b/spectec/src/al/al_util.ml index 9d2e79495a..59bb296edd 100644 --- a/spectec/src/al/al_util.ml +++ b/spectec/src/al/al_util.ml @@ -298,21 +298,13 @@ let atom_of_atom' atom' typ = atom' $$ no_region % (Atom.info typ) let frame_atom = atom_of_name "FRAME_" "evalctx" let frameE ?(at = no) ~note (arity, e) = - let frame_mixop = [[frame_atom]; [atom_of_atom' Atom.LBrace "evalctx"]; [atom_of_atom' Atom.RBrace "evalctx"]] in + let frame_mixop = Mixop.(Seq [Atom frame_atom; Brack (atom_of_atom' Atom.LBrace "evalctx", Arg (), atom_of_atom' Atom.RBrace "evalctx")]) in caseE (frame_mixop, [arity; e]) ~at:at ~note:note - -let get_atom op = - match List.find_opt (fun al -> al <> []) op with - | Some al -> Some (List.hd al) - | None -> None - -let name_of_mixop = Mixop.name - (* Il Types *) (* name for tuple type *) -let no_name = Il.Ast.VarE ("_" $ no_region) $$ no_region % (Il.Ast.TextT $ no_region) +let no_name = "_" $ no_region let varT id args = Il.Ast.VarT (id $ no_region, args) $ no_region let iterT ty iter = Il.Ast.IterT (ty, iter) $ no_region let listT ty = iterT ty Il.Ast.List diff --git a/spectec/src/al/ast.ml b/spectec/src/al/ast.ml index 1f51f2b4eb..53ef0a2ee0 100644 --- a/spectec/src/al/ast.ml +++ b/spectec/src/al/ast.ml @@ -4,7 +4,7 @@ open Xl (* Terminals *) type atom = Atom.atom -type mixop = Mixop.mixop +type mixop = unit Mixop.mixop (* Types *) diff --git a/spectec/src/al/print.ml b/spectec/src/al/print.ml index 19077d84c0..4d8ff82fd2 100644 --- a/spectec/src/al/print.ml +++ b/spectec/src/al/print.ml @@ -152,11 +152,11 @@ and string_of_expr expr = | VarE id -> id | SubE (id, _) -> id | IterE (e, ie) -> string_of_expr e ^ string_of_iterexp ie - | CaseE ([{ it=Atom.Atom ("CONST" | "VCONST"); _ }]::_tl, hd::tl) -> + | CaseE (Mixop.(Seq (Atom { it=Atom.Atom ("CONST" | "VCONST"); _ }::_tl)), hd::tl) -> "(" ^ string_of_expr hd ^ ".CONST " ^ string_of_exprs " " tl ^ ")" - | CaseE ([[ atom ]], []) -> string_of_atom atom + | CaseE (Mixop.Atom atom, []) -> string_of_atom atom | CaseE (op, el) -> - let op' = List.map (fun al -> String.concat "" (List.map string_of_atom al)) op in + let op' = List.map (fun al -> String.concat "" (List.map string_of_atom al)) (Mixop.flatten op) in (match op' with | [] -> "()" | _::tl when List.length tl != List.length el -> diff --git a/spectec/src/al/valid.ml b/spectec/src/al/valid.ml index a6d5cc61b0..fe90248c01 100644 --- a/spectec/src/al/valid.ml +++ b/spectec/src/al/valid.ml @@ -68,7 +68,10 @@ let il_env: IlEnv.t ref = ref IlEnv.empty let varT s = VarT (s $ no_region, []) $ no_region -let is_trivial_mixop = List.for_all (fun atoms -> List.length atoms = 0) +let rec is_trivial_mixop = function + | Mixop.Arg () -> true + | Mixop.Seq mixops -> List.for_all is_trivial_mixop mixops + | _ -> false (* Subtyping *) @@ -128,7 +131,7 @@ let rec unify_deftyp_opt (deftyp: deftyp) : typ option = | StructT _ -> None | VariantT typcases when List.for_all (fun (mixop', _, _) -> is_trivial_mixop mixop') typcases -> - typcases |> List.map (fun (_mixop, (_bs, typ, _ps), _hs) -> typ) |> unify_typs_opt + typcases |> List.map (fun (_mixop, (typ, _qs, _ps), _hs) -> typ) |> unify_typs_opt | _ -> None and unify_deftyps_opt : deftyp list -> typ option = function @@ -226,7 +229,7 @@ let rec get_typfields_of_inst (inst: inst) : typfield list = match dt.it with | StructT typfields -> typfields | AliasT typ -> get_typfields typ - | VariantT [mixop, (_, typ, _), _] when is_trivial_mixop mixop -> + | VariantT [mixop, (typ, _, _), _] when is_trivial_mixop mixop -> get_typfields typ (* TODO: some variants of struct type *) | VariantT _ -> [] @@ -279,7 +282,7 @@ let check_evalctx source typ = | _ -> error_mismatch source typ (varT "evalctx") let check_field source source_typ expr_record typfield = - let atom, (_, typ, _), _ = typfield in + let atom, (typ, _, _), _ = typfield in (* TODO: Use record api *) let f e = e |> fst |> Atom.eq atom in match List.find_opt f expr_record with @@ -402,7 +405,7 @@ let check_inv_call source id indices args result_typ = | _ -> let arg2typ arg = ( match arg.it with - | ExpA exp -> (Il.Ast.VarE ("" $ no_region) $$ no_region % exp.note, exp.note) + | ExpA exp -> ("_" $ no_region, exp.note) | a -> error_valid (Printf.sprintf "wrong result argument") source (Print.string_of_arg (a $ no_region)) ) in @@ -443,7 +446,7 @@ let access (source: source) (typ: typ) (path: path) : typ = | DotP atom -> let typfields = get_typfields typ in match List.find_opt (fun (field, _, _) -> Atom.eq field atom) typfields with - | Some (_, (_, typ', _), _) -> typ' + | Some (_, (typ', _, _), _) -> typ' | None -> error_field source typ atom @@ -555,20 +558,20 @@ and valid_expr env (expr: expr) : unit = | CaseE (op, exprs) -> let is_evalctx_id id = let evalctx_ids = List.filter_map (fun (mixop, _, _) -> - let atom = mixop |> List.hd |> List.hd in + let atom = Mixop.flatten mixop |> List.hd |> List.hd in match atom.it with | Atom.Atom s -> Some s | _ -> None ) (get_typcases source evalctxT) in List.mem id evalctx_ids in - (match op with + (match Mixop.flatten op with | [[{ it=Atom id; _ }]] when is_evalctx_id id -> check_case source exprs (TupT [] $ no_region) | _ -> List.iter (valid_expr env) exprs; let tcs = get_typcases source expr.note in - let _binds, typ, _prems = find_case source tcs op in + let typ, _qs, _prems = find_case source tcs op in check_case source exprs typ; ) | CallE (id, args) -> diff --git a/spectec/src/backend-ast/print.ml b/spectec/src/backend-ast/print.ml index 3f853328d9..924e6901bf 100644 --- a/spectec/src/backend-ast/print.ml +++ b/spectec/src/backend-ast/print.ml @@ -11,10 +11,7 @@ open Ast let bool b = Atom (Bool.to_string b) let text t = Atom ("\"" ^ String.escaped t ^ "\"") let id x = text x.it -let mixop op = - String.concat "%" (List.map ( - fun ats -> String.concat "" (List.map Atom.to_string ats)) op - ) |> text +let mixop op = text (Mixop.to_string op) let num = function | `Nat n -> Node ("nat", [Atom (Z.to_string n)]) @@ -86,14 +83,14 @@ and deftyp dt = | StructT tfs -> Node ("struct", List.map typfield tfs) | VariantT tcs -> Node ("variant", List.map typcase tcs) -and typbind (e, t) = - Node ("bind", [exp e; typ t]) +and typbind (x, t) = + Node ("bind", [id x; typ t]) -and typfield (at, (bs, t, prs), _hints) = - Node ("field", mixop [[at]] :: List.map bind bs @ typ t :: List.map prem prs) +and typfield (at, (t, qs, prs), _hints) = + Node ("field", mixop (Mixop.Atom at) :: typ t :: List.map param qs @ List.map prem prs) -and typcase (op, (bs, t, prs), _hints) = - Node ("case", mixop op :: List.map bind bs @ typ t :: List.map prem prs) +and typcase (op, (t, qs, prs), _hints) = + Node ("case", mixop op :: typ t :: List.map param qs @ List.map prem prs) (* Expressions *) @@ -112,7 +109,7 @@ and exp e = | UpdE (e1, p, e2) -> Node ("upd", [exp e1; path p; exp e2]) | ExtE (e1, p, e2) -> Node ("ext", [exp e1; path p; exp e2]) | StrE efs -> Node ("struct", List.map expfield efs) - | DotE (e1, at) -> Node ("dot", [exp e1; mixop [[at]]]) + | DotE (e1, at) -> Node ("dot", [exp e1; mixop (Mixop.Atom at)]) | CompE (e1, e2) -> Node ("comp", [exp e1; exp e2]) | MemE (e1, e2) -> Node ("mem", [exp e1; exp e2]) | LenE e1 -> Node ("len", [exp e1]) @@ -131,14 +128,14 @@ and exp e = | SubE (e1, t1, t2) -> Node ("sub", [typ t1; typ t2; exp e1]) and expfield (at, e) = - Node ("field", [mixop [[at]]; exp e]) + Node ("field", [mixop (Mixop.Atom at); exp e]) and path p = match p.it with | RootP -> Atom "root" | IdxP (p1, e) -> Node ("idx", [path p1; exp e]) | SliceP (p1, e1, e2) -> Node ("slice", [path p1; exp e1; exp e2]) - | DotP (p1, at) -> Node ("dot", [path p1; mixop [[at]]]) + | DotP (p1, at) -> Node ("dot", [path p1; mixop (Mixop.Atom at)]) and iterexp (it, xes) = iter it :: List.map (fun (x, e) -> Node ("dom", [id x; exp e])) xes @@ -179,39 +176,32 @@ and arg a = | DefA x -> Node ("def", [id x]) | GramA g -> Node ("gram", [sym g]) -and bind bind = - match bind.it with - | ExpB (x, t) -> Node ("exp", [id x; typ t]) - | TypB x -> Node ("typ", [id x]) - | DefB (x, ps, t) -> Node ("def", [id x] @ List.map param ps @ [typ t]) - | GramB (x, ps, t) -> Node ("gram", [id x] @ List.map param ps @ [typ t]) - and param p = match p.it with | ExpP (x, t) -> Node ("exp", [id x; typ t]) | TypP x -> Node ("typ", [id x]) | DefP (x, ps, t) -> Node ("def", [id x] @ List.map param ps @ [typ t]) - | GramP (x, t) -> Node ("gram", [id x; typ t]) + | GramP (x, ps, t) -> Node ("gram", [id x] @ List.map param ps @ [typ t]) let inst inst = match inst.it with - | InstD (bs, as_, dt) -> - Node ("inst", List.map bind bs @ List.map arg as_ @ [deftyp dt]) + | InstD (ps, as_, dt) -> + Node ("inst", List.map param ps @ List.map arg as_ @ [deftyp dt]) let rule rule = match rule.it with - | RuleD (x, bs, op, e, prs) -> - Node ("rule", [id x] @ List.map bind bs @ [mixop op; exp e] @ List.map prem prs) + | RuleD (x, ps, op, e, prs) -> + Node ("rule", [id x] @ List.map param ps @ [mixop op; exp e] @ List.map prem prs) let clause clause = match clause.it with - | DefD (bs, as_, e, prs) -> - Node ("clause", List.map bind bs @ List.map arg as_ @ [exp e] @ List.map prem prs) + | DefD (ps, as_, e, prs) -> + Node ("clause", List.map param ps @ List.map arg as_ @ [exp e] @ List.map prem prs) let prod prod = match prod.it with - | ProdD (bs, g, e, prs) -> - Node ("prod", List.map bind bs @ [sym g; exp e] @ List.map prem prs) + | ProdD (ps, g, e, prs) -> + Node ("prod", List.map param ps @ [sym g; exp e] @ List.map prem prs) let rec def d = match d.it with diff --git a/spectec/src/backend-interpreter/construct.ml b/spectec/src/backend-interpreter/construct.ml index d5d9538dfc..fd5484d89c 100644 --- a/spectec/src/backend-interpreter/construct.ml +++ b/spectec/src/backend-interpreter/construct.ml @@ -124,10 +124,7 @@ and al_to_resulttype: value -> resulttype = function and al_to_comptype: value -> comptype = function | CaseV ("STRUCT", [ ftl ]) -> StructT (al_to_list al_to_fieldtype ftl) | CaseV ("ARRAY", [ ft ]) -> ArrayT (al_to_fieldtype ft) - | CaseV ("FUNC", [ CaseV ("->", [ rt1; rt2 ]) ]) when !version <= 2 -> - FuncT (al_to_resulttype rt1, (al_to_resulttype rt2)) - | CaseV ("FUNC", [ rt1; rt2 ]) -> - FuncT (al_to_resulttype rt1, (al_to_resulttype rt2)) + | CaseV ("->", [ rt1; rt2 ]) -> FuncT (al_to_resulttype rt1, (al_to_resulttype rt2)) | v -> error_value "comptype" v and al_to_subtype: value -> subtype = function @@ -1139,11 +1136,7 @@ and al_of_resulttype rt = al_of_list al_of_valtype rt and al_of_comptype = function | StructT ftl -> CaseV ("STRUCT", [ al_of_list al_of_fieldtype ftl ]) | ArrayT ft -> CaseV ("ARRAY", [ al_of_fieldtype ft ]) - | FuncT (rt1, rt2) -> - if !version <= 2 then - CaseV ("FUNC", [ CaseV ("->", [ al_of_resulttype rt1; al_of_resulttype rt2 ])]) - else - CaseV ("FUNC", [ al_of_resulttype rt1; al_of_resulttype rt2 ]) + | FuncT (rt1, rt2) -> CaseV ("->", [ al_of_resulttype rt1; al_of_resulttype rt2 ]) and al_of_subtype = function | SubT (fin, tul, st) -> @@ -1900,7 +1893,7 @@ let al_of_type ty = match subtypes with | [ subtype ] -> - let rt = subtype |> arg_of_case "SUB" 2 |> arg_of_case "FUNC" 0 in + let rt = subtype |> arg_of_case "SUB" 2 in CaseV ("TYPE", [ rt ]) | _ -> failwith ("Rectype is not supported in Wasm " ^ (string_of_int !version)) else diff --git a/spectec/src/backend-interpreter/host.ml b/spectec/src/backend-interpreter/host.ml index 8e7e3784ee..4d59c5d926 100644 --- a/spectec/src/backend-interpreter/host.ml +++ b/spectec/src/backend-interpreter/host.ml @@ -22,7 +22,7 @@ let spectest () = let code = nullary winstr_tag in let ptype = Array.map nullary type_tags in let arrow = CaseV ("->", [ listV ptype; listV [||] ]) in - let ftype = CaseV ("FUNC", [ listV ptype; listV [||] ]) in + let ftype = CaseV ("->", [ listV ptype; listV [||] ]) in let dtype = CaseV ("_DEF", [ CaseV ("REC", [ @@ -41,9 +41,9 @@ let spectest () = "VALUE", v |> ref ] in - let create_tableinst t elems = StrV [ + let create_tableinst t refs = StrV [ "TYPE", t |> ref; - "REFS", elems |> ref + "REFS", refs |> ref ] in let create_meminst t bytes_ = StrV [ diff --git a/spectec/src/backend-interpreter/interpreter.ml b/spectec/src/backend-interpreter/interpreter.ml index cf790df3fe..16878b2572 100644 --- a/spectec/src/backend-interpreter/interpreter.ml +++ b/spectec/src/backend-interpreter/interpreter.ml @@ -342,7 +342,7 @@ and eval_expr env expr = | [] -> eval_expr env e2 in eval_expr env e1 |> replace ps | CaseE (op, el) -> - (match (get_atom op) with + (match Mixop.head op with | Some a -> caseV (Print.string_of_atom a, List.map (eval_expr env) el) | None -> caseV ("", List.map (eval_expr env) el) ) @@ -370,6 +370,12 @@ and eval_expr env expr = raise Exception.OutOfMemory else Array.make i v |> listV + (* HARDCODE: The case where itered variable does not appear in xes. + --> Insert itered variable. This was instroduced due to the change of IrerE's ListN. *) + | IterE (e1, (ListN (e2, Some x), [])) -> + let dummy_expr = VarE "_" $$ no_region % (Il.Ast.VarT ("_" $ no_region, []) $ no_region) in + let expr' = {expr with it = IterE (e1, (ListN (e2, Some x), [(x, dummy_expr)]))} in + eval_expr env expr' | IterE (inner_e, (iter, xes)) -> let vs = env @@ -480,7 +486,7 @@ and assign lhs rhs env = when List.length lhs_s = Array.length !rhs_s -> List.fold_right2 assign lhs_s (Array.to_list !rhs_s) env | CaseE (op, lhs_s), CaseV (rhs_tag, rhs_s) when List.length lhs_s = List.length rhs_s -> - (match get_atom op with + (match Mixop.head op with | Some lhs_tag when (Print.string_of_atom lhs_tag) = rhs_tag -> List.fold_right2 assign lhs_s rhs_s env | None when "" = rhs_tag -> @@ -600,7 +606,7 @@ and step_instr (fname: string) (ctx: AlContext.t) (env: value Env.t) (instr: ins ) | PopI e -> (match e.it with - | CaseE ([{it = Atom.Atom "FRAME_"; _}] :: _, [_; inner_e]) -> + | CaseE (op, [_; inner_e]) when (Option.get (Mixop.head op)).it = Atom.Atom "FRAME_" -> (match WasmContext.pop_context () with | CaseV ("FRAME_", [_; inner_v]), _, _ -> let new_env = assign inner_e inner_v env in diff --git a/spectec/src/backend-latex/render.ml b/spectec/src/backend-latex/render.ml index 4434e93cbd..b917191444 100644 --- a/spectec/src/backend-latex/render.ml +++ b/spectec/src/backend-latex/render.ml @@ -1676,7 +1676,7 @@ let render_param env p = match p.it with | ExpP (id, t) -> if id.it = "_" then render_typ env t else render_varid env id | TypP id -> render_typid env id - | GramP (id, _t) -> render_gramid env id + | GramP (id, _ps, _t) -> render_gramid env id | DefP (id, _ps, _t) -> render_defid env id let _render_params env = function diff --git a/spectec/src/backend-prose/gen.ml b/spectec/src/backend-prose/gen.ml index 4c88ce6b09..9412078ab5 100644 --- a/spectec/src/backend-prose/gen.ml +++ b/spectec/src/backend-prose/gen.ml @@ -38,7 +38,7 @@ let is_validation_helper_relation def = let is_validation_relation def = match def.it with | Ast.RelD (_, mixop, _, _) -> - List.exists (List.exists (fun atom -> atom.it = Atom.Turnstile)) mixop + List.exists (List.exists (fun atom -> atom.it = Atom.Turnstile)) (Mixop.flatten mixop) | _ -> false let extract_validation_il il = @@ -47,8 +47,6 @@ let extract_validation_il il = |> List.filter (fun rel -> is_validation_relation rel || is_validation_helper_relation rel) -let atomize atom' = atom' $$ no_region % (Atom.info "") - let rel_has_id id rel = match rel.it with | Ast.RelD (id', _, _, _) -> id.it = id'.it @@ -72,11 +70,11 @@ let swap = function `LtOp -> `GtOp | `GtOp -> `LtOp | `LeOp -> `GeOp | `GeOp -> CASE (?()) ~> () *) let recover_optional_singleton_constructor e = match e.it with - | Al.Ast.CaseE ([[atom]; [{it = Quest; _}]], [{it = OptE opt; _ }]) -> + | Al.Ast.CaseE (Mixop.(Seq [Atom atom; Arg ()]), [{it = OptE opt; _ }]) -> ( match opt with - | None -> Al.Ast.CaseE ([[]], []) - | Some _ -> Al.Ast.CaseE ([[atom]], []) + | Some _ -> Al.Ast.CaseE (Mixop.Atom atom, []) + | None -> Al.Ast.CaseE (Mixop.Seq [], []) ) |> (fun it -> {e with it}) | _ -> e @@ -84,10 +82,10 @@ let recover_optional_singleton_constructor e = let remove_empty_arrow_sub e = match e.it with | Al.Ast.CaseE ( - [[]; [{it = ArrowSub; _} as arrow]; []; []], + Mixop.(Infix (Arg (), ({it = ArrowSub; _} as arrow), Seq [Arg (); Arg ()])), [lhs; {it = ListE []; _}; rhs] ) -> - let it = Al.Ast.CaseE ([[];[{arrow with it = Arrow}];[]], [lhs; rhs]) in + let it = Al.Ast.CaseE (Mixop.(Infix (Arg (), {arrow with it = Arrow}, Arg ())), [lhs; rhs]) in {e with it} | _ -> e @@ -135,14 +133,14 @@ type rel_kind = let get_rel_kind def = let open Atom in - let valid_pattern = [[]; [atomize Turnstile]; [atomize Colon; atomize (Atom "OK")]] in - let valid_with_pattern = [[]; [atomize Turnstile]; [atomize Colon]; []] in - let match_pattern = [[]; [atomize Turnstile]; [atomize Sub]; []] in - let const_pattern = [[]; [atomize Turnstile]; [atomize (Atom "CONST")]] in - let valid_const_pattern = [[]; [atomize Turnstile]; [atomize Colon]; [atomize (Atom "CONST")]] in - let valid_with2_pattern = [[]; [atomize Turnstile]; [atomize Colon]; []; []] in - let defaultable_pattern = [[]; [atomize Turnstile]; [atomize (Atom "DEFAULTABLE")]] in - let nondefaultable_pattern = [[]; [atomize Turnstile]; [atomize (Atom "NONDEFAULTABLE")]] in + let valid_pattern = [[]; [Turnstile]; [Colon; Atom "OK"]] in + let valid_with_pattern = [[]; [Turnstile]; [Colon]; []] in + let match_pattern = [[]; [Turnstile]; [Sub]; []] in + let const_pattern = [[]; [Turnstile]; [Atom "CONST"]] in + let valid_const_pattern = [[]; [Turnstile]; [Colon]; [Atom "CONST"]] in + let valid_with2_pattern = [[]; [Turnstile]; [Colon]; []; []] in + let defaultable_pattern = [[]; [Turnstile]; [Atom "DEFAULTABLE"]] in + let nondefaultable_pattern = [[]; [Turnstile]; [Atom "NONDEFAULTABLE"]] in let has_instr_as_second typ = match typ.it with @@ -153,7 +151,8 @@ let get_rel_kind def = match def.it with | Ast.RelD (id, mixop, typ, _) -> - let match_mixop pattern = Mixop.(eq mixop pattern || eq mixop (List.tl pattern)) in + let mixop' = List.map (List.map Util.Source.it) (Mixop.flatten mixop) in + let match_mixop pattern = mixop' = pattern || mixop' = List.tl pattern in if match_mixop valid_pattern then ValidRel else if match_mixop valid_with_pattern then @@ -410,9 +409,9 @@ let preprocess_exp frees m exp = let preprocess_rule m rule = { rule with it = match rule.it with - | Ast.RuleD (id, bs, ops, exp, prems) -> - let frees = Free.(union (free_rule rule) (free_list bound_bind bs)).varid in - Ast.RuleD (id, bs, ops, preprocess_exp frees m exp, prems)} + | Ast.RuleD (id, ps, ops, exp, prems) -> + let frees = Free.(union (free_rule rule) (free_list bound_param ps)).varid in + Ast.RuleD (id, ps, ops, preprocess_exp frees m exp, prems)} let postprocess_rules m rule = let binds = Map.fold (fun _ (v, e) acc -> diff --git a/spectec/src/backend-prose/print.ml b/spectec/src/backend-prose/print.ml index 806f269586..c12405a632 100644 --- a/spectec/src/backend-prose/print.ml +++ b/spectec/src/backend-prose/print.ml @@ -136,13 +136,13 @@ and string_of_expr expr = | VarE id -> id | SubE (id, _) -> id | IterE (e, ie) -> string_of_expr e ^ string_of_iterexp ie - | CaseE ([{ it=Atom.Atom ("CONST" | "VCONST"); _ }]::_tl, hd::tl) -> + | CaseE (op, hd::tl) when Xl.Mixop.head op <> None && List.mem (Option.get (Xl.Mixop.head op)).it Xl.Atom.[Atom "CONST"; Atom "VCONST"] -> "(" ^ string_of_expr hd ^ ".CONST " ^ string_of_exprs " " tl ^ ")" | CaseE (op, el) -> (* Current rules for omitting parenthesis around a CaseE: 1) Has no argument 2) Is infix notation *) - let op' = List.map (string_of_list string_of_atom "" "" "") op in + let op' = List.map (string_of_list string_of_atom "" "" "") (Mixop.flatten op) in let el' = List.map string_of_expr el in let s = Prose_util.alternate op' el' diff --git a/spectec/src/backend-prose/prose_util.ml b/spectec/src/backend-prose/prose_util.ml index 263465b41a..37e20e0517 100644 --- a/spectec/src/backend-prose/prose_util.ml +++ b/spectec/src/backend-prose/prose_util.ml @@ -256,6 +256,8 @@ let apply_prose_hint hint args = ) template; |> String.concat "" +let mixop_name mixop = "`" ^ Xl.Atom.to_string (Option.get (Xl.Mixop.head mixop)) ^ "`" + let string_of_stack_prefix expr = let open Al.Ast in match expr.it with @@ -263,7 +265,7 @@ let string_of_stack_prefix expr = | VarE ("F" | "L") -> "" | _ when Il.Eq.eq_typ expr.note Al.Al_util.frameT -> "the :ref:`frame `" | CaseE (mixop, _) when Il.Eq.eq_typ expr.note Al.Al_util.evalctxT -> - let evalctx_name = Xl.Mixop.name (List.nth mixop 0) + let evalctx_name = mixop_name mixop |> fun s -> String.sub s 0 (String.length s - 1) |> String.lowercase_ascii in Printf.sprintf "the %s" evalctx_name @@ -315,7 +317,7 @@ let find_case_typ s a: El.Ast.typ = let extract_case_hint t mixop = let id1 = Il.Print.string_of_typ t in - let id2 = Xl.Mixop.name (List.nth mixop 0) in + let id2 = mixop_name mixop in let id = id1 ^ "." ^ id2 in match Map.find_opt id !(hintenv.prose_hints) with | Some (Some e, _) -> Some e diff --git a/spectec/src/backend-prose/prose_util.mli b/spectec/src/backend-prose/prose_util.mli index fe4a3c2383..bb140ddbc2 100644 --- a/spectec/src/backend-prose/prose_util.mli +++ b/spectec/src/backend-prose/prose_util.mli @@ -12,7 +12,7 @@ val alternate : 'a list -> 'a list -> 'a list val apply_prose_hint : string -> string list -> string val string_of_stack_prefix : Al.Ast.expr -> string val find_case_typ : string -> Xl.Atom.atom -> El.Ast.typ -val extract_case_hint : Il.Ast.typ -> Xl.Mixop.mixop -> El.Ast.exp option +val extract_case_hint : Il.Ast.typ -> 'a Xl.Mixop.mixop -> El.Ast.exp option val extract_call_hint : string -> El.Ast.exp option val is_allocxs : string -> bool val fill_hole : El.Ast.exp list -> El.Ast.exp -> El.Ast.exp diff --git a/spectec/src/backend-prose/render.ml b/spectec/src/backend-prose/render.ml index aa34ec1b2a..9a6378f7e3 100644 --- a/spectec/src/backend-prose/render.ml +++ b/spectec/src/backend-prose/render.ml @@ -119,8 +119,8 @@ let get_context_var e = | Al.Ast.CaseE (_, [_; {it = Al.Ast.VarE x; _} as e']) when x <> "_" -> e' (* HARDCODE for frame *) | Al.Ast.CaseE (mixop, _) -> let x = mixop - |> List.hd - |> List.hd + |> Mixop.head + |> Option.get |> Atom.to_string |> (fun s -> String.sub s 0 1) in @@ -370,17 +370,6 @@ and al_to_el_expr expr = 2) Is infix notation 3) Is bracketed -> render into BrackE 4) Is argument of CallE -> add first, omit later at CallE *) - let atom_of atom = atom $$ no_region % (Atom.info "") in - let find_brace_opt mixop = - let s = Mixop.to_string mixop in - let first = String.get s 1 in - let last = String.get s (String.length s - 2) in - match first, last with - | '(', ')' -> Some (atom_of Atom.LParen, atom_of Atom.RParen) - | '[', ']' -> Some (atom_of Atom.LBrack, atom_of Atom.RBrack) - | '{', '}' -> Some (atom_of Atom.LBrace, atom_of Atom.RBrace) - | _ -> None - in let elal = mixop_to_el_exprs op in let* elel = al_to_el_exprs el in let eles = case_to_el_exprs elal elel in @@ -389,8 +378,8 @@ and al_to_el_expr expr = | _, [] -> Some ele | None :: Some _ :: _, _ -> Some ele | _ -> - (match find_brace_opt op with - | Some (lbr, rbr) -> + (match op with + | Mixop.Brack (lbr, _, rbr) -> (* Split braces of el expressions *) let _, eles = Util.Lib.List.split_hd eles in let eles, _ = Util.Lib.List.split_last eles in @@ -402,7 +391,7 @@ and al_to_el_expr expr = | _ -> El.Ast.SeqE eles ) in Some (El.Ast.BrackE (lbr, eles $ no_region, rbr)) - | None -> Some (El.Ast.ParenE (ele $ no_region)) + | _ -> Some (El.Ast.ParenE (ele $ no_region)) ) ) ) @@ -438,7 +427,7 @@ and mixop_to_el_exprs op = | [ a ] -> Some((El.Ast.AtomE a) $ no_region) | _ -> None ) - op + (Mixop.flatten op) and al_to_el_exprs exprs = List.fold_left @@ -721,7 +710,7 @@ and render_expr' env expr = (render_math "=") (render_expr env erhs) | Al.Ast.CaseE (mixop, [ arity; arg ]) when Al.Valid.sub_typ expr.note Al.Al_util.evalctxT -> - let atom_name = mixop |> List.hd |> List.hd |> Atom.to_string in + let atom_name = mixop |> Mixop.head |> Option.get |> Atom.to_string in let context_var = get_context_var expr in let rendered_arity = match arity.it with @@ -1047,7 +1036,7 @@ let render_control_frame env expr = let open Al in match expr.it with | Ast.CaseE (mixop, [ arity; arg ]) -> - let atom = mixop |> List.hd |> List.hd in + let atom = mixop |> Mixop.head |> Option.get in let atom_name = Atom.to_string atom in let control_frame_name, rendered_arg = match atom_name with @@ -1322,7 +1311,7 @@ let rec render_instr env algoname index depth instr = ) | Al.Ast.PushI ({ it = Al.Ast.CaseE (mixop, _); _ } as e) when Al.Valid.sub_typ e.note Al.Al_util.evalctxT -> - let atom = mixop |> List.hd |> List.hd in + let atom = mixop |> Mixop.head |> Option.get in let context_var = get_context_var e in let context_var' = to_fresh_var env context_var in sprintf "%s Let %s be %s.\n\n%s%s Push the %s %s." @@ -1338,7 +1327,7 @@ let rec render_instr env algoname index depth instr = (render_stack_prefix e) (render_expr env e) | Al.Ast.PopI ({ it = Al.Ast.CaseE (mixop, _); _ } as expr) when Al.Valid.sub_typ expr.note Al.Al_util.evalctxT -> - let atom = mixop |> List.hd |> List.hd in + let atom = mixop |> Mixop.head |> Option.get in let control_frame_kind = render_atom env atom in sprintf "%s Pop the %s from the stack." (render_order index depth) @@ -1357,7 +1346,7 @@ let rec render_instr env algoname index depth instr = (match e1.it with (* NOTE: This assumes that the first argument of control frame is arity *) | Al.Ast.CaseE (mixop, [ arity; arg ] ) when Al.Valid.sub_typ e1.note Al.Al_util.evalctxT -> - let atom_name = mixop |> List.hd |> List.hd |> Atom.to_string in + let atom_name = mixop |> Mixop.head |> Option.get |> Atom.to_string in let context_var = get_context_var e1 in let rendered_let = sprintf "%s Let %s be %s." @@ -1437,7 +1426,7 @@ let rec render_instr env algoname index depth instr = sprintf "%s Return%s." (render_order index depth) (render_opt " " (render_expr env) "" e_opt) | Al.Ast.EnterI ({ it = Al.Ast.CaseE (mixop, _); _ } as e1, e2, il) -> - let atom = mixop |> List.hd |> List.hd in + let atom = mixop |> Mixop.head |> Option.get in let context_var = (get_context_var e1) in sprintf "%s Let %s be %s.\n\n%s%s Enter the block %s with the %s %s.%s" (render_order index depth) @@ -1500,7 +1489,7 @@ let render_atom_title env name params = | _ -> name.it in let name = name' $$ no_region % name.note in - let op = [name] :: List.init (List.length params) (fun _ -> []) in + let op = Mixop.(Seq (Atom name :: List.init (List.length params) (fun _ -> Arg ()))) in let params = List.filter_map (fun a -> match a.it with Al.Ast.ExpA e -> Some e | _ -> None) params in let expr = Al.Al_util.caseE (op, params) ~at:no_region ~note:Al.Al_util.no_note in match al_to_el_expr expr with diff --git a/spectec/src/el/ast.ml b/spectec/src/el/ast.ml index b56ee187a6..89291e880c 100644 --- a/spectec/src/el/ast.ml +++ b/spectec/src/el/ast.ml @@ -158,7 +158,7 @@ and param = param' phrase and param' = | ExpP of id * typ (* varid `:` typ *) | TypP of id (* `syntax` varid *) - | GramP of id * typ (* `grammar` gramid `:` typ *) + | GramP of id * param list * typ (* `grammar` gramid `:` typ *) | DefP of id * param list * typ (* `def` `$` defid params `:` typ *) and arg = arg' ref phrase diff --git a/spectec/src/el/convert.ml b/spectec/src/el/convert.ml index f3464870c3..932d30353d 100644 --- a/spectec/src/el/convert.ml +++ b/spectec/src/el/convert.ml @@ -206,7 +206,7 @@ let rec param_of_arg a = error id.at "invalid identifer suffix in binding position"; TypP id | GramA {it = AttrG ({it = VarE (id, []); _}, g); _} -> - GramP (id, typ_of_exp (exp_of_sym g)) + GramP (id, [], typ_of_exp (exp_of_sym g)) | _ -> error a.at "malformed parameter" ) $ a.at @@ -214,6 +214,6 @@ let arg_of_param p = (match p.it with | ExpP (id, _t) -> ExpA ((*TypE ( *)VarE (id, []) $ id.at(*, t) $ p.at*)) | TypP id -> TypA (VarT (id, []) $ id.at) - | GramP (id, _t) -> GramA (VarG (id, []) $ id.at) - | DefP (id, _params, _t) -> DefA id + | GramP (id, _ps, _t) -> GramA (VarG (id, []) $ id.at) + | DefP (id, _ps, _t) -> DefA id ) |> ref $ p.at diff --git a/spectec/src/el/debug.ml b/spectec/src/el/debug.ml index 770913cb9c..d6691d4c14 100644 --- a/spectec/src/el/debug.ml +++ b/spectec/src/el/debug.ml @@ -19,18 +19,3 @@ let el_params = list el_param let el_def = string_of_def let nl_list f xs = list f (Convert.filter_nl xs) - -let el_free s = String.concat " " - Free.[ - set s.typid; - set s.varid; - set s.gramid; - set s.defid; - ] -let el_subst s = String.concat " " - Subst.[ - mapping el_typ s.typid; - mapping el_exp s.varid; - mapping el_sym s.gramid; - mapping el_id s.defid; - ] diff --git a/spectec/src/el/eq.ml b/spectec/src/el/eq.ml index f012ed66a4..ddeffdb3fc 100644 --- a/spectec/src/el/eq.ml +++ b/spectec/src/el/eq.ml @@ -179,7 +179,8 @@ and eq_param p1 p2 = match p1.it, p2.it with | ExpP (id1, t1), ExpP (id2, t2) -> eq_id id1 id2 && eq_typ t1 t2 | TypP id1, TypP id2 -> eq_id id1 id2 - | GramP (id1, t1), GramP (id2, t2) -> eq_id id1 id2 && eq_typ t1 t2 + | GramP (id1, ps1, t1), GramP (id2, ps2, t2) -> + eq_id id1 id2 && eq_list eq_param ps1 ps2 && eq_typ t1 t2 | DefP (id1, ps1, t1), DefP (id2, ps2, t2) -> eq_id id1 id2 && eq_list eq_param ps1 ps2 && eq_typ t1 t2 | _, _ -> false diff --git a/spectec/src/el/free.ml b/spectec/src/el/free.ml index 731441e957..793da3250d 100644 --- a/spectec/src/el/free.ml +++ b/spectec/src/el/free.ml @@ -1,66 +1,13 @@ open Util.Source open Ast -open Xl - - -(* Data Structure *) - -module Set = Set.Make(String) - -type sets = - { typid : Set.t; - gramid : Set.t; - relid : Set.t; - varid : Set.t; - defid : Set.t; - } - -let empty = - { typid = Set.empty; - gramid = Set.empty; - relid = Set.empty; - varid = Set.empty; - defid = Set.empty; - } - -let union sets1 sets2 = - { typid = Set.union sets1.typid sets2.typid; - gramid = Set.union sets1.gramid sets2.gramid; - relid = Set.union sets1.relid sets2.relid; - varid = Set.union sets1.varid sets2.varid; - defid = Set.union sets1.defid sets2.defid; - } - -let inter sets1 sets2 = - { typid = Set.inter sets1.typid sets2.typid; - gramid = Set.inter sets1.gramid sets2.gramid; - relid = Set.inter sets1.relid sets2.relid; - varid = Set.inter sets1.varid sets2.varid; - defid = Set.inter sets1.defid sets2.defid; - } - -let diff sets1 sets2 = - { typid = Set.diff sets1.typid sets2.typid; - gramid = Set.diff sets1.gramid sets2.gramid; - relid = Set.diff sets1.relid sets2.relid; - varid = Set.diff sets1.varid sets2.varid; - defid = Set.diff sets1.defid sets2.defid; - } - -let (+) = union -let (-) = diff - -let free_opt free_x xo = Option.(value (map free_x xo) ~default:empty) -let free_list free_x xs = List.(fold_left (+) empty (map free_x xs)) - -let rec free_list_dep free_x bound_x = function - | [] -> empty - | x::xs -> free_x x + (free_list_dep free_x bound_x xs - bound_x x) -let free_nl_elem free_x = function Nl -> empty | Elem x -> free_x x -let free_nl_list free_x xs = List.(fold_left (+) empty (map (free_nl_elem free_x) xs)) +include Xl.Gen_free + + +(* Aggregates *) -let bound_list = free_list +let free_nl_elem free_x = function Nl -> empty | Elem x -> free_x x +let free_nl_list free_x xs = List.(fold_left (++) empty (map (free_nl_elem free_x) xs)) (* Identifiers *) @@ -68,21 +15,10 @@ let bound_list = free_list let free_typid id = let id' = Convert.strip_var_suffix id in match (Convert.typ_of_varid id').it with - | VarT _ -> {empty with typid = Set.singleton id'.it} + | VarT _ -> Xl.Gen_free.free_typid id' | _ -> empty -let free_gramid id = {empty with gramid = Set.singleton id.it} -let free_relid id = {empty with relid = Set.singleton id.it} -let free_varid id = {empty with varid = Set.singleton id.it} -let free_defid id = {empty with defid = Set.singleton id.it} - -let bound_typid id = if id.it = "_" then empty else free_typid id -let bound_gramid id = if id.it = "_" then empty else free_gramid id -let bound_varid id = if id.it = "_" then empty else free_varid id -let bound_defid id = if id.it = "_" then empty else free_defid id - let free_op op = {empty with varid = Set.singleton op} -let bound_op op = free_op op (* Iterations *) @@ -90,43 +26,35 @@ let bound_op op = free_op op let rec free_iter iter = match iter with | Opt | List | List1 -> empty - | ListN (e, id_opt) -> free_exp e + free_opt free_varid id_opt + | ListN (e, id_opt) -> free_exp e ++ free_opt free_varid id_opt (* Types *) and free_typ t = match t.it with - | VarT (id, as_) -> free_typid id + free_args as_ + | VarT (id, as_) -> free_typid id ++ free_args as_ | BoolT | NumT _ | TextT -> empty | ParenT t1 -> free_typ t1 | TupT ts -> free_list free_typ ts - | IterT (t1, iter) -> free_typ t1 + free_iter iter + | IterT (t1, iter) -> free_typ t1 ++ free_iter iter | StrT (_, ts, tfs, _) -> - free_nl_list free_typ ts + - free_nl_list (fun tf -> free_typfield tf - det_typfield tf) tfs + free_nl_list free_typ ts ++ + free_nl_list (fun tf -> free_typfield tf) tfs | CaseT (_, ts, tcs, _) -> - free_nl_list free_typ ts + - free_nl_list (fun tc -> free_typcase tc - det_typcase tc) tcs - | ConT tc -> free_typcon tc - det_typcon tc + free_nl_list free_typ ts ++ + free_nl_list (fun tc -> free_typcase tc) tcs + | ConT tc -> free_typcon tc | RangeT tes -> free_nl_list free_typenum tes | AtomT _ -> empty | SeqT ts -> free_list free_typ ts - | InfixT (t1, _, t2) -> free_typ t1 + free_typ t2 + | InfixT (t1, _, t2) -> free_typ t1 ++ free_typ t2 | BrackT (_, t1, _) -> free_typ t1 -and free_typfield (_, (t, prems), _) = free_typ t + free_prems prems -and free_typcase (_, (t, prems), _) = free_typ t + free_prems prems -and free_typcon ((t, prems), _) = free_typ t + free_prems prems -and free_typenum (e, eo) = free_exp e + free_opt free_exp eo - - -(* Variables can be determined by types through implicit binders *) -and det_typ t = det_exp (Convert.pat_of_typ t) - -and det_typfield (_, (t, prems), _) = det_typ t + det_prems prems -and det_typcase (_, (t, prems), _) = det_typ t + det_prems prems -and det_typcon ((t, prems), _) = det_typ t + det_prems prems +and free_typfield (_, (t, prems), _) = free_typ t ++ free_prems prems +and free_typcase (_, (t, prems), _) = free_typ t ++ free_prems prems +and free_typcon ((t, prems), _) = free_typ t ++ free_prems prems +and free_typenum (e, eo) = free_exp e ++ free_opt free_exp eo (* Expressions *) @@ -137,142 +65,54 @@ and free_unop = function and free_exp e = match e.it with - | VarE (id, as_) -> free_varid id + free_list free_arg as_ + | VarE (id, as_) -> free_varid id ++ free_list free_arg as_ | AtomE _ | BoolE _ | NumE _ | TextE _ | EpsE | HoleE _ | LatexE _ -> empty - | UnE (op, e1) -> free_unop op + free_exp e1 + | UnE (op, e1) -> free_unop op ++ free_exp e1 | CvtE (e1, _) | DotE (e1, _) | LenE e1 | ParenE e1 | BrackE (_, e1, _) | ArithE e1 | UnparenE e1 -> free_exp e1 | SizeE id -> free_gramid id | BinE (e1, _, e2) | CmpE (e1, _, e2) | IdxE (e1, e2) | CommaE (e1, e2) | CatE (e1, e2) | MemE (e1, e2) - | InfixE (e1, _, e2) | FuseE (e1, e2) -> free_exp e1 + free_exp e2 - | SliceE (e1, e2, e3) -> free_exp e1 + free_exp e2 + free_exp e3 + | InfixE (e1, _, e2) | FuseE (e1, e2) -> free_exp e1 ++ free_exp e2 + | SliceE (e1, e2, e3) -> free_exp e1 ++ free_exp e2 ++ free_exp e3 | SeqE es | ListE es | TupE es -> free_list free_exp es | UpdE (e1, p, e2) | ExtE (e1, p, e2) -> - free_exp e1 + free_path p + free_exp e2 + free_exp e1 ++ free_path p ++ free_exp e2 | StrE efs -> free_nl_list free_expfield efs - | CallE (id, as_) -> free_defid id + free_list free_arg as_ - | IterE (e1, iter) -> free_exp e1 + free_iter iter - | TypE (e1, t) -> free_exp e1 + free_typ t + | CallE (id, as_) -> free_defid id ++ free_list free_arg as_ + | IterE (e1, iter) -> free_exp e1 ++ free_iter iter + | TypE (e1, t) -> free_exp e1 ++ free_typ t and free_expfield (_, e) = free_exp e and free_path p = match p.it with | RootP -> empty - | IdxP (p1, e) -> free_path p1 + free_exp e - | SliceP (p1, e1, e2) -> free_path p1 + free_exp e1 + free_exp e2 + | IdxP (p1, e) -> free_path p1 ++ free_exp e + | SliceP (p1, e1, e2) -> free_path p1 ++ free_exp e1 ++ free_exp e2 | DotP (p1, _) -> free_path p1 -and det_unop = - function - | #signop -> - bound_op (Print.string_of_unop `PlusMinusOp) + - bound_op (Print.string_of_unop `MinusPlusOp) - | _ -> empty - -and det_exp e = - match e.it with - | VarE (id, []) -> bound_varid id - | VarE _ -> assert false - | UnE (#signop as op, e1) -> det_unop op + det_exp e1 - | CvtE (e1, _) | UnE (#Num.unop, e1) - | ParenE e1 | BrackE (_, e1, _) | ArithE e1 -> det_exp e1 - (* We consider arithmetic expressions determinate, - * since we sometimes need to use invertible formulas. *) - | BinE (e1, #Num.binop, e2) - | InfixE (e1, _, e2) -> det_exp e1 + det_exp e2 - | SeqE es | ListE es | TupE es -> free_list det_exp es - | StrE efs -> free_nl_list det_expfield efs - | IterE (e1, iter) -> det_exp e1 + det_iter iter - (* As a special hack to work with bijective functions, - * we treat last position of a call as a pattern, too. *) - | CallE (_, []) -> empty - | CallE (_, as_) -> - free_list idx_arg as_ + det_arg (Util.Lib.List.last as_) - | TypE (e1, _) -> det_exp e1 - | AtomE _ | BoolE _ | NumE _ | TextE _ | EpsE -> empty - | UnE _ | BinE _ | CmpE _ - | IdxE _ | SliceE _ | UpdE _ | ExtE _ | CommaE _ | CatE _ | MemE _ - | DotE _ | LenE _ | SizeE _ -> idx_exp e - | HoleE _ | FuseE _ | UnparenE _ | LatexE _ -> assert false - -and det_expfield (_, e) = det_exp e - -and det_iter iter = - match iter with - | Opt | List | List1 -> empty - | ListN (e, id_opt) -> det_exp e + free_opt bound_varid id_opt - -and idx_exp e = - match e.it with - | VarE _ -> empty - | ParenE e1 | BrackE (_, e1, _) | ArithE e1 -> idx_exp e1 - | InfixE (e1, _, e2) -> idx_exp e1 + idx_exp e2 - | SeqE es | ListE es | TupE es -> free_list idx_exp es - | StrE efs -> free_nl_list idx_expfield efs - | IterE (e1, iter) -> idx_exp e1 + idx_iter iter - | CallE (_, as_) -> free_list idx_arg as_ - | TypE (e1, _) -> idx_exp e1 - | IdxE (_, e2) -> det_exp e2 - | _ -> empty - -and idx_expfield (_, e) = idx_exp e - -and idx_iter iter = - match iter with - | Opt | List | List1 -> empty - | ListN (e, id_opt) -> idx_exp e + free_opt bound_varid id_opt - -and det_cond_exp e = - match e.it with - | UnE (#Bool.unop, e1) -> det_cond_exp e1 - | BinE (e1, #Bool.binop, e2) -> det_cond_exp e1 + det_cond_exp e2 - | CmpE (e1, `EqOp, e2) -> det_exp e1 + det_exp e2 - | MemE (e1, _) -> det_exp e1 - | ParenE e1 | ArithE e1 -> det_cond_exp e1 - | _ -> empty - - (* Grammars *) and free_sym g = match g.it with - | VarG (id, as_) -> free_gramid id + free_args as_ + | VarG (id, as_) -> free_gramid id ++ free_args as_ | NumG _ | TextG _ | EpsG -> empty | SeqG gs | AltG gs -> free_nl_list free_sym gs - | RangeG (g1, g2) | FuseG (g1, g2) -> free_sym g1 + free_sym g2 + | RangeG (g1, g2) | FuseG (g1, g2) -> free_sym g1 ++ free_sym g2 | ParenG g1 | UnparenG g1 -> free_sym g1 | TupG gs -> free_list free_sym gs - | IterG (g1, iter) -> free_sym g1 + free_iter iter + | IterG (g1, iter) -> free_sym g1 ++ free_iter iter | ArithG e -> free_exp e - | AttrG (e, g1) -> free_exp e + free_sym g1 - -and det_sym g = - match g.it with - | VarG _ | NumG _ | TextG _ | EpsG -> empty - | SeqG gs | AltG gs -> free_nl_list det_sym gs - | RangeG (g1, g2) -> det_sym g1 + det_sym g2 - | ParenG g1 -> det_sym g1 - | TupG gs -> free_list det_sym gs - | IterG (g1, iter) -> det_sym g1 + det_iter iter - | ArithG e -> det_exp e - | AttrG (e, g1) -> det_exp e + det_sym g1 - | FuseG _ | UnparenG _ -> assert false + | AttrG (e, g1) -> free_exp e ++ free_sym g1 and free_prod prod = match prod.it with - | SynthP (g, e, prems) -> free_sym g + free_exp e + free_prems prems + | SynthP (g, e, prems) -> free_sym g ++ free_exp e ++ free_prems prems | RangeP (g1, e1, g2, e2) -> - free_sym g1 + free_exp e1 + free_sym g2 + free_exp e2 - | EquivP (g1, g2, prems) -> free_sym g1 + free_sym g2 + free_prems prems - -and det_prod prod = - match prod.it with - | SynthP (g, _e, prems) -> det_sym g + det_prems prems - | RangeP (g1, _e1, g2, _e2) -> det_sym g1 + det_sym g2 - | EquivP (g1, _g2, prems) -> det_sym g1 + det_prems prems + free_sym g1 ++ free_exp e1 ++ free_sym g2 ++ free_exp e2 + | EquivP (g1, g2, prems) -> free_sym g1 ++ free_sym g2 ++ free_prems prems and free_gram gram = let (_dots1, prods, _dots2) = gram.it in @@ -284,22 +124,13 @@ and free_gram gram = and free_prem prem = match prem.it with - | VarPr (id, t) -> free_varid id + free_typ t - | RulePr (id, e) -> free_relid id + free_exp e + | VarPr (id, t) -> free_varid id ++ free_typ t + | RulePr (id, e) -> free_relid id ++ free_exp e | IfPr e -> free_exp e | ElsePr -> empty - | IterPr (prem1, iter) -> free_prem prem1 + free_iter iter - -and det_prem prem = - match prem.it with - | VarPr (_id, _t) -> empty - | RulePr (_id, e) -> det_exp e - | IfPr e -> det_cond_exp e - | ElsePr -> empty - | IterPr (prem1, iter) -> det_prem prem1 + det_iter iter + | IterPr (prem1, iter) -> free_prem prem1 ++ free_iter iter and free_prems prems = free_nl_list free_prem prems -and det_prems prems = free_nl_list det_prem prems (* Definitions *) @@ -311,39 +142,23 @@ and free_arg a = | GramA g -> free_sym g | DefA id -> free_defid id -and det_arg a = - match !(a.it) with - | ExpA e -> det_exp e - | TypA t -> free_typ t (* must be an id *) - | GramA g -> free_sym g (* must be an id *) - | DefA id -> free_defid id - -and idx_arg a = - match !(a.it) with - | ExpA e -> idx_exp e - | TypA _ -> empty - | GramA _ -> empty - | DefA _ -> empty - and free_param p = match p.it with | ExpP (_, t) -> free_typ t | TypP _ -> empty - | GramP (_, t) -> free_typ t - impl_bound_typ t - | DefP (_, ps, t) -> free_params ps + free_typ t - bound_params ps + | GramP (_, ps, t) -> free_params ps ++ free_typ t -- bound_params ps -- impl_bound_typ ps t + | DefP (_, ps, t) -> free_params ps ++ free_typ t -- bound_params ps -and impl_bound_typ t = {empty with typid = (free_typ t).typid} +and impl_bound_typ ps t = {empty with typid = (free_typ t).typid} -- bound_params ps and bound_param p = match p.it with | ExpP (id, _) -> bound_varid id | TypP id -> bound_typid id - | GramP (id, t) -> bound_gramid id + impl_bound_typ t + | GramP (id, ps, t) -> bound_gramid id ++ impl_bound_typ ps t | DefP (id, _, _) -> bound_defid id and free_args as_ = free_list free_arg as_ -and det_args as_ = free_list det_arg as_ - and free_params ps = free_list_dep free_param bound_param ps and bound_params ps = bound_list bound_param ps @@ -352,23 +167,16 @@ let free_def d = | FamD (_id, ps, _hints) -> free_list free_param ps | TypD (_id1, _id2, as_, t, _hints) -> - free_args as_ + free_typ t + free_args as_ ++ free_typ t | GramD (_id1, _id2, ps, t, gram, _hints) -> - free_params ps + (free_typ t + free_gram gram - bound_params ps - impl_bound_typ t) + free_params ps ++ (free_typ t ++ free_gram gram -- bound_params ps -- impl_bound_typ ps t) | VarD (_id, t, _hints) -> free_typ t | SepD -> empty | RelD (_id, t, _hints) -> free_typ t | RuleD (id1, _id2, e, prems) -> - free_relid id1 + free_exp e + free_prems prems + free_relid id1 ++ free_exp e ++ free_prems prems | DecD (_id, ps, t, _hints) -> - free_params ps + free_typ t - bound_params ps + free_params ps ++ free_typ t -- bound_params ps | DefD (id, as_, e, prems) -> - free_defid id + free_args as_ + free_exp e + free_prems prems + free_defid id ++ free_args as_ ++ free_exp e ++ free_prems prems | HintD _ -> empty - -let det_def d = - match d.it with - | FamD _ | GramD _ | VarD _ | SepD | RelD _ | DecD _ | HintD _ -> empty - | TypD (_id1, _id2, as_, _t, _hints) -> det_args as_ - | RuleD (_id1, _id2, e, prems) -> det_exp e + det_prems prems - | DefD (_id, as_, e, prems) -> det_args as_ + idx_exp e + det_prems prems diff --git a/spectec/src/el/free.mli b/spectec/src/el/free.mli index 650d4fe1d6..fcd9d6d1d4 100644 --- a/spectec/src/el/free.mli +++ b/spectec/src/el/free.mli @@ -1,21 +1,8 @@ open Ast -module Set : Set.S with type elt = string with type t = Set.Make(String).t +include module type of Xl.Gen_free -type sets = - { typid : Set.t; - gramid : Set.t; - relid : Set.t; - varid : Set.t; - defid : Set.t; - } - -val empty : sets -val union : sets -> sets -> sets -val inter : sets -> sets -> sets -val diff : sets -> sets -> sets - -val free_list : ('a -> sets) -> 'a list -> sets +val free_nl_elem : ('a -> sets) -> 'a nl_elem -> sets val free_nl_list : ('a -> sets) -> 'a nl_list -> sets val free_iter : iter -> sets @@ -26,26 +13,11 @@ val free_typcon : typcon -> sets val free_exp : exp -> sets val free_path : path -> sets val free_arg : arg -> sets -val free_args : arg list -> sets val free_prem : prem -> sets -val free_prems : prem nl_list -> sets -val free_params : param list -> sets +val free_param : param -> sets val free_prod : prod -> sets val free_def : def -> sets -(* A free variable is "determinate" if: - - it occurs as an iteration variable - - it occurs in destructuring position on the lhs - - it occurs in destructuring position on either side of an equational premise - - it occurs in destructuring position as an indexing operand - - it occurs in destructuring position as the last call arg - (this case is to handle function inverses) - This is a pragmatic criterium, intended only for sanity checks. -*) -val det_exp : exp -> sets -val det_sym : sym -> sets -val det_prems : prem nl_list -> sets -val det_prod : prod -> sets -val det_def : def -> sets - -val bound_params : param list -> sets +val free_prems : prem nl_list -> sets +val free_args : arg list -> sets +val free_params : param list -> sets diff --git a/spectec/src/el/iter.ml b/spectec/src/el/iter.ml index 521a0c8c05..d060083f8e 100644 --- a/spectec/src/el/iter.ml +++ b/spectec/src/el/iter.ml @@ -213,7 +213,7 @@ and param p = match p.it with | ExpP (x, t) -> varid x; typ t | TypP x -> typid x - | GramP (x, t) -> gramid x; typ t + | GramP (x, ps, t) -> gramid x; params ps; typ t | DefP (x, ps, t) -> defid x; params ps; typ t and args as_ = list arg as_ @@ -377,7 +377,7 @@ and clone_param p = (match p.it with | ExpP (x, t) -> ExpP (x, clone_typ t) | TypP x -> TypP x - | GramP (x, t) -> GramP (x, clone_typ t) + | GramP (x, ps, t) -> GramP (x, List.map clone_param ps, clone_typ t) | DefP (x, ps, t) -> DefP (x, List.map clone_param ps, clone_typ t) ) $ p.at diff --git a/spectec/src/el/print.ml b/spectec/src/el/print.ml index 37252b052a..c9858920be 100644 --- a/spectec/src/el/print.ml +++ b/spectec/src/el/print.ml @@ -69,7 +69,7 @@ let rec string_of_iter iter = and string_of_numtyp = Num.string_of_typ -and string_of_typ ?(short=false) t = +and string_of_typ ?(short = false) t = match t.it with | VarT (id, args) -> string_of_typid id ^ string_of_args args | BoolT -> "bool" @@ -120,17 +120,17 @@ and string_of_typ ?(short=false) t = and string_of_typs sep ts = concat sep (List.map string_of_typ ts) -and string_of_typfield ?(short=false) (atom, (t, prems), _hints) = +and string_of_typfield ?(short = false) (atom, (t, prems), _hints) = string_of_atom atom ^ " " ^ string_of_typ t ^ if short && prems <> [] then " -- .." else concat "" (map_filter_nl_list (prefix "\n -- " string_of_prem) prems) -and string_of_typcase ?(short=false) (_atom, (t, prems), _hints) = +and string_of_typcase ?(short = false) (_atom, (t, prems), _hints) = string_of_typ t ^ if short && prems <> [] then " -- .." else concat "" (map_filter_nl_list (prefix "\n -- " string_of_prem) prems) -and string_of_typcon ?(short=false) ((t, prems), _hints) = +and string_of_typcon ?(short = false) ((t, prems), _hints) = string_of_typ t ^ if short && prems <> [] then " -- .." else concat "" (map_filter_nl_list (prefix "\n -- " string_of_prem) prems) @@ -289,7 +289,7 @@ let rec string_of_param p = match p.it with | ExpP (id, t) -> (if id.it = "_" then "" else string_of_varid id ^ " : ") ^ string_of_typ t | TypP id -> "syntax " ^ string_of_typid id - | GramP (id, t) -> "grammar " ^ string_of_gramid id ^ " : " ^ string_of_typ t + | GramP (id, ps, t) -> "grammar " ^ string_of_gramid id ^ string_of_params ps ^ " : " ^ string_of_typ t | DefP (id, ps, t) -> "def " ^ string_of_defid id ^ string_of_params ps ^ " : " ^ string_of_typ t and string_of_params = function diff --git a/spectec/src/el/print.mli b/spectec/src/el/print.mli index 72e872d842..1146857537 100644 --- a/spectec/src/el/print.mli +++ b/spectec/src/el/print.mli @@ -5,8 +5,8 @@ val string_of_unop : unop -> string val string_of_binop : binop -> string val string_of_cmpop : cmpop -> string val string_of_iter : iter -> string -val string_of_typ : ?short:bool -> typ -> string -val string_of_typfield : ?short:bool -> typfield -> string +val string_of_typ : ?short: bool -> typ -> string +val string_of_typfield : ?short: bool -> typfield -> string val string_of_exp : exp -> string val string_of_exps : string -> exp list -> string val string_of_expfield : expfield -> string diff --git a/spectec/src/el/subst.ml b/spectec/src/el/subst.ml index 23fa722ace..09c8da368c 100644 --- a/spectec/src/el/subst.ml +++ b/spectec/src/el/subst.ml @@ -252,7 +252,7 @@ and subst_param s p = (match p.it with | ExpP (id, t) -> ExpP (id, subst_typ s t) | TypP id -> TypP id - | GramP (id, t) -> GramP (id, subst_typ s t) + | GramP (id, ps, t) -> GramP (id, List.map (subst_param s) ps, subst_typ s t) | DefP (id, ps, t) -> DefP (id, List.map (subst_param s) ps, subst_typ s t) ) $ p.at diff --git a/spectec/src/exe-spectec/main.ml b/spectec/src/exe-spectec/main.ml index d17c1baa5c..04b317f460 100644 --- a/spectec/src/exe-spectec/main.ml +++ b/spectec/src/exe-spectec/main.ml @@ -152,6 +152,7 @@ let argspec = Arg.align ( "--print-all-il", Arg.Set print_all_il, " Print IL after each step"; "--print-al", Arg.Set print_al, " Print al"; "--print-al-o", Arg.Set_string print_al_o, " Print al with given name"; + "--print-il-notes", Arg.Set Il.Print.print_notes, " Print IL with type annotations"; "--print-no-pos", Arg.Set print_no_pos, " Suppress position info in output"; ] @ List.map pass_argspec all_passes @ [ "--all-passes", Arg.Unit (fun () -> List.iter enable_pass all_passes)," Run all passes"; diff --git a/spectec/src/frontend/det.ml b/spectec/src/frontend/det.ml new file mode 100644 index 0000000000..c48903e05e --- /dev/null +++ b/spectec/src/frontend/det.ml @@ -0,0 +1,217 @@ +open Util.Source +open Il.Ast +open Il.Free + +include Xl.Gen_free + +let det_list = free_list +let det_list_dep = free_list_dep + + +(* Iterations *) + +let rec det_iter iter = + match iter with + | Opt | List | List1 -> empty + | ListN (e, _xo) -> det_exp e + + +(* Types *) + +and det_typ t = + Il.Debug.(log_at "il.det_typ" t.at + (fun _ -> fmt "%s" (il_typ t)) + (fun s -> String.concat ", " (Set.elements s.varid)) + ) @@ fun _ -> + match t.it with + | VarT (_x, as_) -> det_list det_arg as_ + | BoolT | NumT _ | TextT -> empty + | TupT xts -> det_list_dep det_typbind bound_typbind xts + | IterT (t1, iter) -> det_typ t1 ++ det_iter iter + +and det_typbind (_x, t) = det_typ t +and bound_typbind (x, _t) = bound_varid x + + +(* Expressions *) + +and det_exp e = + Il.Debug.(log_at "il.det_exp" e.at + (fun _ -> fmt "%s" (il_exp e)) + (fun s -> String.concat ", " (Set.elements s.varid)) + ) @@ fun _ -> + match e.it with + | VarE x -> bound_varid x + | BoolE _ | NumE _ | TextE _ -> empty + (* We consider arithmetic expressions determinate, + * since we sometimes need to use invertible formulas. *) + | CvtE (e1, _, _) | UnE (#Xl.Num.unop, _, e1) | TheE e1 | LiftE e1 + | SubE (e1, _, _) -> det_exp e1 + | BinE (#Xl.Num.binop, _, e1, e2) | CatE (e1, e2) -> det_exp e1 ++ det_exp e2 + | OptE eo -> free_opt det_exp eo + | ListE es | TupE es -> det_list det_exp es + | CaseE (_, e1) | UncaseE (e1, _) -> det_exp e1 + | StrE efs -> det_list det_expfield efs + | IterE (e1, ite) -> det_iterexp (det_exp e1) ite + (* As a special hack to work with bijective functions, + * we treat last position of a call as a pattern, too. *) + | CallE (_, []) -> empty + | CallE (_, as_) -> det_list det_idx_arg as_ ++ det_arg (Util.Lib.List.last as_) + | UnE _ | BinE _ | CmpE _ + | IdxE _ | SliceE _ | UpdE _ | ExtE _ | CompE _ | MemE _ + | ProjE _ | DotE _ | LenE _ -> det_idx_exp e + +and det_expfield (_, e) = det_exp e + +and det_iterexp s1 (it, xes) = + s1 -- bound_iter it -- free_list bound_varid (List.map fst xes) ++ + det_iter it ++ + det_list det_exp (List.filter_map + (fun (x, e) -> if Set.mem x.it s1.varid then Some e else None) xes) + + +and det_cond_exp e = + Il.Debug.(log_at "il.det_cond_exp" e.at + (fun _ -> fmt "%s" (il_exp e)) + (fun s -> String.concat ", " (Set.elements s.varid)) + ) @@ fun _ -> + match e.it with + | UnE (#Xl.Bool.unop, _, e1) -> det_cond_exp e1 + | BinE (#Xl.Bool.binop, _, e1, e2) -> det_cond_exp e1 ++ det_cond_exp e2 + | CmpE (`EqOp, _, e1, e2) -> det_exp e1 ++ det_exp e2 + | MemE (e1, e2) -> det_exp e1 ++ det_quant_exp e2 + | _ -> det_quant_exp e + + +and det_idx_exp e = + Il.Debug.(log_at "il.det_idx_exp" e.at + (fun _ -> fmt "%s" (il_exp e)) + (fun s -> String.concat ", " (Set.elements s.varid)) + ) @@ fun _ -> + match e.it with + | VarE _ -> empty + | LiftE e1 | SubE (e1, _, _) | CaseE (_, e1) -> det_idx_exp e1 + | OptE eo -> free_opt det_idx_exp eo + | ListE es | TupE es -> det_list det_idx_exp es + | StrE efs -> det_list det_idx_expfield efs + | IterE (e1, ite) -> det_idx_iterexp (det_idx_exp e1) ite + | CallE (_, as_) -> det_list det_idx_arg as_ + | IdxE (e1, e2) -> det_quant_exp e1 ++ det_exp e2 + | _ -> det_quant_exp e + +and det_idx_expfield (_, e) = + det_idx_exp e + +and det_idx_iter iter = + match iter with + | Opt | List | List1 -> empty + | ListN (e, x_opt) -> det_idx_exp e ++ free_opt bound_varid x_opt + +and det_idx_iterexp s1 (it, xes) = + s1 -- free_list bound_varid (List.map fst xes) ++ + det_idx_iter it ++ + det_list det_exp (List.filter_map + (fun (x, e) -> if Set.mem x.it s1.varid then Some e else None) xes) + + +and det_quant_exp e = + Il.Debug.(log_at "il.det_quant_exp" e.at + (fun _ -> fmt "%s" (il_exp e)) + (fun s -> String.concat ", " (Set.elements s.varid)) + ) @@ fun _ -> + match e.it with + | VarE x -> bound_varid x + | BoolE _ | NumE _ | TextE _ -> empty + | UnE (_, _, e1) | ProjE (e1, _) | TheE e1 | LiftE e1 | LenE e1 + | CvtE (e1, _, _) | SubE (e1, _, _) -> + det_quant_exp e1 + | BinE (_, _, e1, e2) | CmpE (_, _, e1, e2) + | IdxE (e1, e2) | MemE (e1, e2) | CatE (e1, e2) | CompE (e1, e2) -> + det_quant_exp e1 ++ det_quant_exp e2 + | SliceE (e1, e2, e3) -> + det_quant_exp e1 ++ det_quant_exp e2 ++ det_quant_exp e3 + | UpdE (e1, p, e2) | ExtE (e1, p, e2) -> + det_quant_exp e1 ++ det_quant_path p ++ det_quant_exp e2 + | DotE (e1, _) | CaseE (_, e1) | UncaseE (e1, _) -> det_quant_exp e1 + | OptE eo -> free_opt det_quant_exp eo + | ListE es | TupE es -> det_list det_quant_exp es + | StrE efs -> det_list det_quant_expfield efs + | IterE (e1, ite) -> det_quant_iterexp (det_quant_exp e1) ite + | CallE (_, as_) -> det_list det_quant_arg as_ + +and det_quant_expfield (_, e) = + det_quant_exp e + +and det_quant_iterexp s1 (it, xes) = + s1 -- bound_iter it -- free_list bound_varid (List.map fst xes) ++ + det_quant_iter it ++ + det_list det_exp (List.filter_map + (fun (x, e) -> if Set.mem x.it s1.varid then Some e else None) xes) + +and det_quant_path p = + match p.it with + | RootP -> empty + | IdxP (p1, e) -> det_quant_path p1 ++ det_quant_exp e + | SliceP (p1, e1, e2) -> + det_quant_path p1 ++ det_quant_exp e1 ++ det_quant_exp e2 + | DotP (p1, _) -> det_quant_path p1 + +and det_quant_iter iter = + match iter with + | Opt | List | List1 -> empty + | ListN (e, _x_opt) -> det_quant_exp e + + +(* Grammars *) + +and det_sym g = + Il.Debug.(log_at "il.det_sym" g.at + (fun _ -> fmt "%s" (il_sym g)) + (fun s -> String.concat ", " (Set.elements s.varid)) + ) @@ fun _ -> + match g.it with + | VarG (_x, as_) -> det_list det_arg as_ + | NumG _ | TextG _ | EpsG -> empty + | SeqG gs | AltG gs -> det_list det_sym gs + | RangeG (g1, g2) -> det_sym g1 ++ det_sym g2 + | IterG (g1, ite) -> det_iterexp (det_sym g1) ite + | AttrG (e, g1) -> det_exp e ++ det_sym g1 + + +(* Premises *) + +and det_prem pr = + Il.Debug.(log_at "il.det_prem" pr.at + (fun _ -> fmt "%s" (il_prem pr)) + (fun s -> String.concat ", " (Set.elements s.varid)) + ) @@ fun _ -> + match pr.it with + | RulePr (_x, _mixop, e) -> det_exp e + | IfPr e -> det_cond_exp e + | LetPr (e1, _e2, _xs) -> det_exp e1 + | ElsePr -> empty + | IterPr (pr1, ite) -> det_iterexp (det_prem pr1) ite + + +(* Definitions *) + +and det_arg a = + match a.it with + | ExpA e -> det_exp e + | TypA t -> free_typ t (* must be an id *) + | GramA g -> free_sym g (* must be an id *) + | DefA x -> bound_defid x + +and det_idx_arg a = + match a.it with + | ExpA e -> det_idx_exp e + | TypA _ -> empty + | GramA _ -> empty + | DefA _ -> empty + +and det_quant_arg a = + match a.it with + | ExpA e -> det_quant_exp e + | TypA _ -> empty + | GramA _ -> empty + | DefA _ -> empty diff --git a/spectec/src/frontend/det.mli b/spectec/src/frontend/det.mli new file mode 100644 index 0000000000..907161e5eb --- /dev/null +++ b/spectec/src/frontend/det.mli @@ -0,0 +1,21 @@ +open Il.Ast + +include module type of Xl.Gen_free + +(* A free variable is "determinate" if: + - it occurs as an iteration variable + - it occurs in destructuring position on the lhs + - it occurs in destructuring position on either side of an equational premise + - it occurs in destructuring position as an indexing operand + - it occurs in destructuring position as the last call arg + (this case is to handle function inverses) + This is a pragmatic criterium, intended only for sanity checks. +*) + +val det_typ : typ -> sets +val det_exp : exp -> sets +val det_sym : sym -> sets +val det_prem : prem -> sets +val det_arg : arg -> sets + +val det_list : ('a -> sets) -> 'a list -> sets diff --git a/spectec/src/frontend/dim.ml b/spectec/src/frontend/dim.ml index a671f4ab83..039eb0941b 100644 --- a/spectec/src/frontend/dim.ml +++ b/spectec/src/frontend/dim.ml @@ -1,8 +1,7 @@ open Util open Source -open El +open Il open Ast -open Convert (* Errors *) @@ -12,19 +11,18 @@ let error at msg = Error.error at "dimension" msg (* Environment *) -module Env = Map.Make(String) +module Map = Map.Make(String) -type outer = id list type ctx = iter list -type env = ctx Env.t -type renv = (region * ctx * [`Impl | `Expl]) list Env.t +type dims = (region * ctx) Map.t +type outer = dims +type rdims = (region * ctx * [`Impl | `Expl | `Outer]) list Map.t -let new_env outer = - List.fold_left (fun env id -> - Env.add id.it [(id.at, [], `Expl)] env) Env.empty outer |> ref +let new_dims outer = + ref (Map.map (fun (at, ctx) -> [(at, ctx, `Outer)]) outer) -let localize outer env = - List.fold_left (fun env id -> Env.remove id.it env) env outer +let localize outer dims = + Map.fold (fun x _ dims -> Map.remove x dims) outer dims let il_occur occur = @@ -32,7 +30,7 @@ let il_occur occur = List.map (fun (x, (t, iters)) -> x ^ ":" ^ Il.Debug.il_typ t ^ String.concat "" (List.map Il.Debug.il_iter iters) - ) (Env.bindings occur) + ) (Map.bindings occur) in "{" ^ String.concat ", " ss ^ "}" @@ -52,14 +50,15 @@ let rec is_prefix ctx1 ctx2 = let rec check_ctx id (at0, ctx0, mode0) = function | [] -> () | (at, ctx, mode)::ctxs -> - if not (is_prefix ctx0 ctx) && (mode0 = `Expl || mode = `Expl) then + if not (is_prefix ctx0 ctx) && (mode0 <> `Impl || mode <> `Impl) then error at ("inconsistent variable context, " ^ string_of_ctx id ctx0 ^ " vs " ^ string_of_ctx id ctx ^ " (" ^ string_of_region at0 ^ ")"); check_ctx id (at0, ctx0, mode0) ctxs -let check_ctxs id ctxs : ctx = +let check_ctxs id ctxs : region * ctx = + (* Invariant: there is at most one Outer occurrence per id. *) let sorted = if List.for_all (fun (_, _, mode) -> mode = `Impl) ctxs then (* Take first occurrence *) @@ -68,18 +67,19 @@ let check_ctxs id ctxs : ctx = ctxs else let sorted = List.stable_sort - (fun (_, ctx1, _) (_, ctx2, _) -> + (fun (_, ctx1, mode1) (_, ctx2, mode2) -> + if mode1 = `Outer then -1 else if mode2 = `Outer then +1 else compare (List.length ctx1) (List.length ctx2)) ctxs in check_ctx id (List.hd sorted) (List.tl sorted); sorted in - let _, ctx, _ = List.hd sorted in - ctx + let at, ctx, _ = List.hd sorted in + at, ctx -let check_env (env : renv ref) : env = - Env.mapi check_ctxs !env +let check_dims (dims : rdims ref) : dims = + Map.mapi check_ctxs !dims (* Collecting constraints *) @@ -88,280 +88,312 @@ let strip_index = function | ListN (e, Some _) -> ListN (e, None) | iter -> iter -let check_typid _env _ctx _id = () (* Types are always global *) -let check_gramid _env _ctx _id = () (* Grammars are always global *) +let check_typid _dims _ctx _id = () (* Types are always global *) +let check_gramid _dims _ctx _id = () (* Grammars are always global *) -let check_varid env ctx mode id = - let ctxs = Option.value (Env.find_opt id.it !env) ~default:[] in - env := Env.add id.it ((id.at, ctx, mode)::ctxs) !env +let check_varid dims ctx mode id = + dims := Map.add_to_list id.it (id.at, ctx, mode) !dims -let rec check_iter env ctx iter = - match iter with +let uncheck_varid dims id = + dims := Map.remove id.it !dims + +let rec check_iter dims ctx it = + match it with | Opt | List | List1 -> () - | ListN (e, id_opt) -> - check_exp env ctx e; - (* TODO(2, rossberg): The dimension for id should match that of e: - * for example, if we b^(i check_varid env [strip_index iter] `Expl id) id_opt - -and check_typ env ctx t = + | ListN (e, x_opt) -> + check_exp dims ctx e; + Option.iter (check_varid dims [] `Expl) x_opt + +and check_iterexp : 'a. _ -> _ -> (_ -> _ -> 'a -> unit) -> 'a -> _ -> unit = + fun dims ctx f body (it, xes) -> + Debug.(log "il.check_iterexp" + (fun _ -> fmt "%s |- %s" (domain !dims) (il_iterexp (it, xes))) + (fun _ -> domain !dims) + ) @@ fun _ -> + check_iter dims ctx it; + List.iter (fun (x, e) -> check_varid dims [] `Expl x; check_exp dims ctx e) xes; + (* Only check body if iteration isn't annotated already. + * That may happen when e.g. an expression got substituted originating from + * a type definition already processed earlier. *) + if xes = [] then f dims (strip_index it::ctx) body; + (* Remove locals. + * All locals are scalar, so no checking or annotation is needed for them. *) + List.iter (fun (x, _) -> uncheck_varid dims x) xes; + match it with + | ListN (_, Some x) -> uncheck_varid dims x + | _ -> () + +and check_typ dims ctx t = match t.it with - | VarT (id, args) -> - check_typid env ctx (Convert.strip_var_suffix id); - check_varid env ctx `Impl id; - List.iter (check_arg env ctx) args + | VarT (x, args) -> + check_typid dims ctx x; + List.iter (check_arg dims ctx) args | BoolT | NumT _ - | TextT -> - check_varid env ctx `Impl (Convert.varid_of_typ t) - | AtomT _ -> () - | ParenT t1 - | BrackT (_, t1, _) -> check_typ env ctx t1 - | TupT ts - | SeqT ts -> List.iter (check_typ env ctx) ts + | TextT -> () + | TupT xts -> List.iter (check_typbind dims ctx) xts | IterT (t1, iter) -> - check_iter env ctx iter; - check_typ env (strip_index iter::ctx) t1 - | StrT (_, ts, tfs, _) -> - iter_nl_list (check_typ env ctx) ts; - iter_nl_list (fun (_, (tI, prems), _) -> - let env' = ref Env.empty in - check_typ env' ctx tI; - iter_nl_list (check_prem env' ctx) prems + check_iter dims ctx iter; + check_typ dims (strip_index iter::ctx) t1 + +and check_typbind dims ctx (x, t) = + check_varid dims ctx `Impl x; + check_typ dims ctx t + +(* +and check_deftyp dims ctx dt = + match dt.it with + | AliasT t -> + check_typ dims ctx t + | StructT tfs -> + List.iter (fun (_, (qs, tI, prems), _) -> + let dims' = ref Map.empty in + assert (qs = []); + check_typ dims' ctx tI; + List.iter (check_prem dims' ctx) prems ) tfs - | CaseT (_, ts, tcs, _) -> - iter_nl_list (check_typ env ctx) ts; - iter_nl_list (fun (_, (tI, prems), _) -> - let env' = ref Env.empty in - check_typ env' ctx tI; - iter_nl_list (check_prem env' ctx) prems + | VariantT tcs -> + List.iter (fun (_, (qs, tI, prems), _) -> + let dims' = ref Map.empty in + assert (qs = []); + check_typ dims' ctx tI; + List.iter (check_prem dims' ctx) prems ) tcs - | ConT ((t1, prems), _) -> - let env' = ref Env.empty in - check_typ env' ctx t1; - iter_nl_list (check_prem env' ctx) prems - | RangeT tes -> - iter_nl_list (fun (eI1, eoI2) -> - let env' = ref Env.empty in - check_exp env' ctx eI1; - Option.iter (check_exp env' ctx) eoI2; - ) tes - | InfixT (t1, _, t2) -> - check_typ env ctx t1; - check_typ env ctx t2 - -and check_exp env ctx e = +*) + +and check_exp dims ctx e = + Debug.(log "il.check_exp" + (fun _ -> il_exp e) + (fun _ -> domain !dims) + ) @@ fun _ -> match e.it with - | VarE (id, args) -> - check_varid env ctx `Expl id; - List.iter (check_arg env ctx) args - | AtomE _ + | VarE x -> + check_varid dims ctx `Expl x | BoolE _ | NumE _ - | TextE _ - | SizeE _ - | EpsE -> () - | CvtE (e1, _) - | UnE (_, e1) - | DotE (e1, _) + | TextE _ -> () + | CvtE (e1, _, _) + | UnE (_, _, e1) | LenE e1 - | ParenE e1 - | BrackE (_, e1, _) - | TypE (e1, _) - | ArithE e1 -> check_exp env ctx e1 - | BinE (e1, _, e2) - | CmpE (e1, _, e2) + | ProjE (e1, _) + | TheE e1 + | LiftE e1 -> + check_exp dims ctx e1 + | BinE (_, _, e1, e2) + | CmpE (_, _, e1, e2) | IdxE (e1, e2) - | CommaE (e1, e2) | CatE (e1, e2) | MemE (e1, e2) - | InfixE (e1, _, e2) -> - check_exp env ctx e1; - check_exp env ctx e2 + | CompE (e1, e2) -> + check_exp dims ctx e1; + check_exp dims ctx e2 | SliceE (e1, e2, e3) -> - check_exp env ctx e1; - check_exp env ctx e2; - check_exp env ctx e3 + check_exp dims ctx e1; + check_exp dims ctx e2; + check_exp dims ctx e3 | UpdE (e1, p, e2) | ExtE (e1, p, e2) -> - check_exp env ctx e1; - check_path env ctx p; - check_exp env ctx e2 - | SeqE es + check_exp dims ctx e1; + check_path dims ctx p; + check_exp dims ctx e2 + | OptE eo -> + Option.iter (check_exp dims ctx) eo | ListE es - | TupE es -> List.iter (check_exp env ctx) es - | StrE efs -> iter_nl_list (fun (_, eI) -> check_exp env ctx eI) efs - | CallE (_, args) -> List.iter (check_arg env ctx) args - | IterE (e1, iter) -> - check_iter env ctx iter; - check_exp env (strip_index iter::ctx) e1 - | HoleE _ - | FuseE _ - | UnparenE _ - | LatexE _ -> assert false - -and check_path env ctx p = + | TupE es -> + List.iter (check_exp dims ctx) es + | StrE efs -> + List.iter (check_expfield dims ctx) efs + | DotE (e1, _) + | CaseE (_, e1) + | UncaseE (e1, _) -> + check_exp dims ctx e1 + | CallE (_, as_) -> + List.iter (check_arg dims ctx) as_ + | IterE (e1, ite) -> + check_iterexp dims ctx check_exp e1 ite + | SubE (e1, t1, t2) -> + check_exp dims ctx e1; + check_typ dims ctx t1; + check_typ dims ctx t2 + +and check_expfield dims ctx (_, e) = + check_exp dims ctx e + +and check_path dims ctx p = match p.it with | RootP -> () | IdxP (p1, e) -> - check_path env ctx p1; - check_exp env ctx e + check_path dims ctx p1; + check_exp dims ctx e | SliceP (p1, e1, e2) -> - check_path env ctx p1; - check_exp env ctx e1; - check_exp env ctx e2 + check_path dims ctx p1; + check_exp dims ctx e1; + check_exp dims ctx e2 | DotP (p1, _) -> - check_path env ctx p1 + check_path dims ctx p1 -and check_sym env ctx g = +and check_sym dims ctx g = match g.it with - | VarG (id, args) -> - check_gramid env ctx id; - List.iter (check_arg env ctx) args + | VarG (x, args) -> + check_gramid dims ctx x; + List.iter (check_arg dims ctx) args | NumG _ | TextG _ | EpsG -> () | SeqG gs - | AltG gs -> iter_nl_list (check_sym env ctx) gs + | AltG gs -> + List.iter (check_sym dims ctx) gs | RangeG (g1, g2) -> - check_sym env ctx g1; - check_sym env ctx g2 - | ParenG g1 -> - check_sym env ctx g1 - | TupG gs -> List.iter (check_sym env ctx) gs - | ArithG e -> check_exp env ctx e + check_sym dims ctx g1; + check_sym dims ctx g2 | AttrG (e, g1) -> - check_exp env ctx e; - check_sym env ctx g1 - | IterG (g1, iter) -> - check_iter env ctx iter; - check_sym env (strip_index iter::ctx) g1 - | FuseG _ - | UnparenG _ -> assert false - -and check_prod env ctx prod = - match prod.it with - | SynthP (g, e, prems) -> - check_sym env ctx g; - check_exp env ctx e; - iter_nl_list (check_prem env ctx) prems - | RangeP (g1, e1, g2, e2) -> - check_sym env ctx g1; - check_exp env ctx e1; - check_sym env ctx g2; - check_exp env ctx e2 - | EquivP (g1, g2, prems) -> - check_sym env ctx g1; - check_sym env ctx g2; - iter_nl_list (check_prem env ctx) prems - -and check_gram env ctx gram = - let (_dots1, prods, _dots2) = gram.it in - iter_nl_list (check_prod env ctx) prods - -and check_prem env ctx prem = + check_exp dims ctx e; + check_sym dims ctx g1 + | IterG (g1, ite) -> + check_iterexp dims ctx check_sym g1 ite + + +and check_prem dims ctx prem = match prem.it with - | VarPr _ -> () (* skip, since var decls need not be under iterations *) - | RulePr (_id, e) -> check_exp env ctx e - | IfPr e -> check_exp env ctx e + | RulePr (_x, _mixop, e) -> check_exp dims ctx e + | IfPr e -> check_exp dims ctx e | ElsePr -> () - | IterPr (prem', iter) -> - check_iter env ctx iter; - check_prem env (strip_index iter::ctx) prem' - -and check_arg env ctx a = - match !(a.it) with - | ExpA e -> check_exp env ctx e - | TypA t -> check_typ env ctx t - | GramA g -> check_sym env ctx g - | DefA _id -> () - -and check_param env ctx p = + | LetPr (e1, e2, _xs) -> + check_exp dims ctx e1; + check_exp dims ctx e2 + | IterPr (prem1, ite) -> + check_iterexp dims ctx check_prem prem1 ite + +and check_arg dims ctx a = + match a.it with + | ExpA e -> check_exp dims ctx e + | TypA t -> check_typ dims ctx t + | GramA g -> check_sym dims ctx g + | DefA _x -> () + +and check_param dims p = match p.it with - | ExpP (id, t) -> - check_varid env ctx `Expl id; - check_typ env ctx t - | TypP id -> - check_typid env ctx id; - check_varid env ctx `Impl id - | GramP (id, t) -> - check_gramid env ctx id; - check_typ env ctx t - | DefP (_id, ps, t) -> - List.iter (check_param env ctx) ps; - check_typ env ctx t - -let check_def d : env = - let env = new_env [] in + | ExpP (x, t) -> + check_varid dims [] `Expl x; + check_typ dims [] t + | TypP x -> + check_typid dims [] x; + check_varid dims [] `Impl x + | GramP (x, ps, t) -> + check_gramid dims [] x; + List.iter (check_param dims) ps; + check_typ dims [] t + | DefP (_x, ps, t) -> + List.iter (check_param dims) ps; + check_typ dims [] t + + +(* External interface *) + +let check outer ps as_ ts es gs prs : dims = + let dims = new_dims outer in + List.iter (check_param dims) ps; + List.iter (check_arg dims []) as_; + List.iter (check_typ dims []) ts; + List.iter (check_exp dims []) es; + List.iter (check_sym dims []) gs; + List.iter (check_prem dims []) prs; + localize outer (check_dims dims) + +(* +let rec check_def d : dims = + let dims = new_dims Map.empty in match d.it with - | FamD (_id, ps, _hints) -> - List.iter (check_param env []) ps; - check_env env - | TypD (_id1, _id2, args, t, _hints) -> - List.iter (check_arg env []) args; - check_typ env [] t; - check_env env - | GramD (_id1, _id2, ps, t, gram, _hints) -> - List.iter (check_param env []) ps; - check_typ env [] t; - check_gram env [] gram; - check_env env - | RelD (_id, t, _hints) -> - check_typ env [] t; - check_env env - | RuleD (_id1, _id2, e, prems) -> - check_exp env [] e; - iter_nl_list (check_prem env []) prems; - check_env env - | VarD (_id, t, _hints) -> - check_typ env [] t; - check_env env - | DecD (_id, ps, t, _hints) -> - List.iter (check_param env []) ps; - check_typ env [] t; - check_env env - | DefD (_id, args, e, prems) -> - List.iter (check_arg env []) args; - check_exp env [] e; - iter_nl_list (check_prem env []) prems; - check_env env - | SepD | HintD _ -> Env.empty - - -let check_prod outer prod : env = - let env = new_env outer in - check_prod env [] prod; - localize outer (check_env env) - -let check_typdef outer t prems : env = - let env = new_env outer in - check_typ env [] t; - iter_nl_list (check_prem env []) prems; - localize outer (check_env env) + | TypD (_x, ps, insts) -> + List.iter (check_param dims) ps; + List.iter (check_inst dims) insts; + check_dims dims + | RelD (_x, _mixop, t, rules) -> + check_typ dims [] t; + List.iter (check_rule dims) rules; + check_dims dims + | DecD (_x, ps, t, clauses) -> + List.iter (check_param dims) ps; + check_typ dims [] t; + List.iter (check_clause dims) clauses; + check_dims dims + | GramD (_x, ps, t, prods) -> + List.iter (check_param dims) ps; + check_typ dims [] t; + List.iter (check_prod dims) prods; + check_dims dims + | RecD _ds -> + assert false + | HintD _ -> + check_dims dims + +and check_inst dims inst = + match inst.it with + | InstD (qs, as_, dt) -> + assert (qs = []); + List.iter (check_arg dims []) as_; + check_deftyp dims [] dt + +and check_rule dims rule = + match rule.it with + | RuleD (_x, qs, _mixop, e, prems) -> + assert (qs = []); + check_exp dims [] e; + List.iter (check_prem dims []) prems + +and check_clause dims clause = + match clause.it with + | DefD (qs, as_, e, prems) -> + assert (qs = []); + List.iter (check_arg dims []) as_; + check_exp dims [] e; + List.iter (check_prem dims []) prems + +and check_prod dims prod = + match prod.it with + | ProdD (qs, g, e, prems) -> + assert (qs = []); + check_sym dims [] g; + check_exp dims [] e; + List.iter (check_prem dims []) prems + + +let check_inst outer as_ dt : dims = + let dims = new_dims outer in + List.iter (check_arg dims []) as_; + check_deftyp dims [] dt; + localize outer (check_dims dims) + +let check_prod outer g e prems : dims = + let dims = new_dims outer in + check_sym dims [] g; + check_exp dims [] e; + List.iter (check_prem dims []) prems; + localize outer (check_dims dims) + +let check_abbr outer g1 g2 prems : dims = + let dims = new_dims outer in + check_sym dims [] g1; + check_sym dims [] g2; + List.iter (check_prem dims []) prems; + localize outer (check_dims dims) + +let check_deftyp outer ts prems : dims = + let dims = new_dims outer in + List.iter (check_typ dims []) ts; + List.iter (check_prem dims []) prems; + localize outer (check_dims dims) +*) (* Annotating iterations *) -open Il.Ast - -type env' = iter list Env.t -type occur = (typ * iter list) Env.t +type occur = (typ * iter list) Map.t -let union = Env.union (fun _ (_, ctx1 as occ1) (_, ctx2 as occ2) -> +let union = Map.union (fun _ (_, ctx1 as occ1) (_, ctx2 as occ2) -> (* For well-typed scripts, t1 == t2. *) Some (if List.length ctx1 < List.length ctx2 then occ1 else occ2)) -let strip_index = function - | ListN (e, Some _) -> ListN (e, None) - | iter -> iter - let annot_varid' id' = function | Opt -> id' ^ Il.Print.string_of_iter Opt | _ -> id' ^ Il.Print.string_of_iter List @@ -370,247 +402,320 @@ let rec annot_varid id = function | [] -> id | iter::iters -> annot_varid (annot_varid' id.it iter $ id.at) iters -let rec annot_iter env iter : Il.Ast.iter * (occur * occur) = + +let rec annot_iter side dims iter : iter * occur = Il.Debug.(log "il.annot_iter" (fun _ -> fmt "%s" (il_iter iter)) - (fun (iter', (occur1, occur2)) -> fmt "%s %s %s" (il_iter iter') - (il_occur occur1) (il_occur occur2)) + (fun (iter', occur) -> fmt "%s %s" (il_iter iter') (il_occur occur)) ) @@ fun _ -> match iter with - | Opt | List | List1 -> iter, Env.(empty, empty) - | ListN (e, id_opt) -> - let e', occur1 = annot_exp env e in - let occur2 = - match id_opt with - | None -> Env.empty - | Some id -> Env.singleton id.it (NumT `NatT $ id.at, Env.find id.it env) - in - ListN (e', id_opt), (occur1, occur2) - -and annot_exp env e : Il.Ast.exp * occur = + | Opt | List | List1 -> iter, Map.empty + | ListN (e, x_opt) -> + let e', occur = annot_exp side dims e in + ListN (e', x_opt), occur + +and annot_iterexp side dims occur1 (it, xes) at : iterexp * occur = + Il.Debug.(log_at "il.annot_iterexp" at + (fun _ -> fmt "%s %s" (il_iter it) (il_occur occur1)) + (fun ((it', _), occur') -> fmt "%s %s" (il_iter it') (il_occur occur')) + ) @@ fun _ -> + assert (xes = []); + let it', occur2 = annot_iter side dims it in + (* Remove locals and lower context level of non-locals *) + let occur1' = + List.filter_map (fun (x, (t, its)) -> + match its with + | [] -> None + | it::its' -> Some (x, (annot_varid' x it, (IterT (t, it) $ at, its'))) + ) (Map.bindings occur1) + in + List.iter (fun (x, _) -> assert (not (Map.mem x.it dims))) xes; + if side = `Rhs && occur1' = [] && match it with Opt | ListN _ -> false | _ -> true then + error at "iteration does not contain iterable variable"; + let xes' = + List.map (fun (x, (x', (t, _))) -> x $ at, VarE (x' $ at) $$ at % t) occur1' in + (it', xes'), union (Map.of_seq (List.to_seq (List.map snd occur1'))) occur2 + +and annot_typ dims t : typ * occur = + Il.Debug.(log "il.annot_typ" + (fun _ -> fmt "%s" (il_typ t)) + (fun (t', occur') -> fmt "%s %s" (il_typ t') (il_occur occur')) + ) @@ fun _ -> + let it, occur = + match t.it with + | VarT (x, as1) -> + let as1', occurs = List.split (List.map (annot_arg dims) as1) in + VarT (x, as1'), List.fold_left union Map.empty occurs + | BoolT | NumT _ | TextT -> + t.it, Map.empty + | TupT xts -> + let xts', occurs = List.split (List.map (annot_typbind dims) xts) in + TupT xts', List.fold_left union Map.empty occurs + | IterT (t1, iter) -> + let t1', occur1 = annot_typ dims t1 in + let (iter', _), occur = annot_iterexp `Lhs dims occur1 (iter, []) t.at in + IterT (t1', iter'), occur + in {t with it}, occur + +and annot_typbind dims (x, t) : (id * typ) * occur = + let occur1 = + if x.it <> "_" && Map.mem x.it dims then + Map.singleton x.it (t, snd (Map.find x.it dims)) + else + Map.empty + in + let t', occur2 = annot_typ dims t in + (x, t'), union occur1 occur2 + + +and annot_exp side dims e : exp * occur = Il.Debug.(log "il.annot_exp" (fun _ -> fmt "%s" (il_exp e)) (fun (e', occur') -> fmt "%s %s" (il_exp e') (il_occur occur')) ) @@ fun _ -> let it, occur = match e.it with - | VarE id when id.it <> "_" && Env.mem id.it env -> - VarE id, Env.singleton id.it (e.note, Env.find id.it env) + | VarE x when x.it <> "_" && Map.mem x.it dims -> + VarE x, Map.singleton x.it (e.note, snd (Map.find x.it dims)) | VarE _ | BoolE _ | NumE _ | TextE _ -> - e.it, Env.empty + e.it, Map.empty | UnE (op, nt, e1) -> - let e1', occur1 = annot_exp env e1 in + let e1', occur1 = annot_exp side dims e1 in UnE (op, nt, e1'), occur1 | BinE (op, nt, e1, e2) -> - let e1', occur1 = annot_exp env e1 in - let e2', occur2 = annot_exp env e2 in + let e1', occur1 = annot_exp side dims e1 in + let e2', occur2 = annot_exp side dims e2 in BinE (op, nt, e1', e2'), union occur1 occur2 | CmpE (op, nt, e1, e2) -> - let e1', occur1 = annot_exp env e1 in - let e2', occur2 = annot_exp env e2 in + let side' = if op = `EqOp then `Lhs else side in + let e1', occur1 = annot_exp side' dims e1 in + let e2', occur2 = annot_exp side' dims e2 in CmpE (op, nt, e1', e2'), union occur1 occur2 | IdxE (e1, e2) -> - let e1', occur1 = annot_exp env e1 in - let e2', occur2 = annot_exp env e2 in + let e1', occur1 = annot_exp side dims e1 in + let e2', occur2 = annot_exp side dims e2 in IdxE (e1', e2'), union occur1 occur2 | SliceE (e1, e2, e3) -> - let e1', occur1 = annot_exp env e1 in - let e2', occur2 = annot_exp env e2 in - let e3', occur3 = annot_exp env e3 in + let e1', occur1 = annot_exp side dims e1 in + let e2', occur2 = annot_exp side dims e2 in + let e3', occur3 = annot_exp side dims e3 in SliceE (e1', e2', e3'), union (union occur1 occur2) occur3 | UpdE (e1, p, e2) -> - let e1', occur1 = annot_exp env e1 in - let p', occur2 = annot_path env p in - let e2', occur3 = annot_exp env e2 in + let e1', occur1 = annot_exp side dims e1 in + let p', occur2 = annot_path dims p in + let e2', occur3 = annot_exp side dims e2 in UpdE (e1', p', e2'), union (union occur1 occur2) occur3 | ExtE (e1, p, e2) -> - let e1', occur1 = annot_exp env e1 in - let p', occur2 = annot_path env p in - let e2', occur3 = annot_exp env e2 in + let e1', occur1 = annot_exp side dims e1 in + let p', occur2 = annot_path dims p in + let e2', occur3 = annot_exp side dims e2 in ExtE (e1', p', e2'), union (union occur1 occur2) occur3 | StrE efs -> - let efs', occurs = List.split (List.map (annot_expfield env) efs) in - StrE efs', List.fold_left union Env.empty occurs + let efs', occurs = List.split (List.map (annot_expfield side dims) efs) in + StrE efs', List.fold_left union Map.empty occurs | DotE (e1, atom) -> - let e1', occur1 = annot_exp env e1 in + let e1', occur1 = annot_exp side dims e1 in DotE (e1', atom), occur1 | CompE (e1, e2) -> - let e1', occur1 = annot_exp env e1 in - let e2', occur2 = annot_exp env e2 in + let e1', occur1 = annot_exp side dims e1 in + let e2', occur2 = annot_exp side dims e2 in CompE (e1', e2'), union occur1 occur2 | LenE e1 -> - let e1', occur1 = annot_exp env e1 in + let e1', occur1 = annot_exp side dims e1 in LenE e1', occur1 | TupE es -> - let es', occurs = List.split (List.map (annot_exp env) es) in - TupE es', List.fold_left union Env.empty occurs + let es', occurs = List.split (List.map (annot_exp side dims) es) in + TupE es', List.fold_left union Map.empty occurs | CallE (id, as1) -> - let as1', occurs = List.split (List.map (annot_arg env) as1) in - CallE (id, as1'), List.fold_left union Env.empty occurs + let as1', occurs = List.split (List.map (annot_arg dims) as1) in + CallE (id, as1'), List.fold_left union Map.empty occurs | IterE (e1, iter) -> - let e1', occur1 = annot_exp env e1 in - let iter', occur' = annot_iterexp env occur1 iter e.at in + let e1', occur1 = annot_exp side dims e1 in + let iter', occur' = annot_iterexp side dims occur1 iter e.at in IterE (e1', iter'), occur' | ProjE (e1, i) -> - let e1', occur1 = annot_exp env e1 in + let e1', occur1 = annot_exp side dims e1 in ProjE (e1', i), occur1 | UncaseE (e1, op) -> - let e1', occur1 = annot_exp env e1 in + let e1', occur1 = annot_exp side dims e1 in UncaseE (e1', op), occur1 | OptE None -> - OptE None, Env.empty + OptE None, Map.empty | OptE (Some e1) -> - let e1', occur1 = annot_exp env e1 in + let e1', occur1 = annot_exp side dims e1 in OptE (Some e1'), occur1 | TheE e1 -> - let e1', occur1 = annot_exp env e1 in + let e1', occur1 = annot_exp side dims e1 in TheE e1', occur1 | ListE es -> - let es', occurs = List.split (List.map (annot_exp env) es) in - ListE es', List.fold_left union Env.empty occurs + let es', occurs = List.split (List.map (annot_exp side dims) es) in + ListE es', List.fold_left union Map.empty occurs | LiftE e1 -> - let e1', occur1 = annot_exp env e1 in + let e1', occur1 = annot_exp side dims e1 in LiftE e1', occur1 | MemE (e1, e2) -> - let e1', occur1 = annot_exp env e1 in - let e2', occur2 = annot_exp env e2 in + let e1', occur1 = annot_exp side dims e1 in + let e2', occur2 = annot_exp side dims e2 in MemE (e1', e2'), union occur1 occur2 | CatE (e1, e2) -> - let e1', occur1 = annot_exp env e1 in - let e2', occur2 = annot_exp env e2 in + let e1', occur1 = annot_exp side dims e1 in + let e2', occur2 = annot_exp side dims e2 in CatE (e1', e2'), union occur1 occur2 | CaseE (atom, e1) -> - let e1', occur1 = annot_exp env e1 in + let e1', occur1 = annot_exp side dims e1 in CaseE (atom, e1'), occur1 | CvtE (e1, nt1, nt2) -> - let e1', occur1 = annot_exp env e1 in + let e1', occur1 = annot_exp side dims e1 in CvtE (e1', nt1, nt2), occur1 | SubE (e1, t1, t2) -> - let e1', occur1 = annot_exp env e1 in - SubE (e1', t1, t2), occur1 + let e1', occur1 = annot_exp side dims e1 in + let t1', occur2 = annot_typ dims t1 in + let t2', occur3 = annot_typ dims t2 in + SubE (e1', t1', t2'), union occur1 (union occur2 occur3) in {e with it}, occur -and annot_expfield env (atom, e) : Il.Ast.expfield * occur = - let e', occur = annot_exp env e in +and annot_expfield side dims (atom, e) : expfield * occur = + let e', occur = annot_exp side dims e in (atom, e'), occur -and annot_path env p : Il.Ast.path * occur = +and annot_path dims p : path * occur = let it, occur = match p.it with - | RootP -> RootP, Env.empty + | RootP -> RootP, Map.empty | IdxP (p1, e) -> - let p1', occur1 = annot_path env p1 in - let e', occur2 = annot_exp env e in + let p1', occur1 = annot_path dims p1 in + let e', occur2 = annot_exp `Rhs dims e in IdxP (p1', e'), union occur1 occur2 | SliceP (p1, e1, e2) -> - let p1', occur1 = annot_path env p1 in - let e1', occur2 = annot_exp env e1 in - let e2', occur3 = annot_exp env e2 in + let p1', occur1 = annot_path dims p1 in + let e1', occur2 = annot_exp `Rhs dims e1 in + let e2', occur3 = annot_exp `Rhs dims e2 in SliceP (p1', e1', e2'), union occur1 (union occur2 occur3) | DotP (p1, atom) -> - let p1', occur1 = annot_path env p1 in + let p1', occur1 = annot_path dims p1 in DotP (p1', atom), occur1 in {p with it}, occur -and annot_iterexp env occur1 (iter, xes) at : Il.Ast.iterexp * occur = - Il.Debug.(log "il.annot_iterexp" - (fun _ -> fmt "%s %s" (il_iter iter) (il_occur occur1)) - (fun ((iter', _), occur') -> fmt "%s %s" (il_iter iter') (il_occur occur')) - ) @@ fun _ -> - assert (xes = []); - let iter', (occur2, occur3) = annot_iter env iter in - let occur1'_l = - List.filter_map (fun (x, (t, iters)) -> - match iters with - | [] -> None - | iter::iters' -> -(* TODO(2, rossberg): this doesn't quite work, since it's comparing - annotated and unannotated expressions: - assert (Il.Eq.eq_iter (strip_index iter') iter); -*) - ignore strip_index; - Some (x, (annot_varid' x iter, (IterT (t, iter) $ at, iters'))) - ) (Env.bindings (union occur1 occur3)) - in -(* TODO(2, rossberg): this should be active - if occur1'_l = [] then - error at "iteration does not contain iterable variable"; -*) - let xes' = - List.map (fun (x, (x', (t, _))) -> x $ at, VarE (x' $ at) $$ at % t) occur1'_l in - (iter', xes'), union (Env.of_seq (List.to_seq (List.map snd occur1'_l))) occur2 - -and annot_sym env g : Il.Ast.sym * occur = +and annot_sym dims g : sym * occur = Il.Debug.(log_in "il.annot_sym" (fun _ -> il_sym g)); let it, occur = match g.it with - | VarG (id, as1) -> - let as1', occurs = List.split (List.map (annot_arg env) as1) in - VarG (id, as1'), List.fold_left union Env.empty occurs + | VarG (x, as1) -> + let as1', occurs = List.split (List.map (annot_arg dims) as1) in + VarG (x, as1'), List.fold_left union Map.empty occurs | NumG _ | TextG _ | EpsG -> - g.it, Env.empty + g.it, Map.empty | SeqG gs -> - let gs', occurs = List.split (List.map (annot_sym env) gs) in - SeqG gs', List.fold_left union Env.empty occurs + let gs', occurs = List.split (List.map (annot_sym dims) gs) in + SeqG gs', List.fold_left union Map.empty occurs | AltG gs -> - let gs', occurs = List.split (List.map (annot_sym env) gs) in - AltG gs', List.fold_left union Env.empty occurs + let gs', occurs = List.split (List.map (annot_sym dims) gs) in + AltG gs', List.fold_left union Map.empty occurs | RangeG (g1, g2) -> - let g1', occur1 = annot_sym env g1 in - let g2', occur2 = annot_sym env g2 in + let g1', occur1 = annot_sym dims g1 in + let g2', occur2 = annot_sym dims g2 in RangeG (g1', g2'), union occur1 occur2 | IterG (g1, iter) -> - let g1', occur1 = annot_sym env g1 in - let iter', occur' = annot_iterexp env occur1 iter g.at in + let g1', occur1 = annot_sym dims g1 in + let iter', occur' = annot_iterexp `Lhs dims occur1 iter g.at in IterG (g1', iter'), occur' | AttrG (e1, g2) -> - let e1', occur1 = annot_exp env e1 in - let g2', occur2 = annot_sym env g2 in + let e1', occur1 = annot_exp `Lhs dims e1 in + let g2', occur2 = annot_sym dims g2 in AttrG (e1', g2'), union occur1 occur2 in {g with it}, occur -and annot_arg env a : Il.Ast.arg * occur = +and annot_arg dims a : arg * occur = let it, occur = match a.it with | ExpA e -> - let e', occur1 = annot_exp env e in + let e', occur1 = annot_exp `Rhs dims e in ExpA e', occur1 - | TypA t -> TypA t, Env.empty - | DefA id -> DefA id, Env.empty + | TypA t -> + let t', occur1 = annot_typ dims t in + TypA t', occur1 + | DefA x -> + DefA x, Map.empty | GramA g -> - let g', occur1 = annot_sym env g in + let g', occur1 = annot_sym dims g in GramA g', occur1 in {a with it}, occur -and annot_prem env prem : Il.Ast.prem * occur = +and annot_param dims p : param * occur = + let it, occur = + match p.it with + | ExpP (x, t) -> + let occur1 = + if x.it <> "_" && Map.mem x.it dims then + Map.singleton x.it (t, snd (Map.find x.it dims)) + else + Map.empty + in + let t', occur2 = annot_typ dims t in + ExpP (x, t'), union occur1 occur2 + | TypP x -> + TypP x, Map.empty + | DefP (x, ps, t) -> + let ps', occurs = List.split (List.map (annot_param dims) ps) in + let t', occur2 = annot_typ dims t in + DefP (x, ps', t'), List.fold_left union occur2 occurs + | GramP (x, ps, t) -> + let ps', occurs = List.split (List.map (annot_param dims) ps) in + let t', occur2 = annot_typ dims t in + GramP (x, ps', t'), List.fold_left union occur2 occurs + in {p with it}, occur + +and annot_prem dims prem : prem * occur = let it, occur = match prem.it with - | RulePr (id, op, e) -> - let e', occur = annot_exp env e in - RulePr (id, op, e'), occur + | RulePr (x, op, e) -> + let e', occur = annot_exp `Rhs dims e in + RulePr (x, op, e'), occur | IfPr e -> - let e', occur = annot_exp env e in + let e', occur = annot_exp `Rhs dims e in IfPr e', occur | LetPr (e1, e2, ids) -> - let e1', occur1 = annot_exp env e1 in - let e2', occur2 = annot_exp env e2 in + let e1', occur1 = annot_exp `Lhs dims e1 in + let e2', occur2 = annot_exp `Rhs dims e2 in LetPr (e1', e2', ids), union occur1 occur2 | ElsePr -> - ElsePr, Env.empty + ElsePr, Map.empty | IterPr (prem1, iter) -> - let prem1', occur1 = annot_prem env prem1 in - let iter', occur' = annot_iterexp env occur1 iter prem.at in + let prem1', occur1 = annot_prem dims prem1 in + let iter', occur' = annot_iterexp `Rhs dims occur1 iter prem.at in IterPr (prem1', iter'), occur' in {prem with it}, occur +(* +let annot_inst dims inst : inst * occur = + let InstD (qs, as_, dt) = inst.it in + assert (qs = []); + let as', occurs = List.split (List.map (annot_arg dims) as_) in + let dt', occur = dt, Map.empty in (* assume dt was already annotated *) + {inst with it = InstD (qs, as', dt')}, List.fold_left union occur occurs +*) + + +(* Top-level entry points *) -let annot_top annot_x env x = - let x', occurs = annot_x env x in - assert (Env.for_all (fun _ (_t, ctx) -> ctx = []) occurs); +let annot_top annot_x dims x = + let x', occurs = annot_x dims x in + assert (Map.for_all (fun _ (_t, ctx) -> ctx = []) occurs); x' -let annot_iter = annot_top (fun env x -> let x', (y, _) = annot_iter env x in x', y) -let annot_exp = annot_top annot_exp +let annot_iter = annot_top (annot_iter `Rhs) +let annot_typ = annot_top annot_typ +let annot_exp = annot_top (annot_exp `Rhs) let annot_sym = annot_top annot_sym -let annot_arg = annot_top annot_arg let annot_prem = annot_top annot_prem +let annot_arg = annot_top annot_arg +let annot_param = annot_top annot_param + + +(* Environment manipulation *) + +let union dims1 dims2 = + Map.union (fun _ _ y -> Some y) dims1 dims2 + +let restrict dims bound = + Map.filter Il.Free.(fun x _ -> Set.mem x bound.varid) dims diff --git a/spectec/src/frontend/dim.mli b/spectec/src/frontend/dim.mli index c21cbae8d2..939231e6db 100644 --- a/spectec/src/frontend/dim.mli +++ b/spectec/src/frontend/dim.mli @@ -1,18 +1,24 @@ -module Env : Map.S with type key = string +open Il.Ast -type outer = El.Ast.id list -type env = El.Ast.iter list Env.t -type env' = Il.Ast.iter list Env.t +module Map : module type of Map.Make(String) -val annot_varid : Il.Ast.id -> Il.Ast.iter list -> Il.Ast.id +type dims = (Util.Source.region * iter list) Map.t +type outer = dims -val check_def : El.Ast.def -> env (* raises Error.Error *) -val check_prod : outer -> El.Ast.prod -> env (* raises Error.Error *) -val check_typdef : outer -> El.Ast.typ -> El.Ast.prem El.Ast.nl_list -> env - (* raises Error.Error *) +val check : + outer -> + param list -> arg list -> typ list -> exp list -> sym list -> prem list -> + dims (* raises Error.Error *) -val annot_iter : env' -> Il.Ast.iter -> Il.Ast.iter -val annot_exp : env' -> Il.Ast.exp -> Il.Ast.exp -val annot_sym : env' -> Il.Ast.sym -> Il.Ast.sym -val annot_arg : env' -> Il.Ast.arg -> Il.Ast.arg -val annot_prem : env' -> Il.Ast.prem -> Il.Ast.prem +val annot_varid : id -> iter list -> id + +val annot_iter : dims -> iter -> iter +val annot_typ : dims -> typ -> typ +val annot_exp : dims -> exp -> exp +val annot_sym : dims -> sym -> sym +val annot_prem : dims -> prem -> prem +val annot_arg : dims -> arg -> arg +val annot_param : dims -> param -> param + +val union : dims -> dims -> dims +val restrict : dims -> Il.Free.sets -> dims diff --git a/spectec/src/frontend/dune b/spectec/src/frontend/dune index c627edcd45..a77e8551e9 100644 --- a/spectec/src/frontend/dune +++ b/spectec/src/frontend/dune @@ -1,7 +1,7 @@ (library (name frontend) - (libraries util el il) - (modules lexer id parser parse dim eval elab) + (libraries util el il xl) + (modules lexer id parser parse dim det elab) ) (ocamllex diff --git a/spectec/src/frontend/elab.ml b/spectec/src/frontend/elab.ml index aebf818eb6..867dd2e839 100644 --- a/spectec/src/frontend/elab.ml +++ b/spectec/src/frontend/elab.ml @@ -6,9 +6,9 @@ open Ast open Convert open Print -module Il = struct include Il include Ast end +module Il = struct include Il include Ast include Print end -module Set = Free.Set +module Set = Il.Free.Set module Map = Map.Make (String) module Debug = struct include El.Debug include Il.Debug end @@ -23,15 +23,20 @@ exception Error = Error.Error let error at msg = Error.error at "type" msg let error_atom at atom t msg = - error at (msg ^ " `" ^ string_of_atom atom ^ "` in type `" ^ string_of_typ ~short:true t ^ "`") + error at (msg ^ " `" ^ string_of_atom atom ^ + "` in type `" ^ Il.string_of_typ t ^ "`") + +let error_mixop at mixop t msg = + error at (msg ^ " `" ^ Il.string_of_mixop mixop ^ + "` in type `" ^ Il.string_of_typ t ^ "`") let error_id id msg = error id.at (msg ^ " `" ^ id.it ^ "`") +let quote s = "`" ^ s ^ "`" -(* Helpers *) -let wild_exp t' = Il.VarE ("_" $ t'.at) $$ t'.at % t' +(* Helpers *) let unparen_exp e = match e.it with @@ -44,25 +49,26 @@ let unseq_exp e = | SeqE es -> es | _ -> [e] +let untup_typ' t' = + match t'.it with + | Il.TupT xts' -> xts' + | _ -> [("_" $ t'.at, t')] + let tup_typ' ts' at = match ts' with | [t'] -> t' - | _ -> Il.TupT (List.map (fun t' -> wild_exp t', t') ts') $ at - -let tup_typ_bind' es' ts' at = - Il.TupT (List.combine es' ts') $ at + | _ -> Il.TupT (List.map (fun t' -> "_" $ t'.at, t') ts') $ at let tup_exp' es' at = + Il.TupE es' $$ (at, tup_typ' (List.map note es') at) + +let tup_exp_nary' es' at = match es' with | [e'] -> e' - | _ -> Il.TupE es' $$ (at, tup_typ' (List.map note es') at) - -let tup_exp_bind' es' at = - let ts' = List.map note es' in - Il.TupE es' $$ (at, tup_typ_bind' (List.map wild_exp ts') ts' at) + | _ -> tup_exp' es' at let lift_exp' e' iter' = - if iter' = Opt then + if iter' = Il.Opt then Il.OptE (Some e') else Il.ListE [e'] @@ -77,17 +83,19 @@ let cat_exp' e1' e2' = (* Environment *) +type notation = (Il.id * Il.typ) Mixop.mixop + type kind = - | Transp (* alias types, notation types *) - | Opaque (* structures or variants, type parameter *) - | Defined of typ * id list * Il.deftyp - | Family of (arg list * typ * Il.inst) list (* family of types *) + | Transp (* forward alias types or notation types *) + | Opaque (* forward structures or variants, type parameter *) + | Defined of Il.deftyp * id list * dots + | Family of Il.inst list (* family of types *) -type var_typ = typ -type typ_typ = param list * kind -type gram_typ = param list * typ * gram option * (id * Il.prod) list -type rel_typ = typ * (id * Il.rule) list -type def_typ = param list * typ * (def * Il.clause) list +type var_typ = Il.typ +type typ_typ = Il.param list * kind +type gram_typ = Il.param list * Il.typ * (id * Il.prod) list * dots option +type rel_typ = Il.mixop * notation * Il.typ * (id * Il.rule) list +type def_typ = Il.param list * Il.typ * (def * Il.clause) list type 'a env' = (region * 'a) Map.t type env = @@ -103,12 +111,12 @@ type env = let new_env () = { gvars = Map.empty - |> Map.add "bool" (no_region, BoolT $ no_region) - |> Map.add "nat" (no_region, NumT `NatT $ no_region) - |> Map.add "int" (no_region, NumT `IntT $ no_region) - |> Map.add "rat" (no_region, NumT `RatT $ no_region) - |> Map.add "real" (no_region, NumT `RealT $ no_region) - |> Map.add "text" (no_region, TextT $ no_region); + |> Map.add "bool" (no_region, Il.BoolT $ no_region) + |> Map.add "nat" (no_region, Il.NumT `NatT $ no_region) + |> Map.add "int" (no_region, Il.NumT `IntT $ no_region) + |> Map.add "rat" (no_region, Il.NumT `RatT $ no_region) + |> Map.add "real" (no_region, Il.NumT `RealT $ no_region) + |> Map.add "text" (no_region, Il.TextT $ no_region); vars = Map.empty; typs = Map.empty; (* @@ -153,24 +161,30 @@ let rebind _space env' id t = assert (bound env' id); Map.add id.it (id.at, t) env' -let find_field fs atom at t = - match List.find_opt (fun (atom', _, _) -> Atom.eq atom' atom) fs with - | Some (_, x, _) -> x +let find_field tfs atom at t = + match List.find_opt (fun (atom', _, _) -> Atom.eq atom' atom) tfs with + | Some tf -> tf | None -> error_atom at atom t "unbound field" -let find_case cases atom at t = - match List.find_opt (fun (atom', _, _) -> Atom.eq atom' atom) cases with - | Some (_, x, _) -> x - | None -> error_atom at atom t "unknown case" - -let find_case_sub cases atom at t = - match List.find_opt (fun (atom', _, _) -> Atom.eq atom' atom || Atom.sub atom' atom) cases with - | Some (_, x, _) -> x +let find_case tcs mixop at t = + match List.find_opt (fun (mixop', _, _) -> Mixop.eq mixop' mixop) tcs with + | Some tc -> tc + | None -> error_mixop at mixop t "unknown case" + +let find_case_atom tcs atom at t = + match List.find_opt + (fun (mixop, _, _) -> + match Mixop.head mixop with + | Some atom' -> Atom.(eq atom' atom || sub atom' atom) + | None -> false + ) tcs + with + | Some tc -> tc | None -> error_atom at atom t "unknown case" -let bound_env' env' = Map.fold (fun id _ s -> Free.Set.add id s) env' Free.Set.empty +let bound_env' env' = Map.fold (fun id _ s -> Il.Free.Set.add id s) env' Il.Free.Set.empty let bound_env env = - Free.{ + Il.Free.{ varid = bound_env' env.vars; typid = bound_env' env.typs; relid = bound_env' env.rels; @@ -178,39 +192,202 @@ let bound_env env = gramid = bound_env' env.grams; } -let vars env = Map.fold (fun id (at, _) ids -> (id $ at)::ids) env.vars [] -let to_eval_var (_at, t) = t +let il_arg_of_param p = + (match p.it with + | Il.ExpP (id, t) -> Il.ExpA (Il.VarE id $$ id.at % t) + | Il.TypP id -> Il.TypA (Il.VarT (id, []) $ id.at) + | Il.DefP (id, _, _) -> Il.DefA id + | Il.GramP (id, _, _) -> Il.GramA (Il.VarG (id, []) $ id.at) + ) $ p.at -let to_eval_typ id (_at, (ps, k)) = +let to_il_var (_at, t) = t +let to_il_def (_at, (ps, t, clauses)) = (ps, t, List.map snd clauses) +let to_il_gram (_at, (ps, t, prods, _)) = (ps, t, List.map snd prods) + +let to_il_typ (_at, (ps, k)) = match k with - | Opaque | Transp -> - let args' = List.map Convert.arg_of_param ps in - [(args', VarT (id $ no_region, args') $ no_region)] - | Defined (t, _ids, _dt') -> - [(List.map Convert.arg_of_param ps, t)] - | Family insts -> - List.map (fun (args, t, _inst') -> (args, t)) insts - -let to_eval_def (_at, (_ps, _t, clauses)) = - List.map (fun (d, _) -> - match d.it with - | DefD (_id, args, e, prems) -> (args, e, Convert.filter_nl prems) - | _ -> assert false - ) clauses - -let to_eval_env env = + | Opaque | Transp -> ps, [] + | Family insts -> ps, insts + | Defined (dt, _, _) -> + ps, [Il.InstD ([], List.map il_arg_of_param ps, dt) $ dt.at] + +let to_il_env env = (* Need to include gvars, since matching can encounter implicit vars *) - let gvars = Map.map to_eval_var env.gvars in - let vars = Map.map to_eval_var env.vars in - let typs = Map.mapi to_eval_typ env.typs in - let defs = Map.map to_eval_def env.defs in - let grams = Map.map ignore env.grams in - Eval.{vars = Map.union (fun _ _ t -> Some t) gvars vars; typs; defs; grams} + let gvars = Map.map to_il_var env.gvars in + let vars = Map.map to_il_var env.vars in + let typs = Map.map to_il_typ env.typs in + let defs = Map.map to_il_def env.defs in + let grams = Map.map to_il_gram env.grams in + Il.Env.{ + vars = Map.union (fun _ _ t -> Some t) gvars vars; + typs; + defs; + rels = Map.empty; + grams; + } + let valid_tid id = id.it <> "" +(* Quantifiers inference *) + +let annot_env env dims = + let vars = + Map.fold (fun x (at, t) vars -> + let x', t' = + match Map.find_opt x dims with + | None -> x, t + | Some (_at, ctx) -> + (Dim.annot_varid (x $ at) ctx).it, + List.fold_left (fun t iter -> + let iter' = match iter with Il.Opt -> Il.Opt | _ -> Il.List in + Il.IterT (t, iter') $ t.at + ) t ctx + in Map.add x' (at, t') vars + ) env.vars Map.empty + in {env with vars} + +let make_quants_iter_arg env (free : Il.Free.sets) dims : Il.quant list ref * (module Il.Iter.Arg) = + let module Arg = + struct + include Il.Iter.Skip + + type scope = var_typ env' + + let left = ref free (* free variables not yet quantified *) + let acc = ref [] (* quantifiers introduced so far *) + + let scope_enter x t = + let varenv = env.vars in + if x.it <> "_" then env.vars <- Map.add x.it (x.at, t) env.vars; + varenv + + let scope_exit _x varenv = + env.vars <- varenv + + let visit_typid id = + if Il.Free.Set.mem id.it !left.typid then ( + acc := !acc @ [Il.TypP id $ id.at]; + left := Il.Free.{!left with typid = Set.remove id.it !left.typid}; + ) + + let visit_varid id = + if Il.Free.(Set.mem id.it !left.varid) then ( + let t = + try find "variable" env.vars id with Error _ -> + find "variable" env.gvars (strip_var_suffix id) + in + (* Raise variable type to its inferred dimension *) + let ctx' = + match Map.find_opt id.it dims with + | None -> [] (* for inherited variables *) + | Some (_, ctx) -> List.map Il.(function Opt -> Opt | _ -> List) ctx + in + let t' = + List.fold_left (fun t iter -> Il.IterT (t, iter) $ t.at) t ctx' in + acc := !acc @ [Il.ExpP (Dim.annot_varid id ctx', t') $ id.at]; + left := Il.Free.{!left with varid = Set.remove id.it !left.varid}; + ) + + let visit_gramid id = + if Il.Free.(Set.mem id.it !left.gramid) then ( + let ps, t, _gram, _prods' = find "grammar" env.grams id in + acc := !acc @ [Il.GramP (id, ps, t) $ id.at]; + left := Il.Free.{!left with varid = Set.remove id.it !left.gramid}; + ) + + let visit_defid id = + if Il.Free.Set.mem id.it !left.defid then ( + let ps, t, _ = find "definition" env.defs id in + acc := !acc @ [Il.DefP (id, ps, t) $ id.at]; + left := Il.Free.{!left with defid = Set.remove id.it !left.defid}; + ) + end + in Arg.acc, (module Arg) + +let infer_quants env env' dims det ps' as' ts' es' gs' prs' at : Il.quant list = + let env' = annot_env env' dims in + Debug.(log_at "il.infer_quants" at + (fun _ -> + "\n ps'=[" ^ list il_param ps' ^ "]" ^ + "\n as'=[" ^ list il_arg as' ^ "]" ^ + "\n ts'=[" ^ list il_typ ts' ^ "]" ^ + "\n es'=[" ^ list il_exp es' ^ "]" ^ + "\n gs'=[" ^ list il_sym gs' ^ "]" ^ + "\n prs'=[" ^ list il_prem prs' ^ "]" ^ + "\n locals=" ^ + (Map.fold (fun id _ ids -> + if Map.mem id env.vars then ids else id::ids + ) env'.vars [] |> List.rev |> String.concat " ") ^ + "\n dims=" ^ + (Map.fold (fun id (_, ctx) ids -> + (id ^ ":" ^ String.concat "" (List.map Il.Print.string_of_iter ctx)) :: ids + ) dims [] |> List.rev |> String.concat " ") ^ + "\n dets=" ^ + (Set.elements det.Det.varid |> String.concat " ") + ) + (fun qs -> fmt "\n... %s" (il_quants qs)) + ) @@ fun _ -> + + (* Check that everything is determined (this is an approximation!) *) + let bound = bound_env env in + let free = Il.Free.( + free_list free_param ps' ++ + free_list free_arg as' ++ + free_list free_typ ts' ++ + free_list free_exp es' ++ + free_list free_sym gs' ++ + free_list free_prem prs' + -- bound -- bound_list bound_param ps' -- det + ) + in + if free <> Il.Free.empty then + error at ("definition contains indeterminate variable(s) " ^ + String.concat ", " (List.map quote (Il.Free.Set.elements free.varid))); + + (* Gather quantifiers *) + let det' = Il.Free.(det -- bound) in + let acc_qs, (module Arg : Il.Iter.Arg) = make_quants_iter_arg env' det' dims in + let module Acc = Il.Iter.Make(Arg) in + Acc.(list param ps'); + Acc.(list arg as'); + Acc.(list typ ts'); + Acc.(list exp es'); + Acc.(list sym gs'); + Acc.(list prem prs'); + + (* Order quantifiers for dependencies by simple fixpoint iteration *) + let qsf = List.map Il.Free.(fun q -> q, bound_quant q, free_quant q) !acc_qs in + let rec iterate bound_ok ok qfs defer progress = + match qfs with + | (q, bound, free)::qfs when Il.Free.subset free bound_ok -> + iterate Il.Free.(bound_ok ++ bound) (q::ok) qfs defer true + | qf1::qfs -> iterate bound_ok ok qfs (qf1::defer) progress + | [] -> + match defer with + | [] -> List.rev ok + | _ when progress -> iterate bound_ok ok (List.rev defer) [] false + | (q, _, free)::_ -> + let fwd = Il.Free.(free -- bound_ok) in + error q.at ("the type of `" ^ Il.Print.string_of_quant q ^ "` depends on " ^ + ( Il.Free.Set.(elements fwd.typid @ elements fwd.gramid @ elements fwd.varid @ elements fwd.defid) |> + List.map (fun id -> "`" ^ id ^ "`") |> + String.concat ", " ) ^ + ", which only occur(s) to its right; " ^ + "try to reorder parameters or premises or introduce an extra parameter") + in + iterate bound [] qsf [] false + +let infer_no_quants env dims det ps' as' ts' es' gs' prs' at = + let qs = infer_quants env env dims det ps' as' ts' es' gs' prs' at in + if qs <> [] then + let bound = Il.Free.bound_quants qs in + error at ("definition contains free variable(s) " ^ + String.concat ", " (List.map quote (Il.Free.Set.elements bound.varid))) + + (* Backtracking *) type trace = Trace of region * string * trace list @@ -236,7 +413,7 @@ let nest at t r = match r with | Ok _ -> r | Fail traces -> - Fail [Trace (at, "cannot parse expression as `" ^ string_of_typ ~short:true t ^ "`", traces)] + Fail [Trace (at, "cannot parse expression as `" ^ Il.string_of_typ t ^ "`", traces)] let rec map_attempt f = function | [] -> Ok [] @@ -255,7 +432,10 @@ let fail at msg = Fail [Trace (at, msg, [])] let fail_silent = Fail [] let fail_atom at atom t msg = - fail at (msg ^ " `" ^ string_of_atom atom ^ "` in type `" ^ string_of_typ ~short:true t ^ "`") + fail at (msg ^ " `" ^ string_of_atom atom ^ "` in type `" ^ Il.string_of_typ t ^ "`") + +let fail_mixop at mixop t msg = + fail at (msg ^ " `" ^ Il.string_of_mixop mixop ^ "` in type `" ^ Il.string_of_typ t ^ "`") let fail_infer at construct = fail at ("cannot infer type of " ^ construct) @@ -286,9 +466,9 @@ let attempt f x = (* More Errors *) let typ_string env t = - let t' = Eval.reduce_typ (to_eval_env env) t in - let s = string_of_typ ~short:true t in - let s' = string_of_typ ~short:true t' in + let t' = Il.Eval.reduce_typ (to_il_env env) t in + let s = Il.string_of_typ t in + let s' = Il.string_of_typ t' in if s = s' then "`" ^ s ^ "`" else @@ -301,6 +481,9 @@ let msg_typ2 env phrase t1 t2 reason = phrase ^ "'s type " ^ typ_string env t1 ^ " does not match type " ^ typ_string env t2 ^ reason +let msg_not _env phrase not = + phrase ^ " does not match notation " ^ Mixop.to_string not + let error_typ env at phrase t = error at (msg_typ env phrase t) @@ -313,163 +496,86 @@ let fail_typ env at phrase t = let fail_typ2 env at phrase t1 t2 reason = fail at (msg_typ2 env phrase t1 t2 reason) +let fail_not env at phrase not = + fail at (msg_not env phrase not) + + type direction = Infer | Check let fail_dir_typ env at phrase dir t expected = match dir with | Check -> fail_typ env at phrase t | Infer -> - fail at (phrase ^ "'s type `" ^ string_of_typ ~short:true t ^ "`" ^ + fail at (phrase ^ "'s type " ^ typ_string env t ^ " does not match type " ^ expected) (* Type Accessors *) -let rec arg_subst s ps args = - match ps, args with - | [], [] -> s - | p::ps', a::as' -> - let s' = - match p.it, !((Subst.subst_arg s a).it) with - | ExpP (id, _), ExpA e -> Subst.add_varid s id e - | TypP id, TypA t -> Subst.add_typid s id t - | GramP (id, _), GramA g -> Subst.add_gramid s id g - | DefP (id, _, _), DefA id' -> Subst.add_defid s id id' - | _, _ -> assert false - in arg_subst s' ps' as' - | _, _ -> assert false - -(* TODO(4, rossberg): eliminate, replace expansion with reduction *) -let aliased dt' = - match dt'.it with - | Il.AliasT _ -> `Alias - | _ -> `NoAlias -let aliased_inst inst' = - let Il.InstD (_, _, dt') = inst'.it in - aliased dt' - -(* TODO(4, rossberg): replace with reduce_typ *) -let as_defined_typid' env id args at : typ' * [`Alias | `NoAlias] = - match find "syntax type" env.typs (strip_var_suffix id) with - | ps, Defined (t, _ids, dt') -> - let t' = if ps = [] then t else (* optimization *) - Subst.subst_typ (arg_subst Subst.empty ps args) t in - t'.it, aliased dt' - | _ps, Opaque -> VarT (id, args), `NoAlias - | _ps, Transp -> - error_id (id.it $ at) "invalid forward use of syntax type" - | _ps, Family insts -> - let env' = to_eval_env env in - let args = List.map (Eval.reduce_arg env') args in - let rec lookup = function - | [] -> error_id (id.it $ at) "undefined or undetermined case of syntax type family" - | (args', t, inst')::insts' -> - Debug.(log "el.lookup" - (fun _ -> fmt "%s(%s) =: %s(%s)" id.it (el_args args) id.it (el_args args')) - (fun (r, _) -> fmt "%s" (el_typ (r $ no_region ))) - ) @@ fun _ -> - if args' = [] && args = [] then t.it, aliased_inst inst' else (* optimisation *) - match Eval.(match_list match_arg env' Subst.empty args args') with - | None -> lookup insts' - | Some s -> (Subst.subst_typ s t).it, aliased_inst inst' - | exception _ -> lookup insts' (* assume coherent matches *) - (* error at "cannot reduce type family application" *) - in lookup insts - -(* Only expand aliases *) -let rec expand' env = function - | VarT (id, args) as t' -> - (match as_defined_typid' env id args id.at with - | t1', `Alias -> expand' env t1' - | _, `NoAlias -> t' - | exception Error _ -> t' - ) - | ParenT t -> expand' env t.it - | t' -> t' - -let expand env t = expand' env t.it +(* TODO(2, rossberg): avoid repeated env conversion *) +let reduce env t : Il.typ = Il.Eval.reduce_typ (to_il_env env) t +let expand env t : Il.typ' = (reduce env t).it -(* Expand all but the last alias. TODO(4, rossberg): remove *) -exception Last -let rec expand_nondef' env t = - match t.it with - | VarT (id, args) -> - (match as_defined_typid' env id args id.at with - | t1', `Alias -> (try expand_nondef' env (t1' $ t.at) with Last -> t) - | _, `NoAlias -> t - | exception Error _ -> t - ) - | ParenT t1 -> expand_nondef' env t1 - | _ -> raise Last - -let expand_nondef env t = try expand_nondef' env t with Last -> t - -(* Expand definitions *) -let expand_def env t = - match expand' env t.it with - | VarT (id, args) as t' -> - (match as_defined_typid' env id args id.at with - | t1', _ -> t1' - | exception Error _ -> t' - ) - | t' -> t' - -let expand_id env t = - match (expand_nondef env t).it with - | VarT (id, _) -> strip_var_suffix id - | _ -> "" $ no_region - -let rec expand_notation env t = +let expand_def env t : Il.deftyp' * dots = match expand env t with - | VarT (id, args) as t' -> - (match as_defined_typid' env id args t.at with - | ConT ((t1, _), _), _ -> expand_notation env t1 - | RangeT _ as t', _ -> t' - | _ -> t' - | exception Error _ -> t' + | Il.VarT (x, as') -> + let x' = strip_var_suffix x in + let _ps, k = find "syntax type" env.typs x' in + (Il.Eval.reduce_typdef (to_il_env env) (Il.VarT (x', as') $ x.at)).it, + (match k with Defined (_, _, dots) -> dots | _ -> NoDots) + | t' -> Il.AliasT (t' $ t.at), NoDots + +let expand_notation env t = + match expand env t with + | Il.VarT (x, as') -> + let x' = strip_var_suffix x in + (match find "syntax type" env.typs x' with + | ps, Defined ({it = Il.VariantT [tc]; _}, _, _) -> + let as_ = List.map il_arg_of_param ps in + Il.Eval.(match_list match_arg (to_il_env env) Il.Subst.empty as' as_) |> + Option.map (fun s -> + let mixop, (t, _qs, _prems), _ = Il.Subst.subst_typcase s tc in + t, mixop, Mixop.apply mixop (untup_typ' t) + ) + | _, _ -> None ) - | ConT ((t1, _), _) -> expand_notation env t1 - | t' -> t' + | _ -> None -let rec expand_iter_notation env t = +let expand_id env t = match expand env t with - | VarT (id, args) as t' -> - (match as_defined_typid' env id args t.at with - | IterT _ as t'', _ -> t'' - | ConT ((t1, _), _), _ -> expand_iter_notation env t1 - | _ -> t' - | exception Error _ -> t' - ) - | ConT ((t1, _), _) -> expand_iter_notation env t1 - | t' -> t' + | Il.VarT (id, _) -> id + | _ -> "" $ no_region let as_nat_typ_opt env t : unit option = - match expand_notation env t with - | NumT `NatT -> Some () - | RangeT _ -> Some () + match expand env t with + | Il.NumT `NatT -> Some () | _ -> None let as_num_typ_opt env t : numtyp option = - match expand_notation env t with - | NumT nt -> Some nt - | RangeT _ -> Some `IntT + match expand env t with + | Il.NumT nt -> Some nt | _ -> None -let as_iter_typ_opt env t : (typ * iter) option = - match expand env t with IterT (t1, iter) -> Some (t1, iter) | _ -> None - -let as_list_typ_opt env t : typ option = - match expand env t with IterT (t1, List) -> Some t1 | _ -> None +let as_iter_typ_opt env t : (Il.typ * Il.iter) option = + match expand env t with + | Il.IterT (t1, iter) -> Some (t1, iter) + | _ -> None -let as_iter_notation_typ_opt env t : (typ * iter) option = - match expand_iter_notation env t with IterT (t1, iter) -> Some (t1, iter) | _ -> None +let as_list_typ_opt env t : Il.typ option = + match expand env t with + | Il.IterT (t1, Il.List) -> Some t1 + | _ -> None -let as_tup_typ_opt env t : typ list option = - match expand env t with TupT ts -> Some ts | _ -> None +let as_tup_typ_opt env t : (Il.id * Il.typ) list option = + match expand env t with + | Il.TupT xts -> Some xts + | _ -> None -let as_empty_typ_opt env t : unit option = - match expand_notation env t with SeqT [] -> Some () | _ -> None +let as_empty_notation_typ_opt env t : unit option = + match expand_notation env t with + | Some (_, _, Seq []) -> Some () + | _ -> None let as_x_typ as_t_opt phrase env dir t at shape = @@ -486,79 +592,35 @@ let as_iter_typ phrase env dir t at = let as_list_typ phrase env dir t at = as_x_typ as_list_typ_opt phrase env dir t at "(_)*" let as_tup_typ phrase env dir t at = - as_x_typ as_tup_typ_opt phrase env dir t at "(_, ..., _)" -let as_iter_notation_typ phrase env dir t at = - as_x_typ as_iter_notation_typ_opt phrase env dir t at "(_)*" -let as_empty_typ phrase env dir t at = - as_x_typ as_empty_typ_opt phrase env dir t at "()" - - -let rec as_notation_typid' phrase env id args at : typ attempt = - match as_defined_typid' env id args at with - | VarT (id', args'), `Alias -> as_notation_typid' phrase env id' args' at - | ConT ((t, _), _), _ -> Ok t - | (AtomT _ | SeqT _ | InfixT _ | BrackT _ | IterT _) as t, _ -> Ok (t $ at) - | _ -> fail_dir_typ env at phrase Infer (VarT (id, args) $ id.at) "_ ... _" - | exception Error (at', msg) -> fail at' msg - -let as_notation_typ phrase env dir t at : typ attempt = - match expand env t with - | VarT (id, args) -> as_notation_typid' phrase env id args at - | _ -> fail_dir_typ env at phrase dir t "_ ... _" + as_x_typ as_tup_typ_opt phrase env dir t at "(_,...,_)" +let as_empty_notation_typ phrase env dir t at = + as_x_typ as_empty_notation_typ_opt phrase env dir t at "()" -let rec as_struct_typid' phrase env id args at : (typfield list * dots) attempt = - match as_defined_typid' env id args at with - | VarT (id', args'), `Alias -> as_struct_typid' phrase env id' args' at - | StrT (_dots1, ts, tfs, dots2), _ -> - let* tfss = map_attempt (fun t -> as_struct_typ "" env Infer t at) (filter_nl ts) in - Ok (List.concat (filter_nl tfs :: List.map fst tfss), dots2) - | _ -> fail_dir_typ env at phrase Infer (VarT (id, args) $ id.at) "{...}" - | exception Error (at', msg) -> fail at' msg -and as_struct_typ phrase env dir t at : (typfield list * dots) attempt = - match expand env t with - | VarT (id, args) -> as_struct_typid' phrase env id args at +let as_struct_typ phrase env dir t at : (Il.typfield list * dots) attempt = + match expand_def env t with + | Il.StructT tfs, dots -> Ok (tfs, dots) | _ -> fail_dir_typ env at phrase dir t "{...}" -let rec as_cat_typid' phrase env dir id args at = - match as_defined_typid' env id args at with - | VarT (id', args'), `Alias -> as_cat_typid' phrase env dir id' args' at - | IterT _, _ -> Ok () - | StrT (_dots1, ts, tfs, dots2), _ -> - let* tfss = map_attempt (fun t -> as_struct_typ "" env Infer t at) (filter_nl ts) in - let tfs' = List.concat (filter_nl tfs :: List.map fst tfss) in - if dots2 = Dots then - error at "used record type is only partially defined at this point"; - iter_attempt (fun (_, (t, _), _) -> as_cat_typ phrase env dir t at) tfs' - | _ -> - fail at (phrase ^ "'s type `" ^ string_of_typ ~short:true (VarT (id, args) $ id.at) ^ - "` is not concatenable") - | exception Error (at', msg) -> fail at' msg +let as_variant_typ phrase env dir t at : (Il.typcase list * dots) attempt = + match expand_def env t with + | Il.VariantT tcs, dots -> Ok (tcs, dots) + | _ -> fail_dir_typ env at phrase dir t "| ..." -and as_cat_typ phrase env dir t at = - match expand env t with - | VarT (id, args) -> as_cat_typid' phrase env dir id args at - | IterT _ -> Ok () +let rec as_cat_typ phrase env dir t at : unit attempt = + match expand_def env t with + | Il.AliasT {it = Il.IterT _; _}, _ -> Ok () + | Il.StructT tfs, dots -> + if dots = Dots then + error at "used record type is only partially defined at this point"; + iter_attempt (fun (_, (t, _, _), _) -> as_cat_typ phrase env dir t at) tfs | _ -> - fail at (phrase ^ "'s type `" ^ string_of_typ ~short:true t ^ "` is not concatenable") - -let rec as_variant_typid' phrase env id args at : (typcase list * dots) attempt = - match as_defined_typid' env id args at with - | VarT (id', args'), `Alias -> as_variant_typid' phrase env id' args' at - | CaseT (_dots1, ts, tcs, dots2), _ -> - let* tcss = map_attempt (fun t -> as_variant_typ "" env Infer t at) (filter_nl ts) in - Ok (List.concat (filter_nl tcs :: List.map fst tcss), dots2) - | _ -> fail_dir_typ env id.at phrase Infer (VarT (id, args) $ id.at) "| ..." - | exception Error (at', msg) -> fail at' msg - -and as_variant_typid phrase env id args : (typcase list * dots) attempt = - as_variant_typid' phrase env id args id.at - -and as_variant_typ phrase env dir t at : (typcase list * dots) attempt = - match expand env t with - | VarT (id, args) -> as_variant_typid' phrase env id args at - | _ -> fail_dir_typ env at phrase dir t "| ..." + fail at (phrase ^ "'s type " ^ typ_string env t ^ " is not concatenable") +let as_notation_typ phrase env dir t at : (Il.typ * _ Mixop.mixop * notation) attempt = + match expand_notation env t with + | Some not -> Ok not + | _ -> fail_dir_typ env at phrase dir t "_ ... _" let is_x_typ as_x_typ env t = match as_x_typ "" env Check t no_region with @@ -566,28 +628,32 @@ let is_x_typ as_x_typ env t = | Fail _ -> false let is_nat_typ = is_x_typ as_nat_typ -let is_empty_typ = is_x_typ as_empty_typ let is_iter_typ = is_x_typ as_iter_typ -let is_iter_notation_typ = is_x_typ as_iter_notation_typ -let is_notation_typ = is_x_typ as_notation_typ let is_variant_typ = is_x_typ as_variant_typ +let is_notation_typ = is_x_typ as_notation_typ +let is_empty_notation_typ = is_x_typ as_empty_notation_typ (* Type Equivalence and Shallow Numeric Subtyping *) let equiv_typ env t1 t2 = - Eval.equiv_typ (to_eval_env env) t1 t2 + Il.Eval.equiv_typ (to_il_env env) t1 t2 let sub_typ env t1 t2 = - Eval.sub_typ (to_eval_env env) t1 t2 + Il.Eval.sub_typ (to_il_env env) t1 t2 let narrow_typ env t1 t2 = - Eval.narrow_typ (to_eval_env env) t1 t2 + Debug.(log "el.narrow_typ" + (fun _ -> fmt "%s <: %s" (il_typ t1) (il_typ t2)) Bool.to_string + ) @@ fun _ -> + match expand env t1, expand env t2 with + | Il.NumT nt1, Il.NumT nt2 -> Num.sub nt1 nt2 + | _, _ -> equiv_typ env t1 t2 (* Hints *) -let elab_hint tid mixop {hintid; hintexp} : Il.hint = +let elab_hint tid case {hintid; hintexp} : Il.hint = let module IterAtoms = Iter.Make( struct @@ -596,46 +662,46 @@ let elab_hint tid mixop {hintid; hintexp} : Il.hint = assert (valid_tid tid); assert (atom.note.Atom.def = ""); atom.note.Atom.def <- tid.it; - atom.note.Atom.case <- Mixop.name mixop + atom.note.Atom.case <- case end ) in IterAtoms.exp hintexp; {Il.hintid; Il.hintexp} -let elab_hints tid mixop = List.map (elab_hint tid mixop) +let elab_hints tid case = List.map (elab_hint tid case) (* Atoms and Operators *) +let new_note note = Atom.{note with def = ""} +let new_atom atom = {atom with note = new_note atom.note} +let new_mixop mixop = Mixop.map_atoms new_atom mixop +let new_typfield (atom, t_prs, hints) = (new_atom atom, t_prs, hints) +let new_typcase (mixop, t_prs, hints) = (new_mixop mixop, t_prs, hints) + let elab_atom atom tid = assert (valid_tid tid); -(* -if atom.note.Atom.def <> "" && atom.note.Atom.def <> tid.it then -Printf.eprintf "[elab_atom %s @ %s] def=%s/%s\n%!" -(Atom.string_of_atom atom) (Source.string_of_region atom.at) tid.it atom.note.Atom.def; - assert (atom.note.Atom.def = "" || atom.note.Atom.def = tid.it); -*) atom.note.Atom.def <- tid.it; atom let infer_unop'' op ts = - List.map (fun t -> op, (t :> Il.optyp), NumT t, NumT t) ts + List.map (fun t -> op, (t :> Il.optyp), Il.NumT t, Il.NumT t) ts let infer_binop'' op ts = - List.map (fun t -> op, (t :> Il.optyp), NumT t, NumT t, NumT t) ts + List.map (fun t -> op, (t :> Il.optyp), Il.NumT t, Il.NumT t, Il.NumT t) ts let infer_cmpop'' op ts = - List.map (fun t -> op, (t :> Il.optyp), NumT t) ts + List.map (fun t -> op, (t :> Il.optyp), Il.NumT t) ts let infer_unop' = function - | #Bool.unop as op -> [op, `BoolT, BoolT, BoolT] + | #Bool.unop as op -> [op, `BoolT, Il.BoolT, Il.BoolT] | #Num.unop as op -> infer_unop'' op [`IntT; `RatT; `RealT] | `PlusMinusOp -> infer_unop'' `PlusOp [`IntT; `RatT; `RealT] | `MinusPlusOp -> infer_unop'' `MinusOp [`IntT; `RatT; `RealT] let infer_binop' = function - | #Bool.binop as op -> [op, `BoolT, BoolT, BoolT, BoolT] + | #Bool.binop as op -> [op, `BoolT, Il.BoolT, Il.BoolT, Il.BoolT] | `AddOp as op -> infer_binop'' op [`NatT; `IntT; `RatT; `RealT] | `SubOp as op -> infer_binop'' op [`IntT; `RatT; `RealT] | `MulOp as op -> infer_binop'' op [`NatT; `IntT; `RatT; `RealT] @@ -644,21 +710,22 @@ let infer_binop' = function | `PowOp as op -> infer_binop'' op [`NatT; `RatT; `RealT] |> List.map (fun (op, nt, t1, t2, t3) -> - (op, nt, t1, (if t2 = NumT `NatT then t2 else NumT `IntT), t3)) + (op, nt, t1, (if t2 = Il.NumT `NatT then t2 else Il.NumT `IntT), t3)) let infer_cmpop' = function | #Bool.cmpop as op -> `Poly op | #Num.cmpop as op -> `Over (infer_cmpop'' op [`NatT; `IntT; `RatT; `RealT]) -let infer_unop env op t1 at : (Il.unop * Il.optyp * typ * typ) attempt = +let infer_unop env op t1 at : (Il.unop * Il.optyp * Il.typ * Il.typ) attempt = let ops = infer_unop' op in match List.find_opt (fun (_, _, t1', _) -> narrow_typ env t1 (t1' $ at)) ops with | Some (op', nt, t1', t2') -> Ok (op', nt, t1' $ at, t2' $ at) | None -> fail at ("unary operator `" ^ string_of_unop op ^ - "` is not defined for operand type `" ^ string_of_typ ~short:true t1 ^ "`") + "` is not defined for operand type " ^ typ_string env t1 + ) -let infer_binop env op t1 t2 at : (Il.binop * Il.optyp * typ * typ * typ) attempt = +let infer_binop env op t1 t2 at : (Il.binop * Il.optyp * Il.typ * Il.typ * Il.typ) attempt = let ops = infer_binop' op in match List.find_opt (fun (_, _, t1', t2', _) -> @@ -667,11 +734,12 @@ let infer_binop env op t1 t2 at : (Il.binop * Il.optyp * typ * typ * typ) attemp | Some (op', nt, t1', t2', t3') -> Ok (op', nt, t1' $ at, t2' $ at, t3' $ at) | None -> fail at ("binary operator `" ^ string_of_binop op ^ - "` is not defined for operand types `" ^ - string_of_typ ~short:true t1 ^ "` and `" ^ string_of_typ ~short:true t2 ^ "`") + "` is not defined for operand types `" ^ typ_string env t1 ^ + " and " ^ typ_string env t2 + ) let infer_cmpop env op - : [`Poly of Il.cmpop | `Over of (typ -> typ -> region -> (Il.cmpop * Il.optyp * typ) attempt)] = + : [`Poly of Il.cmpop | `Over of (Il.typ -> Il.typ -> region -> (Il.cmpop * Il.optyp * Il.typ) attempt)] = match infer_cmpop' op with | `Poly op' -> `Poly op' | `Over ops -> `Over (fun t1 t2 at -> @@ -682,60 +750,81 @@ let infer_cmpop env op | Some (op', nt, t) -> Ok (op', nt, t $ at) | None -> fail at ("comparison operator `" ^ string_of_cmpop op ^ - "` is not defined for operand types `" ^ - string_of_typ ~short:true t1 ^ "` and `" ^ string_of_typ ~short:true t2 ^ "`") + "` is not defined for operand types " ^ typ_string env t1 ^ + " and " ^ typ_string env t2 + ) ) -let merge_mixop mixop1 mixop2 = - match mixop1, mixop2 with - | _, [] -> mixop1 - | [], _ -> mixop2 - | mixop1, atoms2::mixop2' -> - let mixop1', atoms1 = Lib.List.split_last mixop1 in - mixop1' @ [atoms1 @ atoms2] @ mixop2' - -let check_atoms phrase item list at = +let check_atoms phrase item to_atom list at = let _, dups = - List.fold_right (fun (atom, _, _) (set, dups) -> - let s = Print.string_of_atom atom in + List.fold_right (fun (op, _, _) (set, dups) -> + let s = Print.string_of_atom (to_atom op) in if Set.mem s set then (set, s::dups) else (Set.add s set, dups) ) list (Set.empty, []) in if dups <> [] then - error at (phrase ^ " contains duplicate " ^ item ^ "(s) `" ^ - String.concat "`, `" dups ^ "`") + error at (phrase ^ " contains duplicate " ^ item ^ "(s) " ^ + String.concat ", " (List.map quote dups)) (* Iteration *) -let rec elab_iter env iter : Il.iter = - match iter with +let rec elab_iter env (it : iter) : Il.iter = + match it with | Opt -> Il.Opt | List -> Il.List | List1 -> Il.List1 - | ListN (e, id_opt) -> - Option.iter (fun id -> - let e' = checkpoint (elab_exp env (VarE (id, []) $ id.at) (NumT `NatT $ id.at)) in - (* TODO(4, rossberg): extend IL to allow arbitrary pattern exps *) + | ListN (e, xo) -> + Option.iter (fun x -> + let t = Il.NumT `NatT $ x.at in + let e' = checkpoint (elab_exp env (VarE (x, []) $ x.at) t) in match e'.it with | Il.VarE _ -> () - | _ -> error_typ env id.at "iteration variable" (NumT `NatT $ id.at) - ) id_opt; - let e' = checkpoint (elab_exp env e (NumT `NatT $ e.at)) in - Il.ListN (e', id_opt) + | _ -> error_typ env x.at "iteration variable" t + ) xo; + let e' = checkpoint (elab_exp env e (Il.NumT `NatT $ e.at)) in + Il.ListN (e', xo) + +and elab_itertyp env (it : iter) : Il.iter = + let it = + match it with + | List1 | ListN _ -> List + | _ -> it + in + elab_iter env it + +and elab_iterexp : 'a 'b. env -> (env -> 'a -> 'b attempt) -> 'a -> iter -> ('b * Il.iterexp * Il.iter) attempt = + fun env f body (it : iter) -> + let xo = match it with ListN (_, xo) -> xo | _ -> None in + let to_ = Option.join (Option.map (fun x -> Map.find_opt x.it env.vars) xo) in + let it' = elab_iter env it in + let* body' = f env body in + (* Remove local and restore outer if present *) + Option.iter (fun x -> + env.vars <- + match to_ with + | None -> Map.remove x.it env.vars + | Some t -> Map.add x.it t env.vars + ) xo; + (* Iterator list is injected after dimension analysis, leave it empty here *) + Ok (body', (it', []), match it with Opt -> Il.Opt | _ -> Il.List) (* Types *) -and elab_typ env t : Il.typ = +and elab_typ env ?(fwd = true) (t : typ) : Il.typ = match t.it with - | VarT (id, as_) -> - let id' = strip_var_suffix id in - if id'.it <> id.it && as_ = [] then elab_typ env (Convert.typ_of_varid id') else - let ps, _ = find "syntax type" env.typs id' in - let as', _s = elab_args `Rhs env as_ ps t.at in - Il.VarT (id', as') $ t.at + | VarT (x, as_) -> + let x' = strip_var_suffix x in + if x'.it <> x.it && as_ = [] then + elab_typ env (Convert.typ_of_varid x') + else + let ps, k = find "syntax type" env.typs x' in + if not fwd && k = Transp then + error_id x "invalid forward reference to syntax type"; + let as', _s = elab_args `Rhs env as_ ps t.at in + Il.VarT (x', as') $ t.at | BoolT -> Il.BoolT $ t.at | NumT t' -> Il.NumT t' $ t.at | TextT -> Il.TextT $ t.at @@ -743,245 +832,225 @@ and elab_typ env t : Il.typ = | ParenT t1 -> elab_typ env t1 | TupT ts -> tup_typ' (List.map (elab_typ env) ts) t.at | IterT (t1, iter) -> - (match iter with - | List1 | ListN _ -> error t.at "illegal iterator in syntax type" - | _ -> - let iter' = elab_iter env iter in - let t1' = elab_typ env t1 in - Il.IterT (t1', iter') $ t.at - ) - | StrT _ | CaseT _ | ConT _ | RangeT _ | AtomT _ | SeqT _ | InfixT _ | BrackT _ -> + let iter' = elab_itertyp env iter in + let t1' = elab_typ env t1 in + Il.IterT (t1', iter') $ t.at + | StrT _ | CaseT _ | ConT _ | RangeT _ + | AtomT _ | SeqT _ | InfixT _ | BrackT _ -> error t.at "this type is only allowed in type definitions" -and elab_typ_definition env tid t : Il.deftyp = +and elab_typ_definition env outer_dims tid (t : typ) : dots * Il.deftyp * dots = Debug.(log_at "el.elab_typ_definition" t.at - (fun _ -> fmt "%s = %s" tid.it (el_typ t)) il_deftyp + (fun _ -> fmt "%s = %s" tid.it (el_typ t)) + (fun (_, dt, _) -> il_deftyp dt) ) @@ fun _ -> assert (valid_tid tid); - (match t.it with - | StrT (dots1, ts, tfs, _dots2) -> - let tfs0 = - if dots1 = Dots then - fst (checkpoint (as_struct_typid' "own type" env tid [] t.at)) - else [] + match t.it with + | StrT (dots1, ts, tfs, dots2) -> + let tfs1 = + if dots1 = NoDots then [] else + let t1 = Il.VarT (tid, []) $ tid.at in + if not (bound env.typs tid) then + error t.at "extension of previously undefined syntax type"; + let tfs1, dots = checkpoint (as_struct_typ "own type" env Check t1 t1.at) in + if dots = NoDots then + error t.at "extension of non-extensible syntax type"; + List.map new_typfield tfs1 (* ensure atom annotations are fresh *) in - let tfss = - map_filter_nl_list (fun t -> - let tfs, dots = checkpoint (as_struct_typ "parent type" env Infer t t.at) in + let tfs2 = + concat_map_filter_nl_list (fun t -> + let t' = elab_typ env t in + let tfs, dots = checkpoint (as_struct_typ "parent type" env Infer t' t'.at) in if dots = Dots then - error t.at "cannot include incomplete syntax type"; - List.map Iter.clone_typfield tfs (* ensure atom annotations are fresh *) + error t.at "inclusion of incomplete syntax type"; + List.map new_typfield tfs (* ensure atom annotations are fresh *) ) ts in - let tfs1 = List.flatten (List.map Iter.clone_typfield tfs0 :: tfss @ [filter_nl tfs]) in - let tfs' = List.map (elab_typfield env tid t.at) tfs1 in - check_atoms "record" "field" tfs' t.at; - Il.StructT tfs' - | CaseT (dots1, ts, tcs, _dots2) -> - let tcs0 = - if dots1 = Dots then - fst (checkpoint (as_variant_typid "own type" env tid [])) - else [] + let tfs' = tfs1 @ tfs2 @ map_filter_nl_list (elab_typfield env outer_dims tid t.at) tfs in + check_atoms "record" "field" Fun.id tfs' t.at; + dots1, Il.StructT tfs' $ t.at, dots2 + | CaseT (dots1, ts, tcs, dots2) -> + let tcs1 = + if dots1 = NoDots then [] else + let t1 = Il.VarT (tid, []) $ tid.at in + if not (bound env.typs tid) then + error t.at "extension of previously undefined syntax type"; + let tcs1, dots = checkpoint (as_variant_typ "own type" env Check t1 t1.at) in + if dots = NoDots then + error t.at "extension of non-extensible syntax type"; + List.map new_typcase tcs1 (* ensure atom annotations are fresh *) in - let tcss = - map_filter_nl_list (fun t -> - let tcs, dots = checkpoint (as_variant_typ "parent type" env Infer t t.at) in + let tcs2 = + concat_map_filter_nl_list (fun t -> + let t' = elab_typ env t in + let tcs, dots = checkpoint (as_variant_typ "parent type" env Infer t' t'.at) in if dots = Dots then - error t.at "cannot include incomplete syntax type"; - List.map Iter.clone_typcase tcs (* ensure atom annotations are fresh *) + error t.at "inclusion of incomplete syntax type"; + List.map new_typcase tcs (* ensure atom annotations are fresh *) ) ts in - let tcs1 = List.flatten (List.map Iter.clone_typcase tcs0 :: tcss @ [filter_nl tcs]) in - let tcs' = List.map (elab_typcase env tid t.at) tcs1 in - check_atoms "variant" "case" tcs1 t.at; - Il.VariantT tcs' + let tcs' = tcs1 @ tcs2 @ map_filter_nl_list (elab_typcase env outer_dims tid t.at) tcs in + check_atoms "variant" "case" (fun op -> Option.get (Mixop.head op)) tcs' t.at; + dots1, Il.VariantT tcs' $ t.at, dots2 | ConT tc -> - let tc' = elab_typcon env tid t.at tc in - Il.VariantT [tc'] + let tc' = elab_typcon env outer_dims tid t.at tc in + NoDots, Il.VariantT [tc'] $ t.at, NoDots | RangeT tes -> - let ts_fes' = map_filter_nl_list (elab_typenum env tid) tes in - let t1, fe' = + let ts_fes' = map_filter_nl_list (elab_typenum env outer_dims tid) tes in + let t', fe' = List.fold_left (fun (t, fe') (tI, feI') -> (if narrow_typ env tI t then t else tI), fun eid' nt -> let e' = fe' eid' nt and eI' = feI' eid' nt in let at = Source.over_region [e'.at; eI'.at] in - Il.(BinE (`OrOp, `BoolT, e', eI') $$ at % (BoolT $ at)) + Il.(BinE (`OrOp, `BoolT, e', eI') $$ at % (Il.BoolT $ at)) ) (List.hd ts_fes') (List.tl ts_fes') in - let t' = elab_typ env t1 in - let nt = match t1.it with NumT nt -> nt | _ -> assert false in - let id' = "i" $ t.at in - let eid' = Il.VarE id' $$ t.at % t' in - let bs' = [Il.ExpB (id', t') $ t.at] in + let nt = match t'.it with Il.NumT nt -> nt | _ -> assert false in + let x = "i" $ t.at in + let eid' = Il.VarE x $$ t.at % t' in let prems' = [Il.IfPr (fe' eid' nt) $ t.at] in - let tc' = ([[]; []], (bs', Il.TupT [(eid', t')] $ t.at, prems'), []) in - Il.VariantT [tc'] + let tc' = (Mixop.Arg (), (Il.TupT [(x, t')] $ t.at, [], prems'), []) in + NoDots, Il.VariantT [tc'] $ t.at, NoDots | _ -> let t' = elab_typ env t in - Il.AliasT t' - ) $ t.at + NoDots, Il.AliasT t' $ t.at, NoDots -and typ_rep env t : typ = +and typ_rep env t : Il.typ = Debug.(log_at "el.typ_rep" t.at - (fun _ -> fmt "%s" (el_typ t)) - (fun r -> fmt "%s" (el_typ r)) + (fun _ -> fmt "%s" (il_typ t)) + (fun r -> fmt "%s" (il_typ r)) ) @@ fun _ -> - match expand_def env t with - | ConT ((t1, _), _) -> t1 - | RangeT tes -> - let ts_fes' = map_filter_nl_list (elab_typenum env (expand_id env t)) tes in - List.fold_left (fun t (tI, _) -> - if sub_typ env tI t then t else tI - ) (fst (List.hd ts_fes')) (List.tl ts_fes') - | _ -> t - -and elab_typfield env tid at ((atom, (t, prems), hints) as tf) : Il.typfield = - assert (valid_tid tid); - let env' = local_env env in - let _mixop, ts', ts = elab_typ_notation env' tid t in - let es = Convert.pats_of_typs ts in - let dims = Dim.check_typdef (vars env) t prems in - let dims' = Dim.Env.map (List.map (elab_iter env')) dims in - let es' = checkpoint (map2_attempt (elab_exp env') es ts) in - let es' = List.map (Dim.annot_exp dims') es' in - let prems' = List.map (Dim.annot_prem dims') - (concat_map_filter_nl_list (elab_prem env') prems) in - let det = Free.(diff (union (free_list det_exp es) (det_prems prems)) (bound_env env)) in - let free = Free.(diff (free_typfield tf) (union det (bound_env env))) in - if free <> Free.empty then - error at ("type field contains indeterminate variable(s) `" ^ - String.concat "`, `" (Free.Set.elements free.varid) ^ "`"); - let acc_bs', (module Arg : Iter.Arg) = make_binds_iter_arg env' det dims in - let module Acc = Iter.Make(Arg) in - List.iter Acc.exp es; - Acc.prems prems; - ( elab_atom atom tid, - (!acc_bs', (if prems = [] then tup_typ' else tup_typ_bind' es') ts' t.at, prems'), - elab_hints tid [] hints - ) + match expand env t with + | Il.VarT _ as t' -> + (match expand_def env (t' $ t.at) with + | Il.VariantT [_, (t1, _, _), _], NoDots -> typ_rep env t1 + | _ -> t' $ t.at + ) + | Il.TupT [_, t1] -> typ_rep env t1 + | t' -> t' $ t.at + +and elab_typfield env outer_dims tid at (tf : typfield) : Il.typfield = + let atom, (t, prems), hints = tf in + let _mixop, t', qs, prems' = elab_typ_notation env outer_dims tid at t prems in + let hints' = elab_hints tid "" hints in + let t'' = + match t'.it with + | Il.TupT [(_, t1')] when prems' = [] -> t1' + | _ -> t' + in + (elab_atom atom tid, (t'', qs, prems'), hints') -and elab_typcase env tid at ((_atom, (t, prems), hints) as tc) : Il.typcase = - assert (valid_tid tid); - let env' = local_env env in - let mixop, ts', ts = elab_typ_notation env' tid t in - let es = Convert.pats_of_typs ts in - let dims = Dim.check_typdef (vars env) t prems in - let dims' = Dim.Env.map (List.map (elab_iter env')) dims in - let es' = checkpoint (map_attempt Fun.id (List.map2 (elab_exp env') es ts)) in - let es' = List.map (Dim.annot_exp dims') es' in - let prems' = List.map (Dim.annot_prem dims') - (concat_map_filter_nl_list (elab_prem env') prems) in - let det = Free.(diff (union (free_list det_exp es) (det_prems prems)) (bound_env env)) in - let free = Free.(diff (free_typcase tc) (union det (bound_env env))) in - if free <> Free.empty then -(Printf.printf "[typcase] t = %s\n%!" (Print.string_of_typ t); - List.iteri (fun i e -> Printf.printf "[typcase] t%d = %s\n%!" i (Print.string_of_typ e)) ts; - List.iteri (fun i e -> Printf.printf "[typcase] t%d' = %s\n%!" i (Il.Print.string_of_typ e)) ts'; - List.iteri (fun i e -> Printf.printf "[typcase] e%d = %s\n%!" i (Print.string_of_exp e)) es; - error at ("type case contains indeterminate variable(s) `" ^ - String.concat "`, `" (Free.Set.elements free.varid) ^ "`"); -); - let acc_bs', (module Arg : Iter.Arg) = make_binds_iter_arg env' det dims in - let module Acc = Iter.Make(Arg) in - List.iter Acc.exp es; - Acc.prems prems; - ( mixop, - (!acc_bs', tup_typ_bind' es' ts' at, prems'), - elab_hints tid [] hints - ) +and elab_typcase env outer_dims tid at (tc : typcase) : Il.typcase = + let _atom, (t, prems), hints = tc in + let mixop, t', qs, prems' = elab_typ_notation env outer_dims tid at t prems in + let hints' = elab_hints tid "" hints in + (mixop, (t', qs, prems'), hints') -and elab_typcon env tid at (((t, prems), hints) as tc) : Il.typcase = - assert (valid_tid tid); - let env' = local_env env in - let mixop, ts', ts = elab_typ_notation env' tid t in - let es = Convert.pats_of_typs ts in - let dims = Dim.check_typdef (vars env) t prems in - let dims' = Dim.Env.map (List.map (elab_iter env')) dims in - let es' = checkpoint (map_attempt Fun.id (List.map2 (elab_exp env') es ts)) in - let es' = List.map (Dim.annot_exp dims') es' in - let prems' = List.map (Dim.annot_prem dims') - (concat_map_filter_nl_list (elab_prem env') prems) in - let det = Free.(diff (union (free_list det_exp es) (det_prems prems)) (bound_env env)) in - let free = Free.(diff (free_typcon tc) (union det (bound_env env))) in - if free <> Free.empty then - error at ("type constraint contains indeterminate variable(s) `" ^ - String.concat "`, `" (Free.Set.elements free.varid) ^ "`"); - let acc_bs', (module Arg : Iter.Arg) = make_binds_iter_arg env' det dims in - let module Acc = Iter.Make(Arg) in - List.iter Acc.exp es; - Acc.prems prems; - ( mixop, - (!acc_bs', tup_typ_bind' es' ts' at, prems'), - elab_hints tid [Atom.Atom tid.it $$ tid.at % Atom.info ""] hints - ) +and elab_typcon env outer_dims tid at (tc : typcon) : Il.typcase = + let (t, prems), hints = tc in + let mixop, t', qs, prems' = elab_typ_notation env outer_dims tid at t prems in + let hints' = elab_hints tid tid.it hints in + (mixop, (t', qs, prems'), hints') -and elab_typenum env tid (e1, e2o) : typ * (Il.exp -> numtyp -> Il.exp) = +and elab_typenum env outer_dims tid (te : typenum) : Il.typ * (Il.exp -> numtyp -> Il.exp) = assert (valid_tid tid); - let _e1' = elab_exp env e1 (NumT `IntT $ e1.at) in (* ensure it's <= int *) - let _, t1 = checkpoint (infer_exp env e1) in (* get precise type *) + let e1, e2o = te in + let _e1' = elab_exp env e1 (Il.NumT `IntT $ e1.at) in (* ensure it's <= int *) + let _, t1 = checkpoint (infer_exp env e1) in (* get precise type *) match e2o with | None -> t1, fun eid' nt -> - let e1' = checkpoint (elab_exp env e1 (NumT nt $ e1.at)) in (* redo with overall type *) - Il.(CmpE (`EqOp, `BoolT, eid', e1') $$ e1'.at % (BoolT $ e1.at)) + let e1' = checkpoint (elab_exp env e1 (Il.NumT nt $ e1.at)) in (* redo with overall type *) + let dims = Dim.check outer_dims [] [] [] [e1'] [] [] in + let e1' = Dim.annot_exp dims e1' in + infer_no_quants env dims Det.empty [] [] [] [e1'] [] [] e1.at; + Il.(CmpE (`EqOp, `BoolT, eid', e1') $$ e1'.at % (Il.BoolT $ e1.at)) | Some e2 -> let at = Source.over_region [e1.at; e2.at] in - let _e2' = elab_exp env e2 (NumT `IntT $ e2.at) in + let _e2' = checkpoint (elab_exp env e2 (Il.NumT `IntT $ e2.at)) in let _, t2 = checkpoint (infer_exp env e2) in (if narrow_typ env t2 t1 then t1 else t2).it $ at, fun eid' nt -> - let e1' = checkpoint (elab_exp env e1 (NumT nt $ e1.at)) in - let e2' = checkpoint (elab_exp env e2 (NumT nt $ e2.at)) in + let e1' = checkpoint (elab_exp env e1 (Il.NumT nt $ e1.at)) in + let e2' = checkpoint (elab_exp env e2 (Il.NumT nt $ e2.at)) in + let dims = Dim.check outer_dims [] [] [] [e1'; e2'] [] [] in + let e1' = Dim.annot_exp dims e1' in + let e2' = Dim.annot_exp dims e2' in + infer_no_quants env dims Det.empty [] [] [] [e1'; e2'] [] [] at; Il.(BinE (`AndOp, `BoolT, - CmpE (`GeOp, (nt :> Il.optyp), eid', e1') $$ e1'.at % (BoolT $ e1.at), - CmpE (`LeOp, (nt :> Il.optyp), eid', e2') $$ e2'.at % (BoolT $ e2.at) - ) $$ at % (BoolT $ at)) + CmpE (`GeOp, (nt :> Il.optyp), eid', e1') $$ e1'.at % (Il.BoolT $ e1.at), + CmpE (`LeOp, (nt :> Il.optyp), eid', e2') $$ e2'.at % (Il.BoolT $ e2.at) + ) $$ at % (Il.BoolT $ at)) -and elab_typ_notation env tid t : Il.mixop * Il.typ list * typ list = + +and elab_typ_notation env outer_dims tid at (t : typ) (prems : prem nl_list) : + Il.mixop * Il.typ * Il.quant list * Il.prem list = + assert (valid_tid tid); + let env1 = local_env env in + let mixop, xts' = elab_typ_notation' env1 tid t in + let xs', ts' = List.split xts' in + let dims1 = Dim.check outer_dims [] [] ts' [] [] [] in + let ts' = List.map (Dim.annot_typ dims1) ts' in + let t' = Il.TupT (List.combine xs' ts') $ t.at in + let det1 = Det.det_typ t' in + infer_no_quants env dims1 det1 [] [] [t'] [] [] [] at; + + let env2 = local_env env1 in + let prems' = List.concat (map_filter_nl_list (elab_prem env2) prems) in + let dims2 = Dim.check (Dim.union outer_dims dims1) [] [] [] [] [] prems' in + let prems' = List.map (Dim.annot_prem dims2) prems' in + let det2 = Det.(det_list det_prem prems') in + let qs = infer_quants env1 env2 dims2 det2 [] [] [] [] [] prems' at in + mixop, t', qs, prems' + +and elab_typ_notation' env tid (t : typ) : Il.mixop * (Il.id * Il.typ) list = Debug.(log_at "el.elab_typ_notation" t.at (fun _ -> fmt "(%s) %s" tid.it (el_typ t)) - (fun (mixop, ts', _) -> fmt "%s(%s)" (il_mixop mixop) (list il_typ ts')) + (fun (mixop, xts') -> fmt "%s(%s)" (il_mixop mixop) (list (pair il_id ":" il_typ) xts')) ) @@ fun _ -> assert (valid_tid tid); match t.it with - | VarT (id, as_) -> - let id' = strip_var_suffix id in - (match (Convert.typ_of_varid id').it with - | VarT _ -> - (match find "syntax type" env.typs id' with - | _, Transp -> error_id id "invalid forward reference to syntax type" - | ps, _ -> - let as', _s = elab_args `Rhs env as_ ps t.at in - [[]; []], [Il.VarT (id', as') $ t.at], [t] - ) - | t' -> - [[]; []], [elab_typ env (t' $ id.at)], [t] - ) | AtomT atom -> - [[elab_atom atom tid]], [], [] + let atom' = elab_atom atom tid in + Atom atom', [] | SeqT [] -> - [[]], [], [] + Seq [], [] | SeqT (t1::ts2) -> - let mixop1, ts1', ts1 = elab_typ_notation env tid t1 in - let mixop2, ts2', ts2 = elab_typ_notation env tid (SeqT ts2 $ t.at) in - merge_mixop mixop1 mixop2, ts1' @ ts2', ts1 @ ts2 + let mixop1, xts1' = elab_typ_notation' env tid t1 in + let mixop2, xts2' = elab_typ_notation' env tid (SeqT ts2 $ t.at) in + (match mixop2 with Seq mixops2 -> Seq (mixop1::mixops2) | _ -> assert false), + xts1' @ xts2' | InfixT (t1, atom, t2) -> - let mixop1, ts1', ts1 = elab_typ_notation env tid t1 in - let mixop2, ts2', ts2 = elab_typ_notation env tid t2 in - merge_mixop (merge_mixop mixop1 [[elab_atom atom tid]]) mixop2, - ts1' @ ts2', ts1 @ ts2 + let mixop1, xts1' = elab_typ_notation' env tid t1 in + let mixop2, xts2' = elab_typ_notation' env tid t2 in + let atom' = elab_atom atom tid in + Infix (mixop1, atom', mixop2), xts1' @ xts2' | BrackT (l, t1, r) -> - let mixop1, ts1', ts1 = elab_typ_notation env tid t1 in - merge_mixop (merge_mixop [[elab_atom l tid]] mixop1) [[elab_atom r tid]], - ts1', ts1 + let mixop1, xts1' = elab_typ_notation' env tid t1 in + let l' = elab_atom l tid in + let r' = elab_atom r tid in + Brack (l', mixop1, r'), xts1' + | VarT _ | IterT _ | ParenT _ -> + let rec id_of t ctx = + match t.it with + | VarT (x, []) -> Dim.annot_varid x ctx + | ParenT t1 -> id_of t1 ctx + | IterT (t1, iter) -> + let iter' = match iter with Opt -> Il.Opt | _ -> Il.List in + id_of t1 (iter'::ctx) + | _ -> "_" $ t.at + in + let x' = id_of t [] in + let t' = elab_typ env ~fwd: false t in + (* Ignore name if already bound. This may happen if the same type name + * occurs multiple times as a parameter. *) + if not (bound env.vars x') then env.vars <- bind "variable" env.vars x' t'; + Arg (), [x', t'] | _ -> - [[]; []], [elab_typ env t], [t] - - -and (!!!) env tid t = - let _, ts', _ = elab_typ_notation env tid t in tup_typ' ts' t.at + let t' = elab_typ env t in + Arg (), ["_" $ t.at, t'] (* Expressions *) @@ -991,44 +1060,44 @@ and (!!!) env tid t = * - Fail (at, s) when it cannot, where s is the name of the failing construct * - raises Error.Error on fatal, unrecoverable errors *) -and infer_exp env e : (Il.exp * typ) attempt = +and infer_exp env e : (Il.exp * Il.typ) attempt = Debug.(log_at "el.infer_exp" e.at (fun _ -> fmt "%s" (el_exp e)) - (function Ok (e', t) -> fmt "%s : %s" (il_exp e') (el_typ t) | _ -> "fail") + (function Ok (e', t) -> fmt "%s : %s" (il_exp e') (il_typ t) | _ -> "fail") ) @@ fun _ -> let* e', t' = infer_exp' env e in let t = t' $ e.at in - Ok (e' $$ e.at % elab_typ env t, t) + Ok (e' $$ e.at % t, t) -and infer_exp' env e : (Il.exp' * typ') attempt = +and infer_exp' env e : (Il.exp' * Il.typ') attempt = match e.it with - | VarE (id, args) -> + | VarE (x, args) -> (* Args may only occur due to syntactic overloading with types *) if args <> [] then error e.at "malformed expression"; - if id.it = "_" then fail_infer e.at "wildcard" else + if x.it = "_" then fail_infer e.at "wildcard" else let* t = - if bound env.vars id then - Ok (find "variable" env.vars id) - else if bound env.gvars (strip_var_suffix id) then + if bound env.vars x then + Ok (find "variable" env.vars x) + else if bound env.gvars (strip_var_suffix x) then (* If the variable itself is not yet declared, use type hint. *) - let t = find "variable" env.gvars (strip_var_suffix id) in - env.vars <- bind "variable" env.vars id t; + let t = find "variable" env.gvars (strip_var_suffix x) in + env.vars <- bind "variable" env.vars x t; Ok t else fail_infer e.at "variable" - in Ok (Il.VarE id, t.it) + in Ok (Il.VarE x, t.it) | AtomE _ -> fail_infer e.at "atom" | BoolE b -> - Ok (Il.BoolE b, BoolT) + Ok (Il.BoolE b, Il.BoolT) | NumE (_op, n) -> - Ok (Il.NumE n, NumT (Num.to_typ n)) + Ok (Il.NumE n, Il.NumT (Num.to_typ n)) | TextE s -> - Ok (Il.TextE s, TextT) + Ok (Il.TextE s, Il.TextT) | CvtE (e1, nt) -> let* e1', t1 = infer_exp env e1 in let* nt1 = as_num_typ "conversion" env Infer t1 e1.at in - let* e1'' = cast_exp "operand" env e1' t1 (NumT nt1 $ e1.at) in - Ok (Il.CvtE (e1'', nt1, nt), NumT nt) + let* e1'' = cast_exp "operand" env e1' t1 (Il.NumT nt1 $ e1.at) in + Ok (Il.CvtE (e1'', nt1, nt), Il.NumT nt) | UnE (op, e1) -> let* e1', t1 = infer_exp env e1 in let* op', ot, t1', t = infer_unop env op (typ_rep env t1) e.at in @@ -1045,7 +1114,7 @@ and infer_exp' env e : (Il.exp' * typ') attempt = | CmpE (e1, op, ({it = CmpE (e21, _, _); _} as e2)) -> let* e1', _t1 = infer_exp env (CmpE (e1, op, e21) $ e.at) in let* e2', _t2 = infer_exp env e2 in - Ok (Il.BinE (`AndOp, `BoolT, e1', e2'), BoolT) + Ok (Il.BinE (`AndOp, `BoolT, e1', e2'), Il.BoolT) | CmpE (e1, op, e2) -> (match infer_cmpop env op with | `Poly op' -> @@ -1063,25 +1132,25 @@ and infer_exp' env e : (Il.exp' * typ') attempt = ); ] in - Ok (Il.CmpE (op', `BoolT, e1', e2'), BoolT) + Ok (Il.CmpE (op', `BoolT, e1', e2'), Il.BoolT) | `Over elab_cmpop' -> let* e1', t1 = infer_exp env e1 in let* e2', t2 = infer_exp env e2 in let* op', ot, t = elab_cmpop' (typ_rep env t1) (typ_rep env t2) e.at in let* e1'' = cast_exp "operand" env e1' t1 t in let* e2'' = cast_exp "operand" env e2' t2 t in - Ok (Il.CmpE (op', ot, e1'', e2''), BoolT) + Ok (Il.CmpE (op', ot, e1'', e2''), Il.BoolT) ) | IdxE (e1, e2) -> let* e1', t1 = infer_exp env e1 in let* t = as_list_typ "expression" env Infer t1 e1.at in - let* e2' = elab_exp env e2 (NumT `NatT $ e2.at) in + let* e2' = elab_exp env e2 (Il.NumT `NatT $ e2.at) in Ok (Il.IdxE (e1', e2'), t.it) | SliceE (e1, e2, e3) -> let* e1', t1 = infer_exp env e1 in let* _t' = as_list_typ "expression" env Infer t1 e1.at in - let* e2' = elab_exp env e2 (NumT `NatT $ e2.at) in - let* e3' = elab_exp env e3 (NumT `NatT $ e3.at) in + let* e2' = elab_exp env e2 (Il.NumT `NatT $ e2.at) in + let* e3' = elab_exp env e3 (Il.NumT `NatT $ e3.at) in Ok (Il.SliceE (e1', e2', e3'), t1.it) | UpdE (e1, p, e2) -> let* e1', t1 = infer_exp env e1 in @@ -1091,30 +1160,30 @@ and infer_exp' env e : (Il.exp' * typ') attempt = | ExtE (e1, p, e2) -> let* e1', t1 = infer_exp env e1 in let* p', t2 = elab_path env p t1 in - let* _t21 = as_list_typ "path" env Infer t2 p.at in + let* _ = as_list_typ "path" env Infer t2 p.at in let* e2' = elab_exp env e2 t2 in Ok (Il.ExtE (e1', p', e2'), t1.it) | StrE _ -> fail_infer e.at "record" | DotE (e1, atom) -> let* e1', t1 = infer_exp env e1 in - let* tfs, dots1 = as_struct_typ "expression" env Infer t1 e1.at in - if dots1 = Dots then + let* tfs, dots = as_struct_typ "expression" env Infer t1 e1.at in + if dots = Dots then error e1.at "used record type is only partially defined at this point"; - let* t, prems = attempt (find_field tfs atom e1.at) t1 in + let* _, (tF, _qs, prems), _ = attempt (find_field tfs atom e1.at) t1 in let e' = Il.DotE (e1', elab_atom atom (expand_id env t1)) in - let e'' = if prems = [] then e' else Il.ProjE (e' $$ e.at % elab_typ env t, 0) in - Ok (e'', t.it) + let e'' = if prems = [] then e' else Il.ProjE (e' $$ e.at % tF, 0) in + Ok (e'', tF.it) | CommaE (e1, e2) -> let* e1', t1 = infer_exp env e1 in - let* tfs, dots1 = as_struct_typ "expression" env Infer t1 e1.at in - if dots1 = Dots then + let* tfs, dots = as_struct_typ "expression" env Infer t1 e1.at in + if dots = Dots then error e1.at "used record type is only partially defined at this point"; - let* _ = as_cat_typ "expression" env Infer t1 e.at in + let* () = as_cat_typ "expression" env Infer t1 e.at in (* TODO(4, rossberg): this is a bit of a hack, can we avoid it? *) (match e2.it with | SeqE ({it = AtomE atom; at; _} :: es2) -> - let* _t2 = attempt (find_field tfs atom at) t1 in + let* _ = attempt (find_field tfs atom at) t1 in let e2 = match es2 with [e2] -> e2 | _ -> SeqE es2 $ e2.at in let* e2' = elab_exp env (StrE [Elem (atom, e2)] $ e2.at) t1 in Ok (Il.CompE (e2', e1'), t1.it) @@ -1122,60 +1191,59 @@ and infer_exp' env e : (Il.exp' * typ') attempt = ) | CatE (e1, e2) -> let* e1', t1 = infer_exp env e1 in - let* _ = as_cat_typ "operand" env Infer t1 e1.at in + let* () = as_cat_typ "operand" env Infer t1 e1.at in let* e2' = elab_exp env e2 t1 in Ok ((if is_iter_typ env t1 then Il.CatE (e1', e2') else Il.CompE (e1', e2')), t1.it) | MemE (e1, e2) -> choice env [ (fun env -> let* e1', t1 = infer_exp env e1 in - let* e2' = elab_exp env e2 (IterT (t1, List) $ e2.at) in - Ok (Il.MemE (e1', e2'), BoolT) + let* e2' = elab_exp env e2 (Il.IterT (t1, Il.List) $ e2.at) in + Ok (Il.MemE (e1', e2'), Il.BoolT) ); (fun env -> let* e2', t2 = infer_exp env e2 in let* t1 = as_list_typ "operand" env Infer t2 e2.at in let* e1' = elab_exp env e1 t1 in - Ok (Il.MemE (e1', e2'), BoolT) + Ok (Il.MemE (e1', e2'), Il.BoolT) ); ] | LenE e1 -> let* e1', t1 = infer_exp env e1 in let* _t11 = as_list_typ "expression" env Infer t1 e1.at in - Ok (Il.LenE e1', NumT `NatT) + Ok (Il.LenE e1', Il.NumT `NatT) | SizeE id -> let _ = find "grammar" env.grams id in - Ok (Il.NumE (`Nat Z.zero), NumT `NatT) + Ok (Il.NumE (`Nat Z.zero), Il.NumT `NatT) | ParenE e1 | ArithE e1 -> infer_exp' env e1 | TupE es -> let* es', ts = infer_exp_list env es in - Ok (Il.TupE es', TupT ts) + Ok (Il.TupE es', (tup_typ' ts e.at).it) | CallE (id, as_) -> let ps, t, _ = find "definition" env.defs id in let as', s = elab_args `Rhs env as_ ps e.at in - Ok (Il.CallE (id, as'), (Subst.subst_typ s t).it) + Ok (Il.CallE (id, as'), (Il.Subst.subst_typ s t).it) | EpsE -> fail_infer e.at "empty sequence" | SeqE [] -> (* treat as empty tuple, not principal *) - Ok (Il.TupE [], TupT []) + Ok (Il.TupE [], Il.TupT []) | SeqE es | ListE es -> (* treat as homogeneous sequence, not principal *) let* es', ts = infer_exp_list env es in let t = List.hd ts in if List.for_all (equiv_typ env t) (List.tl ts) then - Ok (Il.ListE es', IterT (t, List)) + Ok (Il.ListE es', Il.IterT (t, Il.List)) else fail_infer e.at "expression sequence" | InfixE _ -> fail_infer e.at "infix expression" | BrackE _ -> fail_infer e.at "bracket expression" - | IterE (e1, iter) -> - let iter' = elab_iterexp env iter in - let* e1', t1 = infer_exp env e1 in - Ok (Il.IterE (e1', iter'), IterT (t1, match iter with ListN _ -> List | _ -> iter)) + | IterE (e1, it) -> + let* (e1', t1), ite', itt' = elab_iterexp env infer_exp e1 it in + Ok (Il.IterE (e1', ite'), Il.IterT (t1, itt')) | TypE (e1, t) -> - let _t' = elab_typ env t in - let* e1' = elab_exp env e1 t in - Ok (e1'.it, t.it) + let t' = elab_typ env t in + let* e1' = elab_exp env e1 t' in + Ok (e1'.it, t'.it) | HoleE _ -> error e.at "misplaced hole" | FuseE _ -> error e.at "misplaced token concatenation" | UnparenE _ -> error e.at "misplaced unparenthesize" @@ -1189,9 +1257,9 @@ and infer_exp_list env = function Ok (e'::es', t::ts) -and elab_exp env e t : Il.exp attempt = +and elab_exp env (e : exp) (t : Il.typ) : Il.exp attempt = Debug.(log_at "el.elab_exp" e.at - (fun _ -> fmt "%s : %s" (el_exp e) (el_typ t)) + (fun _ -> fmt "%s : %s" (el_exp e) (il_typ t)) (function Ok e' -> fmt "%s" (il_exp e') | _ -> "fail") ) @@ fun _ -> nest e.at t ( @@ -1209,31 +1277,29 @@ and elab_exp env e t : Il.exp attempt = | VarE ({it = "_"; _}, []) | EpsE | SeqE [] -> fail_silent | _ -> let* e' = elab_exp env e t1 in - let t' = elab_typ env t in - Ok (lift_exp' e' iter $$ e.at % t') + Ok (lift_exp' e' iter $$ e.at % t) ); (fun env -> elab_exp_plain env e t); ] else if is_notation_typ env t then - let* t1 = as_notation_typ "" env Check t e.at in + let* not = as_notation_typ "" env Check t e.at in choice env [ (fun env -> elab_exp_plain env e t); - (fun env -> elab_exp_notation env (expand_id env t) e t1 t); + (fun env -> elab_exp_notation env (expand_id env t) e not t); ] else elab_exp_plain env e t ) -and elab_exp_plain env e t : Il.exp attempt = +and elab_exp_plain env (e : exp) (t : Il.typ) : Il.exp attempt = Debug.(log_at "el.elab_exp_plain" e.at - (fun _ -> fmt "%s : %s" (el_exp e) (el_typ t)) + (fun _ -> fmt "%s : %s" (el_exp e) (il_typ t)) (function Ok e' -> fmt "%s" (il_exp e') | _ -> "fail") ) @@ fun _ -> let* e' = elab_exp_plain' env e t in - let t' = elab_typ env t in - Ok (e' $$ e.at % t') + Ok (e' $$ e.at % t) -and elab_exp_plain' env e t : Il.exp' attempt = +and elab_exp_plain' env (e : exp) (t : Il.typ) : Il.exp' attempt = match e.it with | BoolE _ | NumE _ | CvtE _ | UnE _ | BinE _ | CmpE _ | IdxE _ | DotE _ | MemE _ | LenE _ | SizeE _ | CallE _ | TypE _ @@ -1246,7 +1312,7 @@ and elab_exp_plain' env e t : Il.exp' attempt = if List.length cs = 1 && is_nat_typ env t then let e' = Il.NumE (`Nat (Z.of_int (List.hd cs))) $$ e.at % (Il.NumT `NatT $ e.at) in - cast_exp' "character" env e' (NumT `NatT $ e.at) t + cast_exp' "character" env e' (Il.NumT `NatT $ e.at) t else let* e', t' = infer_exp env e in cast_exp' "expression" env e' t' t @@ -1275,8 +1341,8 @@ and elab_exp_plain' env e t : Il.exp' attempt = | SliceE (e1, e2, e3) -> let* _t' = as_list_typ "expression" env Check t e1.at in let* e1' = elab_exp env e1 t in - let* e2' = elab_exp env e2 (NumT `NatT $ e2.at) in - let* e3' = elab_exp env e3 (NumT `NatT $ e3.at) in + let* e2' = elab_exp env e2 (Il.NumT `NatT $ e2.at) in + let* e3' = elab_exp env e3 (Il.NumT `NatT $ e3.at) in Ok (Il.SliceE (e1', e2', e3')) | UpdE (e1, p, e2) -> let* e1' = elab_exp env e1 t in @@ -1286,7 +1352,7 @@ and elab_exp_plain' env e t : Il.exp' attempt = | ExtE (e1, p, e2) -> let* e1' = elab_exp env e1 t in let* p', t2 = elab_path env p t in - let* _t21 = as_list_typ "path" env Check t2 p.at in + let* _ = as_list_typ "path" env Check t2 p.at in let* e2' = elab_exp env e2 t2 in Ok (Il.ExtE (e1', p', e2')) | StrE efs -> @@ -1300,36 +1366,37 @@ and elab_exp_plain' env e t : Il.exp' attempt = let* tfs, dots1 = as_struct_typ "expression" env Check t e1.at in if dots1 = Dots then error e1.at "used record type is only partially defined at this point"; - let* _ = as_cat_typ "expression" env Check t e.at in + let* () = as_cat_typ "expression" env Check t e.at in (* TODO(4, rossberg): this is a bit of a hack, can we avoid it? *) (match e2.it with | SeqE ({it = AtomE atom; at; _} :: es2) -> - let* _t2 = attempt (find_field tfs atom at) t in + let* _ = attempt (find_field tfs atom at) t in let e2 = match es2 with [e2] -> e2 | _ -> SeqE es2 $ e2.at in let* e2' = elab_exp env (StrE [Elem (atom, e2)] $ e2.at) t in Ok (Il.CompE (e2', e1')) | _ -> error e.at "malformed comma operator" ) | CatE (e1, e2) -> - let* _ = as_cat_typ "expression" env Check t e.at in + let* () = as_cat_typ "expression" env Check t e.at in let* e1' = elab_exp env e1 t in let* e2' = elab_exp env e2 t in Ok (if is_iter_typ env t then Il.CatE (e1', e2') else Il.CompE (e1', e2')) | ParenE e1 | ArithE e1 -> elab_exp_plain' env e1 t | TupE es -> - let* ts = as_tup_typ "tuple" env Check t e.at in - let* es' = elab_exp_list env es ts e.at in + let* xts = as_tup_typ "tuple" env Check t e.at in + let* es' = elab_exp_list env es xts e.at in Ok (Il.TupE es') | ListE es -> let* t1, iter = as_iter_typ "list" env Check t e.at in - if iter <> List then fail_typ env e.at "list" t else - let ts = List.init (List.length es) (fun _ -> t1) in - let* es' = elab_exp_list env es ts e.at in + if iter <> Il.List then fail_typ env e.at "list" t else + let xts = List.init (List.length es) (fun _ -> "_" $ t1.at, t1) in + let* es' = elab_exp_list env es xts e.at in Ok (Il.ListE es') - | SeqE [] when is_empty_typ env t -> + | SeqE [] when is_empty_notation_typ env t -> let* e', t' = infer_exp env e in - cast_exp' "empty expression" env e' t' t + let* e'' = cast_exp' "empty expression" env e' t' t in + Ok (e'') | EpsE | SeqE _ when is_iter_typ env t -> let* t1, iter = as_iter_typ "" env Check t e.at in elab_exp_iter' env (unseq_exp e) (t1, iter) t e.at @@ -1342,8 +1409,8 @@ and elab_exp_plain' env e t : Il.exp' attempt = * either a defined notation/variant type or (for SeqE) an iteration type; * the latter case is already captured above *) if is_notation_typ env t then - let* nt = as_notation_typ "" env Check t e.at in - let* e' = elab_exp_notation env (expand_id env t) e nt t in + let* not = as_notation_typ "" env Check t e.at in + let* e' = elab_exp_notation env (expand_id env t) e not t in Ok e'.it else if is_variant_typ env t then let* tcs, _ = as_variant_typ "" env Check t e.at in @@ -1359,58 +1426,59 @@ and elab_exp_plain' env e t : Il.exp' attempt = | SeqE _ -> "expression sequence" | _ -> assert false in fail_typ env e.at name t - | IterE (e1, iter2) -> - let* t1, iter = as_iter_typ "iteration" env Check t e.at in - let iter2' = elab_iterexp env iter2 in - let* e1' = elab_exp env e1 t1 in - let e' = Il.IterE (e1', iter2') in - match iter2, iter with - | Opt, Opt -> Ok e' - | Opt, List -> - Ok (Il.LiftE (e' $$ e.at % (Il.IterT (elab_typ env t1, Opt) $ e1.at))) - | _, Opt -> fail_typ env e.at "iteration" t + | IterE (e1, it2) -> + let* t1, it = as_iter_typ "iteration" env Check t e.at in + let* e1', ite2', itt2' = elab_iterexp env + (fun env (e, t) -> elab_exp env e t) (e1, t1) it2 in + let e' = Il.IterE (e1', ite2') in + match it2, it with + | Opt, Il.Opt -> Ok e' + | Opt, Il.List -> + Ok (Il.LiftE (e' $$ e.at % (Il.IterT (t1, itt2') $ e1.at))) + | _, Il.Opt -> fail_typ env e.at "iteration" t | _, _ -> Ok e' -and elab_exp_list env es ts at : Il.exp list attempt = - match es, ts with +and elab_exp_list env (es : exp list) (xts : (id * Il.typ) list) at + : Il.exp list attempt = + match es, xts with | [], [] -> Ok [] - | e::es, t::ts -> + | e::es, (_x, t)::xts -> let* e' = elab_exp env e t in - let* es' = elab_exp_list env es ts at in + let* es' = elab_exp_list env es xts at in Ok (e'::es') | _, _ -> fail at "arity mismatch for expression list" -and elab_expfields env tid efs tfs t0 at : Il.expfield list attempt = +and elab_expfields env tid (efs : expfield list) (tfs : Il.typfield list) (t0 : Il.typ) at + : Il.expfield list attempt = Debug.(log_in_at "el.elab_expfields" at - (fun _ -> fmt "{%s} : {%s} = %s" (list el_expfield efs) (list el_typfield tfs) (el_typ t0)) + (fun _ -> fmt "{%s} : {%s} = %s" (list el_expfield efs) (list il_typfield tfs) (il_typ t0)) ); assert (valid_tid tid); match efs, tfs with | [], [] -> Ok [] - | (atom1, e)::efs2, (atom2, (t, prems), _)::tfs2 when atom1.it = atom2.it -> - let* es', _s = elab_exp_notation' env tid e t in + | (atom1, e)::efs2, (atom2, (tF, _qs, prems), _)::tfs2 when atom1.it = atom2.it -> + let* e' = elab_exp env e tF in let* efs2' = elab_expfields env tid efs2 tfs2 t0 at in - let e' = (if prems = [] then tup_exp' else tup_exp_bind') es' e.at in + let e' = if prems = [] then e' else tup_exp' [e'] e.at in Ok ((elab_atom atom1 tid, e') :: efs2') - | _, (atom, (t, prems), _)::tfs2 -> + | _, (atom, (tF, _qs, prems), _)::tfs2 -> let atom' = string_of_atom atom in - let* e1' = - cast_empty ("omitted record field `" ^ atom' ^ "`") env t at (elab_typ env t) in - let e' = (if prems = [] then tup_exp' else tup_exp_bind') [e1'] at in + let* e1' = cast_empty ("omitted record field `" ^ atom' ^ "`") env tF at in + let e' = if prems = [] then e1' else tup_exp' [e1'] at in let* efs2' = elab_expfields env tid efs tfs2 t0 at in Ok ((elab_atom atom tid, e') :: efs2') | (atom, e)::_, [] -> fail_atom e.at atom t0 "undefined or misplaced record field" -and elab_exp_iter env es (t1, iter) t at : Il.exp attempt = +and elab_exp_iter env (es : exp list) (t1, iter) t at : Il.exp attempt = let* e' = elab_exp_iter' env es (t1, iter) t at in - Ok (e' $$ at % elab_typ env t) + Ok (e' $$ at % t) -and elab_exp_iter' env es (t1, iter) t at : Il.exp' attempt = +and elab_exp_iter' env (es : exp list) (t1, iter) t at : Il.exp' attempt = Debug.(log_at "el.elab_exp_iter" at - (fun _ -> fmt "%s : %s = (%s)%s" (seq el_exp es) (el_typ t) (el_typ t1) (el_iter iter)) - (function Ok e' -> fmt "%s" (il_exp (e' $$ at % elab_typ env t)) | _ -> "fail") + (fun _ -> fmt "%s : %s = (%s)%s" (seq el_exp es) (il_typ t) (il_typ t1) (il_iter iter)) + (function Ok e' -> fmt "%s" (il_exp (e' $$ at % t)) | _ -> "fail") ) @@ fun _ -> match es, iter with | [], Opt -> @@ -1432,275 +1500,362 @@ and elab_exp_iter' env es (t1, iter) t at : Il.exp' attempt = | _, (List1 | ListN _) -> assert false -and elab_exp_notation env tid e nt t : Il.exp attempt = +and elab_exp_notation env tid (e : exp) (t1, mixop, not) t : Il.exp attempt = (* Convert notation into applications of mixin operators *) assert (valid_tid tid); - let* es', _s = elab_exp_notation' env tid e nt in - let mixop, ts', _ = elab_typ_notation env tid nt in - assert (List.length es' = List.length ts'); - Ok (Il.CaseE (mixop, tup_exp_bind' es' e.at) $$ e.at % elab_typ env t) + let* es', _s = elab_exp_notation' env tid e not in + Ok (Il.CaseE (mixop, Il.TupE es' $$ e.at % t1) $$ e.at % t) -and elab_exp_notation' env tid e t : (Il.exp list * Subst.t) attempt = +and elab_exp_notation' env tid (e : exp) not : (Il.exp list * Il.Subst.t) attempt = Debug.(log_at "el.elab_exp_notation" e.at - (fun _ -> fmt "%s : %s" (el_exp e) (el_typ t)) - (function Ok (es', _) -> fmt "%s" (seq il_exp es') | _ -> "fail") + (fun _ -> fmt "%s : %s" (el_exp e) (Mixop.to_string_with il_typbind " " not)) + (function Ok (es', s) -> fmt "{%s} [%s]" (seq il_exp es') (il_subst s) | _ -> "fail") ) @@ fun _ -> assert (valid_tid tid); - match e.it, t.it with - | AtomE atom, AtomT atom' -> - if atom.it <> atom'.it then fail_typ env e.at "atom" t else + match e.it, not with + | AtomE atom, Atom atom' -> + if atom.it <> atom'.it then fail_not env e.at "atom" not else let _ = elab_atom atom tid in - Ok ([], Subst.empty) - | InfixE (e1, atom, e2), InfixT (_, atom', _) when Atom.sub atom' atom -> + Ok ([], Il.Subst.empty) + + | InfixE (e1, atom, e2), Infix (_, atom', _) when Atom.sub atom' atom -> let e21 = ParenE (SeqE [] $ e2.at) $ e2.at in elab_exp_notation' env tid - (InfixE (e1, atom', SeqE [e21; e2] $ e2.at) $ e.at) t - | InfixE (e1, atom, e2), InfixT (t1, atom', t2) -> - if atom.it <> atom'.it then fail_typ env e.at "infix expression" t else - let* es1', s1 = elab_exp_notation' env tid e1 t1 in - let* es2', s2 = elab_exp_notation' env tid e2 (Subst.subst_typ s1 t2) in + (InfixE (e1, atom', SeqE [e21; e2] $ e2.at) $ e.at) not + + | InfixE (e1, atom, e2), Infix (not1, atom', not2) -> + if atom.it <> atom'.it then fail_not env e.at "infix expression" not else + let* es1', s1 = elab_exp_notation' env tid e1 not1 in + let not2' = Mixop.map (fun (x, t) -> x, Il.Subst.subst_typ s1 t) not2 in + let* es2', s2 = elab_exp_notation' env tid e2 not2' in let _ = elab_atom atom tid in - Ok (es1' @ es2', Subst.union s1 s2) - | BrackE (l, e1, r), BrackT (l', t1, r') -> - if (l.it, r.it) <> (l'.it, r'.it) then fail_typ env e.at "bracket expression" t else + Ok (es1' @ es2', Il.Subst.union s1 s2) + + | BrackE (l, e1, r), Brack (l', not1, r') -> + if (l.it, r.it) <> (l'.it, r'.it) then fail_not env e.at "bracket expression" not else let _ = elab_atom l tid in let _ = elab_atom r tid in - elab_exp_notation' env tid e1 t1 + elab_exp_notation' env tid e1 not1 + + | SeqE [], Seq [] -> + Ok ([], Il.Subst.empty) - | SeqE [], SeqT [] -> - Ok ([], Subst.empty) - | _, SeqT (t1::ts2) when is_iter_typ env t1 -> + | _, Seq ((Arg (x1, t1))::nots2) when is_iter_typ env t1 -> let* t11, iter = as_iter_typ "iteration" env Check t1 e.at in - elab_exp_notation_iter env tid (unseq_exp e) (t11, iter) t1 ts2 e.at - | SeqE ({it = AtomE atom; at; _}::es2), SeqT ({it = AtomT atom'; _}::_) + elab_exp_notation_iter env tid (unseq_exp e) (t11, iter) x1 t1 nots2 e.at + + | SeqE ({it = AtomE atom; at; _}::es2), Seq ((Atom atom')::_) when Atom.sub atom' atom -> let e21 = ParenE (SeqE [] $ at) $ at in - elab_exp_notation' env tid (SeqE ((AtomE atom' $ at) :: e21 :: es2) $ e.at) t + elab_exp_notation' env tid (SeqE ((AtomE atom' $ at) :: e21 :: es2) $ e.at) not + (* Trailing notation can be flattened *) - | SeqE (e1::es2), SeqT [t1] -> + | SeqE (e1::es2), Seq [Arg (x1, t1) as not1] -> choice env [ (fun env -> - let* es1', s1 = elab_exp_notation' env tid (unparen_exp e1) t1 in + let* es1', s1 = elab_exp_notation' env tid (unparen_exp e1) not1 in let e2 = SeqE es2 $ Source.over_region (after_region e1.at :: List.map Source.at es2) in - let t2 = SeqT [] $ Source.after_region t1.at in - let* es2', s2 = elab_exp_notation' env tid e2 (Subst.subst_typ s1 t2) in - Ok (es1' @ es2', Subst.union s1 s2) + let* es2', s2 = elab_exp_notation' env tid e2 (Seq []) in + Ok (es1' @ es2', Il.Subst.union s1 s2) ); (fun env -> let* e' = elab_exp env e t1 in - Ok ([e'], Subst.empty) + Ok ([e'], Il.Subst.add_varid Il.Subst.empty x1 e') ) ] - | SeqE (e1::es2), SeqT (t1::ts2) -> - let* es1', s1 = elab_exp_notation' env tid (unparen_exp e1) t1 in + + | SeqE (e1::es2), Seq (not1::nots2) -> + let* es1', s1 = elab_exp_notation' env tid (unparen_exp e1) not1 in let e2 = SeqE es2 $ Source.over_region (after_region e1.at :: List.map Source.at es2) in - let t2 = SeqT ts2 $ Source.over_region (after_region t1.at :: List.map Source.at ts2) in - let* es2', s2 = elab_exp_notation' env tid e2 (Subst.subst_typ s1 t2) in - Ok (es1' @ es2', Subst.union s1 s2) + let not2 = Mixop.Seq nots2 in + let not2' = Mixop.map (fun (x, t) -> x, Il.Subst.subst_typ s1 t) not2 in + let* es2', s2 = elab_exp_notation' env tid e2 not2' in + Ok (es1' @ es2', Il.Subst.union s1 s2) + (* Trailing elements can be omitted if they can be eps *) - | SeqE [], SeqT (t1::ts2) -> - let* e1' = cast_empty "omitted sequence tail" env t1 e.at (!!!env tid t1) in - let t2 = SeqT ts2 $ Source.over_region (after_region t1.at :: List.map Source.at ts2) in - let* es2', s2 = elab_exp_notation' env tid e t2 in - Ok (e1' :: es2', s2) - | SeqE (e1::_), SeqT [] -> + | SeqE [], Seq ((Arg (x1, t1))::nots2) -> + let* e1' = cast_empty "omitted sequence tail" env t1 e.at in + let s1 = Il.Subst.add_varid Il.Subst.empty x1 e1' in + let not2 = Mixop.Seq nots2 in + let not2' = Mixop.map (fun (x, t) -> x, Il.Subst.subst_typ s1 t) not2 in + let* es2', s2 = elab_exp_notation' env tid e not2' in + Ok (e1' :: es2', Il.Subst.union s1 s2) + + | SeqE (e1::_), Seq [] -> fail e1.at "expression is not empty" - (* Since trailing elements can be omitted, a singleton may match a sequence *) - | _, SeqT _ -> - elab_exp_notation' env tid (SeqE [e] $ e.at) t - - | ParenE e1, _ - | ArithE e1, _ -> - elab_exp_notation' env tid e1 t - | _, ParenT t1 -> - elab_exp_notation' env tid e t1 - | _, (AtomT _ | InfixT _ | BrackT _) -> - fail_typ env e.at "expression" t + (* Since trailing elements can be omitted, a singleton may match a sequence *) + | _, Seq _ -> + elab_exp_notation' env tid (SeqE [e] $ e.at) not - | _, _ -> + | _, Arg (x, t) -> let* e' = elab_exp env e t in - Ok ([e'], Subst.add_varid Subst.empty (Convert.varid_of_typ t) e) + Ok ([e'], Il.Subst.add_varid Il.Subst.empty x e') + + | _, (Atom _ | Brack _ | Infix _) -> + fail e.at "expression does not match expected notation" -and elab_exp_notation_iter env tid es (t1, iter) t ts at : (Il.exp list * Subst.t) attempt = +and elab_exp_notation_iter env tid (es : exp list) (t1, iter) x t nots at + : (Il.exp list * Il.Subst.t) attempt = assert (valid_tid tid); - let t' = elab_typ env t in - let* e', es', s = elab_exp_notation_iter' env tid es (t1, iter) t ts t' at in + let* e', es', s = elab_exp_notation_iter' env tid es (t1, iter) x t None nots at in Ok (e'::es', s) -and elab_exp_notation_iter' env tid es (t1, iter) t ts t' at : (Il.exp * Il.exp list * Subst.t) attempt = +and elab_exp_notation_iter' env tid (es : exp list) (t1, iter) x t eo' nots at + : (Il.exp * Il.exp list * Il.Subst.t) attempt = Debug.(log_at "el.elab_exp_notation_iter" at - (fun _ -> fmt "%s : %s = (%s)%s" (seq el_exp es) (el_typ t) (el_typ t1) (el_iter iter)) + (fun _ -> fmt "%s : %s = (%s)%s" (seq el_exp es) (il_typ t) (il_typ t1) (il_iter iter)) (function Ok (e', es', _) -> fmt "%s" (seq il_exp (e'::es')) | _ -> "fail") ) @@ fun _ -> - let tat' = Source.over_region (after_region t.at :: List.map Source.at ts) in match es, iter with - | [], Opt -> - let* es', s = elab_exp_notation' env tid (SeqE [] $ at) (SeqT ts $ tat') in - Ok (Il.OptE None $$ at % t', es', s) - | e1::es2, Opt -> + | [], Il.Opt -> + (* Empty option *) + assert (eo' = None); + let e0' = Il.OptE None $$ at % t in + let s0 = Il.Subst.add_varid Il.Subst.empty x e0' in + let not = Mixop.Seq nots in + let not' = Mixop.map (fun (x, t) -> x, Il.Subst.subst_typ s0 t) not in + let* es', s = elab_exp_notation' env tid (SeqE [] $ at) not' in + Ok (e0', es', Il.Subst.union s0 s) + + | e1::es2, Il.Opt -> + assert (eo' = None); choice env [ (fun env -> - let* es', s = elab_exp_notation' env tid (SeqE (e1::es2) $ at) (SeqT ts $ tat') in - Ok (Il.OptE None $$ Source.before_region e1.at % t', es', s) + (* Try parsing as empty option *) + let e0' = Il.OptE None $$ Source.before_region e1.at % t in + let s0 = Il.Subst.add_varid Il.Subst.empty x e0' in + let not = Mixop.Seq nots in + let not' = Mixop.map (fun (x, t) -> x, Il.Subst.subst_typ s0 t) not in + let* es', s = elab_exp_notation' env tid (SeqE es $ at) not' in + Ok (e0', es', Il.Subst.union s0 s) ); (fun env -> + (* Parse as non-empty option *) let* e1' = elab_exp env e1 t in + let s1 = Il.Subst.add_varid Il.Subst.empty x e1' in + let not = Mixop.Seq nots in + let not' = Mixop.map (fun (x, t) -> x, Il.Subst.subst_typ s1 t) not in let at' = Source.over_region (after_region e1.at :: List.map Source.at es2) in - let* es2', s = elab_exp_notation' env tid (SeqE es2 $ at') (SeqT ts $ tat') in - Ok (e1', es2', s) + let* es2', s = elab_exp_notation' env tid (SeqE es2 $ at') not' in + Ok (e1', es2', Il.Subst.union s1 s) ); ] - | [], List -> - let* es', s = elab_exp_notation' env tid (SeqE [] $ at) (SeqT ts $ tat') in - Ok (Il.ListE [] $$ at % t', es', s) - | e1::es2, List -> + | [], Il.List -> + (* Empty list *) + let e' = + match eo' with + | Some e0' -> e0' + | None -> Il.ListE [] $$ at % t + in + let s1 = Il.Subst.add_varid Il.Subst.empty x e' in + let not = Mixop.Seq nots in + let not' = Mixop.map (fun (x, t) -> x, Il.Subst.subst_typ s1 t) not in + let* es', s2 = elab_exp_notation' env tid (SeqE [] $ at) not' in + Ok (e', es', Il.Subst.union s1 s2) + + | e1::es2, Il.List -> choice env [ (fun env -> - let* es', s = elab_exp_notation' env tid (SeqE (e1::es2) $ at) (SeqT ts $ tat') in - Ok (Il.ListE [] $$ at % t', es', s) + (* Try parsing as empty list *) + let e' = + match eo' with + | Some e0' -> e0' + | None -> Il.ListE [] $$ at % t + in + let s1 = Il.Subst.add_varid Il.Subst.empty x e' in + let not = Mixop.Seq nots in + let not' = Mixop.map (fun (x, t) -> x, Il.Subst.subst_typ s1 t) not in + let* es', s2 = elab_exp_notation' env tid (SeqE es $ at) not' in + Ok (e', es', Il.Subst.union s1 s2) ); (fun env -> + (* Try parsing as list element or concatenation *) let* e1' = elab_exp env e1 t in + let e0'' = + match eo' with + | None -> e1' + | Some e0' -> cat_exp' e0' e1' $$ Source.over_region [e0'.at; e1'.at] % t + in let at' = Source.over_region (after_region e1.at :: List.map Source.at es2) in - let* e2', es2', s = elab_exp_notation_iter' env tid es2 (t1, iter) t ts t' at' in - Ok (cat_exp' e1' e2' $$ Source.over_region [e1'.at; e2'.at] % t', es2', s) + let* e', es2', s = + elab_exp_notation_iter' env tid es2 (t1, iter) x t (Some e0'') nots at' in + Ok (e', es2', s) ); ] - | _, (List1 | ListN _) -> + | _, Il.(List1 | ListN _) -> assert false -and elab_exp_variant env tid e cases t at : Il.exp attempt = +and elab_exp_variant env tid (e : exp) (tcs : Il.typcase list) t at : Il.exp attempt = Debug.(log_at "el.elab_exp_variant" e.at - (fun _ -> fmt "%s : %s = %s" (el_exp e) tid.it (el_typ t)) + (fun _ -> fmt "%s : %s = %s" (el_exp e) tid.it (il_typ t)) (function Ok e' -> fmt "%s" (il_exp e') | _ -> "fail") ) @@ fun _ -> assert (valid_tid tid); - let* atom = + let rec head e = match e.it with | AtomE atom - | SeqE ({it = AtomE atom; _}::_) | InfixE (_, atom, _) | BrackE (atom, _, _) -> Ok atom + | SeqE (e1::es) -> + (match head e1 with Ok _ as ok -> ok | _ -> head (SeqE es $ e.at)) | _ -> fail_typ env at "expression" t in - let* t1, _prems = attempt (find_case_sub cases atom atom.at) t in - let* es', _s = elab_exp_notation' env tid e t1 in - let t2 = expand env t $ at in - let t2' = elab_typ env t2 in - let mixop, ts', _ = elab_typ_notation env tid t1 in - assert (List.length es' = List.length ts'); - cast_exp "variant case" env - (Il.CaseE (mixop, tup_exp_bind' es' at) $$ at % t2') t2 t + let* atom = head e in + let* mixop, (tC, _, _), _ = attempt (find_case_atom tcs atom atom.at) t in + let* xts = as_tup_typ "tuple" env Check tC e.at in + let not = Mixop.apply mixop xts in + let* es', _s = elab_exp_notation' env tid e not in + Ok (Il.CaseE (mixop, tup_exp' es' e.at) $$ at % t) -and elab_path env p t : (Il.path * typ) attempt = +(* +r[. = e] ~> e +r[[i] = e] ~> [r0,...,e,...,rN] if r = [r0,...,rN] +r[.l = e] ~> {l0 a0*=r0,...,l a*=e,...,lN aN*=rN} if r = {l0 a0*=r0,...,lN aN*=rN} + a* = q* +*) +and elab_path env (p : path) (t : Il.typ) : (Il.path * Il.typ) attempt = let* p', t' = elab_path' env p t in - Ok (p' $$ p.at % elab_typ env t', t') + Ok (p' $$ p.at % t', t') -and elab_path' env p t : (Il.path' * typ) attempt = +and elab_path' env (p : path) (t : Il.typ) : (Il.path' * Il.typ) attempt = match p.it with | RootP -> Ok (Il.RootP, t) | IdxP (p1, e1) -> let* p1', t1 = elab_path env p1 t in - let e1' = checkpoint (elab_exp env e1 (NumT `NatT $ e1.at)) in + let e1' = checkpoint (elab_exp env e1 (Il.NumT `NatT $ e1.at)) in let* t' = as_list_typ "path" env Check t1 p1.at in Ok (Il.IdxP (p1', e1'), t') | SliceP (p1, e1, e2) -> let* p1', t1 = elab_path env p1 t in - let e1' = checkpoint (elab_exp env e1 (NumT `NatT $ e1.at)) in - let e2' = checkpoint (elab_exp env e2 (NumT `NatT $ e2.at)) in + let e1' = checkpoint (elab_exp env e1 (Il.NumT `NatT $ e1.at)) in + let e2' = checkpoint (elab_exp env e2 (Il.NumT `NatT $ e2.at)) in let* _ = as_list_typ "path" env Check t1 p1.at in Ok (Il.SliceP (p1', e1', e2'), t1) | DotP (p1, atom) -> let* p1', t1 = elab_path env p1 t in - let* tfs, dots1 = as_struct_typ "path" env Check t1 p1.at in - if dots1 = Dots then + let* tfs, dots = as_struct_typ "path" env Check t1 p1.at in + if dots = Dots then error p1.at "used record type is only partially defined at this point"; - let* t', _prems = attempt (find_field tfs atom p1.at) t1 in - Ok (Il.DotP (p1', elab_atom atom (expand_id env t1)), t') + let* _, (tF, _, _), _ = attempt (find_field tfs atom p1.at) t1 in + Ok (Il.DotP (p1', elab_atom atom (expand_id env t1)), tF) -and cast_empty phrase env t at t' : Il.exp attempt = +and cast_empty phrase env (t : Il.typ) at : Il.exp attempt = Debug.(log_at "el.elab_exp_cast_empty" at - (fun _ -> fmt "%s >> (%s)" (el_typ t) (el_typ (expand_notation env t $ t.at))) - (function Ok r -> fmt "%s" (il_exp r) | _ -> "fail") + (fun _ -> fmt "%s >> (%s)" (il_typ t) (il_typ t)) + (function Ok e' -> fmt "%s" (il_exp e') | _ -> "fail") ) @@ fun _ -> nest at t ( - match expand_notation env t with - | SeqT [] -> Ok (Il.ListE [] $$ at % t') - | IterT (_, Opt) -> Ok (Il.OptE None $$ at % t') - | IterT (_, List) -> Ok (Il.ListE [] $$ at % t') - | VarT _ when is_iter_notation_typ env t -> - (match expand_iter_notation env t with - | IterT (_, iter) as t1 -> - let mixop, ts', _ts = elab_typ_notation env (expand_id env t) (t1 $ t.at) in - assert (List.length ts' = 1); - let e1' = if iter = Opt then Il.OptE None else Il.ListE [] in - Ok (Il.CaseE (mixop, tup_exp_bind' [e1' $$ at % List.hd ts'] at) $$ at % t') + match expand env t with + | Il.IterT (_, Opt) -> Ok (Il.OptE None $$ at % t) + | Il.IterT (_, List) -> Ok (Il.ListE [] $$ at % t) + | VarT _ when is_notation_typ env t -> + (match expand_notation env t with + | Some (_, _, Mixop.Seq []) -> Ok (Il.ListE [] $$ at % t) | _ -> fail_typ env at phrase t ) | _ -> fail_typ env at phrase t ) -and cast_exp phrase env e' t1 t2 : Il.exp attempt = +and cast_exp phrase env (e' : Il.exp) t1 t2 : Il.exp attempt = let* e'' = nest e'.at t2 (cast_exp' phrase env e' t1 t2) in - Ok (e'' $$ e'.at % elab_typ env (expand_nondef env t2)) + Ok (e'' $$ e'.at % t2) -and cast_exp' phrase env e' t1 t2 : Il.exp' attempt = +and cast_exp' phrase env (e' : Il.exp) t1 t2 : Il.exp' attempt = Debug.(log_at "el.elab_exp_cast" e'.at - (fun _ -> fmt "%s <: %s >> (%s) <: (%s) = (%s)" (el_typ t1) (el_typ t2) - (el_typ (expand_def env t1 $ t1.at)) (el_typ (expand_def env t2 $ t2.at)) - (el_typ (expand_nondef env t2)) + (fun _ -> fmt "%s <: %s >> (%s) <: (%s) = (%s)" (il_typ t1) (il_typ t2) + (il_deftyp (fst (expand_def env t1) $ t1.at)) + (il_deftyp (fst (expand_def env t2) $ t2.at)) + (il_typ (reduce env t2)) ) - (function Ok r -> fmt "%s" (il_exp (r $$ e'.at % elab_typ env t2)) | _ -> "fail") + (function Ok e'' -> fmt "%s" (il_exp (e'' $$ e'.at % t2)) | _ -> "fail") ) @@ fun _ -> if equiv_typ env t1 t2 then Ok e'.it else - match expand_def env t1, expand_def env t2 with - | _, _ when sub_typ env t1 t2 -> - let t1' = elab_typ env (expand_nondef env t1) in - let t2' = elab_typ env (expand_nondef env t2) in + let t1', t2' = reduce env t1, reduce env t2 in + match t1'.it, t2'.it with + | _, _ when sub_typ env t1' t2' -> Ok (Il.SubE (e', t1', t2')) - | NumT nt1, NumT nt2 when nt1 < nt2 || lax_num && nt1 <> `RealT -> + | Il.NumT nt1, Il.NumT nt2 when nt1 < nt2 || lax_num && nt1 <> `RealT -> Ok (Il.CvtE (e', nt1, nt2)) - | TupT [], SeqT [] -> + + | Il.TupT [], Il.VarT _ when is_empty_notation_typ env t2' -> Ok e'.it - | ConT ((t11, _), _), ConT ((t21, _), _) -> - choice env [ - (fun env -> - let mixop1, ts1', ts1 = elab_typ_notation env (expand_id env t1) t11 in - let mixop2, _ts2', ts2 = elab_typ_notation env (expand_id env t2) t21 in - if mixop1 <> mixop2 then - fail_typ2 env e'.at phrase t1 t2 "" else - let e'' = Il.UncaseE (e', mixop1) $$ e'.at % tup_typ' ts1' e'.at in - let es' = List.mapi (fun i t1I' -> Il.ProjE (e'', i) $$ e''.at % t1I') ts1' in + + | Il.VarT (x1, _), Il.VarT (x2, _) -> + (match expand_def env t1', expand_def env t2' with + | (Il.VariantT [mixop1, (tC1, _, _), _], NoDots), + (Il.VariantT [mixop2, (tC2, _, _), _], NoDots) -> + if mixop1 = mixop2 then + ( + (* Two ConT's with the same operator can be cast pointwise *) + let ts1 = match tC1.it with Il.TupT xts -> List.map snd xts | _ -> [tC1] in + let ts2 = match tC2.it with Il.TupT xts -> List.map snd xts | _ -> [tC2] in + let e'' = Il.UncaseE (e', mixop1) $$ e'.at % tC1 in + let es' = List.mapi (fun i t1I -> Il.ProjE (e'', i) $$ e''.at % t1I) ts1 in let* es'' = map2_attempt (fun eI' (t1I, t2I) -> cast_exp phrase env eI' t1I t2I) es' (List.combine ts1 ts2) in - Ok (Il.CaseE (mixop2, tup_exp_bind' es'' e'.at)) - ); - (fun env -> - Debug.(log_in_at "el.cast_exp" e'.at - (fun _ -> fmt "%s <: %s >> (%s) <: (%s) = (%s) # backtrack 1" (el_typ t1) (el_typ t2) - (el_typ (expand_def env t1 $ t1.at)) (el_typ (expand_def env t2 $ t2.at)) - (el_typ (expand_nondef env t2)) + Ok (Il.CaseE (mixop2, tup_exp' es'' e'.at)) + ) + else + ( + (* Two unary ConT's can be cast transitively + * (composing the to/from payload cases below). *) + let _ = Debug.(log_in_at "el.cast_exp" e'.at + (fun _ -> fmt "%s <: %s >> (%s) <: (%s) = (%s) # backtrack 1" + (il_typ t1) (il_typ t2) + (il_deftyp (fst (expand_def env t1) $ t1.at)) + (il_deftyp (fst (expand_def env t2) $ t2.at)) + (il_typ (reduce env t2)) ) - ); - let mixop, ts', ts = elab_typ_notation env (expand_id env t1) t11 in - let* t111, t111' = match ts, ts' with [t111], [t111'] -> Ok (t111, t111') | _ -> - fail_typ2 env e'.at phrase t1 t2 "" in - let e'' = Il.UncaseE (e', mixop) $$ e'.at % tup_typ' ts' e'.at in - cast_exp' phrase env (Il.ProjE (e'', 0) $$ e'.at % t111') t111 t2 - ); - ] - | ConT ((t11, _), _), t2' -> - choice env [ - (fun env -> - let* e'' = - match t2' with - | IterT (t21, iter) -> + ) in + match expand env tC1 with + | Il.TupT [_, t11'] -> + let e'' = Il.UncaseE (e', mixop1) $$ e'.at % t11' in + cast_exp' phrase env (Il.ProjE (e'', 0) $$ e'.at % t11') t11' t2' + | _ -> fail_typ2 env e'.at phrase t1 t2 "" + ) + + | (Il.VariantT tcs1, dots1), (Il.VariantT tcs2, dots2) -> + let* () = + (* Shallow breadth subtyping on variants *) + match + iter_attempt (fun (mixop, (tC1, _, _), _) -> + let* _, (tC2, _, _), _ = attempt (find_case tcs2 mixop t1.at) t2 in + if equiv_typ env tC1 tC2 then + Ok () + else + fail_mixop e'.at mixop t1 "type mismatch for case" + ) tcs1 + with + | Ok () -> Ok () + | Fail (Trace (_, msg, _) :: _) -> fail_typ2 env e'.at phrase t1 t2 (", " ^ msg) + | Fail [] -> assert false + in + if dots1 = Dots then + error e'.at ("used variant type `" ^ x1.it ^ + "` is only partially defined at this point") + else if dots2 = Dots then + error e'.at ("used variant type `" ^ x2.it ^ + "` is only partially defined at this point"); + Ok (Il.SubE (e', t1', t2')) + + | _, _ -> + fail_typ2 env e'.at phrase t1 t2 "" + ) + + | Il.VarT _, _ -> + (match expand_def env t1' with + | Il.VariantT [mixop1, (tC1, _, _), _], NoDots -> + choice env [ + (fun env -> + (* A ConT can always be cast to a (singleton) iteration *) + match t2'.it with + | Il.IterT (t21, iter) -> let* e1' = cast_exp phrase env e' t1 t21 in (match iter with | Opt -> Ok (Il.OptE (Some e1')) @@ -1708,168 +1863,103 @@ and cast_exp' phrase env e' t1 t2 : Il.exp' attempt = | _ -> assert false ) | _ -> fail_silent - in - Ok e'' - ); - (fun env -> - Debug.(log_in_at "el.cast_exp" e'.at - (fun _ -> fmt "%s <: %s >> (%s) <: (%s) = (%s) # backtrack 2" (el_typ t1) (el_typ t2) - (el_typ (expand_def env t1 $ t1.at)) (el_typ (expand_def env t2 $ t2.at)) - (el_typ (expand_nondef env t2)) - ) ); - let mixop, ts', ts = elab_typ_notation env (expand_id env t1) t11 in - let* t111, t111' = match ts, ts' with [t111], [t111'] -> Ok (t111, t111') | _ -> - fail_typ2 env e'.at phrase t1 t2 "" in - let e'' = Il.UncaseE (e', mixop) $$ e'.at % tup_typ' ts' e'.at in - cast_exp' phrase env (Il.ProjE (e'', 0) $$ e'.at % t111') t111 t2 - ); - ] - | _, ConT ((t21, _), _) -> - let mixop, _ts', ts = elab_typ_notation env (expand_id env t2) t21 in - let* t211 = match ts with [t211] -> Ok t211 | _ -> - fail_typ2 env e'.at phrase t1 t2 "" in - let* e1' = cast_exp phrase env e' t1 t211 in - Ok (Il.CaseE (mixop, tup_exp_bind' [e1'] e'.at)) - | RangeT _, t2' -> - choice env [ - (fun env -> - let* e'' = - match t2' with - | IterT (t21, iter) -> - let* e1' = cast_exp phrase env e' t1 t21 in - (match iter with - | Opt -> Ok (Il.OptE (Some e1')) - | List -> Ok (Il.ListE [e1']) - | _ -> assert false + (fun env -> + (* A ConT can be cast to its payload *) + Debug.(log_in_at "el.cast_exp" e'.at + (fun _ -> fmt "%s <: %s >> (%s) <: (%s) = (%s) # backtrack 2" + (il_typ t1) (il_typ t2) + (il_deftyp (fst (expand_def env t1) $ t1.at)) + (il_deftyp (fst (expand_def env t2) $ t2.at)) + (il_typ (reduce env t2)) ) - | _ -> fail_silent - in - Ok e'' - ); - (fun env -> - Debug.(log_in_at "el.cast_exp" e'.at - (fun _ -> fmt "%s <: %s >> (%s) <: (%s) = (%s) # backtrack 3" (el_typ t1) (el_typ t2) - (el_typ (expand_def env t1 $ t1.at)) (el_typ (expand_def env t2 $ t2.at)) - (el_typ (expand_nondef env t2)) - ) + ); + match expand env tC1 with + | Il.TupT [_, t11'] -> + let e'' = Il.UncaseE (e', mixop1) $$ e'.at % t11' in + cast_exp' phrase env (Il.ProjE (e'', 0) $$ e'.at % t11') t11' t2' + | _ -> fail_typ2 env e'.at phrase t1 t2 "" ); - let t11 = typ_rep env t1 in - let t11' = elab_typ env t11 in - let e'' = Il.UncaseE (e', [[]; []]) $$ e'.at % tup_typ' [t11'] e'.at in - let e''' = Il.ProjE (e'', 0) $$ e'.at % t11' in - cast_exp' phrase env e''' t11 t2 - ); - ] - | _, RangeT _ -> - let t21 = typ_rep env t2 in - let* e'' = cast_exp phrase env e' t1 t21 in - Ok (Il.CaseE ([[]; []], tup_exp_bind' [e''] e'.at)) - | _, IterT (t21, Opt) -> - let* e'' = cast_exp phrase env e' t1 t21 in - Ok (Il.OptE (Some e'')) -(* TODO(3, rossberg): enable; violates invariant that all iterexps are initially empty - | IterT (t11, List), IterT (t21, List) -> - choice env [ - (fun env -> - let id = x $ e'.at in - let t11' = elab_typ env t11 in - let* e'' = cast_exp phrase env (Il.VarE id $$ e'.at % t11') t11 t21 in - Ok (Il.IterE (e'', (List, [x, e']))) - ); - (fun env -> - let* e'' = cast_exp phrase env e' t1 t21 in - Ok (Il.ListE [e'']) - ); - ] -*) - | IterT (t11, Opt), IterT (t21, List) -> + ] + + | _ -> + fail_typ2 env e'.at phrase t1 t2 "" + ) + + | _, Il.VarT _ -> + (match expand_def env t2' with + | Il.VariantT [mixop2, (tC2, _, _), _], NoDots -> + (* A ConT payload can be cast to the ConT *) + (match expand env tC2 with + | Il.TupT [_, t21'] -> + let* e1' = cast_exp phrase env e' t1' t21' in + Ok (Il.CaseE (mixop2, Il.TupE [e1'] $$ e'.at % tC2)) + | _ -> fail_typ2 env e'.at phrase t1 t2 "" + ) + + | _ -> + fail_typ2 env e'.at phrase t1 t2 "" + ) + + | Il.IterT (t11, Opt), Il.IterT (t21, List) -> choice env [ (fun env -> - let t11' = elab_typ env t11 in - let e'' = Il.LiftE e' $$ e'.at % (Il.IterT (t11', Il.List) $ e'.at) in - cast_exp' phrase env e'' (IterT (t11, List) $ e'.at) t2 + let t1' = Il.IterT (t11, Il.List) $ e'.at in + let e'' = Il.LiftE e' $$ e'.at % t1' in + cast_exp' phrase env e'' t1' t2 ); (fun env -> let* e'' = cast_exp phrase env e' t1 t21 in Ok (Il.ListE [e'']) ); ] - | _, IterT (t21, (List | List1)) -> + | _, Il.IterT (t21, (List | List1)) -> let* e'' = cast_exp phrase env e' t1 t21 in Ok (Il.ListE [e'']) - | _, _ when is_variant_typ env t1 && is_variant_typ env t2 && not (is_iter_typ env t1) -> - let cases1, dots1 = checkpoint (as_variant_typ "" env Check t1 e'.at) in - let cases2, _dots2 = checkpoint (as_variant_typ "" env Check t2 e'.at) in - if dots1 = Dots then - error e'.at "used variant type is only partially defined at this point"; - let* _ = - match - iter_attempt (fun (atom, (t1', _prems1), _) -> - let* t2', _prems2 = attempt (find_case cases2 atom t1.at) t2 in - (* Shallow subtyping on variants *) - let env' = to_eval_env env in - if Eq.eq_typ (Eval.reduce_typ env' t1') (Eval.reduce_typ env' t2') then Ok () else - fail_atom e'.at atom t1 "type mismatch for case" - ) cases1 - with - | Ok () -> Ok () - | Fail (Trace (_, msg, _) :: _) -> fail_typ2 env e'.at phrase t1 t2 (", " ^ msg) - | Fail [] -> assert false - in - let t11 = expand env t1 $ t1.at in - let t21 = expand env t2 $ t2.at in - let t11' = elab_typ env (expand_nondef env t1) in - let t21' = elab_typ env (expand_nondef env t2) in - let* e'' = cast_exp phrase env e' t1 t11 in - let e''' = Il.SubE (e'', t11', t21') in - cast_exp' phrase env (e''' $$ e'.at % t21') t21 t2 + | _, _ -> fail_typ2 env e'.at phrase t1 t2 "" -and elab_iterexp env iter : Il.iterexp = - (elab_iter env iter, []) - - (* Premises *) -and elab_prem env prem : Il.prem list = - match prem.it with +and elab_prem env (pr : prem) : Il.prem list = + match pr.it with | VarPr (id, t) -> - env.vars <- bind "variable" env.vars id t; + let t' = elab_typ env t in + env.vars <- bind "variable" env.vars id t'; [] | RulePr (id, e) -> - let t, _ = find "relation" env.rels id in - let mixop, _, _ = elab_typ_notation env id t in - let es', _s = checkpoint (elab_exp_notation' env id e t) in - [Il.RulePr (id, mixop, tup_exp' es' e.at) $ prem.at] + let mixop, not, _, _ = find "relation" env.rels id in + let es', _s = checkpoint (elab_exp_notation' env id e not) in + [Il.RulePr (id, mixop, tup_exp_nary' es' e.at) $ pr.at] | IfPr e -> - let e' = checkpoint (elab_exp env e (BoolT $ e.at)) in - [Il.IfPr e' $ prem.at] + let e' = checkpoint (elab_exp env e (Il.BoolT $ e.at)) in + [Il.IfPr e' $ pr.at] | ElsePr -> - [Il.ElsePr $ prem.at] + [Il.ElsePr $ pr.at] | IterPr ({it = VarPr _; at; _}, _iter) -> error at "misplaced variable premise" - | IterPr (prem1, iter) -> - let iter' = elab_iterexp env iter in - let prem1' = List.hd (elab_prem env prem1) in - [Il.IterPr (prem1', iter') $ prem.at] + | IterPr (pr1, it) -> + let prs1', ite', _itt' = checkpoint (elab_iterexp env + (fun env pr -> Ok (elab_prem env pr)) pr1 it) in + assert (List.length prs1' = 1); + [Il.IterPr (List.hd prs1', ite') $ pr.at] (* Grammars *) -and infer_sym env g : (Il.sym * typ) attempt = +and infer_sym env (g : sym) : (Il.sym * Il.typ) attempt = Debug.(log_at "el.infer_sym" g.at (fun _ -> fmt "%s" (el_sym g)) - (function Ok (g', t) -> fmt "%s : %s" (il_sym g') (el_typ t) | _ -> "fail") + (function Ok (g', t) -> fmt "%s : %s" (il_sym g') (il_typ t) | _ -> "fail") ) @@ fun _ -> - nest g.at (TupT [] $ g.at) ( + nest g.at (Il.TupT [] $ g.at) ( match g.it with - | VarG (id, as_) -> - let ps, t, _gram, _prods' = find "grammar" env.grams id in + | VarG (x, as_) -> + let ps, t, _gram, _prods' = find "grammar" env.grams x in let as', s = elab_args `Rhs env as_ ps g.at in - Ok (Il.VarG (id, as') $ g.at, Subst.subst_typ s t) + Ok (Il.VarG (x, as') $ g.at, Il.Subst.subst_typ s t) | NumG (`CharOp, n) -> (* let s = try Utf8.encode [Z.to_int n] with Z.Overflow | Utf8.Utf8 -> @@ -1879,19 +1969,19 @@ and infer_sym env g : (Il.sym * typ) attempt = if n < Z.of_int 0x00 || n > Z.of_int 0x10ffff then fail g.at "unicode value out of range" else - Ok (Il.NumG (Z.to_int n) $ g.at, NumT `NatT $ g.at) + Ok (Il.NumG (Z.to_int n) $ g.at, Il.NumT `NatT $ g.at) | NumG (_, n) -> if n < Z.of_int 0x00 || n > Z.of_int 0xff then fail g.at "byte value out of range" else - Ok (Il.NumG (Z.to_int n) $ g.at, NumT `NatT $ g.at) + Ok (Il.NumG (Z.to_int n) $ g.at, Il.NumT `NatT $ g.at) | TextG s -> - Ok (Il.TextG s $ g.at, TextT $ g.at) + Ok (Il.TextG s $ g.at, Il.TextT $ g.at) | EpsG -> - Ok (Il.EpsG $ g.at, TupT [] $ g.at) + Ok (Il.EpsG $ g.at, Il.TupT [] $ g.at) | SeqG gs -> - let* gs' = elab_sym_list env (filter_nl gs) (TupT [] $ g.at) in - Ok (Il.SeqG gs' $ g.at, TupT [] $ g.at) + let* gs' = elab_sym_list env (filter_nl gs) (Il.TupT [] $ g.at) in + Ok (Il.SeqG gs' $ g.at, Il.TupT [] $ g.at) | AltG gs -> choice env [ (fun env -> @@ -1902,41 +1992,37 @@ and infer_sym env g : (Il.sym * typ) attempt = ); (fun env -> (* HACK to treat singleton strings in short grammar as characters *) - let* g' = elab_sym env g (NumT `NatT $ g.at) in - Ok (g', NumT `NatT $ g.at) + let* g' = elab_sym env g (Il.NumT `NatT $ g.at) in + Ok (g', Il.NumT `NatT $ g.at) ); (fun env -> - let* g' = elab_sym env g (TupT [] $ g.at) in - Ok (g', TupT [] $ g.at) + let* g' = elab_sym env g (Il.TupT [] $ g.at) in + Ok (g', Il.TupT [] $ g.at) ) ] | RangeG (g1, g2) -> let env1 = local_env env in let env2 = local_env env in - let* g1' = elab_sym env1 g1 (NumT `NatT $ g1.at) in - let* g2' = elab_sym env2 g2 (NumT `NatT $ g2.at) in + let* g1' = elab_sym env1 g1 (Il.NumT `NatT $ g1.at) in + let* g2' = elab_sym env2 g2 (Il.NumT `NatT $ g2.at) in if env1.vars != env.vars then error g1.at "invalid symbol in range"; if env2.vars != env.vars then error g2.at "invalid symbol in range"; - Ok (Il.RangeG (g1', g2') $ g.at, NumT `NatT $ g.at) + Ok (Il.RangeG (g1', g2') $ g.at, Il.NumT `NatT $ g.at) | ParenG g1 -> infer_sym env g1 | TupG _ -> error g.at "malformed grammar" | ArithG e -> infer_sym env (sym_of_exp e) - | IterG (g1, iter) -> - let iterexp' = elab_iterexp env iter in - let* g1', t1 = infer_sym env g1 in - Ok ( - Il.IterG (g1', iterexp') $ g.at, - IterT (t1, match iter with Opt -> Opt | _ -> List) $ g.at - ) + | IterG (g1, it) -> + let* (g1', t1), ite', itt' = elab_iterexp env infer_sym g1 it in + Ok (Il.IterG (g1', ite') $ g.at, Il.IterT (t1, itt') $ g.at) | AttrG (e, g1) -> choice env [ (fun env -> (* HACK to treat singleton strings in short grammar as characters *) - let t1 = NumT `NatT $ g1.at in + let t1 = Il.NumT `NatT $ g1.at in let* g1' = elab_sym env g1 t1 in let* e' = elab_exp env e t1 in Ok (Il.AttrG (e', g1') $ g.at, t1) @@ -1950,23 +2036,23 @@ and infer_sym env g : (Il.sym * typ) attempt = (* let g1', t1 = infer_sym env g1 in let e' = checkpoint (elab_exp env e t1) in - Il.AttrG (e', g1') $ g.at, t1 + Ok (Il.AttrG (e', g1') $ g.at, t1) *) | FuseG _ -> error g.at "misplaced token concatenation" | UnparenG _ -> error g.at "misplaced token unparenthesize" ) -and infer_sym_list env es : (Il.sym list * typ list) attempt = - match es with +and infer_sym_list env (gs : sym list) : (Il.sym list * Il.typ list) attempt = + match gs with | [] -> Ok ([], []) | g::gs -> let* g', t = infer_sym env g in let* gs', ts = infer_sym_list env gs in Ok (g'::gs', t::ts) -and elab_sym env g t : Il.sym attempt = +and elab_sym env (g : sym) (t : Il.typ) : Il.sym attempt = Debug.(log_at "el.elab_sym" g.at - (fun _ -> fmt "%s : %s" (el_sym g) (el_typ t)) + (fun _ -> fmt "%s : %s" (el_sym g) (il_typ t)) (function Ok g' -> fmt "%s" (il_sym g') | _ -> "fail") ) @@ fun _ -> nest g.at t ( @@ -1989,81 +2075,84 @@ and elab_sym env g t : Il.sym attempt = cast_sym env g' t' t ) -and elab_sym_list env es t : Il.sym list attempt = - match es with - | [] -> Ok [] +and elab_sym_list env (gs : sym list) (t : Il.typ) : Il.sym list attempt = + match gs with + | [] -> Ok ([]) | g::gs -> let* g' = elab_sym env g t in let* gs' = elab_sym_list env gs t in Ok (g'::gs') -and cast_sym env g' t1 t2 : Il.sym attempt = +and cast_sym env (g' : Il.sym) t1 t2 : Il.sym attempt = Debug.(log_at "el.elab_cast_sym" g'.at - (fun _ -> fmt "%s : %s :> %s" (il_sym g') (el_typ t1) (el_typ t2)) + (fun _ -> fmt "%s : %s :> %s" (il_sym g') (il_typ t1) (il_typ t2)) (function Ok g'' -> fmt "%s" (il_sym g'') | _ -> "fail") ) @@ fun _ -> nest g'.at t2 ( if equiv_typ env t1 t2 then Ok g' - else if equiv_typ env t2 (TupT [] $ t2.at) then + else if equiv_typ env t2 (Il.TupT [] $ t2.at) then Ok (Il.SeqG [g'] $ g'.at) else fail_typ2 env g'.at "symbol" t1 t2 "" ) -and elab_prod env prod t : Il.prod list = +and elab_prod env outer_dims (prod : prod) (t : Il.typ) : Il.prod list = Debug.(log_in_at "el.elab_prod" prod.at - (fun _ -> fmt "%s : %s" (el_prod prod) (el_typ t)) + (fun _ -> fmt "%s : %s" (el_prod prod) (il_typ t)) ); match prod.it with | SynthP (g, e, prems) -> let env' = local_env env in env'.pm <- false; - let dims = Dim.check_prod (vars env) prod in - let dims' = Dim.Env.map (List.map (elab_iter env')) dims in - let g', _t = checkpoint (infer_sym env' g) in - let g' = Dim.annot_sym dims' g' in + let g', _t' = checkpoint (infer_sym env' g) in let e' = checkpoint ( - if equiv_typ env' t (TupT [] $ e.at) then + let t_unit = Il.TupT [] $ e.at in + if equiv_typ env' t t_unit then (* Special case: ignore unit attributes *) (* TODO(4, rossberg): introduce proper top type? *) let* e', _t = infer_exp env' e in - let t'_unit = Il.TupT [] $ e.at in - let joker () = Il.VarE ("_" $ e.at) $$ e.at % t'_unit in Ok (Il.ProjE ( Il.TupE [ - e'; Il.TupE [] $$ e.at % t'_unit - ] $$ e.at % (Il.TupT [joker (), e'.note; joker (), t'_unit] $ e.at), 1 - ) $$ e.at % t'_unit) + e'; Il.TupE [] $$ e.at % t_unit + ] $$ e.at % (Il.TupT ["_" $ e.at, e'.note; "_" $ e.at, t_unit] $ e.at), 1 + ) $$ e.at % t_unit) else elab_exp env' e t ) in - let e' = Dim.annot_exp dims' e' in - let prems' = List.map (Dim.annot_prem dims') - (concat_map_filter_nl_list (elab_prem env') prems) in - let det = Free.(diff (union (det_sym g) (det_prems prems)) (bound_env env)) in - let free = Free.(diff (free_prod prod) (union (det_prod prod) (bound_env env'))) in - if free <> Free.empty then - error prod.at ("grammar rule contains indeterminate variable(s) `" ^ - String.concat "`, `" (Free.Set.elements free.varid) ^ "`"); - let acc_bs', (module Arg : Iter.Arg) = make_binds_iter_arg env' det dims in - let module Acc = Iter.Make(Arg) in - Acc.sym g; - Acc.exp e; - Acc.prems prems; - let prod' = Il.ProdD (!acc_bs', g', e', prems') $ prod.at in + let prems' = List.concat (map_filter_nl_list (elab_prem env') prems) in + let dims = Dim.check outer_dims [] [] [] [e'] [g'] prems' in + let g' = Dim.annot_sym dims g' in + let e' = Dim.annot_exp dims e' in + let prems' = List.map (Dim.annot_prem dims) prems' in + let det = Det.(det_exp e' ++ det_sym g' ++ det_list det_prem prems') in + let qs = infer_quants env env' dims det [] [] [] [e'] [g'] prems' prod.at in + let prod' = Il.ProdD (qs, g', e', prems') $ prod.at in + let free = Il.Free.(free_prod prod' -- bound_env env') in + if free <> Il.Free.empty then + error prod.at ("grammar rule contains indeterminate variable(s) " ^ + String.concat ", " (List.map quote (Il.Free.Set.elements free.varid))); if not env'.pm then [prod'] else - prod' :: elab_prod env Subst.(subst_prod pm_snd (Iter.clone_prod prod)) t + prod' :: + elab_prod env outer_dims Subst.(subst_prod pm_snd (Iter.clone_prod prod)) t + | RangeP (g1, e1, g2, e2) -> - let t = NumT `NatT $ prod.at in + let t = Il.NumT `NatT $ prod.at in let g1' = checkpoint (elab_sym env g1 t) in let e1' = checkpoint (elab_exp env e1 t) in let g2' = checkpoint (elab_sym env g2 t) in let e2' = checkpoint (elab_exp env e2 t) in + let dims = Dim.check outer_dims [] [] [] [e1'; e2'] [g1'; g2'] [] in + let g1' = Dim.annot_sym dims g1' in + let g2' = Dim.annot_sym dims g2' in + let e1' = Dim.annot_exp dims e1' in + let e2' = Dim.annot_exp dims e2' in + let det = Det.(det_list det_exp [e1'; e2'] ++ det_list det_sym [g1'; g2']) in + infer_no_quants env dims det [] [] [] [e1'; e2'] [g1'; g2'] [] prod.at; let c1 = match g1'.it with | Il.NumG c1 -> c1 @@ -2094,257 +2183,200 @@ and elab_prod env prod t : Il.prod list = let e' = {(if i = 0 then e1' else e2') with it = Il.NumE n} in Il.ProdD ([], g', e', []) $ prod.at ) + | EquivP (g1, g2, prems) -> let env' = local_env env in env'.pm <- false; - let dims = Dim.check_prod (vars env) prod in - let dims' = Dim.Env.map (List.map (elab_iter env')) dims in - let g1', _t1 = checkpoint (infer_sym env' g1) in - let g1' = Dim.annot_sym dims' g1' in - let g2', _t2 = checkpoint (infer_sym env' g2) in - let g2' = Dim.annot_sym dims' g2' in - let prems' = List.map (Dim.annot_prem dims') - (concat_map_filter_nl_list (elab_prem env') prems) in - let det = Free.(diff (union (det_sym g1) (det_prems prems)) (bound_env env)) in - let free = Free.(diff (free_prod prod) (union (det_prod prod) (bound_env env'))) in - if free <> Free.empty then - error prod.at ("grammar rule contains indeterminate variable(s) `" ^ - String.concat "`, `" (Free.Set.elements free.varid) ^ "`"); - let acc_bs', (module Arg : Iter.Arg) = make_binds_iter_arg env' det dims in - let module Acc = Iter.Make(Arg) in - Acc.sym g1; - Acc.sym g2; - Acc.prems prems; -ignore (acc_bs', g1', g2', prems'); -[] + let g1', _t1' = checkpoint (infer_sym env' g1) in + let g2', _t2' = checkpoint (infer_sym env' g2) in + let prems' = List.concat (map_filter_nl_list (elab_prem env') prems) in + let dims = Dim.check outer_dims [] [] [] [] [g1'; g2'] prems' in + let g1' = Dim.annot_sym dims g1' in + let g2' = Dim.annot_sym dims g2' in + let prems' = List.map (Dim.annot_prem dims) prems' in + let det = Det.(det_sym g1' ++ det_sym g2' ++ det_list det_prem prems') in + ignore (infer_quants env env' dims det [] [] [] [] [g1'; g2'] prems' prod.at); + [] (* TODO(4, rossberg): translate equiv grammars properly *) (* - let prod' = Il.ProdD (!acc_bs', g1', e', prems') $ prod.at in + let prod' = Il.ProdD (!acc_qs, g1', e', prems') $ prod.at in if not env'.pm then [prod'] else prod' :: elab_prod env Subst.(subst_prod pm_snd (Iter.clone_prod prod)) t *) -and elab_gram env gram t : Il.prod list = +and elab_gram env outer_dims (gram : gram) (t : Il.typ) : Il.prod list = let (_dots1, prods, _dots2) = gram.it in - concat_map_filter_nl_list (fun prod -> elab_prod env prod t) prods + concat_map_filter_nl_list (fun prod -> elab_prod env outer_dims prod t) prods (* Definitions *) -and make_binds_iter_arg env free dims : Il.bind list ref * (module Iter.Arg) = - let module Arg = - struct - include Iter.Skip - - let left = ref free - let acc = ref [] - - let visit_typid id = - if Free.Set.mem id.it !left.typid then ( - acc := !acc @ [Il.TypB id $ id.at]; - left := Free.{!left with typid = Set.remove id.it !left.typid}; - ) - - let visit_varid id = - if Free.(Set.mem id.it !left.varid) && Dim.Env.mem id.it dims then ( - let t = - try find "variable" env.vars id with Error _ -> - find "variable" env.gvars (strip_var_suffix id) - in - let fwd = Free.(inter (free_typ t) !left) in - if fwd <> Free.empty then - error id.at ("the type of `" ^ id.it ^ "` depends on " ^ - ( Free.Set.(elements fwd.typid @ elements fwd.gramid @ elements fwd.varid @ elements fwd.defid) |> - List.map (fun id -> "`" ^ id ^ "`") |> - String.concat ", " ) ^ - ", which only occur(s) to its right; try to reorder parameters or premises"); - let ctx' = - List.map (function Opt -> Il.Opt | _ -> Il.List) - (Dim.Env.find id.it dims) - in - let t' = - List.fold_left (fun t iter -> - Il.IterT (t, iter) $ t.at - ) (elab_typ env t) ctx' - in - acc := !acc @ [Il.ExpB (Dim.annot_varid id ctx', t') $ id.at]; - left := Free.{!left with varid = Set.remove id.it !left.varid}; - ) - - let visit_gramid id = - if Free.(Set.mem id.it !left.gramid) then ( - let ps, t, _gram, _prods' = find "grammar" env.grams id in - let free' = Free.(union (free_params ps) (diff (free_typ t) (bound_params ps))) in - let fwd = Free.(inter free' !left) in - if fwd <> Free.empty then - error id.at ("the type of `" ^ id.it ^ "` depends on " ^ - ( Free.Set.(elements fwd.typid @ elements fwd.gramid @ elements fwd.varid @ elements fwd.defid) |> - List.map (fun id -> "`" ^ id ^ "`") |> - String.concat ", " ) ^ - ", which only occur(s) to its right; try to reorder parameters or premises"); - left := Free.{!left with varid = Set.remove id.it !left.gramid}; - ) - - let visit_defid id = - if Free.Set.mem id.it !left.defid then ( - let ps, t, _ = find "definition" env.defs id in - let env' = local_env env in - let ps' = elab_params env' ps in - let t' = elab_typ env' t in - let free' = Free.(union (free_params ps) (diff (free_typ t) (bound_params ps))) in - let fwd = Free.(inter free' !left) in - if fwd <> Free.empty then - error id.at ("the type of `" ^ (spaceid "definition" id).it ^ "` depends on " ^ - ( Free.Set.(elements fwd.typid @ elements fwd.gramid @ elements fwd.varid @ elements fwd.defid) |> - List.map (fun id -> "`" ^ id ^ "`") |> - String.concat ", " ) ^ - ", which only occur(s) to its right; try to reorder parameters or premises"); - acc := !acc @ [Il.DefB (id, ps', t') $ id.at]; - left := Free.{!left with defid = Set.remove id.it !left.defid}; - ) - end - in Arg.acc, (module Arg) - -and elab_arg in_lhs env a p s : Il.arg list * Subst.subst = +and elab_arg in_lhs env (a : arg) (p : Il.param) s : Il.arg list * Il.Subst.subst = (match !(a.it), p.it with (* HACK: handle shorthands *) - | ExpA e, TypP _ -> a.it := TypA (typ_of_exp e) - | ExpA e, GramP _ -> a.it := GramA (sym_of_exp e) - | ExpA {it = CallE (id, []); _}, DefP _ -> a.it := DefA id + | ExpA e, Il.TypP _ -> a.it := TypA (typ_of_exp e) + | ExpA e, Il.GramP _ -> a.it := GramA (sym_of_exp e) + | ExpA {it = CallE (id, []); _}, Il.DefP _ -> a.it := DefA id | _, _ -> () ); - match !(a.it), (Subst.subst_param s p).it with - | ExpA e, ExpP (id, t) -> + match !(a.it), (Il.Subst.subst_param s p).it with + | ExpA e, Il.ExpP (x, t) -> let e' = checkpoint (elab_exp env e t) in - [Il.ExpA e' $ a.at], Subst.add_varid s id e - | TypA ({it = VarT (id', []); _} as t), TypP id when in_lhs = `Lhs -> - let id'' = strip_var_suffix id' in + [Il.ExpA e' $ a.at], Il.Subst.add_varid s x e' + | TypA {it = VarT (x', []); _}, Il.TypP x when in_lhs = `Lhs -> + let x'' = strip_var_suffix x' in let is_prim = - match (Convert.typ_of_varid id'').it with + match (Convert.typ_of_varid x'').it with | VarT _ -> false | _ -> true in - env.typs <- bind "syntax type" env.typs id'' ([], Opaque); + let t' = Il.VarT (x'', []) $ x''.at in + env.typs <- bind "syntax type" env.typs x'' ([], Opaque); if not is_prim then - env.gvars <- bind "variable" env.gvars (strip_var_sub id'') (VarT (id'', []) $ id''.at); - [Il.TypA (Il.VarT (id'', []) $ t.at) $ a.at], Subst.add_typid s id t - | TypA t, TypP _ when in_lhs = `Lhs -> + env.gvars <- bind "variable" env.gvars (strip_var_sub x'') t'; + [Il.TypA t' $ a.at], Il.Subst.add_typid s x t' + | TypA t, Il.TypP _ when in_lhs = `Lhs -> error t.at "misplaced syntax type" - | TypA t, TypP id -> + | TypA t, Il.TypP x -> let t' = elab_typ env t in - [Il.TypA t' $ a.at], Subst.add_typid s id t - | GramA g, GramP _ when in_lhs = `Lhs -> + [Il.TypA t' $ a.at], Il.Subst.add_typid s x t' + | GramA g, Il.GramP _ when in_lhs = `Lhs -> error g.at "misplaced grammar symbol" - | GramA g, GramP (id', t) -> + | GramA g, Il.GramP (x', [], t) -> let g', t' = checkpoint (infer_sym env g) in let s' = subst_implicit env s t t' in - if not (equiv_typ env t' (Subst.subst_typ s' t)) then + if not (equiv_typ env t' (Il.Subst.subst_typ s' t)) then error_typ2 env a.at "argument" t' t ""; - let as' = List.map (fun (_id, t) -> Il.TypA (elab_typ env t) $ t.at) Subst.(Map.bindings s'.typid) in - as' @ [Il.GramA g' $ a.at], Subst.add_gramid s' id' g - | DefA id, DefP (id', ps', t') when in_lhs = `Lhs -> - env.defs <- bind "definition" env.defs id (ps', t', []); - [Il.DefA id $ a.at], Subst.add_defid s id' id - | DefA id, DefP (id', ps', t') -> - let ps, t, _ = find "definition" env.defs id in - if not (Eval.equiv_functyp (to_eval_env env) (ps, t) (ps', t')) then + let as' = List.map (fun (_x, t) -> Il.TypA t $ t.at) Il.Subst.(Map.bindings s'.typid) in + as' @ [Il.GramA g' $ a.at], Il.Subst.add_gramid s' x' g' + | GramA g, Il.GramP (x', ps', t') -> + (match g.it with + | VarG (x, []) -> + let ps, t, _ = find "grammar" env.defs x in + if not (Il.Eval.equiv_functyp (to_il_env env) (ps, t) (ps', t')) then + error a.at ("type mismatch in grammar argument, expected `" ^ + (spaceid "grammar" x').it ^ Il.Print.(string_of_params ps' ^ " : " ^ typ_string env t') ^ + "` but got `" ^ + (spaceid "grammar" x).it ^ Il.Print.(string_of_params ps ^ " : " ^ typ_string env t ^ "`") + ); + let g' = Il.VarG (x, []) $ a.at in + [Il.GramA g' $ a.at], Il.Subst.add_gramid s x g' + | _ -> + error g.at "grammar identifier expected for paramaterised grammar parameter" + ) + | DefA x, Il.DefP (x', ps', t') when in_lhs = `Lhs -> + env.defs <- bind "definition" env.defs x (ps', t', []); + [Il.DefA x $ a.at], Il.Subst.add_defid s x' x + | DefA x, Il.DefP (x', ps', t') -> + let ps, t, _ = find "definition" env.defs x in + if not (Il.Eval.equiv_functyp (to_il_env env) (ps, t) (ps', t')) then error a.at ("type mismatch in function argument, expected `" ^ - (spaceid "definition" id').it ^ Print.(string_of_params ps' ^ " : " ^ string_of_typ ~short:true t') ^ + (spaceid "definition" x').it ^ Il.Print.(string_of_params ps' ^ " : " ^ typ_string env t') ^ "` but got `" ^ - (spaceid "definition" id).it ^ Print.(string_of_params ps ^ " : " ^ string_of_typ ~short:true t ^ "`") + (spaceid "definition" x).it ^ Il.Print.(string_of_params ps ^ " : " ^ typ_string env t ^ "`") ); - [Il.DefA id $ a.at], Subst.add_defid s id id' + [Il.DefA x $ a.at], Il.Subst.add_defid s x x' | _, _ -> error a.at "sort mismatch for argument" -and elab_args in_lhs env as_ ps at : Il.arg list * Subst.subst = +and elab_args in_lhs env (as_ : arg list) (ps : Il.param list) at : Il.arg list * Il.Subst.subst = Debug.(log_at "el.elab_args" at - (fun _ -> fmt "(%s) : (%s)" (list el_arg as_) (list el_param ps)) - (fun (r, _) -> fmt "(%s)" (list il_arg r)) + (fun _ -> fmt "(%s) : (%s)" (list el_arg as_) (list il_param ps)) + (fun (as', _) -> fmt "(%s)" (list il_arg as')) ) @@ fun _ -> - elab_args' in_lhs env as_ ps [] Subst.empty at + elab_args' in_lhs env as_ ps [] Il.Subst.empty at -and elab_args' in_lhs env as_ ps as' s at : Il.arg list * Subst.subst = +and elab_args' in_lhs env (as_ : arg list) (ps : Il.param list) as' s at : Il.arg list * Il.Subst.subst = match as_, ps with | [], [] -> List.concat (List.rev as'), s | a::_, [] -> error a.at "too many arguments" | [], _::_ -> error at "too few arguments" + | _, {it = Il.TypP _; at; _}::ps1 when at = Source.no_region -> + (* Implicitly inserted type parameter *) + elab_args' in_lhs env as_ ps1 as' s at | a::as1, p::ps1 -> let a', s' = elab_arg in_lhs env a p s in elab_args' in_lhs env as1 ps1 (a'::as') s' at -and subst_implicit env s t t' : Subst.subst = - let free = Free.(Set.filter (fun id -> not (Map.mem id env.typs)) (free_typ t).typid) in +and subst_implicit env s t t' : Il.Subst.subst = + let free = Il.Free.(Set.filter (fun x -> not (Map.mem x env.typs)) (free_typ t).typid) in let rec inst s t t' = match t.it, t'.it with - | VarT (id, []), _ - when Free.Set.mem id.it free && not (Subst.mem_typid s id) -> - Subst.add_typid s id t' - | ParenT t1, _ -> inst s t1 t' - | _, ParenT t1' -> inst s t t1' - | TupT (t1::ts), TupT (t1'::ts') -> - inst (inst s t1 t1') (TupT ts $ t.at) (TupT ts' $ t'.at) - | IterT (t1, _), IterT (t1', _) -> inst s t1 t1' + | Il.VarT (x, []), _ + when Il.Free.Set.mem x.it free && not (Il.Subst.mem_typid s x) -> + Il.Subst.add_typid s x t' + | Il.TupT ((x, t1)::ts), Il.TupT ((x', t1')::ts') -> + let s' = Il.Subst.add_varid (inst s t1 t1') x' (Il.VarE x $$ x.at % t1) in + inst s' (Il.TupT ts $ t.at) (Il.TupT ts' $ t'.at) + | Il.IterT (t1, _), Il.IterT (t1', _) -> inst s t1 t1' | _ -> s in inst s t t' -and elab_param env p : Il.param list = +and elab_param env (p : param) : Il.param list = match p.it with - | ExpP (id, t) -> + | ExpP (x, t) -> let t' = elab_typ env t in (* If a variable isn't globally declared, this is a local declaration. *) - let id' = strip_var_suffix id in - if bound env.gvars id' then ( - let t2 = find "" env.gvars id' in - if not (sub_typ env t t2) then - error_typ2 env id.at "local variable" t t2 ", shadowing with different type" + let x' = strip_var_suffix x in + if bound env.gvars x' then ( + let t2 = find "" env.gvars x' in + if not (sub_typ env t' t2) then + error_typ2 env x.at "local variable" t' t2 ", shadowing with different type" ); (* Shadowing is allowed, but only with consistent type. *) - if bound env.vars id' then ( - let t2 = find "" env.vars id' in - if not (equiv_typ env t t2) then - error_typ2 env id.at "local variable" t t2 ", shadowing with different type" + if bound env.vars x' then ( + let t2 = find "" env.vars x' in + if not (equiv_typ env t' t2) then + error_typ2 env x.at "local variable" t' t2 ", shadowing with different type" ) else - env.vars <- bind "variable" env.vars id t; - [Il.ExpP (id, t') $ p.at] - | TypP id -> - env.typs <- bind "syntax type" env.typs id ([], Opaque); - env.gvars <- bind "variable" env.gvars (strip_var_sub id) (VarT (id, []) $ id.at); - [Il.TypP id $ p.at] - | GramP (id, t) -> + env.vars <- bind "variable" env.vars x t'; + [Il.ExpP (x, t') $ p.at] + + | TypP x -> + env.typs <- bind "syntax type" env.typs x ([], Opaque); + env.gvars <- bind "variable" env.gvars (strip_var_sub x) (Il.VarT (x, []) $ x.at); + [Il.TypP x $ p.at] + + | GramP (x, ps, t) -> + let env' = local_env env in + let ps' = elab_params env' ps in (* Treat unbound type identifiers in t as implicitly bound. *) let free = Free.free_typ t in - env.grams <- bind "grammar" env.grams id ([], t, None, []); - let ps' = - Free.Set.fold (fun id' ps' -> - if Map.mem id' env.typs then ps' else ( - let id = id' $ t.at in - if id.it <> (strip_var_suffix id).it then - error_id id "invalid identifer suffix in binding position"; - env.typs <- bind "syntax type" env.typs id ([], Opaque); - env.gvars <- bind "variable" env.gvars (strip_var_sub id) (VarT (id, []) $ id.at); - (Il.TypP id $ id.at) :: ps' + let ps_implicit' = + Free.Set.fold (fun x' ps' -> + if Map.mem x' env'.typs then ps' else ( + let x = x' $ t.at in + if x.it <> (strip_var_suffix x).it then + error_id x "invalid identifer suffix in binding position"; + env'.typs <- bind "syntax type" env.typs x ([], Opaque); + env.typs <- bind "syntax type" env.typs x ([], Opaque); + env.gvars <- bind "variable" env.gvars (strip_var_sub x) + (Il.VarT (x, []) $ x.at); + (* Mark as implicit type parameter via empty region. *) + (Il.TypP x $ Source.no_region) :: ps' ) ) free.typid [] in - let t' = elab_typ env t in - ps' @ [Il.GramP (id, t') $ p.at] - | DefP (id, ps, t) -> + let t' = elab_typ env' t in + env.grams <- bind "grammar" env.grams x ([], t', [], None); + ps_implicit' @ [Il.GramP (x, ps', t') $ p.at] + + | DefP (x, ps, t) -> let env' = local_env env in let ps' = elab_params env' ps in let t' = elab_typ env' t in - env.defs <- bind "definition" env.defs id (ps, t, []); - [Il.DefP (id, ps', t') $ p.at] + env.defs <- bind "definition" env.defs x (ps', t', []); + [Il.DefP (x, ps', t') $ p.at] -and elab_params env ps : Il.param list = +and elab_params env (ps : param list) : Il.param list = List.concat_map (elab_param env) ps (* To allow optional atoms such as `MUT?`, preprocess type * definitions to insert implicit type definition * `syntax MUT hint(show MUT) = MUT` and replace atom with type id. *) -and infer_typ_notation env is_con t : typ = +and infer_typ_notation env is_con (t : typ) : typ = (match t.it with | VarT _ | BoolT | NumT _ | TextT | ParenT _ | TupT _ | RangeT _ -> t.it | AtomT _ -> is_con := true; t.it @@ -2378,324 +2410,280 @@ and infer_typ_notation env is_con t : typ = | IterT (t1, iter) -> IterT (infer_typ_notation env is_con t1, iter) ) $ t.at -let infer_typ_definition _env t : kind = +let infer_typ_definition _env (t : typ) : kind = match t.it with | StrT _ | CaseT _ -> Opaque | ConT _ | RangeT _ -> Transp | _ -> Transp -let infer_typdef env d : def = +let infer_typdef env (d : def) : def = match d.it with - | FamD (id, ps, _hints) -> - let _ps' = elab_params (local_env env) ps in - env.typs <- bind "syntax type" env.typs id (ps, Family []); + | FamD (x, ps, _hints) -> + let ps' = elab_params (local_env env) ps in + env.typs <- bind "syntax type" env.typs x (ps', Family []); if ps = [] then (* only types without parameters double as variables *) - env.gvars <- bind "variable" env.gvars (strip_var_sub id) (VarT (id, []) $ id.at); + env.gvars <- bind "variable" env.gvars (strip_var_sub x) (Il.VarT (x, []) $ x.at); d - | TypD (id1, id2, as_, t, hints) -> + | TypD (x1, x2, as_, t, hints) -> let is_con = ref false in let t = infer_typ_notation env is_con t in - if bound env.typs id1 then ( - let _ps, k = find "syntax type" env.typs id1 in + if bound env.typs x1 then ( + let _ps, k = find "syntax type" env.typs x1 in let extension = match t.it with | CaseT (Dots, _, _, _) | StrT (Dots, _, _, _) -> true | _ -> false in if k <> Family [] && not extension then (* force error *) - ignore (env.typs <- bind "syntax type" env.typs id1 ([], Family [])) + ignore (env.typs <- bind "syntax type" env.typs x1 ([], Family [])) ) else ( let ps = List.map Convert.param_of_arg as_ in let env' = local_env env in - let _ps' = elab_params env' ps in + let ps' = elab_params env' ps in let k = infer_typ_definition env' t in - env.typs <- bind "syntax type" env.typs id1 (ps, k); + env.typs <- bind "syntax type" env.typs x1 (ps', k); if ps = [] then (* only types without parameters double as variables *) - env.gvars <- bind "variable" env.gvars (strip_var_sub id1) (VarT (id1, []) $ id1.at); + env.gvars <- bind "variable" env.gvars (strip_var_sub x1) (Il.VarT (x1, []) $ x1.at); ); - TypD (id1, id2, as_, t, hints) $ d.at - | VarD (id, t, _hints) -> + TypD (x1, x2, as_, t, hints) $ d.at + | VarD (x, t, _hints) -> + let t' = elab_typ env t in (* This is to ensure that we get rebind errors in syntactic order. *) - env.gvars <- bind "variable" env.gvars id t; + env.gvars <- bind "variable" env.gvars x t'; d | _ -> d -let infer_gramdef env d = +let infer_gramdef env (d : def) = match d.it with - | GramD (id1, _id2, ps, t, _gram, _hints) -> - (* - Printf.eprintf "[el.infer_gramdef %s]\n%!" (string_of_region d.at); - *) - if not (bound env.grams id1) then ( + | GramD (x1, _x2, ps, t, _gram, _hints) -> + if not (bound env.grams x1) then ( let env' = local_env env in - let _ps' = elab_params env' ps in - let _t' = elab_typ env' t in - env.grams <- bind "grammar" env.grams id1 (ps, t, None, []); + let ps' = elab_params env' ps in + let t' = elab_typ env' t in + env.grams <- bind "grammar" env.grams x1 (ps', t', [], None); ) | _ -> () -let elab_hintdef _env hd : Il.def list = +let elab_hintdef _env (hd : hintdef) : Il.def list = match hd.it with | TypH (id1, _id2, hints) -> if hints = [] then [] else - [Il.HintD (Il.TypH (id1, elab_hints id1 [] hints) $ hd.at) $ hd.at] + [Il.HintD (Il.TypH (id1, elab_hints id1 "" hints) $ hd.at) $ hd.at] | RelH (id, hints) -> if hints = [] then [] else - [Il.HintD (Il.RelH (id, elab_hints id [] hints) $ hd.at) $ hd.at] + [Il.HintD (Il.RelH (id, elab_hints id "" hints) $ hd.at) $ hd.at] | DecH (id, hints) -> if hints = [] then [] else - [Il.HintD (Il.DecH (id, elab_hints id [] hints) $ hd.at) $ hd.at] + [Il.HintD (Il.DecH (id, elab_hints id "" hints) $ hd.at) $ hd.at] | AtomH (id, atom, _hints) -> let _ = elab_atom atom id in [] | GramH _ | VarH _ -> [] -let infer_binds env env' dims d : Il.bind list = - Debug.(log_in_at "el.infer_binds" d.at - (fun _ -> - Map.fold (fun id _ ids -> - if Map.mem id env.vars then ids else id::ids - ) env'.vars [] |> List.rev |> String.concat " " - ) - ); - let det = Free.det_def d in - let free = Free.(diff (free_def d) (union det (bound_env env))) in - if free <> Free.empty then - error d.at ("definition contains indeterminate variable(s) `" ^ - String.concat "`, `" (Free.Set.elements free.varid) ^ "`"); - let acc_bs', (module Arg : Iter.Arg) = make_binds_iter_arg env' det dims in - let module Acc = Iter.Make(Arg) in - Acc.def d; - !acc_bs' - -let infer_no_binds env dims d = - let bs' = infer_binds env env dims d in - assert (bs' = []) - - -let rec elab_def env d : Il.def list = +let rec elab_def env (d : def) : Il.def list = Debug.(log_in "el.elab_def" line); Debug.(log_in_at "el.elab_def" d.at (fun _ -> el_def d)); + let env' = local_env env in + env'.pm <- false; match d.it with - | FamD (id, ps, hints) -> - env.pm <- false; - let ps' = elab_params (local_env env) ps in - if env.pm then error d.at "misplaced +- or -+ operator in syntax type declaration"; - let dims = Dim.check_def d in - infer_no_binds env dims d; - env.typs <- rebind "syntax type" env.typs id (ps, Family []); - [Il.TypD (id, ps', []) $ d.at] - @ elab_hintdef env (TypH (id, "" $ id.at, hints) $ d.at) - | TypD (id1, id2, as_, t, hints) -> - let env' = local_env env in - env'.pm <- false; - let ps1, k1 = find "syntax type" env.typs id1 in - let as', _s = elab_args `Lhs env' as_ ps1 d.at in - let dt' = elab_typ_definition env' id1 t in - let dims = Dim.check_def d in - let dims' = Dim.Env.map (List.map (elab_iter env')) dims in - let bs' = infer_binds env env' dims d in - let inst' = Il.InstD (bs', List.map (Dim.annot_arg dims') as', dt') $ d.at in - let k1', closed = - match k1, t.it with - | Opaque, (CaseT (Dots, _, _, _) | StrT (Dots, _, _, _)) -> - error_id id1 "extension of not yet defined syntax type" - | Opaque, (CaseT (NoDots, _, _, dots2) | StrT (NoDots, _, _, dots2)) -> - Defined (t, [id2], dt'), dots2 = NoDots - | (Opaque | Transp), _ -> - Defined (t, [id2], dt'), true - | Defined ({it = CaseT (dots1, ts1, tcs1, Dots); at; _}, ids, _), - CaseT (Dots, ts2, tcs2, dots2) -> - let ps = List.map Convert.param_of_arg as_ in - if List.exists (fun id -> id.it = id2.it) ids then - error d.at ("duplicate syntax fragment name `" ^ id1.it ^ - (if id2.it = "" then "" else "/" ^ id2.it) ^ "`"); - if not Eq.(eq_list eq_param ps ps1) then - error d.at "syntax parameters differ from previous fragment"; - let t1 = CaseT (dots1, ts1 @ ts2, tcs1 @ tcs2, dots2) $ over_region [at; t.at] in - Defined (t1, id2::ids, dt'), dots2 = NoDots - | Defined ({it = StrT (dots1, ts1, tfs1, Dots); at; _}, ids, _), - StrT (Dots, ts2, tfs2, dots2) -> - let ps = List.map Convert.param_of_arg as_ in - if List.exists (fun id -> id.it = id2.it) ids then - error d.at ("duplicate syntax fragment name `" ^ id1.it ^ - (if id2.it = "" then "" else "/" ^ id2.it) ^ "`"); - if not Eq.(eq_list eq_param ps ps1) then - error d.at "syntax parameters differ from previous fragment"; - let t1 = StrT (dots1, ts1 @ ts2, tfs1 @ tfs2, dots2) $ over_region [at; t.at] in - Defined (t1, id2::ids, dt'), dots2 = NoDots - | Defined _, (CaseT (Dots, _, _, _) | StrT (Dots, _, _, _)) -> - error_id id1 "extension of non-extensible syntax type" - | Defined _, _ -> - error_id id1 "duplicate declaration for syntax type"; - | Family _, (CaseT (dots1, _, _, dots2) | StrT (dots1, _, _, dots2)) - when dots1 = Dots || dots2 = Dots -> - error_id id1 "syntax type family cases are not extensible" - | Family insts, _ -> - Family (insts @ [(as_, t, inst')]), false + | FamD (x, ps, hints) -> + let ps' = elab_params env' ps in + if env'.pm then + error d.at "misplaced +- or -+ operator in syntax type declaration"; + let dims = Dim.check Map.empty ps' [] [] [] [] [] in + let ps' = List.map (Dim.annot_param dims) ps' in + infer_no_quants env dims Det.empty ps' [] [] [] [] [] d.at; + env.typs <- rebind "syntax type" env.typs x (ps', Family []); + [Il.TypD (x, ps', []) $ d.at] + @ elab_hintdef env (TypH (x, "" $ x.at, hints) $ d.at) + + | TypD (x1, x2, as_, t, hints) -> + let ps', k = find "syntax type" env.typs x1 in + let as', _s = elab_args `Lhs env' as_ ps' d.at in + let dims = Dim.check Map.empty [] as' [] [] [] [] in + let dots1, dt', dots2 = elab_typ_definition env' dims x1 t in + let as' = List.map (Dim.annot_arg dims) as' in + let det = Det.(det_list det_arg as') in + let qs = infer_quants env env' dims det [] as' [] [] [] [] d.at in + let inst' = Il.InstD (qs, as', dt') $ d.at in + let k', last = + match k with + | (Opaque | Transp) -> + if dots1 = Dots then + error_id x1 "extension of not yet defined syntax type"; + Defined (dt', [x2], dots2), dots2 = NoDots + | Defined (_, xs, dots) -> + if dots = NoDots then + error_id x1 "extension of non-extensible syntax type"; + if List.exists (fun x -> x.it = x2.it) xs then + error d.at ("duplicate syntax fragment name `" ^ x1.it ^ + (if x2.it = "" then "" else "/" ^ x2.it) ^ "`"); + Defined (dt', x2::xs, dots2), dots2 = NoDots + | Family insts -> + if dots1 = Dots || dots2 = Dots then + error_id x1 "syntax type family cases are not extensible"; + Family (insts @ [inst']), false in - (* - Printf.eprintf "[syntax %s] %s ~> %s\n%!" id1.it - (string_of_typ t) (Il.Print.string_of_deftyp dt'); - *) - env.typs <- rebind "syntax type" env.typs id1 (ps1, k1'); - (if not closed then [] else - let ps = List.map Convert.param_of_arg as_ in - let ps' = elab_params (local_env env) ps in - [Il.TypD (id1, ps', [inst']) $ d.at] - ) @ elab_hintdef env (TypH (id1, id2, hints) $ d.at) @ + env.typs <- rebind "syntax type" env.typs x1 (ps', k'); + (if not last then [] else [Il.TypD (x1, ps', [inst']) $ d.at]) + @ elab_hintdef env (TypH (x1, x2, hints) $ d.at) @ (if not env'.pm then [] else elab_def env Subst.(subst_def pm_snd (Iter.clone_def d))) - | GramD (id1, id2, ps, t, gram, hints) -> - let env' = local_env env in - env'.pm <- false; + + | GramD (x1, x2, ps, t, gram, hints) -> let ps' = elab_params env' ps in let t' = elab_typ env' t in + let dims = Dim.check Map.empty ps' [] [t'] [] [] [] in + let outer_dims = Dim.restrict dims (Il.Free.bound_params ps') in + let prods' = elab_gram env' outer_dims gram t' in + let xprods2' = List.map (fun pr -> x2, pr) prods' in if env'.pm then error d.at "misplaced +- or -+ operator in grammar"; - let prods' = List.map (fun pr -> id2, pr) (elab_gram env' gram t) in - let dims = Dim.check_def d in - infer_no_binds env' dims d; - let ps1, t1, gram1_opt, prods1' = find "grammar" env.grams id1 in - let gram', last = - match gram1_opt, gram.it with - | None, (Dots, _, _) -> - error_id id1 "extension of not yet defined grammar" - | None, (_, _, dots2) -> - gram, dots2 = NoDots - | Some {it = (dots1, prods1, Dots); at; _}, (Dots, prods2, dots2) -> - if List.exists (fun (id, _) -> id.it = id2.it) prods1' then - error d.at ("duplicate grammar fragment name `" ^ id1.it ^ - (if id2.it = "" then "" else "/" ^ id2.it) ^ "`"); - if not Eq.(eq_list eq_param ps ps1) then + let t' = Dim.annot_typ dims t' in + infer_no_quants env' outer_dims Det.empty ps' [] [t'] [] [] [] d.at; + let ps1', t1', xprods1', dots_opt = find "grammar" env.grams x1 in + let dots1, _, dots2 = gram.it in + let xprods' = + match dots_opt with + | None -> + if dots1 = Dots then + error_id x1 "extension of not yet defined grammar"; + xprods2' + | Some dots -> + if dots = NoDots then + error_id x1 "extension of non-extensible grammar"; + if List.exists (fun (x, _) -> x.it = x2.it) xprods1' then + error d.at ("duplicate grammar fragment name `" ^ x1.it ^ + (if x2.it = "" then "" else "/" ^ x2.it) ^ "`"); + if not Il.Eq.(eq_list eq_param ps' ps1') then error d.at "grammar parameters differ from previous fragment"; - if not (equiv_typ env' t t1) then - error_typ2 env d.at "grammar" t1 t " of previous fragment"; - (dots1, prods1 @ prods2, dots2) $ over_region [at; t.at], dots2 = NoDots - | Some _, (Dots, _, _) -> - error_id id1 "extension of non-extensible grammar" - | Some _, _ -> - error_id id1 "duplicate declaration for grammar"; + if not (equiv_typ env' t' t1') then + error_typ2 env d.at "grammar" t1' t' " of previous fragment"; + xprods1' @ xprods2' in - env.grams <- rebind "grammar" env.grams id1 (ps, t, Some gram', prods1' @ prods'); + env.grams <- rebind "grammar" env.grams x1 (ps', t', xprods', Some dots2); (* Only add last fragment to IL defs, so that populate finds it only once *) - (if last then [Il.GramD (id1, ps', t', []) $ d.at] else []) - @ elab_hintdef env (GramH (id1, id2, hints) $ d.at) - | RelD (id, t, hints) -> - env.pm <- false; - let mixop, ts', _ts = elab_typ_notation env id t in - if env.pm then error d.at "misplaced +- or -+ operator in relation"; - let dims = Dim.check_def d in - infer_no_binds env dims d; - env.rels <- bind "relation" env.rels id (t, []); - [Il.RelD (id, mixop, tup_typ' ts' t.at, []) $ d.at] - @ elab_hintdef env (RelH (id, hints) $ d.at) - | RuleD (id1, id2, e, prems) -> - let env' = local_env env in - env'.pm <- false; - let dims = Dim.check_def d in - let dims' = Dim.Env.map (List.map (elab_iter env')) dims in - let t, rules' = find "relation" env.rels id1 in - if List.exists (fun (id, _) -> id.it = id2.it) rules' then - error d.at ("duplicate rule name `" ^ id1.it ^ - (if id2.it = "" then "" else "/" ^ id2.it) ^ "`"); - let mixop, _, _ = elab_typ_notation env id1 t in - let es', _ = checkpoint (elab_exp_notation' env' id1 e t) in - let es' = List.map (Dim.annot_exp dims') es' in - let prems' = List.map (Dim.annot_prem dims') - (concat_map_filter_nl_list (elab_prem env') prems) in - let bs' = infer_binds env env' dims d in - let rule' = Il.RuleD (id2, bs', mixop, tup_exp' es' e.at, prems') $ d.at in - env.rels <- rebind "relation" env.rels id1 (t, rules' @ [id2, rule']); + (if dots2 = Dots then [] else [Il.GramD (x1, ps', t', []) $ d.at]) + @ elab_hintdef env (GramH (x1, x2, hints) $ d.at) + + | RelD (x, t, hints) -> + let mixop, xts' = elab_typ_notation' env' x t in + let ts' = List.map snd xts' in + if env'.pm then error d.at "misplaced +- or -+ operator in relation"; + let dims = Dim.check Map.empty [] [] ts' [] [] [] in + let ts' = List.map (Dim.annot_typ dims) ts' in + infer_no_quants env' dims Det.empty [] [] ts' [] [] [] d.at; + let not = Mixop.apply mixop (List.map (fun t' -> "_" $ d.at, t') ts') in + let t' = tup_typ' ts' t.at in + env.rels <- bind "relation" env.rels x (mixop, not, t', []); + [Il.RelD (x, mixop, t', []) $ d.at] + @ elab_hintdef env (RelH (x, hints) $ d.at) + + | RuleD (x1, x2, e, prems) -> + let mixop, not', t', rules' = find "relation" env.rels x1 in + if List.exists (fun (x, _) -> x.it = x2.it) rules' then + error d.at ("duplicate rule name `" ^ x1.it ^ + (if x2.it = "" then "" else "/" ^ x2.it) ^ "`"); + let es', _ = checkpoint (elab_exp_notation' env' x1 e not') in + let prems' = List.concat (map_filter_nl_list (elab_prem env') prems) in + let dims = Dim.check Map.empty [] [] [] es' [] prems' in + let es' = List.map (Dim.annot_exp dims) es' in + let e' = tup_exp_nary' es' e.at in + let prems' = List.map (Dim.annot_prem dims) prems' in + let det = Det.(det_exp e' ++ det_list det_prem prems') in + let qs = infer_quants env env' dims det [] [] [] es' [] prems' d.at in + let rule' = Il.RuleD (x2, qs, mixop, e', prems') $ d.at in + env.rels <- rebind "relation" env.rels x1 (mixop, not', t', rules' @ [x2, rule']); if not env'.pm then [] else elab_def env Subst.(subst_def pm_snd (Iter.clone_def d)) - | VarD (id, t, _hints) -> - env.pm <- false; - let _t' = elab_typ env t in - if env.pm then error d.at "misplaced +- or -+ operator in variable declaration"; - let dims = Dim.check_def d in - infer_no_binds env dims d; - env.gvars <- rebind "variable" env.gvars id t; + + | VarD (x, t, _hints) -> + let t' = elab_typ env' t in + if env'.pm then + error d.at "misplaced +- or -+ operator in variable declaration"; + let dims = Dim.check Map.empty [] [] [t'] [] [] [] in + let t' = Dim.annot_typ dims t' in + infer_no_quants env' dims Det.empty [] [] [t'] [] [] [] d.at; + env.gvars <- rebind "variable" env.gvars x t'; [] - | DecD (id, ps, t, hints) -> - let env' = local_env env in - env'.pm <- false; + + | DecD (x, ps, t, hints) -> let ps' = elab_params env' ps in let t' = elab_typ env' t in if env'.pm then error d.at "misplaced +- or -+ operator in declaration"; - let dims = Dim.check_def d in - infer_no_binds env dims d; - env.defs <- bind "definition" env.defs id (ps, t, []); - [Il.DecD (id, ps', t', []) $ d.at] - @ elab_hintdef env (DecH (id, hints) $ d.at) - | DefD (id, as_, e, prems) -> - let env' = local_env env in - env'.pm <- false; - let dims = Dim.check_def d in - let dims' = Dim.Env.map (List.map (elab_iter env')) dims in - let ps, t, clauses' = find "definition" env.defs id in - let as', s = elab_args `Lhs env' as_ ps d.at in - let as' = List.map (Dim.annot_arg dims') as' in - let prems' = concat_map_filter_nl_list (elab_prem env') prems in - let e' = checkpoint (elab_exp env' e (Subst.subst_typ s t)) in - let e' = Dim.annot_exp dims' e' in - let prems' = List.map (Dim.annot_prem dims') prems' in - let bs' = infer_binds env env' dims d in - let clause' = Il.DefD (bs', as', e', prems') $ d.at in - env.defs <- rebind "definition" env.defs id (ps, t, clauses' @ [(d, clause')]); + let d' = Il.DecD (x, ps', t', []) $ d.at in + let dims = Dim.check Map.empty ps' [] [t'] [] [] [] in + let t' = Dim.annot_typ dims t' in + infer_no_quants env dims Det.empty ps' [] [t'] [] [] [] d.at; + env.defs <- bind "definition" env.defs x (ps', t', []); + [d'] @ elab_hintdef env (DecH (x, hints) $ d.at) + + | DefD (x, as_, e, prems) -> + let ps', t', clauses' = find "definition" env.defs x in + let as', s = elab_args `Lhs env' as_ ps' d.at in + let prems' = List.concat (map_filter_nl_list (elab_prem env') prems) in + (* Elab e after premises, so that type information can flow to it *) + let e' = checkpoint (elab_exp env' e (Il.Subst.subst_typ s t')) in + let dims = Dim.check Map.empty [] as' [] [e'] [] prems' in + let as' = List.map (Dim.annot_arg dims) as' in + let e' = Dim.annot_exp dims e' in + let prems' = List.map (Dim.annot_prem dims) prems' in + let det = Det.(det_list det_arg as' ++ det_exp e' ++ det_list det_prem prems') in + let qs = infer_quants env env' dims det [] as' [] [e'] [] prems' d.at in + let clause' = Il.DefD (qs, as', e', prems') $ d.at in + env.defs <- rebind "definition" env.defs x (ps', t', clauses' @ [(d, clause')]); if not env'.pm then [] else elab_def env Subst.(subst_def pm_snd (Iter.clone_def d)) + | SepD -> [] + | HintD hd -> - elab_hintdef env hd + elab_hintdef env' hd let check_dots env = - Map.iter (fun id (at, (_ps, k)) -> + Map.iter (fun x (at, (_ps, k)) -> match k with | Transp | Opaque -> assert false - | Defined ({it = (CaseT (_, _, _, Dots) | StrT (_, _, _, Dots)); _}, _, _) -> - error_id (id $ at) "missing final extension to syntax type" + | Defined (_, _, Dots) -> + error_id (x $ at) "missing final extension to syntax type" | Family [] -> - error_id (id $ at) "no defined cases for syntax type family" + error_id (x $ at) "no defined cases for syntax type family" | Defined _ | Family _ -> () ) env.typs; - Map.iter (fun id (at, (_ps, _t, gram_opt, _prods')) -> - match gram_opt with + Map.iter (fun x (at, (_ps, _t, _prods', dots_opt)) -> + match dots_opt with | None -> assert false - | Some {it = (_, _, Dots); _} -> - error_id (id $ at) "missing final extension to grammar" - | _ -> () + | Some Dots -> + error_id (x $ at) "missing final extension to grammar" + | Some _ -> () ) env.grams -let populate_hint env hd' = +let populate_hint env (hd' : Il.hintdef) = match hd'.it with - | Il.TypH (id, _) -> ignore (find "syntax type" env.typs id) - | Il.RelH (id, _) -> ignore (find "relation" env.rels id) - | Il.DecH (id, _) -> ignore (find "definition" env.defs id) - | Il.GramH (id, _) -> ignore (find "grammar" env.grams id) + | Il.TypH (x, _) -> ignore (find "syntax type" env.typs x) + | Il.RelH (x, _) -> ignore (find "relation" env.rels x) + | Il.DecH (x, _) -> ignore (find "definition" env.defs x) + | Il.GramH (x, _) -> ignore (find "grammar" env.grams x) -let populate_def env d' : Il.def = +let populate_def env (d' : Il.def) : Il.def = Debug.(log_in "el.populate_def" dline); Debug.(log_in_at "el.populate_def" d'.at (Fun.const "")); match d'.it with - | Il.TypD (id, ps', _dt') -> - (match find "syntax type" env.typs id with - | _ps, Family insts -> - let insts' = List.map (fun (_, _, inst') -> inst') insts in - Il.TypD (id, ps', insts') $ d'.at - | _ps, _k -> - d' + | Il.TypD (x, ps', _dt') -> + (match find "syntax type" env.typs x with + | _ps, Family insts' -> Il.TypD (x, ps', insts') $ d'.at + | _ps, _k -> d' ) - | Il.RelD (id, mixop, t', []) -> - let _, rules' = find "relation" env.rels id in - Il.RelD (id, mixop, t', List.map snd rules') $ d'.at - | Il.DecD (id, ps', t', []) -> - let _, _, clauses' = find "definition" env.defs id in - Il.DecD (id, ps', t', List.map snd clauses') $ d'.at - | Il.GramD (id, ps', t', []) -> - let _, _, _, prods' = find "grammar" env.grams id in - Il.GramD (id, ps', t', List.map snd prods') $ d'.at + | Il.RelD (x, mixop, t', []) -> + let _, _, _, rules' = find "relation" env.rels x in + Il.RelD (x, mixop, t', List.map snd rules') $ d'.at + | Il.DecD (x, ps', t', []) -> + let _, _, clauses' = find "definition" env.defs x in + Il.DecD (x, ps', t', List.map snd clauses') $ d'.at + | Il.GramD (x, ps', t', []) -> + let _, _, prods', _ = find "grammar" env.grams x in + Il.GramD (x, ps', t', List.map snd prods') $ d'.at | Il.HintD hd' -> populate_hint env hd'; d' | _ -> assert false @@ -2711,7 +2699,7 @@ let deps (map : int Map.t) (set : Il.Free.Set.t) : int array = ) (Array.of_seq (Il.Free.Set.to_seq set)) -let check_recursion ds' = +let check_recursion (ds' : Il.def list) = List.iter (fun d' -> match d'.it, (List.hd ds').it with | Il.HintD _, _ | _, Il.HintD _ @@ -2725,7 +2713,7 @@ let check_recursion ds' = ) ds' (* TODO(4, rossberg): check that notations are non-recursive and defs are inductive? *) -let recursify_defs ds' : Il.def list = +let recursify_defs (ds' : Il.def list) : Il.def list = let open Il.Free in let da = Array.of_list ds' in let map_typid = ref Map.empty in @@ -2761,13 +2749,13 @@ let recursify_defs ds' : Il.def list = ) sccs -let implicit_typdef id (at, atom) ds = +let implicit_typdef id (at, atom) (ds : def list) : def list = let hint = {hintid = "show" $ at; hintexp = AtomE atom $ at} in let t = ConT ((AtomT (El.Iter.clone_atom atom) $ at, []), []) $ at in let d = TypD (id $ at, "" $ at, [], t, [hint]) $ at in d :: ds -let elab ds : Il.script * env = +let elab (ds : script) : Il.script * env = let env = new_env () in let ds = List.map (infer_typdef env) ds in let ds = Map.fold implicit_typdef env.atoms ds in @@ -2777,13 +2765,13 @@ let elab ds : Il.script * env = let ds' = List.map (populate_def env) ds' in recursify_defs ds', env -let elab_exp env e t : Il.exp = +let elab_exp env (e : exp) (t : typ) : Il.exp = let env' = local_env env in - let _ = elab_typ env' t in - checkpoint (elab_exp env' e t) + let t' = elab_typ env' t in + checkpoint (elab_exp env' e t') -let elab_rel env e id : Il.exp = +let elab_rel env (e : exp) (x : id) : Il.exp = let env' = local_env env in - match elab_prem env' (RulePr (id, e) $ e.at) with + match elab_prem env' (RulePr (x, e) $ e.at) with | [{it = Il.RulePr (_, _, e'); _}] -> e' | _ -> assert false diff --git a/spectec/src/frontend/eval.ml b/spectec/src/frontend/eval.ml deleted file mode 100644 index d8be4a396b..0000000000 --- a/spectec/src/frontend/eval.ml +++ /dev/null @@ -1,906 +0,0 @@ -open Util -open Source -open El -open Xl -open Ast - - -(* Environment *) - -module Set = Set.Make(String) -module Map = Map.Make(String) - -type typ_def = (arg list * typ) list -type def_def = (arg list * exp * prem list) list -type gram_def = unit -type env = {vars : typ Map.t; typs : typ_def Map.t; defs : def_def Map.t; grams : gram_def Map.t} -type subst = Subst.t - - -(* Helpers *) - -(* This exception indicates that a an application cannot be reduced because a pattern - * match cannot be decided. - * When assume_coherent_matches is set, that case is treated as a non-match. - *) -exception Irred - -let assume_coherent_matches = ref true - -let (let*) = Option.bind - - -let of_bool_exp = function - | BoolE b -> Some b - | _ -> None - -let of_num_exp = function - | NumE (_, n) -> Some n - | _ -> None - -let to_bool_exp b = BoolE b -let to_num_exp n = NumE (`DecOp, n) - - -(* Matching Lists *) - -let rec match_list match_x env s xs1 xs2 : subst option = - match xs1, xs2 with - | [], [] -> Some s - | x1::xs1', x2::xs2' -> - let* s' = match_x env s x1 x2 in - match_list match_x env (Subst.union s s') xs1' xs2' - | _, _ -> None - -let match_nl_list match_x env s xs1 xs2 = - match_list match_x env s (Convert.filter_nl xs1) (Convert.filter_nl xs2) - - -let equiv_list equiv_x env xs1 xs2 = - List.length xs1 = List.length xs2 && List.for_all2 (equiv_x env) xs1 xs2 -let equiv_nl_list equiv_x env xs1 xs2 = - equiv_list equiv_x env (El.Convert.filter_nl xs1) (El.Convert.filter_nl xs2) -let equiv_opt equiv_x env xo1 xo2 = - match xo1, xo2 with - | None, None -> true - | Some x1, Some x2 -> equiv_x env x1 x2 - | _, _ -> false - -let disj_list disj_x env xs1 xs2 = - List.length xs1 <> List.length xs2 || List.exists2 (disj_x env) xs1 xs2 - - -(* Type Reduction (weak-head) *) - -let rec reduce_typ env t : typ = - Debug.(log_if "el.reduce_typ" (t.it <> NumT `NatT) - (fun _ -> fmt "%s" (el_typ t)) - (fun r -> fmt "%s" (el_typ r)) - ) @@ fun _ -> - match t.it with - | VarT (id, args) -> - let args' = List.map (reduce_arg env) args in - let id' = El.Convert.strip_var_suffix id in - if id'.it <> id.it && args = [] then reduce_typ env (El.Convert.typ_of_varid id') else - (match reduce_typ_app env id args' t.at (Map.find id'.it env.typs) with - | Some t' -> -(* TODO(2, rossberg): reenable? - if id'.it <> id.it then - Error.error id.at "syntax" "identifer suffix encountered during reduction"; -*) - t' - | None -> VarT (id, args') $ t.at - ) - | ParenT t1 -> reduce_typ env t1 - | CaseT (dots1, ts, tcs, _dots2) -> - assert (dots1 = NoDots); -(* TODO(3, rossberg): unclosed case types are not checked early enough for this - assert (dots2 = NoDots); -*) - let tcs' = Convert.concat_map_nl_list (reduce_casetyp env) ts in - CaseT (NoDots, [], tcs' @ tcs, NoDots) $ t.at - | _ -> t - -and reduce_casetyp env t : typcase nl_list = - match (reduce_typ env t).it with - | CaseT (NoDots, [], tcs, NoDots) -> tcs - | _ -> assert false - -and reduce_typ_app env id args at = function - | [] -> - if !assume_coherent_matches then None else - let args = if args = [] then "" else - "(" ^ String.concat ", " (List.map Print.string_of_arg args) ^ ")" in - Error.error at "type" - ("undefined instance of partial syntax type definition: `" ^ id.it ^ args ^ "`") - | (args', t)::insts' -> - Debug.(log "el.reduce_typ_app" - (fun _ -> fmt "%s(%s) =: %s(%s)" id.it (el_args args) id.it (el_args args')) - (fun r -> fmt "%s" (opt (Fun.const "!") r)) - ) @@ fun _ -> - (* HACK: check for forward reference to yet undefined type (should throw?) *) - if Eq.eq_typ t (VarT (id, args') $ id.at) then None else - match match_list match_arg env Subst.empty args args' with - | exception Irred -> - if not !assume_coherent_matches then None else - reduce_typ_app env id args at insts' - | None -> reduce_typ_app env id args at insts' - | Some s -> Some (reduce_typ env (Subst.subst_typ s t)) - - -(* Expression Reduction *) - -and is_head_normal_exp e = - match e.it with - | AtomE _ | BoolE _ | NumE _ | TextE _ - | SeqE _ | TupE _ | InfixE _ | BrackE _ | StrE _ -> true - | _ -> false - -and is_normal_exp e = - match e.it with - | AtomE _ | BoolE _ | NumE _ | TextE _ -> true - | SeqE es | TupE es -> List.for_all is_normal_exp es - | BrackE (_, e, _) -> is_normal_exp e - | InfixE (e1, _, e2) -> is_normal_exp e1 && is_normal_exp e2 - | StrE efs -> Convert.forall_nl_list (fun (_, e) -> is_normal_exp e) efs - | _ -> false - -and reduce_exp env e : exp = - Debug.(log "el.reduce_exp" - (fun _ -> fmt "%s" (el_exp e)) - (fun r -> fmt "%s" (el_exp r)) - ) @@ fun _ -> - match e.it with - | VarE _ | AtomE _ | BoolE _ | TextE _ | SizeE _ -> e - | NumE (numop, n) -> NumE (numop, Num.narrow n) $ e.at - | CvtE (e1, nt) -> - let e1' = reduce_exp env e1 in - (match e1'.it with - | NumE (numop, n) -> - (match Num.cvt nt n with - | Some n' -> NumE (numop, n') $ e.at - | None -> e1' - ) - | _ -> e1' - ) - | UnE (op, e1) -> - let e1' = reduce_exp env e1 in - (match op, e1'.it with - | #Bool.unop as op', BoolE b1 -> BoolE (Bool.un op' b1) $ e.at - | #Num.unop as op', NumE (numop, n1) -> - (match Num.un op' n1 with - | Some n -> NumE (numop, n) - | None -> UnE (op, e1') - ) $ e.at - | `NotOp, UnE (`NotOp, e11') -> e11' - | `MinusOp, UnE (`MinusOp, e11') -> e11' - | `PlusOp, _ -> e1' - | _ -> UnE (op, e1') $ e.at - ) - | BinE (e1, op, e2) -> - let e1' = reduce_exp env e1 in - let e2' = reduce_exp env e2 in - (match op with - | #Bool.binop as op' -> - (match Bool.bin_partial op' e1'.it e2'.it of_bool_exp to_bool_exp with - | None -> BinE (e1', op, e2') - | Some e' -> e' - ) - | #Num.binop as op' -> - let e1'', e2'' = - match e1'.it, e2'.it with - | NumE (numop1, n1), NumE (numop2, n2) -> - let n1', n2' = Num.widen n1 n2 in - NumE (numop1, n1'), NumE (numop2, n2') - | _, _ -> e1'.it, e2'.it - in - (match Num.bin_partial op' e1'' e2'' of_num_exp to_num_exp with - | None -> BinE (e1', op, e2') - | Some e' -> e' - ) - ) $ e.at - | CmpE (e1, op, e2) -> - let e1' = reduce_exp env e1 in - let e2' = reduce_exp env e2 in - (match op, e1'.it, e2'.it with - | `EqOp, _, _ when Eq.eq_exp e1' e2' -> BoolE true - | `NeOp, _, _ when Eq.eq_exp e1' e2' -> BoolE false - | `EqOp, _, _ when is_normal_exp e1' && is_normal_exp e2' -> BoolE false - | `NeOp, _, _ when is_normal_exp e1' && is_normal_exp e2' -> BoolE true - | #Num.cmpop as op', NumE (_, n1), NumE (_, n2) -> - (match Num.cmp op' n1 n2 with - | Some b -> BoolE b - | None -> CmpE (e1', op, e2') - ) - | _ -> CmpE (e1', op, e2') - ) $ e.at - | EpsE -> SeqE [] $ e.at - | SeqE es -> SeqE (List.map (reduce_exp env) es) $ e.at - | ListE es -> SeqE (List.map (reduce_exp env) es) $ e.at - | IdxE (e1, e2) -> - let e1' = reduce_exp env e1 in - let e2' = reduce_exp env e2 in - (match e1'.it, e2'.it with - | SeqE es, NumE (_, `Nat i) when i < Z.of_int (List.length es) -> List.nth es (Z.to_int i) - | _ -> IdxE (e1', e2') $ e.at - ) - | SliceE (e1, e2, e3) -> - let e1' = reduce_exp env e1 in - let e2' = reduce_exp env e2 in - let e3' = reduce_exp env e3 in - (match e1'.it, e2'.it, e3'.it with - | SeqE es, NumE (_, `Nat i), NumE (_, `Nat n) when Z.(i + n) < Z.of_int (List.length es) -> - SeqE (Lib.List.take (Z.to_int n) (Lib.List.drop (Z.to_int i) es)) - | _ -> SliceE (e1', e2', e3') - ) $ e.at - | UpdE (e1, p, e2) -> - let e1' = reduce_exp env e1 in - let e2' = reduce_exp env e2 in - reduce_path env e1' p - (fun e' p' -> if p'.it = RootP then e2' else UpdE (e', p', e2') $ e.at) - | ExtE (e1, p, e2) -> - let e1' = reduce_exp env e1 in - let e2' = reduce_exp env e2 in - reduce_path env e1' p - (fun e' p' -> - if p'.it = RootP - then reduce_exp env (SeqE [e'; e2'] $ e.at) - else ExtE (e', p', e2') $ e.at - ) - | StrE efs -> StrE (Convert.map_nl_list (reduce_expfield env) efs) $ e.at - | DotE (e1, atom) -> - let e1' = reduce_exp env e1 in - (match e1'.it with - | StrE efs -> - snd (Option.get (El.Convert.find_nl_list (fun (atomN, _) -> Atom.eq atomN atom) efs)) - | _ -> DotE (e1', atom) $ e.at - ) - | CommaE (e1, e2) -> - let e1' = reduce_exp env e1 in - let e2' = reduce_exp env e2 in - (match e2'.it with - | SeqE ({it = AtomE atom; _} :: es2') -> - let e21' = match es2' with [e21'] -> e21' | _ -> SeqE es2' $ e2.at in - reduce_exp env (CatE (e1', StrE [Elem (atom, e21')] $ e2.at) $ e.at) - | _ -> CommaE (e1', e2') $ e.at - ) - | CatE (e1, e2) -> - let e1' = reduce_exp env e1 in - let e2' = reduce_exp env e2 in - (match e1'.it, e2'.it with - | SeqE es1, SeqE es2 -> SeqE (es1 @ es2) - | SeqE [], _ -> e2'.it - | _, SeqE [] -> e1'.it - | StrE efs1, StrE efs2 -> - let rec merge efs1 efs2 = - match efs1, efs2 with - | [], _ -> efs2 - | _, [] -> efs1 - | Nl::efs1', _ -> merge efs1' efs2 - | _, Nl::efs2' -> merge efs1 efs2' - | Elem (atom1, e1) :: efs1', Elem (atom2, e2) :: efs2' -> - (* Assume that both lists are sorted in same order *) - if Atom.eq atom1 atom2 then - let e' = reduce_exp env (CatE (e1, e2) $ e.at) in - Elem (atom1, e') :: merge efs1' efs2' - else if El.Convert.exists_nl_list (fun (atom, _) -> Atom.eq atom atom2) efs1 then - Elem (atom1, e1) :: merge efs1' efs2 - else - Elem (atom2, e2) :: merge efs1 efs2' - in StrE (merge efs1 efs2) - | _ -> CatE (e1', e2') - ) $ e.at - | MemE (e1, e2) -> - let e1' = reduce_exp env e1 in - let e2' = reduce_exp env e2 in - (match e2'.it with - | SeqE [] -> BoolE false - | SeqE es2' when List.exists (Eq.eq_exp e1') es2' -> BoolE true - | SeqE es2' when is_normal_exp e1' && List.for_all is_normal_exp es2' -> BoolE false - | _ -> MemE (e1', e2') - ) $ e.at - | LenE e1 -> - let e1' = reduce_exp env e1 in - (match e1'.it with - | SeqE es -> NumE (`DecOp, `Nat (Z.of_int (List.length es))) - | _ -> LenE e1' - ) $ e.at - | ParenE e1 | ArithE e1 | TypE (e1, _) -> reduce_exp env e1 - | TupE es -> TupE (List.map (reduce_exp env) es) $ e.at - | InfixE (e1, atom, e2) -> - let e1' = reduce_exp env e1 in - let e2' = reduce_exp env e2 in - InfixE (e1', atom, e2') $ e.at - | BrackE (atom1, e1, atom2) -> - let e1' = reduce_exp env e1 in - BrackE (atom1, e1', atom2) $ e.at - | CallE (id, args) -> - let args' = List.map (reduce_arg env) args in - let clauses = Map.find id.it env.defs in - (* Allow for uninterpreted functions *) - if not !assume_coherent_matches && clauses = [] then CallE (id, args') $ e.at else - (match reduce_exp_call env id args' e.at clauses with - | None -> CallE (id, args') $ e.at - | Some e -> e - ) - | IterE (e1, iter) -> - let e1' = reduce_exp env e1 in - IterE (e1', iter) $ e.at (* TODO(2, rossberg): simplify? *) - | HoleE _ | FuseE _ | UnparenE _ | LatexE _ -> assert false - -and reduce_expfield env (atom, e) : expfield = (atom, reduce_exp env e) - -and reduce_path env e p f = - match p.it with - | RootP -> f e p - | IdxP (p1, e1) -> - let e1' = reduce_exp env e1 in - let f' e' p1' = - match e'.it, e1'.it with - | SeqE es, NumE (_, `Nat i) when i < Z.of_int (List.length es) -> - SeqE (List.mapi (fun j eJ -> if Z.of_int j = i then f eJ p1' else eJ) es) $ e'.at - | _ -> - f e' (IdxP (p1', e1') $ p.at) - in - reduce_path env e p1 f' - | SliceP (p1, e1, e2) -> - let e1' = reduce_exp env e1 in - let e2' = reduce_exp env e2 in - let f' e' p1' = - match e'.it, e1'.it, e2'.it with - | SeqE es, NumE (_, `Nat i), NumE (_, `Nat n) when Z.(i + n) < Z.of_int (List.length es) -> - let e1' = SeqE Lib.List.(take (Z.to_int i) es) $ e'.at in - let e2' = SeqE Lib.List.(take (Z.to_int n) (drop (Z.to_int i) es)) $ e'.at in - let e3' = SeqE Lib.List.(drop Z.(to_int (i + n)) es) $ e'.at in - reduce_exp env (SeqE [e1'; f e2' p1'; e3'] $ e'.at) - | _ -> - f e' (SliceP (p1', e1', e2') $ p.at) - in - reduce_path env e p1 f' - | DotP (p1, atom) -> - let f' e' p1' = - match e'.it with - | StrE efs -> - StrE (Convert.map_nl_list (fun (atomI, eI) -> - if atomI = atom then (atomI, f eI p1') else (atomI, eI)) efs) $ e'.at - | _ -> - f e' (DotP (p1', atom) $ p.at) - in - reduce_path env e p1 f' - -and reduce_arg env a : arg = - match !(a.it) with - | ExpA e -> ref (ExpA (reduce_exp env e)) $ a.at - | TypA _t -> a (* types are reduced on demand *) - | GramA _g -> a - | DefA _id -> a - -and reduce_exp_call env id args at = function - | [] -> - if !assume_coherent_matches then None else - let args = if args = [] then "" else - "(" ^ String.concat ", " (List.map Print.string_of_arg args) ^ ")" in - Error.error at "type" - ("undefined call to partial function: `$" ^ id.it ^ args ^ "`") - | (args', e, prems)::clauses' -> - match match_list match_arg env Subst.empty args args' with - | exception Irred -> - if not !assume_coherent_matches then None else - reduce_exp_call env id args at clauses' - | None -> reduce_exp_call env id args at clauses' - | Some s -> - match reduce_prems env Subst.(subst_list subst_prem s prems) with - | None -> None - | Some false -> reduce_exp_call env id args at clauses' - | Some true -> Some (reduce_exp env (Subst.subst_exp s e)) - -and reduce_prems env = function - | [] -> Some true - | prem::prems -> - match reduce_prem env prem with - | Some true -> reduce_prems env prems - | other -> other - -and reduce_prem env prem : bool option = - match prem.it with - | VarPr _ - | ElsePr -> Some true - | RulePr _ -> None - | IfPr e -> - (match (reduce_exp env e).it with - | BoolE b -> Some b - | _ -> None - ) - | IterPr (_prem, _iter) -> None (* TODO(2, rossberg): implement *) - - -(* Matching *) - -(* Iteration *) - -and match_iter env s iter1 iter2 : subst option = - match iter1, iter2 with - | Opt, Opt -> Some s - | List, List -> Some s - | List1, List1 -> Some s - | ListN (e1, _ido1), ListN (e2, _ido2) -> match_exp env s e1 e2 - | _, _ -> None - - -(* Types *) - -and match_typ env s t1 t2 : subst option = - match t1.it, t2.it with - | ParenT t11, _ -> match_typ env s t11 t2 - | _, ParenT t21 -> match_typ env s t1 t21 - | _, VarT (id, []) when Subst.mem_typid s id -> - match_typ env s t1 (Subst.subst_typ s t2) - | _, VarT (id, []) when not (Map.mem id.it env.typs) -> - (* An unbound type is treated as a pattern variable *) - Some (Subst.add_typid s id t1) - | VarT (id1, args1), VarT (id2, args2) when id1.it = id2.it -> - (* Optimization for the common case where args are absent or equivalent. *) - (match match_list match_arg env s args1 args2 with - | Some s -> Some s - | None -> - (* If that fails, fall back to reduction. *) - let t1' = reduce_typ env t1 in - let t2' = reduce_typ env t2 in - if Eq.(eq_typ t1 t1' && eq_typ t2 t2') then None else - match_typ env s t1' t2' - ) - | VarT _, _ -> - let t1' = reduce_typ env t1 in - if Eq.eq_typ t1 t1' then None else - match_typ env s t1' t2 - | _, VarT _ -> - let t2' = reduce_typ env t2 in - if Eq.eq_typ t2 t2' then None else - match_typ env s t1 t2' - | TupT ts1, TupT ts2 -> match_list match_typ env s ts1 ts2 - | IterT (t11, iter1), IterT (t21, iter2) -> - let* s' = match_typ env s t11 t21 in match_iter env s' iter1 iter2 - | _, _ -> None - - -(* Expressions *) - -(* Matching can produce one of several results: - - Some s: matches producing substitutions - - None: does not match - - exception Irred: lacking normal form, can't decide between Some or None - - exception Error: some inner application was undefined, i.e., non-exhaustive -*) - -and match_exp env s e1 e2 : subst option = - Debug.(log "el.match_exp" - (fun _ -> fmt "%s =: %s" (el_exp e1) (el_exp e2)) - (fun r -> fmt "%s" (opt el_subst r)) - ) @@ fun _ -> - match e1.it, (reduce_exp env (Subst.subst_exp s e2)).it with -(* - | (ParenE e11 | TypE (e11, _)), _ -> match_exp env s e11 e2 - | _, (ParenE e21 | TypE (e21, _)) -> match_exp env s e1 e21 - | _, VarE (id, []) when Subst.mem_varid s id -> - match_exp env s e1 (Subst.subst_exp s e2) - | VarE (id1, args1), VarE (id2, args2) when id1.it = id2.it -> - match_list match_arg env s args1 args2 -*) - | _, VarE (id2, []) when Subst.mem_varid s id2 -> - (* A pattern variable already in the substitution is non-linear *) - let e2' = Subst.subst_exp s e2 in - if equiv_exp env e1 e2' then - Some s - else if is_head_normal_exp e1 && is_head_normal_exp e2' then - None - else - raise Irred - | _, VarE (id2, []) -> - (* Treat as a fresh pattern variable. If declared, need to check domain. *) - let find_var id = - match Map.find_opt id.it env.vars with - | None -> - (* Implicitly bound *) - Map.find_opt (El.Convert.strip_var_suffix id).it env.vars (* TODO(2, rossberg): should be gvars *) - | some -> some - in - if - match Map.find_opt (El.Convert.strip_var_suffix id2).it env.vars (* gvars *) with - | None -> true (* undeclared pattern variable always matches *) - | Some t2 -> - let t2' = reduce_typ env t2 in - match e1.it, t2'.it with - | BoolE _, BoolT - | TextE _, TextT -> true - | NumE (_, n), NumT t -> t >= Num.to_typ (Num.narrow n) - | UnE ((`MinusOp | `PlusOp), _), NumT t1 -> t1 >= `IntT - | NumE (_, `Nat n), RangeT tes -> - List.exists (function - | ({it = NumE (_, `Nat n1); _}, None) -> n1 = n - | ({it = NumE (_, `Nat n1); _}, Some {it = NumE (_, `Nat n2); _}) -> n1 <= n && n <= n2 - | _ -> false - ) (Convert.filter_nl tes) - | (AtomE atom | SeqE ({it = AtomE atom; _}::_)), CaseT (_, _, tcs, _) -> - (match El.Convert.find_nl_list (fun (atomN, _, _) -> atomN.it = atom.it) tcs with - | Some (_, (tN, _), _) -> - match_exp env s e1 (Convert.exp_of_typ tN) <> None - | None -> false - ) - | VarE (id1, []), _ -> - (match find_var id1 with - | None -> raise Irred - | Some t1 -> sub_typ env t1 t2' || - if disj_typ env t1 t2' then false else raise Irred - ) - | _, (StrT _ | CaseT _ | ConT _ | RangeT _) -> raise Irred - | _, _ -> true - then - if id2.it = "_" then Some s else - Some (Subst.add_varid s id2 e1) - else None - | AtomE atom1, AtomE atom2 when atom1.it = atom2.it -> Some s - | BoolE b1, BoolE b2 when b1 = b2 -> Some s - | NumE (_, n1), NumE (_, n2) when n1 = n2 -> Some s - | TextE s1, TextE s2 when s1 = s2 -> Some s - | NumE (_, n1), UnE (`PlusOp, e21) when not (Num.is_neg n1) -> - match_exp env s e1 e21 - | NumE (numop, n1), UnE (`MinusOp, e21) when Num.is_neg n1 -> - match_exp env s (reduce_exp env {e1 with it = NumE (numop, Num.abs n1)}) e21 - | NumE (_, n1), UnE (#signop as op, _) -> - let pm, mp = - if Num.is_neg n1 = (op = `MinusPlusOp) - then `PlusOp, `MinusOp else `MinusOp, `PlusOp - in - match_exp env - (Subst.add_unop (Subst.add_unop s `PlusMinusOp pm) `MinusPlusOp mp) e1 e2 -(* - | UnE (op1, e11), UnE (op2, e21) when op1 = op2 -> match_exp env s e11 e21 - | BinE (e11, op1, e12), BinE (e21, op2, e22) when op1 = op2 -> - let* s' = match_exp env s e11 e21 in match_exp env s' e12 e22 - | CmpE (e11, op1, e12), CmpE (e21, op2, e22) when op1 = op2 -> - let* s' = match_exp env s e11 e21 in match_exp env s' e12 e22 - | (EpsE | SeqE []), (EpsE | SeqE []) -> Some s -*) - | SeqE es1, SeqE es2 - | TupE es1, TupE es2 -> match_list match_exp env s es1 es2 -(* - | IdxE (e11, e12), IdxE (e21, e22) - | CommaE (e11, e12), CommaE (e21, e22) - | CatE (e11, e12), CatE (e21, e22) -> - let* s' = match_exp env s e11 e21 in match_exp env s' e12 e22 - | SliceE (e11, e12, e13), SliceE (e21, e22, e23) -> - let* s' = match_exp env s e11 e21 in - let* s'' = match_exp env s' e12 e22 in - match_exp env s'' e13 e23 - | UpdE (e11, p1, e12), UpdE (e21, p2, e22) - | ExtE (e11, p1, e12), ExtE (e21, p2, e22) -> - let* s' = match_exp env s e11 e21 in - let* s'' = match_path env s' p1 p2 in - match_exp env s'' e12 e22 -*) - | StrE efs1, StrE efs2 -> match_nl_list match_expfield env s efs1 efs2 -(* - | DotE (e11, atom1), DotE (e21, atom2) when atom1 = atom2 -> - match_exp env s e11 e21 - | LenE e11, LenE e21 -> match_exp env s e11 e21 - | SizeE id1, SizeE id2 when id1.it = id2.it -> Some s -*) - | InfixE (e11, atom1, e12), InfixE (e21, atom2, e22) when atom1 = atom2 -> - let* s' = match_exp env s e11 e21 in match_exp env s' e12 e22 - | BrackE (atom11, e11, atom12), BrackE (atom21, e21, atom22) - when atom11 = atom21 && atom12 = atom22 -> - match_exp env s e11 e21 -(* - | CallE (id1, args1), CallE (id2, args2) when id1.it = id2.it -> - match_list match_arg env s args1 args2 -*) - | IterE (e11, iter1), IterE (e21, iter2) -> - let* s' = match_exp env s e11 e21 in match_iter env s' iter1 iter2 - | (HoleE _ | FuseE _ | UnparenE _), _ - | _, (HoleE _ | FuseE _ | UnparenE _) -> assert false - | _, _ when is_head_normal_exp e1 -> None - | _, _ -> raise Irred - -and match_expfield env s (atom1, e1) (atom2, e2) = - if atom1 <> atom2 then None else - match_exp env s e1 e2 - -(* -and match_path env s p1 p2 = - match p1.it, p2.it with - | RootP, RootP -> Some s - | IdxP (p11, e1), IdxP (p21, e2) -> - let* s' = match_path env s p11 p21 in - match_exp env s' e1 e2 - | SliceP (p11, e11, e12), SliceP (p21, e21, e22) -> - let* s' = match_path env s p11 p21 in - let* s'' = match_exp env s' e11 e21 in - match_exp env s'' e12 e22 - | DotP (p11, atom1), DotP (p21, atom2) when atom1 = atom2 -> - match_path env s p11 p21 - | _, _ -> None -*) - - -(* Grammars *) - -and match_sym env s g1 g2 : subst option = - Debug.(log "el.match_sym" - (fun _ -> fmt "%s =: %s" (el_sym g1) (el_sym g2)) - (fun r -> fmt "%s" (opt el_subst r)) - ) @@ fun _ -> - match g1.it, g2.it with - | ParenG g11, _ -> match_sym env s g11 g2 - | _, ParenG g21 -> match_sym env s g1 g21 - | _, VarG (id, []) when Subst.mem_gramid s id -> - match_sym env s g1 (Subst.subst_sym s g2) - | _, VarG (id, []) when not (Map.mem id.it env.grams) -> - (* An unbound id is treated as a pattern variable *) - Some (Subst.add_gramid s id g1) - | VarG (id1, args1), VarG (id2, args2) when id1.it = id2.it -> - match_list match_arg env s args1 args2 - | TupG gs1, TupG gs2 -> match_list match_sym env s gs1 gs2 - | IterG (g11, iter1), IterG (g21, iter2) -> - let* s' = match_sym env s g11 g21 in match_iter env s' iter1 iter2 - | _, _ -> None - - -(* Parameters *) - -and match_arg env s a1 a2 : subst option = - Debug.(log "el.match_arg" - (fun _ -> fmt "%s =: %s" (el_arg a1) (el_arg a2)) - (fun r -> fmt "%s" (opt el_subst r)) - ) @@ fun _ -> - match !(a1.it), !(a2.it) with - | ExpA e1, ExpA e2 -> match_exp env s e1 e2 - | TypA t1, TypA t2 -> match_typ env s t1 t2 - | GramA g1, GramA g2 -> match_sym env s g1 g2 - | DefA id1, DefA id2 -> - if id2.it = "_" then Some s else - Some (Subst.add_defid s id2 id1) - | _, _ -> assert false - - -(* Type Equivalence *) - -and equiv_typ env t1 t2 = - Debug.(log "el.equiv_typ" - (fun _ -> fmt "%s == %s" (el_typ t1) (el_typ t2)) Bool.to_string - ) @@ fun _ -> - match t1.it, t2.it with - | VarT (id1, args1), VarT (id2, args2) -> - (El.Convert.strip_var_suffix id1).it = (El.Convert.strip_var_suffix id2).it && - equiv_list equiv_arg env args1 args2 || (* optimization *) - let t1' = reduce_typ env t1 in - let t2' = reduce_typ env t2 in - (t1' <> t1 || t2' <> t2) && equiv_typ env t1' t2' - | VarT _, _ -> - let t1' = reduce_typ env t1 in - t1' <> t1 && equiv_typ env t1' t2 - | _, VarT _ -> - let t2' = reduce_typ env t2 in - t2' <> t2 && equiv_typ env t1 t2' - | ParenT t11, _ -> equiv_typ env t11 t2 - | _, ParenT t21 -> equiv_typ env t1 t21 - | TupT ts1, TupT ts2 | SeqT ts1, SeqT ts2 -> equiv_list equiv_typ env ts1 ts2 - | IterT (t11, iter1), IterT (t21, iter2) -> - equiv_typ env t11 t21 && Eq.eq_iter iter1 iter2 - | AtomT atom1, AtomT atom2 -> atom1.it = atom2.it - | InfixT (t11, atom1, t12), InfixT (t21, atom2, t22) -> - equiv_typ env t11 t21 && atom1.it = atom2.it && equiv_typ env t12 t22 - | BrackT (atom11, t11, atom12), BrackT (atom21, t21, atom22) -> - atom11.it = atom21.it && equiv_typ env t11 t21 && atom12 = atom22 - | StrT (NoDots, [], tfs1, NoDots), StrT (NoDots, [], tfs2, NoDots) -> - equiv_nl_list equiv_typfield env tfs1 tfs2 - | CaseT (NoDots, [], tcs1, NoDots), CaseT (NoDots, [], tcs2, NoDots) -> - equiv_nl_list equiv_typcase env tcs1 tcs2 - | ConT tc1, ConT tc2 -> equiv_typcon env tc1 tc2 - | RangeT tes1, RangeT tes2 -> equiv_nl_list equiv_typenum env tes1 tes2 - | _, _ -> t1.it = t2.it - -and equiv_typfield env (atom1, (t1, prems1), _) (atom2, (t2, prems2), _) = - atom1.it = atom2.it && equiv_typ env t1 t2 && Eq.(eq_nl_list eq_prem prems1 prems2) -and equiv_typcase env (atom1, (t1, prems1), _) (atom2, (t2, prems2), _) = - atom1.it = atom2.it && equiv_typ env t1 t2 && Eq.(eq_nl_list eq_prem prems1 prems2) -and equiv_typcon env ((t1, prems1), _) ((t2, prems2), _) = - equiv_typ env t1 t2 && Eq.(eq_nl_list eq_prem prems1 prems2) -and equiv_typenum env (e11, e12o) (e21, e22o) = - equiv_exp env e11 e21 && equiv_opt equiv_exp env e12o e22o - -and equiv_exp env e1 e2 = - Debug.(log "el.equiv_exp" - (fun _ -> fmt "%s == %s" (el_exp e1) (el_exp e2)) Bool.to_string - ) @@ fun _ -> - (* TODO(3, rossberg): this does not reduce inner type arguments *) - Eq.eq_exp (reduce_exp env e1) (reduce_exp env e2) - -and equiv_arg env a1 a2 = - Debug.(log "el.equiv_arg" - (fun _ -> fmt "%s == %s" (el_arg a1) (el_arg a2)) Bool.to_string - ) @@ fun _ -> - (* - Printf.eprintf "[el.equiv_arg] %s == %s\n%!" - (Print.string_of_arg a1) - (Print.string_of_arg a2); - *) - match !(a1.it), !(a2.it) with - | ExpA e1, ExpA e2 -> equiv_exp env e1 e2 - | TypA t1, TypA t2 -> equiv_typ env t1 t2 - | GramA g1, GramA g2 -> Eq.eq_sym g1 g2 - | DefA id1, DefA id2 -> id1.it = id2.it - | _, _ -> false - - -and equiv_functyp env (ps1, t1) (ps2, t2) = - List.length ps1 = List.length ps2 && - match equiv_params env ps1 ps2 with - | None -> false - | Some s -> equiv_typ env t1 (Subst.subst_typ s t2) - -and equiv_params env ps1 ps2 = - List.fold_left2 (fun s_opt p1 p2 -> - let* s = s_opt in - match p1.it, (Subst.subst_param s p2).it with - | ExpP (id1, t1), ExpP (id2, t2) -> - if not (equiv_typ env t1 t2) then None else - Some (Subst.add_varid s id2 (VarE (id1, []) $ p1.at)) - | TypP _, TypP _ -> Some s - | GramP (id1, t1), GramP (id2, t2) -> - if not (equiv_typ env t1 t2) then None else - Some (Subst.add_gramid s id2 (VarG (id1, []) $ p1.at)) - | DefP (id1, ps1, t1), DefP (id2, ps2, t2) -> - if not (equiv_functyp env (ps1, t1) (ps2, t2)) then None else - Some (Subst.add_defid s id2 id1) - | _, _ -> None - ) (Some Subst.empty) ps1 ps2 - - -(* Subtyping *) - -and sub_prems _env prems1 prems2 = - Debug.(log "el.sub_prems" - (fun _ -> fmt "%s <: %s" (nl_list el_prem prems1) (nl_list el_prem prems2)) - Bool.to_string - ) @@ fun _ -> - let open Convert in - forall_nl_list (fun prem2 -> exists_nl_list (Eq.eq_prem prem2) prems1) prems2 - -and sub_typ env t1 t2 = - Debug.(log "el.sub_typ" - (fun _ -> fmt "%s <: %s" (el_typ t1) (el_typ t2)) Bool.to_string - ) @@ fun _ -> - let t1 = reduce_typ env t1 in - let t2 = reduce_typ env t2 in - match t1.it, t2.it with -(*| NumT nt1, NumT nt2 -> Num.sub nt1 nt2*) - | StrT (NoDots, [], tfs1, NoDots), StrT (NoDots, [], tfs2, NoDots) -> - El.Convert.forall_nl_list (fun (atom, (t2, prems2), _) -> - match find_field tfs1 atom with - | Some (t1, prems1) -> - equiv_typ env t1 t2 && sub_prems env prems1 prems2 - | None -> false - ) tfs2 - | CaseT (NoDots, [], tcs1, NoDots), CaseT (NoDots, [], tcs2, NoDots) -> - El.Convert.forall_nl_list (fun (atom, (t1, prems1), _) -> - match find_case tcs2 atom with - | Some (t2, prems2) -> - equiv_typ env t1 t2 && sub_prems env prems1 prems2 - | None -> false - ) tcs1 - | ConT ((t11, prems1), _), ConT ((t21, prems2), _) -> - sub_typ env t11 t21 && sub_prems env prems1 prems2 || - equiv_typ env t1 t2 -(* - | ConT ((t11, _), _), _ -> sub_typ env t11 t2 - | _, ConT ((t21, _), _) -> sub_typ env t1 t21 - | RangeT [], NumT _ -> true - | RangeT (Elem (e1, _)::tes1), NumT t2' -> - (match (reduce_exp env e1).it with - | NumE _ -> true - | UnE (`MinusOp, _) -> t2' <= `IntT - | _ -> assert false - ) && sub_typ env (RangeT tes1 $ t1.at) t2 - | NumT _, RangeT [] -> true - | NumT t1', RangeT (Elem (e2, _)::tes2) -> - (match (reduce_exp env e2).it with - | NumE (_, `Nat _) -> t1' = `NatT - | UnE (`MinusOp, _) -> true - | _ -> assert false - ) && sub_typ env t1 (RangeT tes2 $ t2.at) -*) - | TupT ts1, TupT ts2 - | SeqT ts1, SeqT ts2 -> - List.length ts1 = List.length ts2 && List.for_all2 (sub_typ env) ts1 ts2 - | _, _ -> equiv_typ env t1 t2 - -and find_field tfs atom = - El.Convert.find_nl_list (fun (atom', _, _) -> atom'.it = atom.it) tfs - |> Option.map snd3 - -and find_case tcs atom = - El.Convert.find_nl_list (fun (atom', _, _) -> atom'.it = atom.it) tcs - |> Option.map snd3 - -and fst3 (x, _, _) = x -and snd3 (_, x, _) = x - - -(* Type Disjointness *) - -and disj_typ env t1 t2 = - Debug.(log "el.disj_typ" - (fun _ -> fmt "%s ## %s" (el_typ t1) (el_typ t2)) Bool.to_string - ) @@ fun _ -> - match t1.it, t2.it with - | VarT (id1, args1), VarT (id2, args2) -> - let t1' = reduce_typ env t1 in - let t2' = reduce_typ env t2 in - if t1' <> t1 || t2' <> t2 then - disj_typ env t1' t2' - else - (El.Convert.strip_var_suffix id1).it <> (El.Convert.strip_var_suffix id2).it || - disj_list disj_arg env args1 args2 - | VarT _, _ -> - let t1' = reduce_typ env t1 in - t1' <> t1 && disj_typ env t1' t2 - | _, VarT _ -> - let t2' = reduce_typ env t2 in - t2' <> t2 && disj_typ env t1 t2' - | ParenT t11, _ -> disj_typ env t11 t2 - | _, ParenT t21 -> disj_typ env t1 t21 - | TupT ts1, TupT ts2 | SeqT ts1, SeqT ts2 -> disj_list disj_typ env ts1 ts2 - | IterT (t11, iter1), IterT (t21, iter2) -> - disj_typ env t11 t21 || not (Eq.eq_iter iter1 iter2) - | AtomT atom1, AtomT atom2 -> atom1.it <> atom2.it - | InfixT (t11, atom1, t12), InfixT (t21, atom2, t22) -> - disj_typ env t11 t21 || atom1.it <> atom2.it || disj_typ env t12 t22 - | BrackT (atom11, t11, atom12), BrackT (atom21, t21, atom22) -> - atom11.it <> atom21.it || disj_typ env t11 t21 || atom12 = atom22 - | StrT (NoDots, [], tfs1, NoDots), StrT (NoDots, [], tfs2, NoDots) -> - unordered (atoms tfs1) (atoms tfs2) || - El.Convert.exists_nl_list (fun (atom, (t2, _prems2), _) -> - match find_field tfs1 atom with - | Some (t1, _prems1) -> disj_typ env t1 t2 - | None -> true - ) tfs2 - | CaseT (NoDots, [], tcs1, NoDots), CaseT (NoDots, [], tcs2, NoDots) -> - Set.disjoint (atoms tcs1) (atoms tcs2) || - El.Convert.exists_nl_list (fun (atom, (t1, _prems1), _) -> - match find_case tcs2 atom with - | Some (t2, _prems2) -> disj_typ env t1 t2 - | None -> false - ) tcs1 - | ConT ((t11, _), _), ConT ((t21, _), _) -> disj_typ env t11 t21 - | RangeT _, RangeT _ -> false (* approximation *) - | _, _ -> t1.it <> t2.it - -and narrow_typ env t1 t2 = - Debug.(log "el.narrow_typ" - (fun _ -> fmt "%s <: %s" (el_typ t1) (el_typ t2)) Bool.to_string - ) @@ fun _ -> - let t1 = reduce_typ env t1 in - let t2 = reduce_typ env t2 in - match t1.it, t2.it with - | NumT nt1, NumT nt2 -> Num.sub nt1 nt2 - | _, _ -> equiv_typ env t1 t2 - -and atoms xs = - Set.of_list (List.map Print.string_of_atom - (El.Convert.map_filter_nl_list fst3 xs)) - -and unordered s1 s2 = not Set.(subset s1 s2 || subset s2 s1) - -and disj_exp env e1 e2 = - (* TODO(3, rossberg): this does not reduce inner type arguments *) - let e1' = reduce_exp env e1 in - let e2' = reduce_exp env e2 in - is_normal_exp e1' && is_normal_exp e2' && not (Eq.eq_exp e1' e2') - -and disj_arg env a1 a2 = - match !(a1.it), !(a2.it) with - | ExpA e1, ExpA e2 -> disj_exp env e1 e2 - | TypA t1, TypA t2 -> disj_typ env t1 t2 - | GramA _, GramA _ -> false - | DefA _, DefA _ -> false - | _, _ -> false diff --git a/spectec/src/frontend/eval.mli b/spectec/src/frontend/eval.mli deleted file mode 100644 index ae743d5cf0..0000000000 --- a/spectec/src/frontend/eval.mli +++ /dev/null @@ -1,29 +0,0 @@ -open El.Ast - -module Map : Map.S with type key = string with type 'a t = 'a Map.Make(String).t - -type typ_def = (arg list * typ) list -type def_def = (arg list * exp * prem list) list -type gram_def = unit -type env = {vars : typ Map.t; typs : typ_def Map.t; defs : def_def Map.t; grams : gram_def Map.t} -type subst = El.Subst.t - -val (let*) : subst option -> (subst -> subst option) -> subst option - -val reduce_exp : env -> exp -> exp -val reduce_typ : env -> typ -> typ -val reduce_arg : env -> arg -> arg - -val equiv_functyp : env -> param list * typ -> param list * typ -> bool -val equiv_typ : env -> typ -> typ -> bool -val sub_typ : env -> typ -> typ -> bool -val narrow_typ : env -> typ -> typ -> bool - -val match_iter : env -> subst -> iter -> iter -> subst option -val match_exp : env -> subst -> exp -> exp -> subst option -val match_typ : env -> subst -> typ -> typ -> subst option -val match_arg : env -> subst -> arg -> arg -> subst option - -val match_list : - (env -> subst -> 'a -> 'a -> subst option) -> - env -> subst -> 'a list -> 'a list -> subst option diff --git a/spectec/src/frontend/parser.mly b/spectec/src/frontend/parser.mly index 2607b27f94..f768a128da 100644 --- a/spectec/src/frontend/parser.mly +++ b/spectec/src/frontend/parser.mly @@ -1025,10 +1025,12 @@ param_ : | varid_bind_with_suffix COLON typ { ExpP ($1, $3) } | typ { let id = - try El.Convert.varid_of_typ $1 with Error.Error _ -> "" $ $sloc + try El.Convert.varid_of_typ $1 with Error.Error _ -> "_" $ $sloc in ExpP (id, $1) } | SYNTAX varid_bind { TypP $2 } - | GRAMMAR gramid COLON typ { GramP ($2, $4) } + | GRAMMAR gramid COLON typ { GramP ($2, [], $4) } + | GRAMMAR gramid_lparen enter_scope comma_list(param) RPAREN COLON typ exit_scope + { GramP ($2, $4, $7) } | DEF DOLLAR defid COLON typ { DefP ($3, [], $5) } | DEF DOLLAR defid_lparen enter_scope comma_list(param) RPAREN COLON typ exit_scope diff --git a/spectec/src/il/ast.ml b/spectec/src/il/ast.ml index 9132687342..2360d83af4 100644 --- a/spectec/src/il/ast.ml +++ b/spectec/src/il/ast.ml @@ -8,7 +8,7 @@ type num = Num.num type text = string type id = string phrase type atom = Atom.atom -type mixop = Mixop.mixop +type mixop = unit Mixop.mixop (* Iteration *) @@ -31,7 +31,7 @@ and typ' = | BoolT (* `bool` *) | NumT of numtyp (* numtyp *) | TextT (* `text` *) - | TupT of (exp * typ) list (* typ * ... * typ *) + | TupT of (id * typ) list (* (id : typ, ..., id : typ) *) | IterT of typ * iter (* typ iter *) and deftyp = deftyp' phrase @@ -40,8 +40,8 @@ and deftyp' = | StructT of typfield list (* record type *) | VariantT of typcase list (* variant type *) -and typfield = atom * (bind list * typ * prem list) * hint list (* record field *) -and typcase = mixop * (bind list * typ * prem list) * hint list (* variant case *) +and typfield = atom * (typ * quant list * prem list) * hint list (* record field *) +and typcase = mixop * (typ * quant list * prem list) * hint list (* variant case *) (* Expressions *) @@ -52,44 +52,44 @@ and cmpop = [Bool.cmpop | Num.cmpop] and exp = (exp', typ) note_phrase and exp' = - | VarE of id (* varid *) - | BoolE of bool (* bool *) - | NumE of num (* num *) - | TextE of text (* text *) - | UnE of unop * optyp * exp (* unop exp *) - | BinE of binop * optyp * exp * exp (* exp binop exp *) - | CmpE of cmpop * optyp * exp * exp (* exp cmpop exp *) - | TupE of exp list (* ( exp* ) *) - | ProjE of exp * int (* exp.i *) - | CaseE of mixop * exp (* atom exp? *) - | UncaseE of exp * mixop (* exp!mixop *) - | OptE of exp option (* exp? *) - | TheE of exp (* exp! *) - | StrE of expfield list (* { expfield* } *) - | DotE of exp * atom (* exp.atom *) - | CompE of exp * exp (* exp @ exp *) - | ListE of exp list (* [exp ... exp] *) - | LiftE of exp (* exp : _? <: _* *) - | MemE of exp * exp (* exp `<-` exp *) - | LenE of exp (* |exp| *) - | CatE of exp * exp (* exp :: exp *) - | IdxE of exp * exp (* exp[exp]` *) - | SliceE of exp * exp * exp (* exp[exp : exp] *) - | UpdE of exp * path * exp (* exp[path = exp] *) - | ExtE of exp * path * exp (* exp[path =.. exp] *) - | CallE of id * arg list (* defid( arg* ) *) - | IterE of exp * iterexp (* exp iter *) - | CvtE of exp * numtyp * numtyp (* exp : typ1 <:> typ2 *) - | SubE of exp * typ * typ (* exp : typ1 <: typ2 *) - -and expfield = atom * exp (* atom exp *) + | VarE of id (* varid *) + | BoolE of bool (* bool *) + | NumE of num (* num *) + | TextE of text (* text *) + | UnE of unop * optyp * exp (* unop exp *) + | BinE of binop * optyp * exp * exp (* exp binop exp *) + | CmpE of cmpop * optyp * exp * exp (* exp cmpop exp *) + | TupE of exp list (* ( exp* ) *) + | ProjE of exp * int (* exp.i *) + | CaseE of mixop * exp (* atom exp? *) + | UncaseE of exp * mixop (* exp!mixop *) + | OptE of exp option (* exp? *) + | TheE of exp (* exp! *) + | StrE of expfield list (* { expfield* } *) + | DotE of exp * atom (* exp.atom *) + | CompE of exp * exp (* exp @ exp *) + | ListE of exp list (* [exp ... exp] *) + | LiftE of exp (* exp : _? <: _* *) + | MemE of exp * exp (* exp `<-` exp *) + | LenE of exp (* |exp| *) + | CatE of exp * exp (* exp :: exp *) + | IdxE of exp * exp (* exp[exp]` *) + | SliceE of exp * exp * exp (* exp[exp : exp] *) + | UpdE of exp * path * exp (* exp[path = exp] *) + | ExtE of exp * path * exp (* exp[path =.. exp] *) + | CallE of id * arg list (* defid( arg* ) *) + | IterE of exp * iterexp (* exp iter *) + | CvtE of exp * numtyp * numtyp (* exp : typ1 <:> typ2 *) + | SubE of exp * typ * typ (* exp : typ1 <: typ2 *) + +and expfield = atom * exp (* atom exp *) and path = (path', typ) note_phrase and path' = - | RootP (* *) - | IdxP of path * exp (* path `[` exp `]` *) - | SliceP of path * exp * exp (* path `[` exp `:` exp `]` *) - | DotP of path * atom (* path `.` atom *) + | RootP (* *) + | IdxP of path * exp (* path[exp] *) + | SliceP of path * exp * exp (* path[exp : exp] *) + | DotP of path * atom (* path.atom *) and iterexp = iter * (id * exp) list @@ -98,39 +98,34 @@ and iterexp = iter * (id * exp) list and sym = sym' phrase and sym' = - | VarG of id * arg list (* gramid (`(` arg,* `)`)? *) - | NumG of int (* num *) - | TextG of string (* `"`text`"` *) - | EpsG (* `eps` *) - | SeqG of sym list (* sym sym *) - | AltG of sym list (* sym `|` sym *) - | RangeG of sym * sym (* sym `|` `...` `|` sym *) - | IterG of sym * iterexp (* sym iter *) - | AttrG of exp * sym (* exp `:` sym *) + | VarG of id * arg list (* gramid( arg* ) *) + | NumG of int (* num *) + | TextG of string (* text *) + | EpsG (* epsilon *) + | SeqG of sym list (* sym sym *) + | AltG of sym list (* sym | sym *) + | RangeG of sym * sym (* sym | ... | sym *) + | IterG of sym * iterexp (* sym iter *) + | AttrG of exp * sym (* exp : sym *) (* Definitions *) and arg = arg' phrase and arg' = - | ExpA of exp (* exp *) - | TypA of typ (* `syntax` typ *) - | DefA of id (* `def` defid *) - | GramA of sym (* `grammar` sym *) - -and bind = bind' phrase -and bind' = - | ExpB of id * typ - | TypB of id - | DefB of id * param list * typ - | GramB of id * param list * typ + | ExpA of exp (* exp *) + | TypA of typ (* `syntax` typ *) + | DefA of id (* `def` defid *) + | GramA of sym (* `grammar` sym *) and param = param' phrase and param' = - | ExpP of id * typ (* varid `:` typ *) - | TypP of id (* `syntax` varid *) - | DefP of id * param list * typ (* `def` defid params `:` typ *) - | GramP of id * typ (* `grammar` gramid params `:` typ *) + | ExpP of id * typ (* varid : typ *) + | TypP of id (* `syntax` varid *) + | DefP of id * param list * typ (* `def` defid params : typ *) + | GramP of id * param list * typ (* `grammar` gramid param : typ *) + +and quant = param and def = def' phrase and def' = @@ -143,19 +138,19 @@ and def' = and inst = inst' phrase and inst' = - | InstD of bind list * arg list * deftyp (* family instance clause *) + | InstD of quant list * arg list * deftyp (* family instance clause *) and rule = rule' phrase and rule' = - | RuleD of id * bind list * mixop * exp * prem list (* relation rule *) + | RuleD of id * quant list * mixop * exp * prem list (* relation rule *) and clause = clause' phrase and clause' = - | DefD of bind list * arg list * exp * prem list (* definition clause *) + | DefD of quant list * arg list * exp * prem list (* definition clause *) and prod = prod' phrase and prod' = - | ProdD of bind list * sym * exp * prem list (* grammar production *) + | ProdD of quant list * sym * exp * prem list (* grammar production *) and prem = prem' phrase and prem' = diff --git a/spectec/src/il/debug.ml b/spectec/src/il/debug.ml index e3dd99fe81..111d7f5e37 100644 --- a/spectec/src/il/debug.ml +++ b/spectec/src/il/debug.ml @@ -7,18 +7,22 @@ let il_id = Util.Source.it let il_atom = string_of_atom let il_mixop = string_of_mixop let il_iter = string_of_iter +let il_iterexp = string_of_iterexp let il_typ = string_of_typ -let il_deftyp = string_of_deftyp `H +let il_typbind (x, t) = "(" ^ il_id x ^ ":" ^ il_typ t ^ ")" +let il_typfield = string_of_typfield ~layout: `H +let il_typcase = string_of_typcase ~layout: `H +let il_deftyp = string_of_deftyp ~layout: `H let il_exp = string_of_exp let il_sym = string_of_sym let il_prod = string_of_prod +let il_clause = string_of_clause let il_prem = string_of_prem let il_arg = string_of_arg -let il_bind = string_of_bind +let il_args = string_of_args let il_param = string_of_param -let il_args = list il_arg -let il_binds = string_of_binds -let il_params = list il_param +let il_params = string_of_params +let il_quants = string_of_quants let il_def = string_of_def let il_free s = String.concat " " Free.[ diff --git a/spectec/src/il/dune b/spectec/src/il/dune index dc411c64e4..7ed9035a82 100644 --- a/spectec/src/il/dune +++ b/spectec/src/il/dune @@ -1,5 +1,5 @@ (library (name il) (libraries util zarith xl el) - (modules ast eq free subst iter env eval print debug valid) + (modules ast eq free fresh subst iter env eval print debug valid) ) diff --git a/spectec/src/il/eq.ml b/spectec/src/il/eq.ml index c002877536..fe6d6f54ea 100644 --- a/spectec/src/il/eq.ml +++ b/spectec/src/il/eq.ml @@ -19,8 +19,8 @@ let eq_pair eq_x eq_y (x1, y1) (x2, y2) = (* Ids *) -let eq_id i1 i2 = - i1.it = i2.it +let eq_id x1 x2 = + x1.it = x2.it let eq_atom atom1 atom2 = Atom.eq atom1 atom2 @@ -33,7 +33,7 @@ let eq_mixop op1 op2 = let rec eq_iter iter1 iter2 = match iter1, iter2 with - | ListN (e1, ido1), ListN (e2, ido2) -> eq_exp e1 e2 && eq_opt eq_id ido1 ido2 + | ListN (e1, xo1), ListN (e2, xo2) -> eq_exp e1 e2 && eq_opt eq_id xo1 xo2 | _, _ -> iter1 = iter2 @@ -41,8 +41,8 @@ let rec eq_iter iter1 iter2 = and eq_typ t1 t2 = match t1.it, t2.it with - | VarT (id1, as1), VarT (id2, as2) -> eq_id id1 id2 && eq_list eq_arg as1 as2 - | TupT xts1, TupT xts2 -> eq_list (eq_pair eq_exp eq_typ) xts1 xts2 + | VarT (x1, as1), VarT (x2, as2) -> eq_id x1 x2 && eq_list eq_arg as1 as2 + | TupT xts1, TupT xts2 -> eq_list (eq_pair eq_id eq_typ) xts1 xts2 | IterT (t11, iter1), IterT (t21, iter2) -> eq_typ t11 t21 && eq_iter iter1 iter2 | _, _ -> t1.it = t2.it @@ -54,18 +54,20 @@ and eq_deftyp dt1 dt2 = | VariantT tcs1, VariantT tcs2 -> eq_list eq_typcase tcs1 tcs2 | _, _ -> false -and eq_typfield (atom1, (_binds1, t1, prems1), _) (atom2, (_binds2, t2, prems2), _) = - eq_atom atom1 atom2 && eq_typ t1 t2 && eq_list eq_prem prems1 prems2 +and eq_typfield (atom1, (t1, qs1, prems1), _) (atom2, (t2, qs2, prems2), _) = + eq_atom atom1 atom2 && eq_typ t1 t2 && + eq_list eq_param qs1 qs2 && eq_list eq_prem prems1 prems2 -and eq_typcase (op1, (_binds1, t1, prems1), _) (op2, (_binds2, t2, prems2), _) = - eq_mixop op1 op2 && eq_typ t1 t2 && eq_list eq_prem prems1 prems2 +and eq_typcase (op1, (t1, qs1, prems1), _) (op2, (t2, qs2, prems2), _) = + eq_mixop op1 op2 && eq_typ t1 t2 && + eq_list eq_param qs1 qs2 && eq_list eq_prem prems1 prems2 (* Expressions *) and eq_exp e1 e2 = match e1.it, e2.it with - | VarE id1, VarE id2 -> eq_id id1 id2 + | VarE x1, VarE x2 -> eq_id x1 x2 | UnE (op1, ot1, e11), UnE (op2, ot2, e21) -> op1 = op2 && ot1 = ot2 && eq_exp e11 e21 | BinE (op1, ot1, e11, e12), BinE (op2, ot2, e21, e22) -> @@ -86,15 +88,18 @@ and eq_exp e1 e2 = | TupE es1, TupE es2 | ListE es1, ListE es2 -> eq_list eq_exp es1 es2 | StrE efs1, StrE efs2 -> eq_list eq_expfield efs1 efs2 - | DotE (e11, atom1), DotE (e21, atom2) -> eq_exp e11 e21 && eq_atom atom1 atom2 - | UncaseE (e1, op1), UncaseE (e2, op2) -> eq_mixop op1 op2 && eq_exp e1 e2 - | CallE (id1, as1), CallE (id2, as2) -> eq_id id1 id2 && eq_list eq_arg as1 as2 + | DotE (e11, atom1), DotE (e21, atom2) -> + eq_exp e11 e21 && eq_atom atom1 atom2 + | UncaseE (e1, op1), UncaseE (e2, op2) -> + eq_mixop op1 op2 && eq_exp e1 e2 + | CallE (x1, as1), CallE (x2, as2) -> eq_id x1 x2 && eq_list eq_arg as1 as2 | IterE (e11, iter1), IterE (e21, iter2) -> eq_exp e11 e21 && eq_iterexp iter1 iter2 | OptE eo1, OptE eo2 -> eq_opt eq_exp eo1 eo2 | ProjE (e1, i1), ProjE (e2, i2) -> eq_exp e1 e2 && i1 = i2 | TheE e1, TheE e2 -> eq_exp e1 e2 - | CaseE (op1, e1), CaseE (op2, e2) -> eq_mixop op1 op2 && eq_exp e1 e2 + | CaseE (op1, e1), CaseE (op2, e2) -> + eq_mixop op1 op2 && eq_exp e1 e2 | CvtE (e1, nt11, nt12), CvtE (e2, nt21, nt22) -> eq_exp e1 e2 && nt11 = nt21 && nt12 = nt22 | SubE (e1, t11, t12), SubE (e2, t21, t22) -> @@ -110,7 +115,8 @@ and eq_path p1 p2 = | IdxP (p11, e1), IdxP (p21, e2) -> eq_path p11 p21 && eq_exp e1 e2 | SliceP (p11, e11, e12), SliceP (p21, e21, e22) -> eq_path p11 p21 && eq_exp e11 e21 && eq_exp e12 e22 - | DotP (p11, atom1), DotP (p21, atom2) -> eq_path p11 p21 && eq_atom atom1 atom2 + | DotP (p11, atom1), DotP (p21, atom2) -> + eq_path p11 p21 && eq_atom atom1 atom2 | _, _ -> p1.it = p2.it and eq_iterexp (iter1, xes1) (iter2, xes2) = @@ -121,8 +127,8 @@ and eq_iterexp (iter1, xes1) (iter2, xes2) = and eq_sym g1 g2 = match g1.it, g2.it with - | VarG (id1, args1), VarG (id2, args2) -> - eq_id id1 id2 && eq_list eq_arg args1 args2 + | VarG (x1, args1), VarG (x2, args2) -> + eq_id x1 x2 && eq_list eq_arg args1 args2 | SeqG gs1, SeqG gs2 | AltG gs1, AltG gs2 -> eq_list eq_sym gs1 gs2 | RangeG (g11, g12), RangeG (g21, g22) -> eq_sym g11 g21 && eq_sym g12 g22 @@ -136,13 +142,13 @@ and eq_sym g1 g2 = and eq_prem prem1 prem2 = match prem1.it, prem2.it with - | RulePr (id1, op1, e1), RulePr (id2, op2, e2) -> - eq_id id1 id2 && eq_mixop op1 op2 && eq_exp e1 e2 + | RulePr (x1, op1, e1), RulePr (x2, op2, e2) -> + eq_id x1 x2 && eq_mixop op1 op2 && eq_exp e1 e2 | IfPr e1, IfPr e2 -> eq_exp e1 e2 | IterPr (prem1, e1), IterPr (prem2, e2) -> eq_prem prem1 prem2 && eq_iterexp e1 e2 - | LetPr (e1, e1', ids1), LetPr (e2, e2', ids2) -> - eq_exp e1 e2 && eq_exp e1' e2' && ids1 = ids2 + | LetPr (e1, e1', xs1), LetPr (e2, e2', xs2) -> + eq_exp e1 e2 && eq_exp e1' e2' && xs1 = xs2 | _, _ -> prem1.it = prem2.it @@ -152,6 +158,16 @@ and eq_arg a1 a2 = match a1.it, a2.it with | ExpA e1, ExpA e2 -> eq_exp e1 e2 | TypA t1, TypA t2 -> eq_typ t1 t2 - | DefA id1, DefA id2 -> eq_id id1 id2 + | DefA x1, DefA x2 -> eq_id x1 x2 | GramA g1, GramA g2 -> eq_sym g1 g2 | _, _ -> false + +and eq_param p1 p2 = + match p1.it, p2.it with + | ExpP (x1, t1), ExpP (x2, t2) -> eq_id x1 x2 && eq_typ t1 t2 + | TypP x1, TypP x2 -> eq_id x1 x2 + | DefP (x1, ps1, t1), DefP (x2, ps2, t2) -> + eq_id x1 x2 && eq_list eq_param ps1 ps2 && eq_typ t1 t2 + | GramP (x1, ps1, t1), GramP (x2, ps2, t2) -> + eq_id x1 x2 && eq_list eq_param ps1 ps2 && eq_typ t1 t2 + | _, _ -> false diff --git a/spectec/src/il/eq.mli b/spectec/src/il/eq.mli index ba61131680..18f0b69b97 100644 --- a/spectec/src/il/eq.mli +++ b/spectec/src/il/eq.mli @@ -12,6 +12,7 @@ val eq_path : path -> path -> bool val eq_sym : sym -> sym -> bool val eq_prem : prem -> prem -> bool val eq_arg : arg -> arg -> bool +val eq_param : param -> param -> bool val eq_opt : ('a -> 'a -> bool) -> 'a option -> 'a option -> bool val eq_list : ('a -> 'a -> bool) -> 'a list -> 'a list -> bool diff --git a/spectec/src/il/eval.ml b/spectec/src/il/eval.ml index a2cc93fad0..26d8d917c1 100644 --- a/spectec/src/il/eval.ml +++ b/spectec/src/il/eval.ml @@ -25,9 +25,6 @@ let (let*) = Option.bind let ($>) it e = {e with it} -let fst3 (x, _, _) = x -let snd3 (_, x, _) = x - let unordered s1 s2 = not Set.(subset s1 s2 || subset s2 s1) @@ -112,7 +109,7 @@ and reduce_typ_app' env id args at = function if !assume_coherent_matches then None else Error.error at "validation" ("undefined instance of partial type `" ^ id.it ^ "`") - | Some (ps, {it = InstD (_binds, args', dt); _}::insts') -> + | Some (ps, {it = InstD (_ps, args', dt); _}::insts') -> Debug.(log "il.reduce_typ_app'" (fun _ -> fmt "%s(%s) =: %s(%s)" id.it (il_args args) id.it (il_args args')) (fun r -> fmt "%s" (opt (Fun.const "!") r)) @@ -242,7 +239,12 @@ and reduce_exp env e : exp = let merge (atom1, e1) (atom2, e2) = assert (Atom.eq atom1 atom2); (atom1, reduce_exp env (CompE (e1, e2) $> e1)) - in StrE (List.map2 merge efs1 efs2) + in + (try + StrE (List.map2 merge efs1 efs2) + with Irred | Failure _ -> + CompE (e1', e2') + ) | _ -> CompE (e1', e2') ) $> e | MemE (e1, e2) -> @@ -264,13 +266,13 @@ and reduce_exp env e : exp = | _ -> LenE e1' ) $> e | TupE es -> TupE (List.map (reduce_exp env) es) $> e - | CallE (id, args) -> - let args' = List.map (reduce_arg env) args in + | CallE (id, as_) -> + let as' = List.map (reduce_arg env) as_ in let _ps, _t, clauses = Env.find_def env id in (* Allow for uninterpreted functions *) - if not !assume_coherent_matches && clauses = [] then CallE (id, args') $> e else - (match reduce_exp_call env id args' e.at clauses with - | None -> CallE (id, args') $> e + if not !assume_coherent_matches && clauses = [] then CallE (id, as') $> e else + (match reduce_exp_call env id as' e.at clauses with + | None -> CallE (id, as') $> e | Some e -> e ) | IterE (e1, iterexp) -> @@ -375,19 +377,17 @@ and reduce_exp env e : exp = reduce_exp env (SubE (e11', t11', t2') $> e) | TupE es' -> (match t1.it, t2.it with - | TupT ets1, TupT ets2 -> + | TupT xts1, TupT xts2 -> (match - List.fold_left2 (fun opt eI ((e1I, t1I), (e2I, t2I)) -> + List.fold_left2 (fun opt eI ((x1I, t1I), (x2I, t2I)) -> let* (s1, s2, res') = opt in let t1I' = Subst.subst_typ s1 t1I in let t2I' = Subst.subst_typ s2 t2I in - let e1I' = reduce_exp env (Subst.subst_exp s1 e1I) in - let e2I' = reduce_exp env (Subst.subst_exp s2 e2I) in - let* s1' = try match_exp env s1 eI e1I' with Irred -> None in - let* s2' = try match_exp env s2 eI e2I' with Irred -> None in + let s1' = Subst.add_varid s1 x1I eI in + let s2' = Subst.add_varid s2 x2I eI in let eI' = reduce_exp env (SubE (eI, t1I', t2I') $$ eI.at % t2I') in Some (s1', s2', eI'::res') - ) (Some (Subst.empty, Subst.empty, [])) es' (List.combine ets1 ets2) + ) (Some (Subst.empty, Subst.empty, [])) es' (List.combine xts1 xts2) with | Some (_, _, res') -> TupE (List.rev res') $> e | None -> SubE (e1', t1', t2') $> e @@ -406,7 +406,8 @@ and reduce_iter env = function and reduce_iterexp env (iter, xes) = (reduce_iter env iter, List.map (fun (id, e) -> id, reduce_exp env e) xes) -and reduce_expfield env (atom, e) : expfield = (atom, reduce_exp env e) +and reduce_expfield env (atom, e) : expfield = + (atom, reduce_exp env e) and reduce_path env e p f = match p.it with @@ -440,7 +441,10 @@ and reduce_path env e p f = match e'.it with | StrE efs -> StrE (List.map (fun (atomI, eI) -> - if Eq.eq_atom atomI atom then (atomI, f eI p1') else (atomI, eI)) efs) $> e' + if Eq.eq_atom atomI atom + then (atomI, f eI p1') + else (atomI, eI) + ) efs) $> e' | _ -> f e' (DotP (p1', atom) $> p) in @@ -462,7 +466,7 @@ and reduce_exp_call env id args at = function if !assume_coherent_matches then None else Error.error at "validation" ("undefined call to partial function `$" ^ id.it ^ "`") - | {it = DefD (_binds, args', e, prems); _}::clauses' -> + | {it = DefD (_ps, args', e, prems); _}::clauses' -> Debug.(log "il.reduce_exp_call" (fun _ -> fmt "$%s(%s) =: $%s(%s)" id.it (il_args args) id.it (il_args args')) (function None -> "-" | Some e' -> fmt "%s" (il_exp e')) @@ -631,6 +635,10 @@ and match_iter env s iter1 iter2 : subst option = (* Types *) and match_typ env s t1 t2 : subst option = + Debug.(log "il.match_typ" + (fun _ -> fmt "%s =: %s" (il_typ t1) (il_typ (Subst.subst_typ s t2))) + (fun r -> fmt "%s" (opt il_subst r)) + ) @@ fun _ -> match t1.it, t2.it with | _, VarT (id, []) when Subst.mem_typid s id -> match_typ env s t1 (Subst.subst_typ s t2) @@ -661,8 +669,8 @@ and match_typ env s t1 t2 : subst option = let* s' = match_typ env s t11 t21 in match_iter env s' iter1 iter2 | _, _ -> None -and match_typbind env s (e1, t1) (e2, t2) = - let* s' = match_exp env s e1 (Subst.subst_exp s e2) in +and match_typbind env s (x1, t1) (x2, t2) = + let s' = Subst.add_varid s x2 (VarE x1 $$ x1.at % t1) in let* s'' = match_typ env s' t1 (Subst.subst_typ s t2) in Some s'' @@ -832,8 +840,8 @@ and match_exp' env s e1 e2 : subst option = | _ -> false ) | VarE id1, _ -> - let t1 = reduce_typ env (Env.find_var env id1) in - sub_typ env t1 t21 || raise Irred + let t1 = Env.find_var env id1 in + sub_typ env (reduce_typ env t1) t21 || raise Irred | _, _ -> false then match_exp' env s {e1 with note = t21} e21 else None @@ -844,25 +852,25 @@ and match_exp' env s e1 e2 : subst option = and match_expfield env s (atom1, e1) (atom2, e2) = if not (Eq.eq_atom atom1 atom2) then None else - match_exp' env s e1 e2 + match_exp' env s e1 (Subst.subst_exp s e2) and match_iterexp env s (iter1, _ids1) (iter2, _ids2) = match_iter env s iter1 iter2 and eta_tup_exp env e : exp list option = - let ets = + let xts = match (reduce_typ env e.note).it with - | TupT ets -> ets + | TupT xts -> xts | _ -> assert false in let* es' = - List.fold_left (fun opt (eI, tI) -> + List.fold_left (fun opt (xI, tI) -> let* res', i, s = opt in let eI' = ProjE (e, i) $$ e.at % Subst.subst_typ s tI in - let* s' = try match_exp env s eI' eI with Irred -> None in + let s' = Subst.add_varid s xI eI' in Some (eI'::res', i + 1, s') - ) (Some ([], 0, Subst.empty)) ets |> Option.map fst3 |> Option.map List.rev + ) (Some ([], 0, Subst.empty)) xts |> Option.map Lib.fst3 |> Option.map List.rev in Some es' and eta_iter_exp env e : exp * iterexp = @@ -930,16 +938,12 @@ and equiv_typ env t1 t2 = | _, _ -> t1.it = t2.it -and equiv_tup env s ets1 ets2 = - match ets1, ets2 with - | (e1, t1)::ets1', (e2, t2)::ets2' -> +and equiv_tup env s xts1 xts2 = + match xts1, xts2 with + | (x1, t1)::xts1', (x2, t2)::xts2' -> equiv_typ env t1 (Subst.subst_typ s t2) && - (match match_exp env s e1 e2 with - | None -> false - | Some s' -> equiv_tup env s' ets1' ets2' - | exception Irred -> false - ) - | _, _ -> ets1 = ets2 + equiv_tup env (Subst.add_varid s x2 (VarE x1 $$ x1.at % t1)) xts1' xts2' + | _, _ -> xts1 = xts2 and equiv_iter env iter1 iter2 = match iter1, iter2 with @@ -1002,8 +1006,8 @@ and equiv_params env ps1 ps2 = | DefP (id1, ps1, t1), DefP (id2, ps2, t2) -> if not (equiv_functyp env (ps1, t1) (ps2, t2)) then None else Some (Subst.add_defid s id2 id1) - | GramP (id1, t1), GramP (id2, t2) -> - if not (equiv_typ env t1 t2) then None else + | GramP (id1, ps1, t1), GramP (id2, ps2, t2) -> + if not (equiv_functyp env (ps1, t1) (ps2, t2)) then None else Some (Subst.add_gramid s id2 (VarG (id1, []) $ p1.at)) | _, _ -> assert false ) (Some Subst.empty) ps1 ps2 @@ -1027,16 +1031,16 @@ and sub_typ env t1 t2 = | VarT _, VarT _ -> (match (reduce_typdef env t1').it, (reduce_typdef env t2').it with | StructT tfs1, StructT tfs2 -> - List.for_all (fun (atom, (_binds2, t2, prems2), _) -> + List.for_all (fun (atom, (t2, _qs2, prems2), _) -> match find_field tfs1 atom with - | Some (_binds1, t1, prems1) -> + | Some (t1, _qs1, prems1) -> sub_typ env t1 t2 && sub_prems env prems1 prems2 | None -> false ) tfs2 | VariantT tcs1, VariantT tcs2 -> - List.for_all (fun (mixop, (_binds1, t1, prems1), _) -> + List.for_all (fun (mixop, (t1, _qs1, prems1), _) -> match find_case tcs2 mixop with - | Some (_binds2, t2, prems2) -> + | Some (t2, _qs2, prems2) -> sub_typ env t1 t2 && sub_prems env prems1 prems2 | None -> false ) tcs1 @@ -1045,23 +1049,19 @@ and sub_typ env t1 t2 = | _, _ -> false -and sub_tup env s ets1 ets2 = - match ets1, ets2 with - | (e1, t1)::ets1', (e2, t2)::ets2' -> +and sub_tup env s xts1 xts2 = + match xts1, xts2 with + | (x1, t1)::xts1', (x2, t2)::xts2' -> sub_typ env t1 (Subst.subst_typ s t2) && - (match match_exp env s e1 e2 with - | None -> false - | Some s' -> sub_tup env s' ets1' ets2' - | exception Irred -> false - ) - | _, _ -> ets1 = ets2 + sub_tup env (Subst.add_varid s x2 (VarE x1 $$ x1.at % t1)) xts1' xts2' + | _, _ -> xts1 = xts2 and find_field tfs atom = - List.find_opt (fun (atom', _, _) -> Eq.eq_atom atom' atom) tfs |> Option.map snd3 + List.find_opt (fun (atom', _, _) -> Eq.eq_atom atom' atom) tfs |> Option.map Lib.snd3 and find_case tcs op = - List.find_opt (fun (op', _, _) -> Eq.eq_mixop op' op) tcs |> Option.map snd3 + List.find_opt (fun (op', _, _) -> Eq.eq_mixop op' op) tcs |> Option.map Lib.snd3 (* Type Disjointness *) @@ -1075,16 +1075,16 @@ and disj_typ env t1 t2 = (match (reduce_typdef env t1).it, (reduce_typdef env t2).it with | StructT tfs1, StructT tfs2 -> unordered (atoms tfs1) (atoms tfs2) || - List.exists (fun (atom, (_binds2, t2, _prems2), _) -> + List.exists (fun (atom, (t2, _qs2, _prems2), _) -> match find_field tfs1 atom with - | Some (_binds1, t1, _prems1) -> disj_typ env t1 t2 + | Some (t1, _qs1, _prems1) -> disj_typ env t1 t2 | None -> true ) tfs2 | VariantT tcs1, VariantT tcs2 -> Set.disjoint (mixops tcs1) (mixops tcs2) || - List.exists (fun (atom, (_binds1, t1, _prems1), _) -> + List.exists (fun (atom, (t1, _qs1, _prems1), _) -> match find_case tcs2 atom with - | Some (_binds2, t2, _prems2) -> disj_typ env t1 t2 + | Some (t2, _qs2, _prems2) -> disj_typ env t1 t2 | None -> false ) tcs1 | _, _ -> true @@ -1101,16 +1101,12 @@ and disj_typ env t1 t2 = | _, _ -> t1.it <> t2.it -and atoms xs = Set.of_list (List.map Print.string_of_atom (List.map fst3 xs)) -and mixops xs = Set.of_list (List.map Print.string_of_mixop (List.map fst3 xs)) +and atoms xs = Set.of_list (List.map Print.string_of_atom (List.map Lib.fst3 xs)) +and mixops xs = Set.of_list (List.map Print.string_of_mixop (List.map Lib.fst3 xs)) -and disj_tup env s ets1 ets2 = - match ets1, ets2 with - | (e1, t1)::ets1', (e2, t2)::ets2' -> +and disj_tup env s xts1 xts2 = + match xts1, xts2 with + | (x1, t1)::xts1', (x2, t2)::xts2' -> disj_typ env t1 (Subst.subst_typ s t2) || - (match match_exp env s e1 e2 with - | None -> false - | Some s' -> disj_tup env s' ets1' ets2' - | exception Irred -> false - ) - | _, _ -> ets1 = ets2 + disj_tup env (Subst.add_varid s x2 (VarE x1 $$ x1.at % t1)) xts1' xts2' + | _, _ -> xts1 = xts2 diff --git a/spectec/src/il/free.ml b/spectec/src/il/free.ml index bce500e9c6..9820ccf7c9 100644 --- a/spectec/src/il/free.ml +++ b/spectec/src/il/free.ml @@ -1,78 +1,7 @@ open Util.Source open Ast - -(* Data Structure *) - -module Set = Env.Set - -type sets = - {typid : Set.t; relid : Set.t; varid : Set.t; defid : Set.t; gramid : Set.t} - -let empty = - { typid = Set.empty; - relid = Set.empty; - varid = Set.empty; - defid = Set.empty; - gramid = Set.empty - } - -let union sets1 sets2 = - { typid = Set.union sets1.typid sets2.typid; - relid = Set.union sets1.relid sets2.relid; - varid = Set.union sets1.varid sets2.varid; - defid = Set.union sets1.defid sets2.defid; - gramid = Set.union sets1.gramid sets2.gramid; - } - -let diff sets1 sets2 = - { typid = Set.diff sets1.typid sets2.typid; - relid = Set.diff sets1.relid sets2.relid; - varid = Set.diff sets1.varid sets2.varid; - defid = Set.diff sets1.defid sets2.defid; - gramid = Set.diff sets1.gramid sets2.gramid; - } - -let (+) = union -let (-) = diff - -let subset sets1 sets2 = - Set.subset sets1.typid sets2.typid && - Set.subset sets1.relid sets2.relid && - Set.subset sets1.varid sets2.varid && - Set.subset sets1.defid sets2.defid && - Set.subset sets1.gramid sets2.gramid - -let disjoint sets1 sets2 = - Set.disjoint sets1.typid sets2.typid && - Set.disjoint sets1.relid sets2.relid && - Set.disjoint sets1.varid sets2.varid && - Set.disjoint sets1.defid sets2.defid && - Set.disjoint sets1.gramid sets2.gramid - -let free_opt free_x xo = Option.(value (map free_x xo) ~default:empty) -let free_list free_x xs = List.(fold_left (+) empty (map free_x xs)) -let free_pair free_x free_y (x, y) = free_x x + free_y y -let bound_list = free_list - -let rec free_list_dep free_x bound_x = function - | [] -> empty - | x::xs -> free_x x + (free_list_dep free_x bound_x xs - bound_x x) - - -(* Identifiers *) - -let free_typid id = {empty with typid = Set.singleton id.it} -let free_relid id = {empty with relid = Set.singleton id.it} -let free_varid id = {empty with varid = Set.singleton id.it} -let free_defid id = {empty with defid = Set.singleton id.it} -let free_gramid id = {empty with gramid = Set.singleton id.it} - -let bound_typid id = if id.it = "_" then empty else free_typid id -let bound_relid id = if id.it = "_" then empty else free_relid id -let bound_varid id = if id.it = "_" then empty else free_varid id -let bound_defid id = if id.it = "_" then empty else free_defid id -let bound_gramid id = if id.it = "_" then empty else free_gramid id +include Xl.Gen_free (* Iterations *) @@ -85,27 +14,31 @@ let rec free_iter iter = and bound_iter iter = match iter with | Opt | List | List1 -> empty - | ListN (_, id_opt) -> free_opt bound_varid id_opt + | ListN (_, xo) -> free_opt bound_varid xo (* Types *) and free_typ t = + Util.Debug_log.(log "il.free_typ" + (fun _ -> Print.string_of_typ t) + (fun s -> list quote (Set.elements s.typid @ Set.elements s.varid)) + ) @@ fun _ -> match t.it with - | VarT (id, as_) -> free_typid id + free_args as_ + | VarT (x, as_) -> free_typid x ++ free_args as_ | BoolT | NumT _ | TextT -> empty - | TupT ets -> free_typbinds ets - | IterT (t1, iter) -> free_typ t1 + free_iter iter + | TupT xts -> free_typbinds xts + | IterT (t1, iter) -> free_typ t1 ++ free_iter iter and bound_typ t = match t.it with - | VarT _ | BoolT | NumT _ | TextT -> empty - | TupT ets -> bound_list bound_typbind ets - | IterT (t1, _iter) -> bound_typ t1 - -and free_typbind (_e, t) = free_typ t -and bound_typbind (e, _t) = free_exp e + | TupT xts -> bound_typbinds xts + | _ -> empty + +and free_typbind (_, t) = free_typ t +and bound_typbind (x, _) = bound_varid x and free_typbinds xts = free_list_dep free_typbind bound_typbind xts +and bound_typbinds xts = free_list bound_typbind xts and free_deftyp dt = match dt.it with @@ -113,69 +46,73 @@ and free_deftyp dt = | StructT tfs -> free_list free_typfield tfs | VariantT tcs -> free_list free_typcase tcs -and free_typfield (_, (bs, t, prems), _) = - free_binds bs + (free_typ t + (free_prems prems - bound_typ t) - bound_binds bs) -and free_typcase (_, (bs, t, prems), _) = - free_binds bs + (free_typ t + (free_prems prems - bound_typ t) - bound_binds bs) +and free_typfield (_, (t, qs, prems), _) = + free_typ t ++ (free_quants qs ++ (free_prems prems -- bound_quants qs) -- bound_typ t) +and free_typcase (_, (t, qs, prems), _) = + free_typ t ++ (free_quants qs ++ (free_prems prems -- bound_quants qs) -- bound_typ t) (* Expressions *) and free_exp e = + Util.Debug_log.(log "il.free_exp" + (fun _ -> Print.string_of_exp e) + (fun s -> list quote (Set.elements s.typid @ Set.elements s.varid)) + ) @@ fun _ -> match e.it with - | VarE id -> free_varid id + | VarE x -> free_varid x | BoolE _ | NumE _ | TextE _ -> empty - | UnE (_, _, e1) | LiftE e1 | LenE e1 | ProjE (e1, _) | TheE e1 | DotE (e1, _) -> free_exp e1 + | UnE (_, _, e1) | LiftE e1 | LenE e1 | ProjE (e1, _) | TheE e1 -> free_exp e1 | BinE (_, _, e1, e2) | CmpE (_, _, e1, e2) - | IdxE (e1, e2) | CompE (e1, e2) | MemE (e1, e2) | CatE (e1, e2) -> free_exp e1 + free_exp e2 + | IdxE (e1, e2) | CompE (e1, e2) | MemE (e1, e2) | CatE (e1, e2) -> free_exp e1 ++ free_exp e2 | SliceE (e1, e2, e3) -> free_list free_exp [e1; e2; e3] | OptE eo -> free_opt free_exp eo | TupE es | ListE es -> free_list free_exp es - | UpdE (e1, p, e2) | ExtE (e1, p, e2) -> free_exp e1 + free_path p + free_exp e2 + | UpdE (e1, p, e2) | ExtE (e1, p, e2) -> free_exp e1 ++ free_path p ++ free_exp e2 | StrE efs -> free_list free_expfield efs - | CaseE (_, e1) | UncaseE (e1, _) -> free_exp e1 - | CallE (id, as1) -> free_defid id + free_args as1 - | IterE (e1, iter) -> (free_exp e1 - bound_iterexp iter) + free_iterexp iter + | DotE (e1, _) | CaseE (_, e1) | UncaseE (e1, _) -> free_exp e1 + | CallE (x, as1) -> free_defid x ++ free_args as1 + | IterE (e1, ite) -> (free_exp e1 -- bound_iterexp ite) ++ free_iterexp ite | CvtE (e1, _nt1, _nt2) -> free_exp e1 - | SubE (e1, t1, t2) -> free_exp e1 + free_typ t1 + free_typ t2 + | SubE (e1, t1, t2) -> free_exp e1 ++ free_typ t1 ++ free_typ t2 and free_expfield (_, e) = free_exp e and free_path p = match p.it with | RootP -> empty - | IdxP (p1, e) -> free_path p1 + free_exp e - | SliceP (p1, e1, e2) -> free_path p1 + free_exp e1 + free_exp e2 + | IdxP (p1, e) -> free_path p1 ++ free_exp e + | SliceP (p1, e1, e2) -> free_path p1 ++ free_exp e1 ++ free_exp e2 | DotP (p1, _atom) -> free_path p1 and free_iterexp (iter, xes) = - free_iter iter + free_list (free_pair free_varid free_exp) xes + free_iter iter ++ free_list free_exp (List.map snd xes) and bound_iterexp (iter, xes) = - bound_iter iter + free_list bound_varid (List.map fst xes) + bound_iter iter ++ free_list bound_varid (List.map fst xes) (* Grammars *) and free_sym g = match g.it with - | VarG (id, as_) -> free_gramid id + free_args as_ + | VarG (x, as_) -> free_gramid x ++ free_args as_ | NumG _ | TextG _ | EpsG -> empty | SeqG gs | AltG gs -> free_list free_sym gs - | RangeG (g1, g2) -> free_sym g1 + free_sym g2 - | IterG (g1, iter) -> (free_sym g1 - bound_iterexp iter) + free_iterexp iter - | AttrG (e, g1) -> free_exp e + free_sym g1 + | RangeG (g1, g2) -> free_sym g1 ++ free_sym g2 + | IterG (g1, ite) -> (free_sym g1 -- bound_iterexp ite) ++ free_iterexp ite + | AttrG (e, g1) -> free_exp e ++ free_sym g1 (* Premises *) and free_prem prem = match prem.it with - | RulePr (id, _op, e) -> free_relid id + free_exp e + | RulePr (x, _op, e) -> free_relid x ++ free_exp e | IfPr e -> free_exp e - | LetPr (e1, e2, _) -> free_exp e1 + free_exp e2 + | LetPr (e1, e2, _) -> free_exp e1 ++ free_exp e2 | ElsePr -> empty - | IterPr (prem1, iter) -> (free_prem prem1 - bound_iterexp iter) + free_iterexp iter + | IterPr (prem1, ite) -> (free_prem prem1 -- bound_iterexp ite) ++ free_iterexp ite and free_prems prems = free_list free_prem prems @@ -186,88 +123,80 @@ and free_arg a = match a.it with | ExpA e -> free_exp e | TypA t -> free_typ t - | DefA id -> free_defid id + | DefA x -> free_defid x | GramA g -> free_sym g -and free_bind b = - match b.it with - | ExpB (_, t) -> free_typ t - | TypB _ -> empty - | DefB (_, ps, t) -> free_params ps + (free_typ t - bound_params ps) - | GramB (_, ps, t) -> free_params ps + (free_typ t - bound_params ps) - and free_param p = + Util.Debug_log.(log "il.free_param" + (fun _ -> Print.string_of_param p) + (fun s -> list quote (Set.elements s.typid @ Set.elements s.varid)) + ) @@ fun _ -> match p.it with | ExpP (_, t) -> free_typ t | TypP _ -> empty - | DefP (_, ps, t) -> free_params ps + (free_typ t - bound_params ps) - | GramP (_, t) -> free_typ t - -and bound_bind b = - match b.it with - | ExpB (id, _) -> bound_varid id - | TypB id -> bound_typid id - | DefB (id, _, _) -> bound_defid id - | GramB (id, _, _) -> bound_gramid id + | DefP (_, ps, t) -> free_params ps ++ (free_typ t -- bound_params ps) + | GramP (_, ps, t) -> free_params ps ++ (free_typ t -- bound_params ps) and bound_param p = match p.it with - | ExpP (id, _) -> bound_varid id - | TypP id -> bound_typid id - | DefP (id, _, _) -> bound_defid id - | GramP (id, _) -> bound_gramid id + | ExpP (x, _) -> bound_varid x + | TypP x -> bound_typid x + | DefP (x, _, _) -> bound_defid x + | GramP (x, _, _) -> bound_gramid x + +and free_quant q = free_param q +and bound_quant q = bound_param q and free_args as_ = free_list free_arg as_ -and free_binds bs = free_list_dep free_bind bound_bind bs and free_params ps = free_list_dep free_param bound_param ps - -and bound_binds bs = free_list bound_bind bs +and free_quants qs = free_list_dep free_quant bound_quant qs and bound_params ps = free_list bound_param ps +and bound_quants qs = free_list bound_quant qs let free_inst inst = match inst.it with - | InstD (bs, as_, dt) -> - free_binds bs + (free_args as_ + free_deftyp dt - bound_binds bs) + | InstD (qs, as_, dt) -> + free_quants qs ++ (free_args as_ ++ free_deftyp dt -- bound_quants qs) let free_rule rule = match rule.it with - | RuleD (_id, bs, _op, e, prems) -> - free_binds bs + (free_exp e + free_prems prems - bound_binds bs) + | RuleD (_x, qs, _op, e, prems) -> + free_quants qs ++ (free_exp e ++ free_prems prems -- bound_quants qs) let free_clause clause = match clause.it with - | DefD (bs, as_, e, prems) -> - free_binds bs + (free_args as_ + free_exp e + free_prems prems - bound_binds bs) + | DefD (qs, as_, e, prems) -> + free_quants qs ++ (free_args as_ ++ free_exp e ++ free_prems prems -- bound_quants qs) let free_prod prod = match prod.it with - | ProdD (bs, g, e, prems) -> - free_binds bs + (free_sym g + free_exp e + free_prems prems - bound_binds bs) + | ProdD (qs, g, e, prems) -> + free_quants qs ++ (free_sym g ++ free_exp e ++ free_prems prems -- bound_quants qs) let free_hintdef hd = match hd.it with - | TypH (id, _) -> free_typid id - | RelH (id, _) -> free_relid id - | DecH (id, _) -> free_defid id - | GramH (id, _) -> free_gramid id + | TypH (x, _) -> free_typid x + | RelH (x, _) -> free_relid x + | DecH (x, _) -> free_defid x + | GramH (x, _) -> free_gramid x let rec free_def d = match d.it with - | TypD (_id, ps, insts) -> free_params ps + free_list free_inst insts - | RelD (_id, _mixop, t, rules) -> free_typ t + free_list free_rule rules - | DecD (_id, ps, t, clauses) -> - free_params ps + (free_typ t - bound_params ps) - + free_list free_clause clauses - | GramD (_id, ps, t, prods) -> - free_params ps + (free_typ t + free_list free_prod prods - bound_params ps) + | TypD (_x, ps, insts) -> free_params ps ++ free_list free_inst insts + | RelD (_x, _mixop, t, rules) -> free_typ t ++ free_list free_rule rules + | DecD (_x, ps, t, clauses) -> + free_params ps ++ (free_typ t -- bound_params ps) + ++ free_list free_clause clauses + | GramD (_x, ps, t, prods) -> + free_params ps ++ (free_typ t ++ free_list free_prod prods -- bound_params ps) | RecD ds -> free_list free_def ds | HintD hd -> free_hintdef hd let rec bound_def d = match d.it with - | TypD (id, _, _) -> bound_typid id - | RelD (id, _, _, _) -> bound_relid id - | DecD (id, _, _, _) -> bound_defid id - | GramD (id, _, _, _) -> bound_gramid id + | TypD (x, _, _) -> bound_typid x + | RelD (x, _, _, _) -> bound_relid x + | DecD (x, _, _, _) -> bound_defid x + | GramD (x, _, _, _) -> bound_gramid x | RecD ds -> free_list bound_def ds | HintD _ -> empty diff --git a/spectec/src/il/free.mli b/spectec/src/il/free.mli index ba5d3aaacb..1b962475c4 100644 --- a/spectec/src/il/free.mli +++ b/spectec/src/il/free.mli @@ -1,25 +1,12 @@ open Ast -module Set : Set.S with type elt = string with type t = Set.Make(String).t - -type sets = {typid : Set.t; relid : Set.t; varid : Set.t; defid : Set.t; gramid : Set.t} - -val empty : sets -val union : sets -> sets -> sets -val diff : sets -> sets -> sets - -val subset : sets -> sets -> bool -val disjoint : sets -> sets -> bool - -val free_opt : ('a -> sets) -> 'a option -> sets -val free_list : ('a -> sets) -> 'a list -> sets - -val free_varid : id -> sets +include module type of Xl.Gen_free val free_iter : iter -> sets val free_typ : typ -> sets val free_exp : exp -> sets val free_path : path -> sets +val free_sym : sym -> sets val free_prem : prem -> sets val free_arg : arg -> sets val free_def : def -> sets @@ -27,9 +14,19 @@ val free_rule : rule -> sets val free_clause : clause -> sets val free_prod : prod -> sets val free_deftyp : deftyp -> sets +val free_quant : quant -> sets val free_param : param -> sets -val bound_typbind : exp * typ -> sets -val bound_bind : bind -> sets +val free_prems : prem list -> sets +val free_args : arg list -> sets +val free_quants : param list -> sets +val free_params : param list -> sets + +val bound_iter : iter -> sets +val bound_iterexp : iterexp -> sets +val bound_quant : quant -> sets val bound_param : param -> sets val bound_def : def -> sets + +val bound_quants : quant list -> sets +val bound_params : param list -> sets diff --git a/spectec/src/il/fresh.ml b/spectec/src/il/fresh.ml new file mode 100644 index 0000000000..a13b3f7bf0 --- /dev/null +++ b/spectec/src/il/fresh.ml @@ -0,0 +1,65 @@ +open Util.Source + +module Map = Map.Make(String) + +let typids = ref Map.empty +let varids = ref Map.empty +let defids = ref Map.empty +let gramids = ref Map.empty + +let fresh_id map s = + if s = "_" then s else + let i = + match Map.find_opt s !map with + | None -> 1 + | Some i -> i + 1 + in + map := Map.add s i !map; + s ^ "#" ^ string_of_int i + +let refresh_id map x = + let s = + match String.rindex_opt x.it '#' with + | None -> x.it + | Some i -> String.sub x.it 0 i + in + fresh_id map s $ x.at + +let fresh_typid = fresh_id typids +let fresh_varid = fresh_id varids +let fresh_defid = fresh_id defids +let fresh_gramid = fresh_id gramids + +let refresh_typid = refresh_id typids +let refresh_varid = refresh_id varids +let refresh_defid = refresh_id defids +let refresh_gramid = refresh_id gramids + +(* +let refresh_quant s q = + match q.it with + | ExpP (x, t) -> + let x' = refresh_varid x in + let t' = Subst.subst_typ s t in + let s' = Subst.add_varid s x (VarE x' $$ x.at % t') in + s', ExpP (x', t') $ q.at + | TypP x -> + let x' = refresh_typid x in + let s' = Subst.add_typid s x (VarT (x', []) $ x.at) in + s', TypP x' $ q.at + | DefP (x, ps, t) -> + let x' = refresh_defid x in + let ps', s' = Subst.subst_params s ps in + let t' = Subst.subst_typ s' t in + let s' = Subst.add_defid s x x' in + s', DefP (x', ps', t') $ q.at + | GramP (x, ps, t) -> + let x' = refresh_gramid x in + let ps', s' = Subst.subst_params s ps in + let t' = Subst.subst_typ s' t in + let s' = Subst.add_gramid s x (VarG (x', []) $ x.at) in + s', GramP (x', ps', t') $ q.at + +let refresh_quants qs = + let s, qs' = List.fold_left_map refresh_quant Subst.empty qs in qs', s +*) diff --git a/spectec/src/il/fresh.mli b/spectec/src/il/fresh.mli new file mode 100644 index 0000000000..bae8cc561a --- /dev/null +++ b/spectec/src/il/fresh.mli @@ -0,0 +1,15 @@ +open Ast + +val fresh_typid : string -> string +val fresh_varid : string -> string +val fresh_defid : string -> string +val fresh_gramid : string -> string + +val refresh_typid : id -> id +val refresh_varid : id -> id +val refresh_defid : id -> id +val refresh_gramid : id -> id + +(* +val refresh_quants : quant list -> quant list * Subst.t +*) diff --git a/spectec/src/il/iter.ml b/spectec/src/il/iter.ml index 7db263fbcf..44b7fb80bd 100644 --- a/spectec/src/il/iter.ml +++ b/spectec/src/il/iter.ml @@ -5,6 +5,8 @@ open Xl module type Arg = sig + type scope + val visit_atom : atom -> unit val visit_mixop : mixop -> unit val visit_typid : id -> unit @@ -23,10 +25,15 @@ sig val visit_def : def -> unit val visit_hint : hint -> unit + + val scope_enter : id -> typ -> scope + val scope_exit : id -> scope -> unit end module Skip = struct + type scope = unit + let visit_atom _ = () let visit_mixop _ = () let visit_typid _ = () @@ -45,6 +52,9 @@ struct let visit_def _ = () let visit_hint _ = () + + let scope_enter _ _ = () + let scope_exit _ _ = () end @@ -85,7 +95,23 @@ let hints = list hint let rec iter it = match it with | Opt | List | List1 -> () - | ListN (e, xo) -> exp e; opt varid xo + | ListN _ -> assert false + +and iterexp : 'a. ('a -> unit) -> 'a -> _ -> unit = fun f body (it, xes) -> + let eo, xo, xts1 = + match it with + | ListN (e, Some x) -> Some e, Some x, [(x, NumT `NatT $ x.at)] + | ListN (e, None) -> Some e, None, [] + | _ -> None, None, [] + in + let xts = xts1 @ List.map (fun (x, e) -> x, e.note) xes in + let old_scopes = List.map (fun (x, t) -> scope_enter x t) xts in + f body; + opt varid xo; + list (pair varid ignore) xes; + List.iter2 (fun (x, _) scope -> scope_exit x scope) + (List.rev xts) (List.rev old_scopes); + opt exp eo; list (pair ignore exp) xes (* Types *) @@ -94,13 +120,19 @@ and dots _ = () and numtyp _nt = () and optyp = function #Bool.typ -> () | #Num.typ as nt -> numtyp nt -and typ t = +and typ ?(quants = []) ?(prems = []) t = visit_typ t; match t.it with | VarT (x, as_) -> typid x; args as_ | BoolT | TextT -> () | NumT nt -> numtyp nt - | TupT ets -> list (pair exp typ) ets + | TupT [] -> params quants; list prem prems + | TupT ((x, t)::xts) -> + typ t; + let scope = scope_enter x t in + varid x; + typ (TupT xts $ t.at) ~quants ~prems; + scope_exit x scope | IterT (t1, it) -> typ t1; iter it and deftyp t = @@ -110,8 +142,10 @@ and deftyp t = | StructT tfs -> list typfield tfs | VariantT tcs -> list typcase tcs -and typfield (at, (bs, t, prs), hs) = atom at; binds bs; typ t; prems prs; hints hs -and typcase (op, (bs, t, prs), hs) = mixop op; binds bs; typ t; prems prs; hints hs +and typfield (at, (t, quants, prems), hs) = + atom at; typ t ~quants ~prems; hints hs +and typcase (op, (t, quants, prems), hs) = + mixop op; typ t ~quants ~prems; hints hs (* Expressions *) @@ -137,10 +171,10 @@ and exp e = | SliceE (e1, e2, e3) -> exp e1; exp e2; exp e3 | UpdE (e1, p, e2) | ExtE (e1, p, e2) -> exp e1; path p; exp e2 | CallE (x, as_) -> defid x; args as_ - | IterE (e1, it) -> exp e1; iterexp it + | IterE (e1, it) -> iterexp exp e1 it | CvtE (e1, nt1, nt2) -> exp e1; numtyp nt1; numtyp nt2 | SubE (e1, t1, t2) -> exp e1; typ t1; typ t2 - + and expfield (at, e) = atom at; exp e and path p = @@ -151,8 +185,6 @@ and path p = | SliceP (p1, e1, e2) -> path p1; exp e1; exp e2 | DotP (p1, at) -> path p1; atom at -and iterexp (it, xes) = iter it; list (pair varid exp) xes - (* Grammars *) @@ -165,7 +197,7 @@ and sym g = | EpsG -> () | SeqG gs | AltG gs -> list sym gs | RangeG (g1, g2) -> sym g1; sym g2 - | IterG (g1, it) -> sym g1; iterexp it + | IterG (g1, it) -> iterexp sym g1 it | AttrG (e, g1) -> exp e; sym g1 @@ -177,7 +209,7 @@ and prem pr = | RulePr (x, op, e) -> relid x; mixop op; exp e | IfPr e -> exp e | ElsePr -> () - | IterPr (pr1, it) -> prem pr1; iterexp it + | IterPr (pr1, it) -> iterexp prem pr1 it | LetPr (e1, e2, _) -> exp e1; exp e2 and prems prs = list prem prs @@ -192,22 +224,14 @@ and arg a = | DefA x -> defid x | GramA g -> sym g -and bind b = - match b.it with - | ExpB (id, t) -> varid id; typ t - | TypB id -> typid id - | DefB (id, ps, t) -> defid id; params ps; typ t - | GramB (id, ps, t) -> gramid id; params ps; typ t - and param p = match p.it with | ExpP (x, t) -> varid x; typ t | TypP x -> typid x | DefP (x, ps, t) -> defid x; params ps; typ t - | GramP (x, t) -> gramid x; typ t + | GramP (x, ps, t) -> gramid x; params ps; typ t and args as_ = list arg as_ -and binds bs = list bind bs and params ps = list param ps let hintdef d = @@ -219,19 +243,19 @@ let hintdef d = let inst i = match i.it with - | InstD (bs, as_, dt) -> binds bs; args as_; deftyp dt + | InstD (ps, as_, dt) -> params ps; args as_; deftyp dt let rule r = match r.it with - | RuleD (x, bs, op, e, prs) -> ruleid x; binds bs; mixop op; exp e; prems prs + | RuleD (x, ps, op, e, prs) -> ruleid x; params ps; mixop op; exp e; prems prs let clause c = match c.it with - | DefD (bs, as_, e, prs) -> binds bs; args as_; exp e; prems prs + | DefD (ps, as_, e, prs) -> params ps; args as_; exp e; prems prs let prod p = match p.it with - | ProdD (bs, g, e, prs) -> binds bs; sym g; exp e; prems prs + | ProdD (ps, g, e, prs) -> params ps; sym g; exp e; prems prs let rec def d = visit_def d; diff --git a/spectec/src/il/print.ml b/spectec/src/il/print.ml index 3d3a69f95f..9657e871b4 100644 --- a/spectec/src/il/print.ml +++ b/spectec/src/il/print.ml @@ -10,6 +10,8 @@ let concat = String.concat let prefix s f x = s ^ f x let space f x = " " ^ f x ^ " " +let print_notes = ref false + (* Identifiers *) @@ -17,13 +19,11 @@ let is_alphanum = function | '0'..'9' | 'A'..'Z' | 'a'..'z' - | '_' | '.' | '\'' -> true + | '_' | '\'' | '#' -> true | _ -> false -let string_of_id id = - if String.for_all is_alphanum id.it - then id.it - else "`" ^ id.it ^ "`" +let string_of_id x = + if String.for_all is_alphanum x.it then x.it else "`" ^ x.it ^ "`" (* Operators *) @@ -41,7 +41,9 @@ let string_of_cmpop = function | #Num.cmpop as op -> Num.string_of_cmpop op let string_of_atom = Atom.to_string -let string_of_mixop = Mixop.to_string +let string_of_mixop mixop = + let s = Mixop.to_string mixop in + if String.for_all is_alphanum s then s else "`" ^ s ^ "`" (* Types *) @@ -52,23 +54,22 @@ let rec string_of_iter iter = | List -> "*" | List1 -> "+" | ListN (e, None) -> "^" ^ string_of_exp e - | ListN (e, Some id) -> - "^(" ^ string_of_id id ^ "<" ^ string_of_exp e ^ ")" + | ListN (e, Some x) -> "^(" ^ string_of_id x ^ "<" ^ string_of_exp e ^ ")" and string_of_numtyp = Num.string_of_typ and string_of_typ t = match t.it with - | VarT (id, as1) -> string_of_id id ^ string_of_args as1 + | VarT (x, as1) -> string_of_id x ^ string_of_args as1 | BoolT -> "bool" | NumT t -> string_of_numtyp t | TextT -> "text" - | TupT ets -> "(" ^ concat ", " (List.map string_of_typbind ets) ^ ")" + | TupT xts -> "(" ^ concat ", " (List.map string_of_typbind xts) ^ ")" | IterT (t1, iter) -> string_of_typ t1 ^ string_of_iter iter and string_of_typ_name t = match t.it with - | VarT (id, _) -> string_of_id id + | VarT (x, _) -> string_of_id x | _ -> assert false and string_of_typ_args t = @@ -77,37 +78,44 @@ and string_of_typ_args t = | TupT _ -> string_of_typ t | _ -> "(" ^ string_of_typ t ^ ")" -and string_of_typbind (e, t) = - match e.it with - | VarE {it = "_"; _} -> string_of_typ t - | _ -> string_of_exp e ^ " : " ^ string_of_typ t +and string_of_typbind (x, t) = + match x.it with + | "_" -> string_of_typ t + | _ -> string_of_id x ^ " : " ^ string_of_typ t -and string_of_deftyp layout dt = +and string_of_deftyp ?(layout = `H) dt = match dt.it with | AliasT t -> string_of_typ t | StructT tfs when layout = `H -> - "{" ^ concat ", " (List.map string_of_typfield tfs) ^ "}" + "{" ^ concat ", " (List.map (string_of_typfield ~layout) tfs) ^ "}" | StructT tfs -> - "\n{\n " ^ concat ",\n " (List.map string_of_typfield tfs) ^ "\n}" + "\n{\n " ^ concat ",\n " (List.map (string_of_typfield ~layout) tfs) ^ "\n}" | VariantT tcs when layout = `H -> - "| " ^ concat " | " (List.map string_of_typcase tcs) + "| " ^ concat " | " (List.map (string_of_typcase ~layout) tcs) | VariantT tcs -> - "\n | " ^ concat "\n | " (List.map string_of_typcase tcs) + "\n | " ^ concat "\n | " (List.map (string_of_typcase ~layout) tcs) -and string_of_typfield (atom, (bs, t, prems), _hints) = - string_of_mixop [[atom]] ^ string_of_binds bs ^ " " ^ string_of_typ t ^ - concat "" (List.map (prefix "\n -- " string_of_prem) prems) +and string_of_typfield ?(layout = `H) (atom, (t, qs, prems), _hints) = + string_of_mixop (Mixop.Atom atom) ^ " " ^ string_of_typ t ^ + if prems = [] then "" else + if layout = `H then " -- .." else + (if qs = [] then "" else " " ^ string_of_quants qs) ^ + concat "" (List.map (prefix "\n -- " string_of_prem) prems) -and string_of_typcase (op, (bs, t, prems), _hints) = - string_of_mixop op ^ string_of_binds bs ^ string_of_typ_args t ^ - concat "" (List.map (prefix "\n -- " string_of_prem) prems) +and string_of_typcase ?(layout = `H) (op, (t, qs, prems), _hints) = + string_of_mixop op ^ string_of_typ_args t ^ + if prems = [] then "" else + if layout = `H then " -- .." else + (if qs = [] then "" else " " ^ string_of_quants qs) ^ + concat "" (List.map (prefix "\n -- " string_of_prem) prems) (* Expressions *) and string_of_exp e = - match e.it with - | VarE id -> string_of_id id + (if !print_notes then "(" else "") ^ + (match e.it with + | VarE x -> string_of_id x | BoolE b -> string_of_bool b | NumE n -> Num.to_string n | TextE t -> "\"" ^ String.escaped t ^ "\"" @@ -128,16 +136,18 @@ and string_of_exp e = "[" ^ string_of_path p ^ " =++ " ^ string_of_exp e2 ^ "]" | StrE efs -> "{" ^ concat ", " (List.map string_of_expfield efs) ^ "}" | DotE (e1, atom) -> - string_of_exp e1 ^ "." ^ string_of_mixop [[atom]] ^ "_" ^ string_of_typ_name e1.note + string_of_exp e1 ^ "." ^ + string_of_mixop (Mixop.Atom atom) ^ "_" ^ string_of_typ_name e1.note | CompE (e1, e2) -> string_of_exp e1 ^ " +++ " ^ string_of_exp e2 | MemE (e1, e2) -> "(" ^ string_of_exp e1 ^ " <- " ^ string_of_exp e2 ^ ")" | LenE e1 -> "|" ^ string_of_exp e1 ^ "|" | TupE es -> "(" ^ string_of_exps ", " es ^ ")" - | CallE (id, as1) -> "$" ^ string_of_id id ^ string_of_args as1 + | CallE (x, as1) -> "$" ^ string_of_id x ^ string_of_args as1 | IterE (e1, iter) -> string_of_exp e1 ^ string_of_iterexp iter | ProjE (e1, i) -> string_of_exp e1 ^ "." ^ string_of_int i | UncaseE (e1, op) -> - string_of_exp e1 ^ "!" ^ string_of_mixop op ^ "_" ^ string_of_typ_name e1.note + string_of_exp e1 ^ "!" ^ + string_of_mixop op ^ "_" ^ string_of_typ_name e1.note | OptE eo -> "?(" ^ string_of_exps "" (Option.to_list eo) ^ ")" | TheE e1 -> "!(" ^ string_of_exp e1 ^ ")" | ListE es -> "[" ^ string_of_exps " " es ^ "]" @@ -149,6 +159,8 @@ and string_of_exp e = "(" ^ string_of_exp e1 ^ " : " ^ string_of_numtyp nt1 ^ " <:> " ^ string_of_numtyp nt2 ^ ")" | SubE (e1, t1, t2) -> "(" ^ string_of_exp e1 ^ " : " ^ string_of_typ t1 ^ " <: " ^ string_of_typ t2 ^ ")" + ) ^ + (if !print_notes then ")@[" ^ string_of_typ e.note ^ "]" else "") and string_of_exp_args e = match e.it with @@ -160,30 +172,34 @@ and string_of_exps sep es = concat sep (List.map string_of_exp es) and string_of_expfield (atom, e) = - string_of_mixop [[atom]] ^ " " ^ string_of_exp e + string_of_mixop (Mixop.Atom atom) ^ " " ^ string_of_exp e and string_of_path p = - match p.it with + (if !print_notes then "(" else "") ^ + (match p.it with | RootP -> "" | IdxP (p1, e) -> string_of_path p1 ^ "[" ^ string_of_exp e ^ "]" | SliceP (p1, e1, e2) -> string_of_path p1 ^ "[" ^ string_of_exp e1 ^ " : " ^ string_of_exp e2 ^ "]" | DotP ({it = RootP; note; _}, atom) -> - string_of_mixop [[atom]] ^ "_" ^ string_of_typ_name note + string_of_mixop (Mixop.Atom atom) ^ "_" ^ string_of_typ_name note | DotP (p1, atom) -> - string_of_path p1 ^ "." ^ string_of_mixop [[atom]] ^ "_" ^ string_of_typ_name p1.note + string_of_path p1 ^ "." ^ + string_of_mixop (Mixop.Atom atom) ^ "_" ^ string_of_typ_name p1.note + ) ^ + (if !print_notes then ")@[" ^ string_of_typ p.note ^ "]" else "") and string_of_iterexp (iter, xes) = string_of_iter iter ^ "{" ^ String.concat ", " - (List.map (fun (id, e) -> string_of_id id ^ " <- " ^ string_of_exp e) xes) ^ "}" + (List.map (fun (x, e) -> string_of_id x ^ " <- " ^ string_of_exp e) xes) ^ "}" (* Grammars *) and string_of_sym g = match g.it with - | VarG (id, args) -> string_of_id id ^ string_of_args args + | VarG (x, args) -> string_of_id x ^ string_of_args args | NumG n -> Printf.sprintf "0x%02X" n | TextG t -> "\"" ^ String.escaped t ^ "\"" | EpsG -> "eps" @@ -198,13 +214,13 @@ and string_of_sym g = and string_of_prem prem = match prem.it with - | RulePr (id, mixop, e) -> - string_of_id id ^ ": " ^ string_of_mixop mixop ^ string_of_exp_args e + | RulePr (x, mixop, e) -> + string_of_id x ^ ": " ^ string_of_mixop mixop ^ string_of_exp_args e | IfPr e -> "if " ^ string_of_exp e - | LetPr (e1, e2, ids) -> - let ids' = List.map (fun x -> x $ no_region) ids in + | LetPr (e1, e2, xs) -> + let xs' = List.map (fun x -> x $ no_region) xs in "where " ^ string_of_exp e1 ^ " = " ^ string_of_exp e2 ^ - " {" ^ (String.concat ", " (List.map string_of_id ids')) ^ "}" + " {" ^ (String.concat ", " (List.map string_of_id xs')) ^ "}" | ElsePr -> "otherwise" | IterPr ({it = IterPr _; _} as prem', iter) -> string_of_prem prem' ^ string_of_iterexp iter @@ -218,96 +234,90 @@ and string_of_arg a = match a.it with | ExpA e -> string_of_exp e | TypA t -> "syntax " ^ string_of_typ t - | DefA id -> "def $" ^ string_of_id id + | DefA x -> "def $" ^ string_of_id x | GramA g -> "grammar " ^ string_of_sym g and string_of_args = function | [] -> "" | as_ -> "(" ^ concat ", " (List.map string_of_arg as_) ^ ")" -and string_of_bind bind = - match bind.it with - | ExpB (id, t) -> string_of_id id ^ " : " ^ string_of_typ t - | TypB id -> "syntax " ^ string_of_id id - | DefB (id, ps, t) -> - "def $" ^ string_of_id id ^ string_of_params ps ^ " : " ^ string_of_typ t - | GramB (id, ps, t) -> - "grammar " ^ string_of_id id ^ string_of_params ps ^ " : " ^ string_of_typ t - -and string_of_binds = function - | [] -> "" - | bs -> "{" ^ concat ", " (List.map string_of_bind bs) ^ "}" - and string_of_param p = match p.it with - | ExpP (id, t) -> - (if string_of_id id = "_" then "" else string_of_id id ^ " : ") ^ string_of_typ t - | TypP id -> - "syntax " ^ string_of_id id - | DefP (id, ps, t) -> - "def $" ^ string_of_id id ^ string_of_params ps ^ " : " ^ string_of_typ t - | GramP (id, t) -> - "grammar " ^ string_of_id id ^ " : " ^ string_of_typ t + | ExpP (x, t) -> + (if string_of_id x = "_" then "" else string_of_id x ^ " : ") ^ string_of_typ t + | TypP x -> + "syntax " ^ string_of_id x + | DefP (x, ps, t) -> + "def $" ^ string_of_id x ^ string_of_params ps ^ " : " ^ string_of_typ t + | GramP (x, ps, t) -> + "grammar " ^ string_of_id x ^ string_of_params ps ^ " : " ^ string_of_typ t + +and string_of_quant q = string_of_param q and string_of_params = function | [] -> "" | ps -> "(" ^ concat ", " (List.map string_of_param ps) ^ ")" +and string_of_quants = function + | [] -> "" + | ps -> "{" ^ concat ", " (List.map string_of_quant ps) ^ "}" + + let region_comment ?(suppress_pos = false) indent at = if at = no_region then "" else let s = if suppress_pos then at.left.file else string_of_region at in indent ^ ";; " ^ s ^ "\n" -let string_of_inst ?(suppress_pos = false) id inst = +let string_of_inst ?(suppress_pos = false) x inst = match inst.it with - | InstD (bs, as_, dt) -> + | InstD (qs, as_, dt) -> "\n" ^ region_comment ~suppress_pos " " inst.at ^ - " syntax " ^ string_of_id id ^ string_of_binds bs ^ string_of_args as_ ^ " = " ^ - string_of_deftyp `V dt ^ "\n" + " syntax " ^ string_of_id x ^ string_of_quants qs ^ string_of_args as_ ^ " = " ^ + string_of_deftyp ~layout: `V dt ^ "\n" let string_of_rule ?(suppress_pos = false) rule = match rule.it with - | RuleD (id, bs, mixop, e, prems) -> - let id' = if id.it = "" then "_" else string_of_id id in + | RuleD (x, qs, mixop, e, prems) -> + let x' = if x.it = "" then "_" else string_of_id x in "\n" ^ region_comment ~suppress_pos " " rule.at ^ - " rule " ^ id' ^ string_of_binds bs ^ ":\n " ^ + " rule " ^ x' ^ string_of_quants qs ^ ":\n " ^ string_of_mixop mixop ^ string_of_exp_args e ^ concat "" (List.map (prefix "\n -- " string_of_prem) prems) -let string_of_clause ?(suppress_pos = false) id clause = +let string_of_clause ?(suppress_pos = false) x clause = match clause.it with - | DefD (bs, as_, e, prems) -> + | DefD (qs, as_, e, prems) -> "\n" ^ region_comment ~suppress_pos " " clause.at ^ - " def $" ^ string_of_id id ^ string_of_binds bs ^ string_of_args as_ ^ " = " ^ + " def $" ^ string_of_id x ^ string_of_quants qs ^ string_of_args as_ ^ " = " ^ string_of_exp e ^ concat "" (List.map (prefix "\n -- " string_of_prem) prems) let string_of_prod ?(suppress_pos = false) prod = match prod.it with - | ProdD (bs, g, e, prems) -> + | ProdD (qs, g, e, prems) -> "\n" ^ region_comment ~suppress_pos " " prod.at ^ - " prod" ^ string_of_binds bs ^ " " ^ string_of_sym g ^ " => " ^ + " prod" ^ string_of_quants qs ^ " " ^ string_of_sym g ^ " => " ^ string_of_exp e ^ concat "" (List.map (prefix "\n -- " string_of_prem) prems) let rec string_of_def ?(suppress_pos = false) d = let pre = "\n" ^ region_comment ~suppress_pos "" d.at in match d.it with - | TypD (id, _ps, [{it = InstD (bs, as_, dt); _}]) -> - pre ^ "syntax " ^ string_of_id id ^ string_of_binds bs ^ string_of_args as_ ^ " = " ^ - string_of_deftyp `V dt ^ "\n" - | TypD (id, ps, insts) -> - pre ^ "syntax " ^ string_of_id id ^ string_of_params ps ^ - concat "\n" (List.map (string_of_inst ~suppress_pos id) insts) ^ "\n" - | RelD (id, mixop, t, rules) -> - pre ^ "relation " ^ string_of_id id ^ ": " ^ + | TypD (x, _ps, [{it = InstD (qs, as_, dt); _}]) -> + pre ^ "syntax " ^ string_of_id x ^ string_of_quants qs ^ string_of_args as_ ^ " = " ^ + string_of_deftyp ~layout: `V dt ^ "\n" + | TypD (x, ps, insts) -> + pre ^ "syntax " ^ string_of_id x ^ string_of_params ps ^ + concat "\n" (List.map (string_of_inst ~suppress_pos x) insts) ^ "\n" + | RelD (x, mixop, t, rules) -> + pre ^ "relation " ^ string_of_id x ^ ": " ^ string_of_mixop mixop ^ string_of_typ_args t ^ concat "\n" (List.map (string_of_rule ~suppress_pos) rules) ^ "\n" - | DecD (id, ps, t, clauses) -> - pre ^ "def $" ^ string_of_id id ^ string_of_params ps ^ " : " ^ string_of_typ t ^ - concat "" (List.map (string_of_clause ~suppress_pos id) clauses) ^ "\n" - | GramD (id, ps, t, prods) -> - pre ^ "grammar " ^ string_of_id id ^ string_of_params ps ^ " : " ^ string_of_typ t ^ + | DecD (x, ps, t, clauses) -> + pre ^ "def $" ^ string_of_id x ^ string_of_params ps ^ " : " ^ string_of_typ t ^ + concat "" (List.map (string_of_clause ~suppress_pos x) clauses) ^ "\n" + | GramD (x, ps, t, prods) -> + pre ^ "grammar " ^ string_of_id x ^ string_of_params ps ^ " : " ^ string_of_typ t ^ concat "" (List.map (string_of_prod ~suppress_pos) prods) ^ "\n" | RecD ds -> pre ^ "rec {\n" ^ concat "" (List.map string_of_def ds) ^ "}" ^ "\n" diff --git a/spectec/src/il/print.mli b/spectec/src/il/print.mli index 4f6cd93598..0002db4db4 100644 --- a/spectec/src/il/print.mli +++ b/spectec/src/il/print.mli @@ -7,6 +7,7 @@ val string_of_binop : binop -> string val string_of_cmpop : cmpop -> string val string_of_mixop : mixop -> string val string_of_iter : iter -> string +val string_of_iterexp : iterexp -> string val string_of_numtyp : numtyp -> string val string_of_typ : typ -> string val string_of_typ_name : typ -> string @@ -15,13 +16,19 @@ val string_of_path : path -> string val string_of_sym : sym -> string val string_of_prem : prem -> string val string_of_arg : arg -> string -val string_of_bind : bind -> string -val string_of_binds : bind list -> string +val string_of_args : arg list -> string val string_of_param : param -> string -val string_of_deftyp : [`H | `V] -> deftyp -> string -val string_of_def : ?suppress_pos:bool -> def -> string -val string_of_rule : ?suppress_pos:bool -> rule -> string -val string_of_prod : ?suppress_pos:bool -> prod -> string -val string_of_inst : ?suppress_pos:bool -> id -> inst -> string -val string_of_clause : ?suppress_pos:bool -> id -> clause -> string -val string_of_script : ?suppress_pos:bool -> script -> string +val string_of_params : param list -> string +val string_of_quant : quant -> string +val string_of_quants : quant list -> string +val string_of_typfield : ?layout: [`H | `V] -> typfield -> string +val string_of_typcase : ?layout: [`H | `V] -> typcase -> string +val string_of_deftyp : ?layout: [`H | `V] -> deftyp -> string +val string_of_def : ?suppress_pos: bool -> def -> string +val string_of_rule : ?suppress_pos: bool -> rule -> string +val string_of_prod : ?suppress_pos: bool -> prod -> string +val string_of_inst : ?suppress_pos: bool -> id -> inst -> string +val string_of_clause : ?suppress_pos: bool -> id -> clause -> string +val string_of_script : ?suppress_pos: bool -> script -> string + +val print_notes : bool ref diff --git a/spectec/src/il/subst.ml b/spectec/src/il/subst.ml index 7e1bde0280..d2707a920a 100644 --- a/spectec/src/il/subst.ml +++ b/spectec/src/il/subst.ml @@ -17,36 +17,35 @@ let empty = gramid = Map.empty; } -let mem_varid s id = Map.mem id.it s.varid -let mem_typid s id = Map.mem id.it s.typid -let mem_defid s id = Map.mem id.it s.defid -let mem_gramid s id = Map.mem id.it s.gramid - -let find_varid s id = Map.find id.it s.varid -let find_typid s id = Map.find id.it s.typid -let find_defid s id = Map.find id.it s.defid -let find_gramid s id = Map.find id.it s.gramid - -let add_varid s id e = if id.it = "_" then s else {s with varid = Map.add id.it e s.varid} -let add_typid s id t = if id.it = "_" then s else {s with typid = Map.add id.it t s.typid} -let add_defid s id x = if id.it = "_" then s else {s with defid = Map.add id.it x s.defid} -let add_gramid s id g = if id.it = "_" then s else {s with gramid = Map.add id.it g s.gramid} - -let remove_varid s id = if id.it = "_" then s else {s with varid = Map.remove id.it s.varid} -let remove_typid s id = if id.it = "_" then s else {s with typid = Map.remove id.it s.typid} -let remove_defid s id = if id.it = "_" then s else {s with defid = Map.remove id.it s.defid} -let remove_gramid s id = if id.it = "_" then s else {s with gramid = Map.remove id.it s.gramid} +let mem_varid s x = Map.mem x.it s.varid +let mem_typid s x = Map.mem x.it s.typid +let mem_defid s x = Map.mem x.it s.defid +let mem_gramid s x = Map.mem x.it s.gramid + +let find_varid s x = Map.find x.it s.varid +let find_typid s x = Map.find x.it s.typid +let find_defid s x = Map.find x.it s.defid +let find_gramid s x = Map.find x.it s.gramid + +let add_varid s x e = if x.it = "_" then s else {s with varid = Map.add x.it e s.varid} +let add_typid s x t = if x.it = "_" then s else {s with typid = Map.add x.it t s.typid} +let add_defid s x x' = if x.it = "_" then s else {s with defid = Map.add x.it x' s.defid} +let add_gramid s x g = if x.it = "_" then s else {s with gramid = Map.add x.it g s.gramid} + +let remove_varid s x = if x.it = "_" then s else {s with varid = Map.remove x.it s.varid} +let remove_typid s x = if x.it = "_" then s else {s with typid = Map.remove x.it s.typid} +let remove_defid s x = if x.it = "_" then s else {s with defid = Map.remove x.it s.defid} +let remove_gramid s x = if x.it = "_" then s else {s with gramid = Map.remove x.it s.gramid} let union s1 s2 = { varid = Map.union (fun _ _e1 e2 -> Some e2) s1.varid s2.varid; typid = Map.union (fun _ _t1 t2 -> Some t2) s1.typid s2.typid; defid = Map.union (fun _ _x1 x2 -> Some x2) s1.defid s2.defid; - gramid = Map.union (fun _ _x1 x2 -> Some x2) s1.gramid s2.gramid; + gramid = Map.union (fun _ _g1 g2 -> Some g2) s1.gramid s2.gramid; } -let remove_varid' s id' = {s with varid = Map.remove id' s.varid} -let remove_varids s ids' = - Free.Set.(fold (fun id' s -> remove_varid' s id') ids' s) +let remove_varid' s x' = {s with varid = Map.remove x' s.varid} +let remove_varids s xs' = Free.Set.(fold (fun x' s -> remove_varid' s x') xs' s) (* Helpers *) @@ -64,52 +63,73 @@ let rec subst_list_dep subst_x bound_x s = function (* Identifiers *) -let subst_varid s id = - match Map.find_opt id.it s.varid with - | None -> id - | Some {it = VarE id'; _} -> id' - | Some _ -> raise (Invalid_argument "subst_varid") +let subst_defid s x = + match Map.find_opt x.it s.defid with + | None -> x + | Some x' -> x' -let subst_defid s id = - match Map.find_opt id.it s.defid with - | None -> id - | Some id' -> id' - -let subst_gramid s id = - match Map.find_opt id.it s.gramid with - | None -> id - | Some {it = VarG (id', []); _} -> id' - | Some _ -> raise (Invalid_argument "subst_varid") +let subst_gramid s x = + match Map.find_opt x.it s.gramid with + | None -> x + | Some {it = VarG (x', []); _} -> x' + | Some _ -> raise (Invalid_argument "subst_gramid") (* Iterations *) let rec subst_iter s iter = match iter with - | Opt | List | List1 -> iter, s - | ListN (e, id_opt) -> - ListN (subst_exp s e, subst_opt subst_varid s id_opt), - Option.fold id_opt ~none:s ~some:(remove_varid s) + | Opt | List | List1 -> iter + | ListN (e, xo) -> ListN (subst_exp s e, xo) + +and subst_iterexp : 'a. subst -> (subst -> 'a -> 'a) -> 'a -> _ -> 'a * _ = + fun s f body (it, xes) -> + let it', xxts1 = + match it with + | ListN (e, Some x) -> + let x' = Fresh.refresh_varid x in + ListN (e, Some x'), [(x, x', NumT `NatT $ x.at)] + | _ -> it, [] + in + let it'' = subst_iter s it' in + let xes' = List.map (fun (x, e) -> Fresh.refresh_varid x, subst_exp s e) xes in + let xxts = List.map2 (fun (x, _) (x', e') -> x, x', e'.note) xes xes' in + let s' = + List.fold_left (fun s (x, x', t) -> + add_varid s x (VarE x' $$ x'.at % t) + ) s (xxts1 @ xxts) + in + f s' body, + (it'', xes') (* Types *) and subst_typ s t = (match t.it with - | VarT (id, as_) -> - (match Map.find_opt id.it s.typid with - | None -> VarT (id, subst_args s as_) + | VarT (x, as_) -> + (match Map.find_opt x.it s.typid with + | None -> VarT (x, subst_args s as_) | Some t' -> assert (as_ = []); t'.it (* We do not support higher-order substitutions yet *) ) | BoolT | NumT _ | TextT -> t.it - | TupT ets -> TupT (fst (subst_list_dep subst_typbind Free.bound_typbind s ets)) - | IterT (t1, iter) -> - let iter', s' = subst_iter s iter in - IterT (subst_typ s' t1, iter') + | TupT xts -> TupT (fst (subst_tup_typ s xts)) + | IterT (t1, it) -> IterT (subst_typ s t1, subst_iter s it) ) $ t.at -and subst_typbind s (e, t) = - (e, subst_typ s t) +and subst_typ' s t = + match t.it with + | TupT xts -> let xts', s' = subst_tup_typ s xts in TupT xts' $ t.at, s' + | _ -> subst_typ s t, s + +and subst_tup_typ s = function + | [] -> [], s + | (x, t)::xts -> + let x' = Fresh.refresh_varid x in + let t' = subst_typ s t in + let s' = add_varid s x (VarE x' $$ x'.at % t') in + let xts', s'' = subst_tup_typ s' xts in + (x', t') :: xts', s'' and subst_deftyp s dt = (match dt.it with @@ -118,22 +138,24 @@ and subst_deftyp s dt = | VariantT tcs -> VariantT (subst_list subst_typcase s tcs) ) $ dt.at -and subst_typfield s (atom, (bs, t, prems), hints) = - let bs', s' = subst_binds s bs in - (atom, (bs', subst_typ s' t, subst_list subst_prem s' prems), hints) +and subst_typfield s (atom, (t, qs, prems), hints) = + let t', s' = subst_typ' s t in + let qs', s'' = subst_quants s' qs in + (atom, (t', qs', subst_list subst_prem s'' prems), hints) -and subst_typcase s (op, (bs, t, prems), hints) = - let bs', s' = subst_binds s bs in - (op, (bs', subst_typ s' t, subst_list subst_prem s' prems), hints) +and subst_typcase s (op, (t, qs, prems), hints) = + let t', s' = subst_typ' s t in + let qs', s'' = subst_quants s' qs in + (op, (t', qs', subst_list subst_prem s'' prems), hints) (* Expressions *) and subst_exp s e = (match e.it with - | VarE id -> - (match Map.find_opt id.it s.varid with - | None -> VarE id + | VarE x -> + (match Map.find_opt x.it s.varid with + | None -> VarE x | Some e' -> e'.it ) | BoolE _ | NumE _ | TextE _ -> e.it @@ -150,10 +172,10 @@ and subst_exp s e = | MemE (e1, e2) -> MemE (subst_exp s e1, subst_exp s e2) | LenE e1 -> LenE (subst_exp s e1) | TupE es -> TupE (subst_list subst_exp s es) - | CallE (id, as_) -> CallE (subst_defid s id, subst_args s as_) + | CallE (x, as_) -> CallE (subst_defid s x, subst_args s as_) | IterE (e1, iterexp) -> - let it', s' = subst_iterexp s iterexp in - IterE (subst_exp s' e1, it') + let e1', it' = subst_iterexp s subst_exp e1 iterexp in + IterE (e1', it') | ProjE (e1, i) -> ProjE (subst_exp s e1, i) | UncaseE (e1, op) -> let e1' = subst_exp s e1 in @@ -182,26 +204,25 @@ and subst_path s p = | DotP (p1, atom) -> DotP (subst_path s p1, atom) ) $$ p.at % subst_typ s p.note -and subst_iterexp s (iter, xes) = - (* TODO(3, rossberg): This is assuming expressions in s are closed, is that okay? *) - let iter', s' = subst_iter s iter in - (iter', List.map (fun (id, e) -> (id, subst_exp s e)) xes), - List.fold_left remove_varid s' (List.map fst xes) - (* Grammars *) and subst_sym s g = (match g.it with - | VarG (id, args) -> VarG (subst_gramid s id, List.map (subst_arg s) args) + | VarG (x, []) -> + (match Map.find_opt x.it s.gramid with + | None -> VarG (x, []) + | Some g' -> g'.it + ) + | VarG (x, args) -> VarG (subst_gramid s x, List.map (subst_arg s) args) | NumG _ | TextG _ -> g.it | EpsG -> EpsG | SeqG gs -> SeqG (subst_list subst_sym s gs) | AltG gs -> AltG (subst_list subst_sym s gs) | RangeG (g1, g2) -> RangeG (subst_sym s g1, subst_sym s g2) | IterG (g1, iterexp) -> - let it', s' = subst_iterexp s iterexp in - IterG (subst_sym s' g1, it') + let g1', it' = subst_iterexp s subst_sym g1 iterexp in + IterG (g1', it') | AttrG (e, g1) -> AttrG (subst_exp s e, subst_sym s g1) ) $ g.at @@ -210,13 +231,13 @@ and subst_sym s g = and subst_prem s prem = (match prem.it with - | RulePr (id, op, e) -> RulePr (id, op, subst_exp s e) + | RulePr (x, op, e) -> RulePr (x, op, subst_exp s e) | IfPr e -> IfPr (subst_exp s e) | ElsePr -> ElsePr | IterPr (prem1, iterexp) -> - let it', s' = subst_iterexp s iterexp in - IterPr (subst_prem s' prem1, it') - | LetPr (e1, e2, ids) -> LetPr (subst_exp s e1, subst_exp s e2, ids) + let prem1', it' = subst_iterexp s subst_prem prem1 iterexp in + IterPr (prem1', it') + | LetPr (e1, e2, xs) -> LetPr (subst_exp s e1, subst_exp s e2, xs) ) $ prem.at @@ -226,35 +247,25 @@ and subst_arg s a = (match a.it with | ExpA e -> ExpA (subst_exp s e) | TypA t -> TypA (subst_typ s t) - | DefA id -> DefA (subst_defid s id) + | DefA x -> DefA (subst_defid s x) | GramA g -> GramA (subst_sym s g) ) $ a.at -and subst_bind s b = - (match b.it with - | ExpB (id, t) -> ExpB (id, subst_typ s t) - | TypB id -> TypB id - | DefB (id, ps, t) -> - let ps', s' = subst_params s ps in - DefB (id, ps', subst_typ s' t) - | GramB (id, ps, t) -> - let ps', s' = subst_params s ps in - GramB (id, ps', subst_typ s' t) - ) $ b.at - and subst_param s p = (match p.it with - | ExpP (id, t) -> ExpP (id, subst_typ s t) - | TypP id -> TypP id - | DefP (id, ps, t) -> + | ExpP (x, t) -> ExpP (x, subst_typ s t) + | TypP x -> TypP x + | DefP (x, ps, t) -> + let ps', s' = subst_params s ps in + DefP (x, ps', subst_typ s' t) + | GramP (x, ps, t) -> let ps', s' = subst_params s ps in - DefP (id, ps', subst_typ s' t) - | GramP (id, t) -> GramP (id, subst_typ s t) + GramP (x, ps', subst_typ s' t) ) $ p.at and subst_args s as_ = subst_list subst_arg s as_ -and subst_binds s bs = subst_list_dep subst_bind Free.bound_bind s bs and subst_params s ps = subst_list_dep subst_param Free.bound_param s ps +and subst_quants s ps = subst_list_dep subst_param Free.bound_quant s ps (* Optimizations *) diff --git a/spectec/src/il/subst.mli b/spectec/src/il/subst.mli index 37c98645be..c8fd8fc5d8 100644 --- a/spectec/src/il/subst.mli +++ b/spectec/src/il/subst.mli @@ -1,6 +1,6 @@ open Ast -module Map : Map.S with type key = string with type 'a t = 'a Map.Make(String).t +module Map : module type of Map.Make(String) type subst = {varid : exp Map.t; typid : typ Map.t; defid : id Map.t; gramid : sym Map.t} type t = subst @@ -38,10 +38,8 @@ val subst_param : subst -> param -> param val subst_deftyp : subst -> deftyp -> deftyp val subst_typcase : subst -> typcase -> typcase val subst_typfield : subst -> typfield -> typfield -val subst_typbind : subst -> exp * typ -> exp * typ val subst_args : subst -> arg list -> arg list -val subst_binds : subst -> bind list -> bind list * subst val subst_params : subst -> param list -> param list * subst val subst_list : (subst -> 'a -> 'a) -> subst -> 'a list -> 'a list diff --git a/spectec/src/il/valid.ml b/spectec/src/il/valid.ml index 86ef948a29..936464d768 100644 --- a/spectec/src/il/valid.ml +++ b/spectec/src/il/valid.ml @@ -12,8 +12,6 @@ let error at msg = Error.error at "validation" msg (* Environment *) -let local_env envr = ref !envr - let find_field fs atom at = match List.find_opt (fun (atom', _, _) -> Eq.eq_atom atom' atom) fs with | Some (_, x, _) -> x @@ -63,9 +61,9 @@ let as_list_typ phrase env dir t at : typ = | IterT (t1, (List | List1 | ListN _)) -> t1 | _ -> as_error at phrase dir t "(_)*" -let as_tup_typ phrase env dir t at : (exp * typ) list = +let as_tup_typ phrase env dir t at : (id * typ) list = match expand_typ env t with - | TupT ets -> ets + | TupT xts -> xts | _ -> as_error at phrase dir t "(_,...,_)" @@ -83,10 +81,20 @@ let rec as_comp_typ phrase env dir t at = match expand_typdef env t with | AliasT {it = IterT _; _} -> () | StructT tfs -> - List.iter (fun (_, (_, t, _), _) -> as_comp_typ phrase env dir t at) tfs + List.iter (fun (_, (t, _, _), _) -> as_comp_typ phrase env dir t at) tfs | _ -> error at (phrase ^ "'s type `" ^ string_of_typ t ^ "` is not composable") +let proj_tup_typ i xts e at = + let rec loop i xts s = + match i, xts with + | _, [] -> error at "invalid tuple projection" + | 0, (_, tI)::_ -> Subst.subst_typ s tI + | i, (xI, tI)::xts' -> + let eI = ProjE (e, i) $$ at % Subst.subst_typ s tI in + loop (i - 1) xts' (Subst.add_varid s xI eI) + in loop i xts Subst.empty + (* Type Equivalence and Subtyping *) @@ -157,6 +165,10 @@ let valid_list valid_x_y env xs ys at = string_of_int (List.length ys) ^ ", got " ^ string_of_int (List.length xs)); List.iter2 (valid_x_y env) xs ys +let rec valid_binders valid_x env xs : Env.t = + match xs with + | [] -> env + | x::xs -> valid_binders valid_x (valid_x env x) xs let rec valid_iter ?(side = `Rhs) env iter : Env.t = match iter with @@ -167,54 +179,72 @@ let rec valid_iter ?(side = `Rhs) env iter : Env.t = Env.bind_var env id (NumT `NatT $ e.at) ) +and valid_iterexp ?(side = `Rhs) env (it, xes) at : iter * Env.t = + Debug.(log_at "il.valid_iterexp" at + (fun _ -> il_iter it) + (fun (it', _) -> il_iter it') + ) @@ fun _ -> + let env' = valid_iter ~side env it in + if xes = [] && it <= List1 && side = `Rhs then error at "empty iteration"; + let it' = match it with Opt -> Opt | _ -> List in + it', + List.fold_left (fun env' (x, e) -> + let t = infer_exp env e in + valid_exp ~side env e t; + let t1 = as_iter_typ it' "iterator" env Check t e.at in + Env.bind_var env' x t1 + ) env' xes + (* Types *) -and valid_typ env t = +and valid_typ env t = ignore (valid_typ_bind env t) + +and valid_typ_bind env t : Env.t = Debug.(log_at "il.valid_typ" t.at (fun _ -> fmt "%s" (il_typ t)) (Fun.const "ok") ) @@ fun _ -> match t.it with | VarT (id, as_) -> let ps, _insts = Env.find_typ env id in - ignore (valid_args env as_ ps Subst.empty t.at) + ignore (valid_args env as_ ps Subst.empty t.at); + env | BoolT | NumT _ | TextT -> - () - | TupT ets -> - List.iter (valid_typbind env) ets + env + | TupT [] -> + env + | TupT ((x1, t1)::xts) -> + valid_typ env t1; + valid_typ_bind (Env.bind_var env x1 t1) (TupT xts $ t.at) | IterT (t1, iter) -> match iter with | ListN (e, _) -> error e.at "definite iterator not allowed in type" | _ -> let env' = valid_iter env iter in - valid_typ env' t1 - -and valid_typbind env (e, t) = - valid_typ env t; - valid_exp ~side:`Lhs env e t + valid_typ env' t1; + env -and valid_deftyp envr dt = +and valid_deftyp env dt = match dt.it with | AliasT t -> - valid_typ !envr t + valid_typ env t | StructT tfs -> - check_mixops "record" "field" (List.map (fun (atom, _, _) -> [[atom]]) tfs) dt.at; - List.iter (valid_typfield envr) tfs + check_mixops "record" "field" (List.map (fun (atom, _, _) -> Mixop.Atom atom) tfs) dt.at; + List.iter (valid_typfield env) tfs | VariantT tcs -> check_mixops "variant" "case" (List.map (fun (op, _, _) -> op) tcs) dt.at; - List.iter (valid_typcase envr) tcs + List.iter (valid_typcase env) tcs -and valid_typfield envr (_atom, (bs, t, prems), _hints) = - let envr' = local_env envr in - List.iter (valid_bind envr') bs; - valid_typ !envr' t; - List.iter (valid_prem !envr') prems +and valid_typfield env (_atom, (t, qs, prems), _hints) = + let env' = valid_typ_bind env t in + let env'' = valid_quants env' qs in + List.iter (valid_prem env'') prems -and valid_typcase envr (mixop, (bs, t, prems), _hints) = +and valid_typcase env (mixop, (t, qs, prems), _hints) = Debug.(log_at "il.valid_typcase" t.at - (fun _ -> fmt "%s %s" (il_binds bs) (il_typ t)) + (fun _ -> fmt "%s" (il_typ t)) (fun _ -> "ok") ) @@ fun _ -> let arity = @@ -222,25 +252,12 @@ and valid_typcase envr (mixop, (bs, t, prems), _hints) = | TupT ts -> List.length ts | _ -> 1 in - if List.length mixop <> arity + 1 then + if Mixop.arity mixop <> arity then error t.at ("inconsistent arity in mixin notation, `" ^ string_of_mixop mixop ^ - "` applied to " ^ typ_string !envr t); - let envr' = local_env envr in - List.iter (valid_bind envr') bs; - valid_typ !envr' t; - List.iter (valid_prem !envr') prems - - -and proj_tup_typ env s e ets i : typ option = - match ets, i with - | (_eI, tI)::_, 0 -> Some tI - | (eI, tI)::ets', i -> - (match Eval.match_exp env s (ProjE (e, i) $$ e.at % tI) eI with - | None -> None - | Some s' -> proj_tup_typ env s' e ets' (i - 1) - | exception Eval.Irred -> None - ) - | [], _ -> assert false + "` applied to " ^ typ_string env t); + let env' = valid_typ_bind env t in + let env'' = valid_quants env' qs in + List.iter (valid_prem env'') prems (* Expressions *) @@ -251,7 +268,7 @@ and infer_exp (env : Env.t) e : typ = (fun r -> fmt "%s" (il_typ r)) ) @@ fun _ -> match e.it with - | VarE id -> Env.find_var env id + | VarE x -> Env.find_var env x | BoolE _ -> BoolT $ e.at | NumE n -> NumT (Num.to_typ n) $ e.at | TextE _ -> TextT $ e.at @@ -266,30 +283,25 @@ and infer_exp (env : Env.t) e : typ = | StrE _ -> error e.at "cannot infer type of record" | DotE (e1, atom) -> let tfs = as_struct_typ "expression" env Infer (infer_exp env e1) e1.at in - let _binds, t, _prems = find_field tfs atom e1.at in + let t, _qs, _prems = find_field tfs atom e1.at in t | TupE es -> - TupT (List.map (fun eI -> eI, infer_exp env eI) es) $ e.at - | CallE (id, as_) -> - let ps, t, _ = Env.find_def env id in + TupT (List.map (fun eI -> "_" $ eI.at, infer_exp env eI) es) $ e.at + | CallE (x, as_) -> + let ps, t, _ = Env.find_def env x in let s = valid_args env as_ ps Subst.empty e.at in Subst.subst_typ s t - | IterE (e1, iterexp) -> - let iter, env' = valid_iterexp env iterexp e.at in - IterT (infer_exp env' e1, iter) $ e.at + | IterE (e1, ite) -> + let it, env' = valid_iterexp env ite e.at in + IterT (infer_exp env' e1, it) $ e.at | ProjE (e1, i) -> let t1 = infer_exp env e1 in - let ets = as_tup_typ "expression" env Infer t1 e1.at in - if i >= List.length ets then - error e.at "invalid tuple projection"; - (match proj_tup_typ env Subst.empty e1 ets i with - | Some tI -> tI - | None -> error e.at "cannot infer type of tuple projection" - ) + let xts = as_tup_typ "expression" env Infer t1 e1.at in + proj_tup_typ i xts e1 e.at | UncaseE (e1, op) -> let t1 = infer_exp env e1 in (match as_variant_typ "expression" env Infer t1 e1.at with - | [(op', (_, t, _), _)] when Eq.eq_mixop op op' -> t + | [(op', (t, _, _), _)] when Eq.eq_mixop op op' -> t | _ -> error e.at "invalid case projection"; ) | OptE _ -> error e.at "cannot infer type of option" @@ -324,11 +336,11 @@ and valid_exp ?(side = `Rhs) env e t = (fun _ -> fmt "%s :%s %s == %s" (il_exp e) (il_side side) (il_typ e.note) (il_typ t)) (Fun.const "ok") ) @@ fun _ -> -try + valid_typ env t; match e.it with - | VarE id when id.it = "_" && side = `Lhs -> () - | VarE id -> - let t' = Env.find_var env id in + | VarE x when x.it = "_" && side = `Lhs -> () + | VarE x -> + let t' = Env.find_var env x in equiv_typ env t' t e.at | BoolE _ | NumE _ | TextE _ -> let t' = infer_exp env e in @@ -385,7 +397,7 @@ try let t1 = infer_exp env e1 in valid_exp env e1 t1; let tfs = as_struct_typ "expression" env Check t1 e1.at in - let _binds, t', _prems = find_field tfs atom e1.at in + let t', _qs, _prems = find_field tfs atom e1.at in equiv_typ env t' t e.at | CompE (e1, e2) -> let _ = as_comp_typ "expression" env Check t e.at in @@ -403,36 +415,39 @@ try valid_exp env e1 t1; equiv_typ env (NumT `NatT $ e.at) t e.at | TupE es -> - let ets = as_tup_typ "tuple" env Check t e.at in - if List.length es <> List.length ets then - error e.at ("arity mismatch for tuple, expected " ^ - string_of_int (List.length ets) ^ ", got " ^ string_of_int (List.length es)); - if not (valid_tup_exp ~side env Subst.empty es ets) then - as_error e.at "tuple" Check t "" - | CallE (id, as_) -> - let ps, t', _ = Env.find_def env id in + let xts = as_tup_typ "tuple" env Check t e.at in + let rec loop i es xts s = + match es, xts with + | [], [] -> () + | eI::es', (xI, tI)::xts' -> + valid_exp ~side env eI (Subst.subst_typ s tI); + let s' = Subst.add_varid s xI eI in + loop (i + 1) es' xts' s' + | _, _ -> + error e.at ("arity mismatch for tuple, expected " ^ + string_of_int (i + List.length xts) ^ ", got " ^ + string_of_int (i + List.length es)); + in loop 0 es xts Subst.empty + | CallE (x, as_) -> + let ps, t', _ = Env.find_def env x in let s = valid_args env as_ ps Subst.empty e.at in equiv_typ env (Subst.subst_typ s t') t e.at - | IterE (e1, iterexp) -> - let iter, env' = valid_iterexp ~side env iterexp e.at in - let t1 = as_iter_typ iter "iteration" env Check t e.at in + | IterE (e1, ite) -> + let it, env' = valid_iterexp ~side env ite e.at in + let t1 = as_iter_typ it "iteration" env Check t e.at in valid_exp ~side env' e1 t1 | ProjE (e1, i) -> let t1 = infer_exp env e1 in - let ets = as_tup_typ "expression" env Infer t1 e1.at in - if i >= List.length ets then - error e.at "invalid tuple projection"; - let side' = if List.length ets > 1 then `Rhs else side in - valid_exp ~side:side' env e1 t1; - (match proj_tup_typ env Subst.empty e1 ets i with - | Some tI -> equiv_typ env tI t e.at - | None -> error e.at "invalid tuple projection, cannot match pattern" - ) + let xts = as_tup_typ "expression" env Infer t1 e1.at in + let side' = if List.length xts > 1 then `Rhs else side in + valid_exp ~side:side' env e1 (TupT xts $ t1.at); + equiv_typ env (proj_tup_typ i xts e1 e.at) t e.at | UncaseE (e1, op) -> let t1 = infer_exp env e1 in valid_exp ~side env e1 t1; (match as_variant_typ "expression" env Infer t1 e1.at with - | [(op', (_, t', _), _)] when Eq.eq_mixop op op' -> equiv_typ env t' t e.at + | [(op', (t', _, _), _)] when Eq.eq_mixop op op' -> + equiv_typ env t' t e.at | _ -> error e.at "invalid case projection"; ) | OptE eo -> @@ -457,7 +472,7 @@ try valid_exp env e2 t | CaseE (op, e1) -> let cases = as_variant_typ "case" env Check t e.at in - let _binds, t1, _prems = find_case cases op e1.at in + let t1, _qs, _prems = find_case cases op e1.at in valid_exp ~side env e1 t1 | CvtE (e1, nt1, nt2) -> valid_exp ~side env e1 (NumT nt1 $ e1.at); @@ -468,10 +483,6 @@ try valid_exp ~side env e1 t1; equiv_typ env t2 t e.at; sub_typ env t1 t2 e.at -with exn -> - let bt = Printexc.get_raw_backtrace () in - Printf.eprintf "[valid_exp] %s\n%!" (Debug.il_exp e); - Printexc.raise_with_backtrace exn bt and valid_expmix ?(side = `Rhs) env mixop e (mixop', t) at = @@ -482,25 +493,18 @@ and valid_expmix ?(side = `Rhs) env mixop e (mixop', t) at = ); valid_exp ~side env e t -and valid_tup_exp ?(side = `Rhs) env s es ets = - Debug.(log_in "il.valid_tup_exp" - (fun _ -> fmt "(%s) :%s (%s)[%s]" (list il_exp es) (il_side side) (list il_typ (List.map snd ets)) (il_subst s)) - ); - match es, ets with - | e1::es', (e2, t)::ets' -> - valid_exp ~side env e1 (Subst.subst_typ s t); - (match Eval.match_exp env s e1 e2 with - | Some s' -> valid_tup_exp ~side env s' es' ets' - | None -> false - | exception Eval.Irred -> false +and valid_expfield ~side env (atom1, e) (atom2, (t, _qs, _prems), _) = + Debug.(log_in_at "il.valid_expfield" e.at + (fun _ -> fmt "%s %s :%s %s %s" + (il_atom atom1) (il_exp e) (il_side side) + (il_atom atom2) (il_typ t) ) - | _, _ -> true - -and valid_expfield ~side env (atom1, e) (atom2, (_binds, t, _prems), _) = + ); if not (Eq.eq_atom atom1 atom2) then error e.at "unexpected record field"; valid_exp ~side env e t and valid_path env p t : typ = + valid_typ env t; let t' = match p.it with | RootP -> t @@ -517,32 +521,20 @@ and valid_path env p t : typ = | DotP (p1, atom) -> let t1 = valid_path env p1 t in let tfs = as_struct_typ "path" env Check t1 p1.at in - let _bs, t, _prems = find_field tfs atom p1.at in + let t, _qs, _prems = find_field tfs atom p1.at in t in equiv_typ env p.note t' p.at; t' -and valid_iterexp ?(side = `Rhs) env (iter, xes) at : iter * Env.t = - let env' = valid_iter ~side env iter in - if xes = [] && iter <= List1 && side = `Rhs then error at "empty iteration"; - let iter' = match iter with Opt -> Opt | _ -> List in - iter', - List.fold_left (fun env' (id, e) -> - let t = infer_exp env e in - valid_exp ~side env e t; - let t1 = as_iter_typ iter' "iterator" env Check t e.at in - Env.bind_var env' id t1 - ) env' xes - (* Grammars *) and valid_sym env g : typ = Debug.(log_at "il.valid_sym" g.at (fun _ -> il_sym g) (fun t -> il_typ t)) @@ fun _ -> match g.it with - | VarG (id, as_) -> - let ps, t, _ = Env.find_gram env id in + | VarG (x, as_) -> + let ps, t, _ = Env.find_gram env x in let s = valid_args env as_ ps Subst.empty g.at in Subst.subst_typ s t | NumG _ -> @@ -565,10 +557,10 @@ and valid_sym env g : typ = equiv_typ env t1 (NumT `NatT $ g1.at) g.at; equiv_typ env t2 (NumT `NatT $ g2.at) g.at; NumT `NatT $ g.at - | IterG (g1, iterexp) -> - let iter, env' = valid_iterexp ~side:`Lhs env iterexp g.at in + | IterG (g1, ite) -> + let it, env' = valid_iterexp ~side:`Lhs env ite g.at in let t1 = valid_sym env' g1 in - IterT (t1, iter) $ g.at + IterT (t1, it) $ g.at | AttrG (e, g1) -> let t1 = valid_sym env g1 in valid_exp ~side:`Lhs env e t1; @@ -580,28 +572,28 @@ and valid_sym env g : typ = and valid_prem env prem = Debug.(log_in_at "il.valid_prem" prem.at (fun _ -> il_prem prem)); match prem.it with - | RulePr (id, mixop, e) -> - let mixop', t, _rules = Env.find_rel env id in + | RulePr (x, mixop, e) -> + let mixop', t, _rules = Env.find_rel env x in assert (Mixop.eq mixop mixop'); valid_expmix env mixop e (mixop, t) e.at | IfPr e -> valid_exp env e (BoolT $ e.at) - | LetPr (e1, e2, ids) -> + | LetPr (e1, e2, xs) -> let t = infer_exp env e2 in valid_exp ~side:`Lhs env e1 t; valid_exp env e2 t; - let target_ids = Free.{empty with varid = Set.of_list ids} in + let target_ids = Free.{empty with varid = Set.of_list xs} in let free_ids = Free.(free_exp e1) in if not (Free.subset target_ids free_ids) then error prem.at ("target identifier(s) " ^ ( Free.Set.elements (Free.diff target_ids free_ids).varid |> - List.map (fun id -> "`" ^ id ^ "`") |> + List.map (fun x -> "`" ^ x ^ "`") |> String.concat ", " ) ^ " do not occur in left-hand side expression") | ElsePr -> () - | IterPr (prem', iterexp) -> - let _iter, env' = valid_iterexp env iterexp prem.at in + | IterPr (prem', ite) -> + let _it, env' = valid_iterexp env ite prem.at in valid_prem env' prem' @@ -612,25 +604,30 @@ and valid_arg env a p s = (fun _ -> fmt "%s : %s" (il_arg a) (il_param p)) (Fun.const "ok") ) @@ fun _ -> match a.it, (Subst.subst_param s p).it with - | ExpA e, ExpP (id, t) -> valid_exp ~side:`Lhs env e t; Subst.add_varid s id e - | TypA t, TypP id -> valid_typ env t; Subst.add_typid s id t - | DefA id', DefP (id, ps, t) -> - let ps', t', _ = Env.find_def env id' in + | ExpA e, ExpP (x, t) -> + valid_exp ~side:`Lhs env e t; Subst.add_varid s x e + | TypA t, TypP x -> valid_typ env t; Subst.add_typid s x t + | DefA x', DefP (x, ps, t) -> + let ps', t', _ = Env.find_def env x' in if not (Eval.equiv_functyp env (ps', t') (ps, t)) then error a.at "type mismatch in function argument"; - Subst.add_defid s id id' - | GramA g, GramP (id, t) -> + Subst.add_defid s x x' + | GramA g, GramP (x, [], t) -> let t' = valid_sym env g in - if not (Eval.equiv_typ env t' t) then + equiv_typ env t' t a.at; + Subst.add_gramid s x g + | GramA ({it = VarG (x', as'); _} as g), GramP (x, ps, t) -> + let ps', t', _ = Env.find_gram env x' in + if as' <> [] || not (Eval.equiv_functyp env (ps', t') (ps, t)) then error a.at "type mismatch in grammar argument"; - Subst.add_gramid s id g + Subst.add_gramid s x g | _, _ -> error a.at ("sort mismatch for argument, expected `" ^ Print.string_of_param p ^ "`, got `" ^ Print.string_of_arg a ^ "`") and valid_args env as_ ps s at : Subst.t = Debug.(log_if "il.valid_args" (as_ <> [] || ps <> []) - (fun _ -> fmt "(%s) : (%s)" (il_args as_) (il_params ps)) (Fun.const "ok") + (fun _ -> fmt "{%s} : {%s}" (il_args as_) (il_params ps)) (Fun.const "ok") ) @@ fun _ -> match as_, ps with | [], [] -> s @@ -640,140 +637,117 @@ and valid_args env as_ ps s at : Subst.t = let s' = valid_arg env a p s in valid_args env as' ps' s' at -and valid_bind envr b = - match b.it with - | ExpB (id, t) -> - valid_typ !envr t; - envr := Env.bind_var !envr id t - | TypB id -> - envr := Env.bind_typ !envr id ([], []) - | DefB (id, ps, t) -> - let envr' = local_env envr in - List.iter (valid_param envr') ps; - valid_typ !envr' t; - envr := Env.bind_def !envr id (ps, t, []) - | GramB (id, ps, t) -> - let envr' = local_env envr in - List.iter (valid_param envr') ps; - valid_typ !envr' t; - envr := Env.bind_gram !envr id (ps, t, []) - -and valid_param envr p = +and valid_param env p : Env.t = match p.it with - | ExpP (id, t) -> - valid_typ !envr t; - envr := Env.bind_var !envr id t - | TypP id -> - envr := Env.bind_typ !envr id ([], []) - | DefP (id, ps, t) -> - let envr' = local_env envr in - List.iter (valid_param envr') ps; - valid_typ !envr' t; - envr := Env.bind_def !envr id (ps, t, []) - | GramP (id, t) -> - valid_typ !envr t; - envr := Env.bind_gram !envr id ([], t, []) - -let valid_inst envr ps inst = + | ExpP (x, t) -> + valid_typ env t; + Env.bind_var env x t + | TypP x -> + Env.bind_typ env x ([], []) + | DefP (x, ps, t) -> + let env' = valid_params env ps in + valid_typ env' t; + Env.bind_def env x (ps, t, []) + | GramP (x, ps, t) -> + let env' = valid_params env ps in + valid_typ env' t; + Env.bind_gram env x (ps, t, []) + +and valid_quant env q = valid_param env q + +and valid_params env ps = valid_binders valid_param env ps +and valid_quants env qs = valid_binders valid_quant env qs + +let valid_inst env ps inst = Debug.(log_in "il.valid_inst" line); Debug.(log_in_at "il.valid_inst" inst.at (fun _ -> fmt "(%s) = ..." (il_params ps)) ); match inst.it with - | InstD (bs, as_, dt) -> - let envr' = local_env envr in - List.iter (valid_bind envr') bs; - let _s = valid_args !envr' as_ ps Subst.empty inst.at in - valid_deftyp envr' dt + | InstD (qs, as_, dt) -> + let env' = valid_quants env qs in + let _s = valid_args env' as_ ps Subst.empty inst.at in + valid_deftyp env' dt -let valid_rule envr mixop t rule = +let valid_rule env mixop t rule = Debug.(log_in "il.valid_rule" line); Debug.(log_in_at "il.valid_rule" rule.at (fun _ -> fmt "%s : %s = ..." (il_mixop mixop) (il_typ t)) ); match rule.it with - | RuleD (_id, bs, mixop', e, prems) -> - let envr' = local_env envr in - List.iter (valid_bind envr') bs; - valid_expmix ~side:`Lhs !envr' mixop' e (mixop, t) e.at; - List.iter (valid_prem !envr') prems + | RuleD (_x, qs, mixop', e, prems) -> + let env' = valid_quants env qs in + valid_expmix ~side:`Lhs env' mixop' e (mixop, t) e.at; + List.iter (valid_prem env') prems -let valid_clause envr ps t clause = +let valid_clause env x ps t clause = Debug.(log_in "il.valid_clause" line); Debug.(log_in_at "il.valid_clause" clause.at - (fun _ -> fmt ": (%s) -> %s" (il_params ps) (il_typ t)) + (fun _ -> fmt "%s : (%s) -> %s" (il_id x) (il_params ps) (il_typ t)) ); match clause.it with - | DefD (bs, as_, e, prems) -> - let envr' = local_env envr in - List.iter (valid_bind envr') bs; - let s = valid_args !envr' as_ ps Subst.empty clause.at in - valid_exp !envr' e (Subst.subst_typ s t); - List.iter (valid_prem !envr') prems - -let valid_prod envr ps t prod = + | DefD (qs, as_, e, prems) -> + let env' = valid_quants env qs in + let s = valid_args env' as_ ps Subst.empty clause.at in + valid_exp env' e (Subst.subst_typ s t); + List.iter (valid_prem env') prems + +let valid_prod env ps t prod = Debug.(log_in "il.valid_prod" line); Debug.(log_in_at "il.valid_prod" prod.at (fun _ -> fmt ": (%s) -> %s" (il_params ps) (il_typ t)) ); match prod.it with - | ProdD (bs, g, e, prems) -> - let envr' = local_env envr in - List.iter (valid_bind envr') bs; - let _t' = valid_sym !envr' g in - valid_exp !envr' e t; - List.iter (valid_prem !envr') prems - -let infer_def envr d = + | ProdD (qs, g, e, prems) -> + let env' = valid_quants env qs in + let _t' = valid_sym env' g in + valid_exp env' e t; + List.iter (valid_prem env') prems + +let infer_def env d : Env.t = match d.it with - | TypD (id, ps, _insts) -> - let envr' = local_env envr in - List.iter (valid_param envr') ps; - envr := Env.bind_typ !envr id (ps, []) - | RelD (id, mixop, t, rules) -> - valid_typcase envr (mixop, ([], t, []), []); - envr := Env.bind_rel !envr id (mixop, t, rules) - | DecD (id, ps, t, clauses) -> - let envr' = local_env envr in - List.iter (valid_param envr') ps; - valid_typ !envr' t; - envr := Env.bind_def !envr id (ps, t, clauses) - | GramD (id, ps, t, prods) -> - let envr' = local_env envr in - List.iter (valid_param envr') ps; - valid_typ !envr' t; - envr := Env.bind_gram !envr id (ps, t, prods) - | _ -> () - - -let rec valid_def envr d = + | TypD (x, ps, _insts) -> + let _env' = valid_params env ps in + Env.bind_typ env x (ps, []) + | RelD (x, mixop, t, rules) -> + valid_typ env t; + Env.bind_rel env x (mixop, t, rules) + | DecD (x, ps, t, clauses) -> + let env' = valid_params env ps in + valid_typ env' t; + Env.bind_def env x (ps, t, clauses) + | GramD (x, ps, t, prods) -> + let env' = valid_params env ps in + valid_typ env' t; + Env.bind_gram env x (ps, t, prods) + | _ -> env + + +let rec valid_def env d : Env.t = Debug.(log_in "il.valid_def" line); Debug.(log_in_at "il.valid_def" d.at (fun _ -> il_def d)); match d.it with - | TypD (id, ps, insts) -> - let envr' = local_env envr in - List.iter (valid_param envr') ps; - List.iter (valid_inst envr ps) insts; - envr := Env.bind_typ !envr id (ps, insts); - | RelD (id, mixop, t, rules) -> - valid_typcase envr (mixop, ([], t, []), []); - List.iter (valid_rule envr mixop t) rules; - envr := Env.bind_rel !envr id (mixop, t, rules) - | DecD (id, ps, t, clauses) -> - let envr' = local_env envr in - List.iter (valid_param envr') ps; - valid_typ !envr' t; - List.iter (valid_clause envr ps t) clauses; - envr := Env.bind_def !envr id (ps, t, clauses) - | GramD (id, ps, t, prods) -> - let envr' = local_env envr in - List.iter (valid_param envr') ps; - valid_typ !envr' t; - List.iter (valid_prod envr' ps t) prods; - envr := Env.bind_gram !envr id (ps, t, prods) + | TypD (x, ps, insts) -> + let env' = valid_params env ps in + List.iter (valid_inst env' ps) insts; + Env.bind_typ env x (ps, insts); + | RelD (x, mixop, t, rules) -> + valid_typcase env (mixop, (t, [], []), []); + List.iter (valid_rule env mixop t) rules; + Env.bind_rel env x (mixop, t, rules) + | DecD (x, ps, t, clauses) -> + let env' = valid_params env ps in + valid_typ env' t; + List.iter (valid_clause env' x ps t) clauses; + Env.bind_def env x (ps, t, clauses) + | GramD (x, ps, t, prods) -> + let env' = valid_params env ps in + valid_typ env' t; + List.iter (valid_prod env' ps t) prods; + Env.bind_gram env x (ps, t, prods) | RecD ds -> - List.iter (infer_def envr) ds; - List.iter (valid_def envr) ds; + let env' = valid_binders infer_def env ds in + let env' = valid_binders valid_def env' ds in List.iter (fun d -> match (List.hd ds).it, d.it with | HintD _, _ | _, HintD _ @@ -784,13 +758,13 @@ let rec valid_def envr d = | _, _ -> error (List.hd ds).at (" " ^ string_of_region d.at ^ ": invalid recursion between definitions of different sort") - ) ds + ) ds; + env' | HintD _ -> - () + env (* Scripts *) let valid ds = - let envr = ref Env.empty in - List.iter (valid_def envr) ds + ignore (valid_binders valid_def Env.empty ds) diff --git a/spectec/src/il2al/animate.ml b/spectec/src/il2al/animate.ml index 8d70ddf832..5a19fe4614 100644 --- a/spectec/src/il2al/animate.ml +++ b/spectec/src/il2al/animate.ml @@ -251,7 +251,8 @@ let is_not_lhs e = match e.it with (* Hack to handle RETURN_CALL_ADDR, eventually should be removed *) let is_atomic_lhs e = match e.it with -| CaseE ([{it = Atom "FUNC"; _}]::_, { it = CaseE ([[]; [{it = Arrow; _}]; []], { it = TupE [ { it = IterE (_, (ListN _, _)); _} ; { it = IterE (_, (ListN _, _)); _} ] ; _} ); _ }) -> true +| CaseE (op, { it = CaseE (Xl.Mixop.(Infix (Arg (), {it = Arrow; _}, Arg ())), { it = TupE [ { it = IterE (_, (ListN _, _)); _} ; { it = IterE (_, (ListN _, _)); _} ] ; _} ); _ }) -> + Il2al_util.case_head op = "FUNC" | _ -> false (* Hack to handle ARRAY.INIT_DATA, eventually should be removed *) @@ -349,7 +350,7 @@ let animate_rule r = match r.it with | RuleD(id, binds, mixop, args, prems) -> ( match (mixop, args.it) with (* lhs ~> rhs *) - | ([ [] ; [{it = SqArrow; _}] ; []] , TupE ([_lhs; _rhs])) -> + | (Xl.Mixop.(Infix (Arg (), {it = SqArrow; _}, Arg ())) , TupE ([_lhs; _rhs])) -> let new_prems = animate_prems {empty with varid = Set.of_list Encode.input_vars} prems in RuleD(id, binds, mixop, args, new_prems) $ r.at | _ -> r diff --git a/spectec/src/il2al/encode.ml b/spectec/src/il2al/encode.ml index f926d01cd7..238ef53b7b 100644 --- a/spectec/src/il2al/encode.ml +++ b/spectec/src/il2al/encode.ml @@ -42,14 +42,7 @@ let args_of_case e = | _ -> error e.at "cannot get arguments of case expression" let is_context e = - is_case e && - match case_of_case e with - | (atom :: _) :: _ -> - (match it atom with - - | Atom a -> List.mem a Al.Al_util.context_names - | _ -> false) - | _ -> false + is_case e && List.mem (Il2al_util.case_head (case_of_case e)) Al.Al_util.context_names let rec stack_to_list e = match e.it with @@ -140,7 +133,7 @@ let encode_stack stack = (* ASSUMPTION: the inner stack of the ctxt instruction is always the last arg *) let args', inner_stack = Lib.List.split_last args in - let mixop', _ = Lib.List.split_last mixop in + let mixop' = Il2al_util.split_last_case mixop in let e1 = { e with it = CaseE (mixop', TupE args' $$ no_region % (mk_varT "")) } in let e2 = (mk_varE "ctxt" "contextT") in @@ -159,7 +152,7 @@ let encode_stack stack = (* Encode lhs *) let encode_lhs lhs = match lhs.it with - | CaseE ([[]; [{it = Semicolon; _}]; []], {it = TupE [z; stack]; _}) -> + | CaseE (Xl.Mixop.(Infix (Arg (), {it = Semicolon; _}, Arg ())), {it = TupE [z; stack]; _}) -> let prem = LetPr (z, mk_varE "state" "stateT", free_ids z) $ z.at in prem :: encode_stack stack | _ -> @@ -172,7 +165,7 @@ let encode_rule r = | RuleD(id, binds, mixop, args, prems) -> match (mixop, args.it) with (* lhs ~> rhs *) - | ([ [] ; [{it = SqArrow; _}] ; []] , TupE ([lhs; _rhs])) -> + | (Xl.Mixop.(Infix (Arg (), {it = SqArrow; _}, Arg ())), TupE ([lhs; _rhs])) -> let name = String.split_on_char '-' id.it |> List.hd in if List.mem name ["pure"; "read"; "trap"; "ctxt"] then (* Administrative rules *) r diff --git a/spectec/src/il2al/free.ml b/spectec/src/il2al/free.ml index 5418adf196..273b3e6fac 100644 --- a/spectec/src/il2al/free.ml +++ b/spectec/src/il2al/free.ml @@ -12,10 +12,6 @@ include Il.Free let free_varid id = {empty with varid = Set.singleton id.it} let free_defid id = {empty with defid = Set.singleton id.it} -(* TODO: Make a .mli file *) -let tmp = (+) -let (+) = union - let rec free_exp ignore_listN e = let f = free_exp ignore_listN in let fp = free_path ignore_listN in @@ -26,7 +22,9 @@ let rec free_exp ignore_listN e = | VarE id -> free_varid id | BoolE _ | NumE _ | TextE _ -> empty | CvtE (e1, _, _) | UnE (_, _, e1) | LiftE e1 | LenE e1 | TheE e1 | SubE (e1, _, _) - | DotE (e1, _) | CaseE (_, e1) | ProjE (e1, _) | UncaseE (e1, _) -> + | ProjE (e1, _) -> + f e1 + | DotE (e1, _) | CaseE (_, e1) | UncaseE (e1, _) -> f e1 | BinE (_, _, e1, e2) | CmpE (_, _, e1, e2) | IdxE (e1, e2) | CompE (e1, e2) | MemE (e1, e2) | CatE (e1, e2) -> free_list f [e1; e2] @@ -34,15 +32,16 @@ let rec free_exp ignore_listN e = | OptE eo -> free_opt f eo | TupE es | ListE es -> free_list f es | UpdE (e1, p, e2) | ExtE (e1, p, e2) -> - free_list f [e1; e2] + fp p + free_list f [e1; e2] ++ fp p | StrE efs -> free_list fef efs | CallE (_, args) -> free_list fa args | IterE (e1, iter) -> let free1 = f e1 in let bound, free2 = fi iter in - diff free1 bound + free2 + free1 -- bound ++ free2 -and free_expfield ignore_listN (_, e) = free_exp ignore_listN e +and free_expfield ignore_listN (_, e) = + free_exp ignore_listN e and free_arg ignore_listN arg = let f = free_exp ignore_listN in @@ -57,9 +56,9 @@ and free_path ignore_listN p = let fp = free_path ignore_listN in match p.it with | RootP -> empty - | IdxP (p1, e) -> fp p1 + f e + | IdxP (p1, e) -> fp p1 ++ f e | SliceP (p1, e1, e2) -> - fp p1 + f e1 + f e2 + fp p1 ++ f e1 ++ f e2 | DotP (p1, _) -> fp p1 and free_iterexp ignore_listN (iter, xes) = @@ -68,12 +67,12 @@ and free_iterexp ignore_listN (iter, xes) = let free = free_list f (List.map snd xes) in match iter with | ListN (e, None) -> - bound, if ignore_listN then free else free + f e + bound, if ignore_listN then free else free ++ f e | ListN (e, Some id) -> (* Do not regard i* as free *) let snd' = (fun (x, e) -> if Il.Eq.eq_id id x then None else Some e) in let free = free_list f (List.filter_map snd' xes) in - bound + free_varid id, if ignore_listN then empty else free + f e + bound ++ free_varid id, if ignore_listN then empty else free ++ f e | _ -> bound, free let rec free_prem ignore_listN prem = @@ -83,12 +82,12 @@ let rec free_prem ignore_listN prem = match prem.it with | RulePr (_id, _op, e) -> f e | IfPr e -> f e - | LetPr (e1, e2, _ids) -> f e1 + f e2 + | LetPr (e1, e2, _ids) -> f e1 ++ f e2 | ElsePr -> empty | IterPr (prem', iter) -> let free1 = fp prem' in let bound, free2 = fi iter in - diff (free1 + free2) bound + (free1 ++ free2) -- bound (* For unification *) @@ -97,7 +96,7 @@ let free_rule rule = match rule.it with | RuleD (_id, _bs, _op, e, prems) -> List.fold_left - (+) + (++) (Il.Free.free_exp e) (List.map Il.Free.free_prem prems) @@ -105,30 +104,28 @@ let free_clause clause = match clause.it with | DefD (_bs, as_, e, prems) -> List.fold_left - (+) + (++) (Il.Free.free_exp e) (List.map Il.Free.free_prem prems @ List.map Il.Free.free_arg as_) let free_params params = - List.fold_left (fun s param -> s + free_param param) empty params + List.fold_left (fun s param -> s ++ free_param param) empty params let free_clauses clss = - List.fold_left (fun s c -> s + free_clause c) empty clss + List.fold_left (fun s c -> s ++ free_clause c) empty clss let free_rules rules = - List.fold_left (fun s r -> s + free_rule r) empty rules + List.fold_left (fun s r -> s ++ free_rule r) empty rules let free_rule_def rd = let (_, _, clauses) = rd.it in List.fold_left (fun s c -> let _, lhs, rhs, prems = c in - List.fold_left (fun s p -> s + Il.Free.free_prem p) s prems - |> union (Il.Free.free_exp lhs) - |> union (Il.Free.free_exp rhs) + List.fold_left (fun s p -> s ++ Il.Free.free_prem p) s prems + |> (++) (Il.Free.free_exp lhs) + |> (++) (Il.Free.free_exp rhs) ) empty clauses let free_helper_def hd = let (_, clauses, _) = hd.it in free_clauses clauses - -let (+) = tmp diff --git a/spectec/src/il2al/il2al_util.ml b/spectec/src/il2al/il2al_util.ml index 42423fc77a..72e1826c4b 100644 --- a/spectec/src/il2al/il2al_util.ml +++ b/spectec/src/il2al/il2al_util.ml @@ -56,6 +56,35 @@ let case_of_case e = | _ -> error e.at (Printf.sprintf "expected a CaseE, but got `%s`" (Il.Print.string_of_exp e)) +let case_head mixop = + match Mixop.head mixop with + | Some {it = Atom.Atom id; _} -> id + | _ -> "" + +let rec split_last_case' = function + | Mixop.Arg () -> Some (Mixop.Seq []) + | Mixop.Seq [] | Mixop.Atom _ -> None + | Mixop.Seq mixops -> + let mixops', mixop = Lib.List.split_last mixops in + (match split_last_case' mixop with + | Some (Mixop.Seq []) -> Some (Mixop.Seq mixops') + | Some mixop' -> Some (Mixop.Seq (mixops' @ [mixop'])) + | None -> split_last_case' (Mixop.Seq mixops') + ) + | Mixop.Brack (l, mixop, _) -> + (match split_last_case' mixop with + | Some (Mixop.Seq []) -> Some (Mixop.Atom l) + | Some mixop' -> Some (Mixop.Seq [Mixop.Atom l; mixop']) + | None -> None + ) + | Mixop.Infix (mixop1, atom, mixop2) -> + (match split_last_case' mixop2 with + | Some mixop2' -> Some (Mixop.Infix (mixop1, atom, mixop2')) + | None -> split_last_case' mixop1 + ) + +let split_last_case mixop = Option.get (split_last_case' mixop) + let is_let_prem_with_rhs_type t prem = match prem.it with | LetPr (_, e, _) -> diff --git a/spectec/src/il2al/il_walk.ml b/spectec/src/il2al/il_walk.ml index 03532befc7..8c8ddf246c 100644 --- a/spectec/src/il2al/il_walk.ml +++ b/spectec/src/il2al/il_walk.ml @@ -5,7 +5,7 @@ open Il.Ast type transformer = { transform_exp: exp -> exp; - transform_bind: bind -> bind; + transform_param: param -> param; transform_prem: prem -> prem; transform_iterexp: iterexp -> iterexp; } @@ -13,7 +13,7 @@ type transformer = { let id = Fun.id let base_transformer = { transform_exp = id; - transform_bind = id; + transform_param = id; transform_prem = id; transform_iterexp = id; } @@ -78,20 +78,20 @@ and transform_prem t p = in f { p with it } -and transform_bind t b = - let f = t.transform_bind in - let it = match b.it with - | ExpB (id, typ) -> ExpB (id, typ) - | TypB id -> TypB id - | DefB (id, params, typ) -> DefB (id, params, typ) - | GramB (id, params, typ) -> GramB (id, params, typ) +and transform_param t p = + let f = t.transform_param in + let it = match p.it with + | ExpP (id, typ) -> ExpP (id, typ) + | TypP id -> TypP id + | DefP (id, params, typ) -> DefP (id, params, typ) + | GramP (id, params, typ) -> GramP (id, params, typ) in - f { b with it } + f { p with it } and transform_clause t c = { c with it = match c.it with | DefD (bs, args, e, ps) -> - DefD (List.map (transform_bind t) bs, List.map (transform_arg t) args, transform_exp t e, List.map (transform_prem t) ps) } + DefD (List.map (transform_param t) bs, List.map (transform_arg t) args, transform_exp t e, List.map (transform_prem t) ps) } (* For unification *) @@ -109,5 +109,5 @@ and transform_helper_def t hd = | (id, cs, partial) -> (id, List.map (transform_clause t) cs, partial) } and transform_rule t r = - let RuleD (id, binds, mixop, exp, prems) = r.it in - RuleD (id, binds, mixop, transform_exp t exp, List.map (transform_prem t) prems) $ r.at + let RuleD (id, params, mixop, exp, prems) = r.it in + RuleD (id, params, mixop, transform_exp t exp, List.map (transform_prem t) prems) $ r.at diff --git a/spectec/src/il2al/il_walk.mli b/spectec/src/il2al/il_walk.mli index 34752bf481..895b794364 100644 --- a/spectec/src/il2al/il_walk.mli +++ b/spectec/src/il2al/il_walk.mli @@ -3,7 +3,7 @@ open Def type transformer = { transform_exp: exp -> exp; - transform_bind: bind -> bind; + transform_param: param -> param; transform_prem: prem -> prem; transform_iterexp: iterexp -> iterexp; } diff --git a/spectec/src/il2al/postprocess.ml b/spectec/src/il2al/postprocess.ml index 5820f018de..9192e2daae 100644 --- a/spectec/src/il2al/postprocess.ml +++ b/spectec/src/il2al/postprocess.ml @@ -1,7 +1,7 @@ open Al -open Xl open Ast open Util +open Il2al_util open Source let rec merge_pop_assert' instrs = @@ -11,8 +11,8 @@ let rec merge_pop_assert' instrs = ({ it = PopI e2; _ } as i2) :: ({ it = AssertI ({ it = BinE (`EqOp, e31, e32); _ }); _ } as i3) :: il -> (match e2.it, e32.it with - | CaseE ([{ it = Atom.Atom ("CONST" | "VCONST"); _ }]::_, hd::_), VarE _ - when Eq.eq_expr e31 hd -> + | CaseE (op, hd::_), VarE _ + when List.mem (case_head op) ["CONST"; "VCONST"] && Eq.eq_expr e31 hd -> let e1 = { e1 with it = TopValueE (Some e32) } in let i1 = { i1 with it = AssertI e1 } in merge_helper (i2 :: i1 :: acc) il @@ -22,15 +22,15 @@ let rec merge_pop_assert' instrs = | ({ it = AssertI ({ it = TopValueE None; _ } as e1); _ } as i1) :: ({ it = PopI e2; _ } as i2) :: il -> (match e2.it with - | CaseE ([{ it = Atom.Atom ("CONST" | "VCONST"); _ }]::_, - ({ it = CaseE (_, []); _ } as hd)::_tl) -> + | CaseE (op, ({ it = CaseE (_, []); _ } as hd)::_tl) + when List.mem (case_head op) ["CONST"; "VCONST"] -> let e1 = { e1 with it = TopValueE (Some hd) } in let i1 = { i1 with it = AssertI e1 } in merge_helper (i2 :: i1 :: acc) il - | CaseE ([{ it = Atom.Atom ("CONST" | "VCONST" as cons); _ }]::_ , - { it = VarE _; _ }::_tl) -> + | CaseE (op, { it = VarE _; _ }::_tl) + when List.mem (case_head op) ["CONST"; "VCONST"] -> (* HARDCODE: name of type according to constructor *) - let vt = if cons = "CONST" then "num" else "vec" in + let vt = if case_head op = "CONST" then "num" else "vec" in let hd = VarE vt $$ no_region % (Il.Ast.VarT (vt $ no_region, []) $ no_region) in let e1 = { e1 with it = TopValueE (Some hd) } in let i1 = { i1 with it = AssertI e1 } in diff --git a/spectec/src/il2al/preprocess.ml b/spectec/src/il2al/preprocess.ml index 98f7e3030e..6a79fa26ab 100644 --- a/spectec/src/il2al/preprocess.ml +++ b/spectec/src/il2al/preprocess.ml @@ -130,7 +130,7 @@ let rec preprocess_prem prem = |> List.map (fun new_prem -> IterPr (new_prem, iterexp) $ prem.at) | RulePr (id, mixop, exp) -> let lhs_rhs_opt = - match mixop, exp.it with + match Xl.Mixop.flatten mixop, exp.it with (* `id`: |- `lhs` : `rhs` *) | [[turnstile]; [colon]; []], TupE [lhs; rhs] (* `id`: C |- `lhs` : `rhs` *) diff --git a/spectec/src/il2al/translate.ml b/spectec/src/il2al/translate.ml index 62121c0023..f1719b2639 100644 --- a/spectec/src/il2al/translate.ml +++ b/spectec/src/il2al/translate.ml @@ -35,7 +35,7 @@ let is_store: Il.exp -> bool = check_typ_of_exp "store" let is_frame: Il.exp -> bool = check_typ_of_exp "frame" let is_config: Il.exp -> bool = check_typ_of_exp "config" -let field t = Il.VarE ("_" $ Source.no_region) $$ Source.no_region % t, t +let field t = "_" $ Source.no_region, t let typ_store = Il.VarT ("store" $ Source.no_region, []) $ Source.no_region let typ_frame = Il.VarT ("frame" $ Source.no_region, []) $ Source.no_region let typ_state = Il.VarT ("state" $ Source.no_region, []) $ Source.no_region @@ -44,17 +44,17 @@ let typ_state_arg = Il.TupT [field typ_store; field typ_frame] $ Source.no_regio let split_config (exp: Il.exp): Il.exp * Il.exp = assert(is_config exp); match exp.it with - | Il.CaseE ([[]; [{it = Atom.Semicolon; _}]; []], {it = TupE [ e1; e2 ]; _}) + | Il.CaseE (Mixop.(Infix (Arg (), {it = Atom.Semicolon; _}, Arg ())), {it = TupE [ e1; e2 ]; _}) when is_state e1 -> e1, e2 - | Il.CaseE ([[]; [{it = Atom.Semicolon; _}]; []], {it = TupE [ e1; e2 ]; _}) + | Il.CaseE (Mixop.(Infix (Arg (), {it = Atom.Semicolon; _}, Arg ())), {it = TupE [ e1; e2 ]; _}) when is_frame e1 -> let store = Il.StrE [] $$ e1.at % typ_store in - let state = Il.CaseE ([[]; [Atom.Semicolon $$ e1.at % Atom.info ""]; []], Il.TupE [ store; e1 ] $$ e1.at % typ_state_arg) $$ e1.at % typ_state in + let state = Il.CaseE (Mixop.(Infix (Arg (), Atom.Semicolon $$ e1.at % Atom.info "", Arg ())), Il.TupE [ store; e1 ] $$ e1.at % typ_state_arg) $$ e1.at % typ_state in state, e2 - | Il.CaseE ([[]; [{it = Atom.Semicolon; _}]; []], {it = TupE [ e1; e2 ]; _}) + | Il.CaseE (Mixop.(Infix (Arg (), {it = Atom.Semicolon; _}, Arg ())), {it = TupE [ e1; e2 ]; _}) when is_store e1 -> let frame = Il.StrE [] $$ e1.at % typ_frame in - let state = Il.CaseE ([[]; [Atom.Semicolon $$ e1.at % Atom.info ""]; []], Il.TupE [ e1; frame ] $$ e1.at % typ_state_arg) $$ e1.at % typ_state in + let state = Il.CaseE (Mixop.(Infix (Arg (), Atom.Semicolon $$ e1.at % Atom.info "", Arg ())), Il.TupE [ e1; frame ] $$ e1.at % typ_state_arg) $$ e1.at % typ_state in state, e2 | _ -> error exp.at (sprintf "can not recognize `%s` as a `config` expression" (Il.Print.string_of_exp exp)) @@ -62,7 +62,7 @@ let split_config (exp: Il.exp): Il.exp * Il.exp = let split_state (exp: Il.exp): Il.exp * Il.exp = assert(is_state exp); match exp.it with - | Il.CaseE ([[]; [{it = Atom.Semicolon; _}]; []], {it = TupE [ e1; e2 ]; _}) + | Il.CaseE (Mixop.(Infix (Arg (), {it = Atom.Semicolon; _}, Arg ())), {it = TupE [ e1; e2 ]; _}) when is_store e1 && is_frame e2 -> e1, e2 | _ -> error exp.at (sprintf "can not recognize `%s` as a `state` expression" (Il.Print.string_of_exp exp)) @@ -97,7 +97,7 @@ let is_simple_separator = function let is_context exp = is_case exp && - match case_of_case exp with + match Mixop.flatten (case_of_case exp) with | (atom :: _) :: _ -> (match it atom with | Atom a -> List.mem a context_names @@ -146,8 +146,8 @@ let rec is_wasm_value e = (* TODO: use hint? *) match e.it with | Il.SubE (e, _, _) -> is_wasm_value e - | Il.CaseE ([{it = Atom id; _}]::_, _) when - List.mem id [ + | Il.CaseE (op, _) when + List.mem (case_head op) [ "CONST"; "VCONST"; "REF.I31_NUM"; @@ -253,23 +253,23 @@ and translate_exp exp = in match (op, exps) with (* Singleton *) - | [ []; [] ], [ e1 ] -> + | Mixop.Arg (), [ e1 ] -> { (translate_exp e1) with note=note } (* State *) - | _ when List.for_all is_simple_separator op + | _ when List.for_all is_simple_separator (Mixop.flatten op) && Il.Print.string_of_typ_name exp.note = "state" -> tupE (List.map translate_exp exps) ~at ~note (* Normal Case *) | _ -> - if List.length op = List.length exps + 1 then + if Mixop.arity op = List.length exps then caseE (op, translate_argexp e) ~at ~note else error_exp exp "arity mismatch for CaseE mixop and args" ) | Il.UncaseE (e, op) -> (match op with - | [ []; [] ] -> translate_exp e + | Mixop.Arg () -> translate_exp e | _ -> yetE (Il.Print.string_of_exp exp) ~at ~note ) | Il.ProjE (e, 0) -> translate_exp e @@ -319,12 +319,13 @@ and translate_iterexp (iter, xes) = let insert_assert exp = let at = exp.at in match exp.it with - | Il.CaseE ([{it = Atom.Atom id; _}]::_, _) when List.mem id context_names -> - assertI (contextKindE (atom_of_name id "evalctx") ~note:boolT) ~at:at + | Il.CaseE (op, _) when List.mem (case_head op) context_names -> + assertI (contextKindE (atom_of_name (case_head op) "evalctx") ~note:boolT) ~at:at | Il.IterE (_, (Il.ListN (e, None), _)) -> assertI (topValuesE (translate_exp e) ~at ~note:boolT) ~at:at | Il.IterE (_, (Il.List, _)) -> nopI () ~at:at - | Il.CaseE ([{it = Atom.Atom "CONST"; _}]::_, { it = Il.TupE (ty' :: _); _ }) -> + | Il.CaseE (op, { it = Il.TupE (ty' :: _); _ }) + when case_head op = "CONST" -> assertI (topValueE (Some (translate_exp ty')) ~note:boolT) ~at:at | _ -> assertI (topValueE None ~note:boolT) ~at:at @@ -333,8 +334,8 @@ let cond_of_pop_value e = let at = e.at in let bt = boolT in match e.it with - (* | CaseE (op, [t; _]) -> - (match get_atom op with + (* | CaseE (op, _, [t; _]) -> + (match Mixop.head op with | Some {it = Atom.Atom "CONST"; _} -> topValueE (Some t) ~note:bt | Some {it = Atom.Atom "VCONST"; _} -> topValueE (Some t) ~note:bt | _ -> topValueE None ~note:bt @@ -425,7 +426,7 @@ let rec translate_rhs exp = let at = exp.at in match exp.it with (* Trap *) - | Il.CaseE ([{it = Atom "TRAP"; _}]::_, _) -> [ trapI () ~at ] + | Il.CaseE (op, _) when case_head op = "TRAP" -> [ trapI () ~at ] (* Context *) | _ when is_context exp -> translate_context_rhs exp (* Config *) @@ -492,13 +493,13 @@ and translate_context_rhs exp = let at = exp.at in let case = case_of_case exp in - let atom = case |> List.hd |> List.hd in + let atom = Option.get (Mixop.head case) in let args = args_of_case exp in - let case', _ = Lib.List.split_last case in + let case' = split_last_case case in let args, instrs = Lib.List.split_last args in let args' = List.map translate_exp args in - let e' = caseE ([[atom]], []) ~at:instrs.at ~note:instrT in + let e' = caseE (Mixop.Atom atom, []) ~at:instrs.at ~note:instrT in let instrs', al = translate_context_instrs e' instrs in let ectx = caseE (case', args') ~at ~note:evalctxT in [ @@ -791,7 +792,7 @@ and handle_special_lhs lhs rhs free_ids = )] (* Normal cases *) | CaseE (op, es) -> - let tag_opt = get_atom op in + let tag_opt = Mixop.head op in let bindings, es' = extract_non_names es in let rec inject_isCaseOf tag expr = match expr.it with @@ -927,6 +928,15 @@ let rec translate_iterpr pr (iter, xes) = let iter' = translate_iter iter in let lhs_iter = match iter' with | ListN (e, _) -> ListN (e, None) | _ -> iter' in + (* HARDCODE: Handle the case where iterated variable of ListN is not in xes *) + let xes = + match iter with + | ListN (_, Some x) when List.for_all (fun (x', _) -> x.it <> x'.it) xes -> + let dummy_expr = Il.Ast.VarE ("_" $ no_region) $$ no_region % (Il.Ast.VarT ("_" $ no_region, []) $ no_region) in + (x, dummy_expr) :: xes + | _ -> xes + in + let handle_iter_ty ty = match iter' with | Opt -> iterT ty Il.Opt @@ -1041,7 +1051,7 @@ let to_frame_instr r = let rec e_to_frame_instr e = match e with - | {it = Il.Ast.CaseE ([[]; [{it = Semicolon; _}]; []], {it = TupE [lhs; rhs]; _}); _} -> + | {it = Il.Ast.CaseE (Mixop.(Infix (Arg (), {it = Semicolon; _}, Arg ())), {it = TupE [lhs; rhs]; _}); _} -> let i = e_to_frame_instr lhs in if i = [] then e_to_frame_instr rhs else i | {it = Il.Ast.VarE _; note = {it = Il.Ast.VarT ({it = "frame"; _}, _); _}; _} -> @@ -1082,11 +1092,11 @@ let translate_context_winstr winstr = let at = winstr.at in let case = case_of_case winstr in - let kind = case |> List.hd |> List.hd in + let kind = Option.get (Mixop.head case) in let args = args_of_case winstr in let args, vals = Lib.List.split_last args in (* The last element of case is for instr*, which should not be present in the context record *) - let case, _ = Lib.List.split_last case in + let case = split_last_case case in let destruct = caseE (case, List.map translate_exp args) ~note:evalctxT ~at in [ @@ -1101,7 +1111,8 @@ let translate_context ctx = let at = ctx.at in match ctx.it with - | Il.CaseE ([{it = Atom.Atom id; _} as atom]::_ as case, { it = Il.TupE args; _ }) when List.mem id context_names -> + | Il.CaseE (case, { it = Il.TupE args; _ }) when List.mem (case_head case) context_names -> + let atom = Option.get (Mixop.head case) in let destruct = caseE (case, List.map translate_exp args) ~note:evalctxT ~at in [ letI (destruct, getCurContextE atom ~note:evalctxT) ~at:at; @@ -1136,7 +1147,7 @@ let rec translate_rgroup' (rule: rule_def) = | Some _ -> let pops, u_group = extract_pops subgroup in let ctxt = extract_context (List.hd u_group) |> Option.get in - let atom = case_of_case ctxt |> List.hd |> List.hd in + let atom = case_of_case ctxt |> Mixop.head |> Option.get in let cond = ContextKindE atom $$ atom.at % boolT in let head_instrs, middle_instr = translate_context ctxt in let is_otherwise = function [{it = OtherwiseI _; _}] -> true | _ -> false in @@ -1202,10 +1213,10 @@ and translate_rgroup (rule: rule_def) = let name = try - match case_of_case winstr with - | (atom :: _) :: _ -> atom + match Mixop.head (case_of_case winstr) with + | Some atom -> atom | _ -> failwith "" - with | _ -> error rule.at "The reduction rules do not have valid or consistent target Wasm instructions." + with _ -> error rule.at "The reduction rules do not have valid or consistent target Wasm instructions." in let anchor = rel_id.it ^ "/" ^ instr_name in let al_params = diff --git a/spectec/src/il2al/transpile.ml b/spectec/src/il2al/transpile.ml index d0c4d4a29b..7c81e63732 100644 --- a/spectec/src/il2al/transpile.ml +++ b/spectec/src/il2al/transpile.ml @@ -158,7 +158,7 @@ let is_case e = let atom_of_case e = match e.it with - | CaseE ((atom :: _) :: _, _) -> atom + | CaseE (op, _) when Mixop.head op <> None -> Option.get (Mixop.head op) | _ -> Error.error e.at "prose transformation" "expected a CaseE" let rec replace_names binds instr = @@ -795,7 +795,7 @@ let remove_trivial_case_check instr = | IsCaseOfE (expr, atom) -> (match get_typ_cases expr.note with | Some [ mixop, _, _ ] -> - List.exists (List.mem atom) mixop + List.exists (List.mem atom) (Mixop.flatten mixop) | _ -> false ) | _ -> false @@ -1292,7 +1292,7 @@ let remove_exit algo = let unused_var = varE "_" ~note:no_note in let control_frame_expr = caseE ( - [[atom]; [{ atom with it=Atom.LBrace}]; [{ atom with it=Atom.RBrace}]; []], + Mixop.(Seq [Atom atom; Arg (); Brack ({ atom with it=Atom.LBrace}, Arg (), { atom with it=Atom.RBrace}); Arg ()]), [ unused_var; unused_var ] ) ~note:evalctxT in @@ -1313,7 +1313,8 @@ let remove_exit algo = let remove_enter algo = let enter_frame_to_push instr = match instr.it with - | EnterI (e_frame, { it = ListE ([ { it = CaseE ([[{ it = Atom.Atom "FRAME_"; _ }]], []); _ } ]); _ }, il) -> + | EnterI (e_frame, { it = ListE ([ { it = CaseE (op, []); _ } ]); _ }, il) + when case_head op = "FRAME_" -> pushI e_frame ~at:instr.at :: il | _ -> [ instr ] in @@ -1322,13 +1323,13 @@ let remove_enter algo = match instr.it with | EnterI ( e_label, - { it = CatE (e_instrs, { it = ListE ([ { it = CaseE ([[{ it = Atom.Atom "LABEL_"; _ }]], []); _ } ]); _ }); note; _ }, - [ { it = PushI e_vals; _ } ]) -> + { it = CatE (e_instrs, { it = ListE ([ { it = CaseE (op, []); _ } ]); _ }); note; _ }, + [ { it = PushI e_vals; _ } ]) when case_head op = "LABEL_" -> enterI (e_label, catE (e_vals, e_instrs) ~note:note, []) ~at:instr.at | EnterI ( e_label, - { it = CatE (e_instrs, { it = ListE ([ { it = CaseE ([[{ it = Atom.Atom "LABEL_"; _ }]], []); _ } ]); _ }); _ }, - []) -> + { it = CatE (e_instrs, { it = ListE ([ { it = CaseE (op, []); _ } ]); _ }); _ }, + []) when case_head op = "LABEL_" -> enterI (e_label, e_instrs, []) ~at:instr.at | _ -> instr in @@ -1382,7 +1383,7 @@ let prosify_control_frame algo = let walk_instr walker instr = match instr.it with - | LetI ({ it = CaseE ([{ it = Atom "LABEL_"; _ }] :: _, [ _; cont ]); _ }, _) -> + | LetI ({ it = CaseE (op, [ _; cont ]); _ }, _) when case_head op = "LABEL_" -> cont_ref := cont; [ instr ] | ExecuteSeqI expr when Eq.eq_expr expr !cont_ref -> [ { instr with it = ExecuteSeqI (callE ("__prose:_jump_to_the_cont", [expA expr]) ~note:no_note) } ] diff --git a/spectec/src/il2al/unify.ml b/spectec/src/il2al/unify.ml index 90b42f6e67..fba8cba1c4 100644 --- a/spectec/src/il2al/unify.ml +++ b/spectec/src/il2al/unify.ml @@ -122,7 +122,7 @@ let rec overlap env e1 e2 = if eq_exp e1 e2 then e1 else UpdE (overlap env e1 e2, path1, overlap env e1' e2') |> replace_it | ExtE (e1, path1, e1'), ExtE (e2, path2, e2') when eq_path path1 path2 -> ExtE (overlap env e1 e2, path1, overlap env e1' e2') |> replace_it - | StrE efs1, StrE efs2 when List.map fst efs1 = List.map fst efs2 -> + | StrE efs1, StrE efs2 when List.map (fun (a, _) -> a) efs1 = List.map (fun (a, _) -> a) efs2 -> StrE (List.map2 (fun (a1, e1) (_, e2) -> (a1, overlap env e1 e2)) efs1 efs2) |> replace_it | DotE (e1, atom1), DotE (e2, atom2) when eq_atom atom1 atom2 -> DotE (overlap env e1 e2, atom1) |> replace_it @@ -203,8 +203,8 @@ and overlap_typ env t1 t2 = if eq_typ t1 t2 then t1 else (match t1.it, t2.it with | VarT (id1, args1), VarT (id2, args2) when id1 = id2 -> VarT (id1, List.map2 (overlap_arg env) args1 args2) - | TupT ets1, TupT ets2 when List.for_all2 (fun (e1, _) (e2, _) -> eq_exp e1 e2) ets1 ets2 -> - TupT (List.map2 (fun (e1, t1) (_, t2) -> (e1, (overlap_typ env) t1 t2)) ets1 ets2) + | TupT xts1, TupT xts2 when List.for_all2 (fun (x1, _) (x2, _) -> eq_id x1 x2) xts1 xts2 -> + TupT (List.map2 (fun (x1, t1) (_, t2) -> (x1, (overlap_typ env) t1 t2)) xts1 xts2) | IterT (t1, iter1), IterT (t2, iter2) when eq_iter iter1 iter2 -> IterT (overlap_typ env t1 t2, iter1) | _ -> assert false (* Unreachable due to IL validation *) @@ -218,17 +218,14 @@ let rec collect_unified template e = if eq_exp template e then [], [] else | IterE ({ it = VarE id; _}, _) , _ when is_unified_id id.it -> [IfPr (CmpE (`EqOp, `BoolT, template, e) $$ e.at % (BoolT $ e.at)) $ e.at], - [ExpB (id, template.note) $ e.at] + [ExpP (id, template.note) $ e.at] | UnE (_, _, e1), UnE (_, _, e2) - | DotE (e1, _), DotE (e2, _) | LiftE e1, LiftE e2 | LenE e1, LenE e2 | IterE (e1, _), IterE (e2, _) | ProjE (e1, _), ProjE (e2, _) - | UncaseE (e1, _), UncaseE (e2, _) | OptE (Some e1), OptE (Some e2) | TheE e1, TheE e2 - | CaseE (_, e1), CaseE (_, e2) | SubE (e1, _, _), SubE (e2, _, _) -> collect_unified e1 e2 | BinE (_, _, e1, e1'), BinE (_, _, e2, e2') | CmpE (_, _, e1, e1'), CmpE (_, _, e2, e2') @@ -236,8 +233,11 @@ let rec collect_unified template e = if eq_exp template e then [], [] else | UpdE (e1, _, e1'), UpdE (e2, _, e2') | ExtE (e1, _, e1'), ExtE (e2, _, e2') | CompE (e1, e1'), CompE (e2, e2') - | CatE (e1, e1'), CatE (e2, e2') -> pairwise_concat (collect_unified e1 e2) (collect_unified e1' e2') + | CatE (e1, e1'), CatE (e2, e2') | MemE (e1, e1'), MemE (e2, e2') -> pairwise_concat (collect_unified e1 e2) (collect_unified e1' e2') + | DotE (e1, _), DotE (e2, _) + | UncaseE (e1, _), UncaseE (e2, _) + | CaseE (_, e1), CaseE (_, e2) -> collect_unified e1 e2 | SliceE (e1, e1', e1''), SliceE (e2, e2', e2'') -> pairwise_concat (pairwise_concat (collect_unified e1 e2) (collect_unified e1' e2')) (collect_unified e1'' e2'') | StrE efs1, StrE efs2 -> diff --git a/spectec/src/middlend/sideconditions.ml b/spectec/src/middlend/sideconditions.ml index 5e3fa71818..7d9c3f1146 100644 --- a/spectec/src/middlend/sideconditions.ml +++ b/spectec/src/middlend/sideconditions.ml @@ -32,9 +32,7 @@ let iterPr (pr, (iter, vars)) = let vars' = List.filter (fun (id, _) -> Set.mem id.it frees.varid ) vars in - (* Must keep at least one variable to keep the iteration well-formed *) - let vars'' = if vars' <> [] then vars' else [List.hd vars] in - IterPr (pr, (iter, vars'')) + IterPr (pr, (iter, vars')) let is_null e = CmpE (`EqOp, `BoolT, e, OptE None $$ e.at % e.note) $$ e.at % (BoolT $ e.at) let iffE e1 e2 = IfPr (BinE (`EquivOp, `BoolT, e1, e2) $$ e1.at % (BoolT $ e1.at)) $ e1.at @@ -74,14 +72,11 @@ let rec t_exp env e : prem list = | VarE _ | BoolE _ | NumE _ | TextE _ | OptE None -> [] | UnE (_, _, exp) - | DotE (exp, _) | LenE exp | ProjE (exp, _) - | UncaseE (exp, _) | OptE (Some exp) | TheE exp | LiftE exp - | CaseE (_, exp) | CvtE (exp, _, _) | SubE (exp, _, _) -> t_exp env exp @@ -99,8 +94,12 @@ let rec t_exp env e : prem list = -> t_exp env exp1 @ t_path env path @ t_exp env exp2 | CallE (_, args) -> List.concat_map (t_arg env) args + | CaseE (_, exp) + | UncaseE (exp, _) + | DotE (exp, _) + -> t_exp env exp | StrE fields - -> List.concat_map (fun (_, e) -> t_exp env e) fields + -> List.concat_map (fun (_, exp) -> t_exp env exp) fields | TupE es | ListE es -> List.concat_map (t_exp env) es | IterE (e1, iterexp) @@ -167,16 +166,17 @@ let reduce_prems prems = prems |> Util.Lib.List.nub implies let t_rule' = function - | RuleD (id, binds, mixop, exp, prems) -> - let env = List.fold_left (fun env bind -> - match bind.it with - | ExpB (v, t) -> Env.add v.it t env - | TypB _ | DefB _ | GramB _ -> error bind.at "unexpected type argument in rule") Env.empty binds + | RuleD (id, params, mixop, exp, prems) -> + let env = List.fold_left (fun env param -> + match param.it with + | ExpP (v, t) -> Env.add v.it t env + | TypP _ | DefP _ | GramP _ -> error param.at "unexpected type argument in rule" + ) Env.empty params in let prems' = t_prems env prems in let extra_prems = t_exp env exp in let reduced_prems = reduce_prems (extra_prems @ prems') in - RuleD (id, binds, mixop, exp, reduced_prems) + RuleD (id, params, mixop, exp, reduced_prems) let t_rule x = { x with it = t_rule' x.it } diff --git a/spectec/src/middlend/sub.ml b/spectec/src/middlend/sub.ml index 97de47859d..1db340d051 100644 --- a/spectec/src/middlend/sub.ml +++ b/spectec/src/middlend/sub.ml @@ -63,7 +63,7 @@ let arg_of_param param = | ExpP (id, t) -> ExpA (VarE id $$ param.at % t) $ param.at | TypP id -> TypA (VarT (id, []) $ param.at) $ param.at | DefP (id, _ps, _t) -> DefA id $ param.at - | GramP (id, _t) -> GramA (VarG (id, []) $ param.at) $ param.at + | GramP (id, _ps, _t) -> GramA (VarG (id, []) $ param.at) $ param.at let register_variant (env : env) (id : id) params (cases : typcase list) = if M.mem id.it env.typ then @@ -132,10 +132,10 @@ and t_deftyp' env = function | StructT typfields -> StructT (List.map (t_typfield env) typfields) | VariantT typcases -> VariantT (List.map (t_typcase env) typcases) -and t_typfield env (atom, (binds, t, prems), hints) = - (atom, (t_binds env binds, t_typ env t, t_prems env prems), hints) -and t_typcase env (atom, (binds, t, prems), hints) = - (atom, (t_binds env binds, t_typ env t, t_prems env prems), hints) +and t_typfield env (atom, (t, quants, prems), hints) = + (atom, (t_typ env t, t_params env quants, t_prems env prems), hints) +and t_typcase env (atom, (t, quants, prems), hints) = + (atom, (t_typ env t, t_params env quants, t_prems env prems), hints) and t_exp2 env x = { x with it = t_exp' env x.it; note = t_typ env x.note } @@ -202,24 +202,15 @@ and t_arg' env = function and t_arg env x = { x with it = t_arg' env x.it } -and t_bind' env = function - | ExpB (id, t) -> ExpB (id, t_typ env t) - | TypB id -> TypB id - | DefB (id, ps, t) -> DefB (id, t_params env ps, t_typ env t) - | GramB (id, ps, t) -> GramB (id, t_params env ps, t_typ env t) - -and t_bind env x = { x with it = t_bind' env x.it } - and t_param' env = function | ExpP (id, t) -> ExpP (id, t_typ env t) | TypP id -> TypP id | DefP (id, ps, t) -> DefP (id, t_params env ps, t_typ env t) - | GramP (id, t) -> GramP (id, t_typ env t) + | GramP (id, ps, t) -> GramP (id, t_params env ps, t_typ env t) and t_param env x = { x with it = t_param' env x.it } and t_args env = List.map (t_arg env) -and t_binds env = List.map (t_bind env) and t_params env = List.map (t_param env) and t_prem' env = function @@ -234,32 +225,32 @@ and t_prem env x = { x with it = t_prem' env x.it } and t_prems env = List.map (t_prem env) let t_clause' env = function - | DefD (binds, lhs, rhs, prems) -> - DefD (t_binds env binds, (*DO NOT intro calls on LHS: t_args env*) lhs, t_exp env rhs, t_prems env prems) + | DefD (params, lhs, rhs, prems) -> + DefD (t_params env params, (*DO NOT intro calls on LHS: t_args env*) lhs, t_exp env rhs, t_prems env prems) let t_clause env (clause : clause) = { clause with it = t_clause' env clause.it } let t_clauses env = List.map (t_clause env) let t_inst' env = function - | InstD (binds, args, deftyp) -> - InstD (t_binds env binds, (*DO NOT intro calls on LHS: t_args env*) args, t_deftyp env deftyp) + | InstD (params, args, deftyp) -> + InstD (t_params env params, (*DO NOT intro calls on LHS: t_args env*) args, t_deftyp env deftyp) let t_inst env (inst : inst) = { inst with it = t_inst' env inst.it } let t_insts env = List.map (t_inst env) let t_prod' env = function - | ProdD (binds, lhs, rhs, prems) -> - ProdD (t_binds env binds, t_sym env lhs, t_exp env rhs, t_prems env prems) + | ProdD (params, lhs, rhs, prems) -> + ProdD (t_params env params, t_sym env lhs, t_exp env rhs, t_prems env prems) let t_prod env (prod : prod) = { prod with it = t_prod' env prod.it } let t_prods env = List.map (t_prod env) let t_rule' env = function - | RuleD (id, binds, mixop, exp, prems) -> - RuleD (id, t_binds env binds, mixop, t_exp env exp, t_prems env prems) + | RuleD (id, params, mixop, exp, prems) -> + RuleD (id, t_params env params, mixop, t_exp env exp, t_prems env prems) let t_rule env x = { x with it = t_rule' env x.it } @@ -315,9 +306,9 @@ let rec rename_params s = function let id' = (id.it ^ "_2") $ id.at in (DefP (id', ps, t) $ at) :: rename_params (Il.Subst.add_defid s id id') params - | { it = GramP (id, t); at; _ } :: params -> + | { it = GramP (id, ps, t); at; _ } :: params -> let id' = (id.it ^ "_2") $ id.at in - (GramP (id', t) $ at) :: + (GramP (id', ps, t) $ at) :: rename_params (Il.Subst.add_gramid s id (VarG (id', []) $ id.at)) params let insert_injections env (def : def) : def list = @@ -332,23 +323,23 @@ let insert_injections env (def : def) : def list = let sub_ty = VarT (sub, List.map arg_of_param params_sub) $ no_region in let sup_ty = VarT (sup, List.map arg_of_param params_sup') $ no_region in let real_ty = VarT (real_id_sub, args_sub) $ no_region in - let clauses = List.map (fun (a, (_binds, arg_typ, _prems), _hints) -> + let clauses = List.map (fun (a, (arg_typ, _quants, _prems), _hints) -> match arg_typ.it with | TupT ts -> - let binds = List.mapi (fun i (_, arg_typ_i) -> ExpB ("x" ^ string_of_int i $ no_region, arg_typ_i) $ no_region) ts in - let xes = List.map (fun bind -> - match bind.it with - | ExpB (x, arg_typ_i) -> VarE x $$ no_region % arg_typ_i - | TypB _ | DefB _ | GramB _ -> assert false) binds + let params = List.mapi (fun i (_, arg_typ_i) -> ExpP ("x" ^ string_of_int i $ no_region, arg_typ_i) $ no_region) ts in + let xes = List.map (fun param -> + match param.it with + | ExpP (x, arg_typ_i) -> VarE x $$ no_region % arg_typ_i + | TypP _ | DefP _ | GramP _ -> assert false) params in let xe = TupE xes $$ no_region % arg_typ in - DefD (binds, + DefD (params, [ExpA (CaseE (a, xe) $$ no_region % real_ty) $ no_region], CaseE (a, xe) $$ no_region % sup_ty, []) $ no_region | _ -> let x = "x" $ no_region in let xe = VarE x $$ no_region % arg_typ in - DefD ([ExpB (x, arg_typ) $ x.at], + DefD ([ExpP (x, arg_typ) $ x.at], [ExpA (CaseE (a, xe) $$ no_region % real_ty) $ no_region], CaseE (a, xe) $$ no_region % sup_ty, []) $ no_region ) cases_sub in diff --git a/spectec/src/middlend/totalize.ml b/spectec/src/middlend/totalize.ml index ea995d35db..c9813e737a 100644 --- a/spectec/src/middlend/totalize.ml +++ b/spectec/src/middlend/totalize.ml @@ -67,10 +67,10 @@ and t_deftyp' env = function | StructT typfields -> StructT (List.map (t_typfield env) typfields) | VariantT typcases -> VariantT (List.map (t_typcase env) typcases) -and t_typfield env (atom, (binds, t, prems), hints) = - (atom, (t_binds env binds, t_typ env t, t_prems env prems), hints) -and t_typcase env (atom, (binds, t, prems), hints) = - (atom, (t_binds env binds, t_typ env t, t_prems env prems), hints) +and t_typfield env (atom, (t, quants, prems), hints) = + (atom, (t_typ env t, t_params env quants, t_prems env prems), hints) +and t_typcase env (atom, (t, quants, prems), hints) = + (atom, (t_typ env t, t_params env quants, t_prems env prems), hints) (* Expr traversal *) @@ -140,24 +140,15 @@ and t_arg' env = function and t_arg env x = { x with it = t_arg' env x.it } -and t_bind' env = function - | ExpB (id, t) -> ExpB (id, t_typ env t) - | TypB id -> TypB id - | DefB (id, ps, t) -> DefB (id, t_params env ps, t_typ env t) - | GramB (id, ps, t) -> GramB (id, t_params env ps, t_typ env t) - -and t_bind env x = { x with it = t_bind' env x.it } - and t_param' env = function | ExpP (id, t) -> ExpP (id, t_typ env t) | TypP id -> TypP id | DefP (id, ps, t) -> DefP (id, t_params env ps, t_typ env t) - | GramP (id, t) -> GramP (id, t_typ env t) + | GramP (id, ps, t) -> GramP (id, t_params env ps, t_typ env t) and t_param env x = { x with it = t_param' env x.it } and t_args env = List.map (t_arg env) -and t_binds env = List.map (t_bind env) and t_params env = List.map (t_param env) and t_prem' env = function @@ -172,28 +163,28 @@ and t_prem env x = { x with it = t_prem' env x.it } and t_prems env = List.map (t_prem env) let t_clause' env = function - | DefD (binds, lhs, rhs, prems) -> - DefD (t_binds env binds, t_args env lhs, t_exp env rhs, t_prems env prems) + | DefD (params, lhs, rhs, prems) -> + DefD (t_params env params, t_args env lhs, t_exp env rhs, t_prems env prems) let t_clause env (clause : clause) = { clause with it = t_clause' env clause.it } let t_inst' env = function - | InstD (binds, args, deftyp) -> - InstD (t_binds env binds, t_args env args, t_deftyp env deftyp) + | InstD (params, args, deftyp) -> + InstD (t_params env params, t_args env args, t_deftyp env deftyp) let t_inst env (inst : inst) = { inst with it = t_inst' env inst.it } let t_insts env = List.map (t_inst env) let t_prod' env = function - | ProdD (binds, lhs, rhs, prems) -> - ProdD (t_binds env binds, t_sym env lhs, t_exp env rhs, t_prems env prems) + | ProdD (params, lhs, rhs, prems) -> + ProdD (t_params env params, t_sym env lhs, t_exp env rhs, t_prems env prems) let t_prod env (prod : prod) = { prod with it = t_prod' env prod.it } let t_rule' env = function - | RuleD (id, binds, mixop, exp, prems) -> - RuleD (id, t_binds env binds, mixop, t_exp env exp, t_prems env prems) + | RuleD (id, params, mixop, exp, prems) -> + RuleD (id, t_params env params, mixop, t_exp env exp, t_prems env prems) let t_rule env x = { x with it = t_rule' env x.it } @@ -206,19 +197,19 @@ let rec t_def' env = function if is_partial env id then let typ'' = IterT (typ', Opt) $ no_region in let clauses'' = List.map (fun clause -> match clause.it with - DefD (binds, lhs, rhs, prems) -> + DefD (params, lhs, rhs, prems) -> { clause with - it = DefD (t_binds env binds, lhs, OptE (Some rhs) $$ no_region % typ'', prems) } + it = DefD (t_params env params, lhs, OptE (Some rhs) $$ no_region % typ'', prems) } ) clauses' in - let binds, args = List.mapi (fun i param -> match param.it with + let params, args = List.mapi (fun i param -> match param.it with | ExpP (_, typI) -> let x = ("x" ^ string_of_int i) $ no_region in - [ExpB (x, typI) $ x.at], ExpA (VarE x $$ no_region % typI) $ no_region + [ExpP (x, typI) $ x.at], ExpA (VarE x $$ no_region % typI) $ no_region | TypP id -> [], TypA (VarT (id, []) $ no_region) $ no_region | DefP (id, _, _) -> [], DefA id $ no_region - | GramP (id, _) -> [], GramA (VarG (id, []) $ no_region) $ no_region + | GramP (id, _, _) -> [], GramA (VarG (id, []) $ no_region) $ no_region ) params' |> List.split in - let catch_all = DefD (List.concat binds, args, + let catch_all = DefD (List.concat params, args, OptE None $$ no_region % typ'', []) $ no_region in DecD (id, params', typ'', clauses'' @ [ catch_all ]) else diff --git a/spectec/src/middlend/unthe.ml b/spectec/src/middlend/unthe.ml index f1ec243a0d..7f4e024637 100644 --- a/spectec/src/middlend/unthe.ml +++ b/spectec/src/middlend/unthe.ml @@ -19,7 +19,7 @@ let error at msg = Error.error at "option projection" msg (* We pull out fresh variables and equating side conditions. *) -type eqn = bind * prem +type eqn = param * prem type eqns = eqn list (* Fresh name generation *) @@ -42,19 +42,19 @@ let update_iterexp_vars (sets : Il.Free.sets) ((iter, vs) : iterexp) : iterexp = | _ -> [List.hd vs] (* prevent empty iterator list *) in (iter, vs'') -(* If a bind and premise is generated under an iteration, wrap them accordingly *) +(* If a param and premise is generated under an iteration, wrap them accordingly *) let under_iterexp (iter, vs) eqns : iterexp * eqns = - let new_vs = List.map (fun (bind, _) -> - match bind.it with - | ExpB (v, t) -> + let new_vs = List.map (fun (param, _) -> + match param.it with + | ExpP (v, t) -> (v, VarE v $$ v.at % (IterT (t, match iter with Opt -> Opt | _ -> List) $ v.at)) - | TypB _ | DefB _ | GramB _ -> error bind.at "unexpected type binding" + | TypP _ | DefP _ | GramP _ -> error param.at "unexpected sort of parameter" ) eqns in - let eqns' = List.map2 (fun (bind, pr) (v, e) -> + let eqns' = List.map2 (fun (param, pr) (v, e) -> let iterexp' = update_iterexp_vars (Il.Free.free_prem pr) (iter, vs @ [(v, e)]) in let pr' = IterPr (pr, iterexp') $ no_region in - (ExpB (v, e.note) $ bind.at, pr') + (ExpP (v, e.note) $ param.at, pr') ) eqns new_vs in (iter, vs @ new_vs), eqns' @@ -104,11 +104,11 @@ let rec t_exp n e : eqns * exp = in let x = fresh_id n in let xe = VarE x $$ no_region % t in - let bind = ExpB (x, t) $ no_region in + let param = ExpP (x, t) $ no_region in let prem = IfPr ( CmpE (`EqOp, `BoolT, exp, OptE (Some xe) $$ no_region % ot) $$ no_region % (BoolT $ no_region) ) $ no_region in - eqns @ [(bind, prem)], xe + eqns @ [(param, prem)], xe | _ -> eqns, e' (* Traversal helpers *) @@ -164,12 +164,12 @@ and t_field n ((a, e) : expfield) = unary t_exp n e (fun e' -> (a, e')) and t_iterexp n iterexp = - binary t_iter t_iterbinds n iterexp Fun.id + binary t_iter t_iterparams n iterexp Fun.id -and t_iterbinds n binds = - t_list t_iterbind n binds Fun.id +and t_iterparams n params = + t_list t_iterparam n params Fun.id -and t_iterbind n (id, e) = +and t_iterparam n (id, e) = unary t_exp n e (fun e' -> (id, e')) and t_iter n iter = match iter with @@ -211,12 +211,12 @@ and t_prem' n prem : eqns * prem' = let t_prems n k = t_list t_prem n k (fun x -> x) let t_rule' = function - | RuleD (id, binds, mixop, exp, prems) -> + | RuleD (id, params, mixop, exp, prems) -> (* Counter for fresh variables *) let n = ref 0 in let eqns, (exp', prems') = binary t_exp t_prems n (exp, prems) (fun x -> x) in - let extra_binds, extra_prems = List.split eqns in - RuleD (id, binds @ extra_binds, mixop, exp', extra_prems @ prems') + let extra_params, extra_prems = List.split eqns in + RuleD (id, params @ extra_params, mixop, exp', extra_prems @ prems') let t_rule x = { x with it = t_rule' x.it } diff --git a/spectec/src/util/debug_log.ml b/spectec/src/util/debug_log.ml index 5b38b10d61..2442fce9bd 100644 --- a/spectec/src/util/debug_log.ml +++ b/spectec/src/util/debug_log.ml @@ -8,7 +8,7 @@ let log_exn _exn = if !active <> [] then Printf.eprintf "\n%s\n%!" (Printexc.get_backtrace ()) -let log_at (type a) label at (arg_f : unit -> string) (res_f : a -> string) (f : unit -> a) : a = +let log_at' (type a) label at (arg_f : unit -> string) (res_f : a -> string option) (f : unit -> a) : a = if not (label = "" || List.exists (fun s -> String.starts_with ~prefix: s label) !active) then f () else let ats = if at = Source.no_region then "" else " " ^ Source.string_of_region at in let arg = arg_f () in @@ -19,11 +19,12 @@ let log_at (type a) label at (arg_f : unit -> string) (res_f : a -> string) (f : Printf.eprintf "[%s%s] %s => raise %s\n%!" label ats arg (Printexc.to_string exn); Printexc.raise_with_backtrace exn bt | x -> - let res = res_f x in - if res <> "" then Printf.eprintf "[%s%s] %s => %s\n%!" label ats arg res; + res_f x |> Option.iter (fun res -> + Printf.eprintf "[%s%s] %s => %s\n%!" label ats arg res); x -let log_in_at label at arg_f = log_at label at arg_f (Fun.const "") Fun.id +let log_at label at arg_f res_f = log_at' label at arg_f (fun x -> Some (res_f x)) +let log_in_at label at arg_f = log_at' label at arg_f (Fun.const None) Fun.id let log_in label = log_in_at label Source.no_region let log label = log_at label Source.no_region let log_if_at label at b arg_f res_f f = if b then log_at label at arg_f res_f f else f () @@ -32,11 +33,14 @@ let log_if label = log_if_at label Source.no_region module MySet = Set.Make(String) module MyMap = Map.Make(String) +let quote x = "`" ^ x ^ "`" +let pair f s g (x, y) = f x ^ s ^ g y let opt f = function None -> "-" | Some x -> f x let result f g = function Ok x -> f x | Error y -> g y let seq f xs = String.concat " " (List.map f xs) let list f xs = String.concat ", " (List.map f xs) let set s = seq Fun.id (MySet.elements s) +let domain m = seq fst (MyMap.bindings m) let mapping f m = seq (fun (x, y) -> x ^ "=" ^ f y) (MyMap.bindings m) let qline _ = "--------------------" diff --git a/spectec/src/util/lib.ml b/spectec/src/util/lib.ml index 351ed0a24c..6ad5a31025 100644 --- a/spectec/src/util/lib.ml +++ b/spectec/src/util/lib.ml @@ -1,3 +1,7 @@ +let fst3 (x, _, _) = x +let snd3 (_, y, _) = y +let thd3 (_, _, z) = z + module List = struct include List diff --git a/spectec/src/util/lib.mli b/spectec/src/util/lib.mli index 56e29ffc52..b959912e8f 100644 --- a/spectec/src/util/lib.mli +++ b/spectec/src/util/lib.mli @@ -1,5 +1,9 @@ (* Things that should be in the OCaml library... *) +val fst3 : 'a * 'b * 'c -> 'a +val snd3 : 'a * 'b * 'c -> 'b +val thd3 : 'a * 'b * 'c -> 'c + module List : sig val take : int -> 'a list -> 'a list (* raises Failure *) diff --git a/spectec/src/xl/dune b/spectec/src/xl/dune index 95adcc4b49..ab8ef18e0f 100644 --- a/spectec/src/xl/dune +++ b/spectec/src/xl/dune @@ -1,5 +1,5 @@ (library (name xl) (libraries util zarith) - (modules bool num atom mixop) + (modules bool num atom mixop gen_free) ) diff --git a/spectec/src/xl/gen_free.ml b/spectec/src/xl/gen_free.ml new file mode 100644 index 0000000000..231dda5d80 --- /dev/null +++ b/spectec/src/xl/gen_free.ml @@ -0,0 +1,90 @@ +open Util.Source + + +(* Data Structure *) + +module Set = Set.Make(String) + +type id = string phrase + +type sets = + {typid : Set.t; relid : Set.t; varid : Set.t; defid : Set.t; gramid : Set.t} + +let empty = + { typid = Set.empty; + relid = Set.empty; + varid = Set.empty; + defid = Set.empty; + gramid = Set.empty + } + +let union sets1 sets2 = + { typid = Set.union sets1.typid sets2.typid; + relid = Set.union sets1.relid sets2.relid; + varid = Set.union sets1.varid sets2.varid; + defid = Set.union sets1.defid sets2.defid; + gramid = Set.union sets1.gramid sets2.gramid; + } + +let inter sets1 sets2 = + { typid = Set.inter sets1.typid sets2.typid; + gramid = Set.inter sets1.gramid sets2.gramid; + relid = Set.inter sets1.relid sets2.relid; + varid = Set.inter sets1.varid sets2.varid; + defid = Set.inter sets1.defid sets2.defid; + } + +let diff sets1 sets2 = + { typid = Set.diff sets1.typid sets2.typid; + relid = Set.diff sets1.relid sets2.relid; + varid = Set.diff sets1.varid sets2.varid; + defid = Set.diff sets1.defid sets2.defid; + gramid = Set.diff sets1.gramid sets2.gramid; + } + +let ( ++ ) = union +let ( ** ) = inter +let ( -- ) = diff + +let subset sets1 sets2 = + Set.subset sets1.typid sets2.typid && + Set.subset sets1.relid sets2.relid && + Set.subset sets1.varid sets2.varid && + Set.subset sets1.defid sets2.defid && + Set.subset sets1.gramid sets2.gramid + +let disjoint sets1 sets2 = + Set.disjoint sets1.typid sets2.typid && + Set.disjoint sets1.relid sets2.relid && + Set.disjoint sets1.varid sets2.varid && + Set.disjoint sets1.defid sets2.defid && + Set.disjoint sets1.gramid sets2.gramid + + +(* Identifiers *) + +let free_typid x = {empty with typid = Set.singleton x.it} +let free_relid x = {empty with relid = Set.singleton x.it} +let free_varid x = {empty with varid = Set.singleton x.it} +let free_defid x = {empty with defid = Set.singleton x.it} +let free_gramid x = {empty with gramid = Set.singleton x.it} + +let bound_typid x = if x.it = "_" then empty else free_typid x +let bound_relid x = if x.it = "_" then empty else free_relid x +let bound_varid x = if x.it = "_" then empty else free_varid x +let bound_defid x = if x.it = "_" then empty else free_defid x +let bound_gramid x = if x.it = "_" then empty else free_gramid x + + +(* Aggregates *) + +let free_empty _ = empty +let free_pair free_x free_y (x, y) = free_x x ++ free_y y +let free_opt free_x xo = Option.(value (map free_x xo) ~default:empty) +let free_list free_x xs = List.(fold_left (++) empty (map free_x xs)) + +let rec free_list_dep free_x bound_x = function + | [] -> empty + | x::xs -> free_x x ++ (free_list_dep free_x bound_x xs -- bound_x x) + +let bound_list = free_list diff --git a/spectec/src/xl/gen_free.mli b/spectec/src/xl/gen_free.mli new file mode 100644 index 0000000000..8c2983fe81 --- /dev/null +++ b/spectec/src/xl/gen_free.mli @@ -0,0 +1,37 @@ +module Set : Set.S with type elt = string with type t = Set.Make(String).t + +type id = string Util.Source.phrase + +type sets = {typid : Set.t; relid : Set.t; varid : Set.t; defid : Set.t; gramid : Set.t} + +val empty : sets +val union : sets -> sets -> sets +val inter : sets -> sets -> sets +val diff : sets -> sets -> sets + +val ( ++ ) : sets -> sets -> sets (* union *) +val ( ** ) : sets -> sets -> sets (* intersection *) +val ( -- ) : sets -> sets -> sets (* difference *) + +val subset : sets -> sets -> bool +val disjoint : sets -> sets -> bool + +val free_typid : id -> sets +val free_relid : id -> sets +val free_varid : id -> sets +val free_defid : id -> sets +val free_gramid : id -> sets + +val bound_typid : id -> sets +val bound_relid : id -> sets +val bound_varid : id -> sets +val bound_defid : id -> sets +val bound_gramid : id -> sets + +val free_empty : 'a -> sets +val free_pair : ('a -> sets) -> ('b -> sets) -> 'a * 'b -> sets +val free_opt : ('a -> sets) -> 'a option -> sets +val free_list : ('a -> sets) -> 'a list -> sets +val free_list_dep : ('a -> sets) -> ('a -> sets) -> 'a list -> sets + +val bound_list : ('a -> sets) -> 'a list -> sets diff --git a/spectec/src/xl/mixop.ml b/spectec/src/xl/mixop.ml index 0a61c67445..221fb279af 100644 --- a/spectec/src/xl/mixop.ml +++ b/spectec/src/xl/mixop.ml @@ -1,25 +1,91 @@ -open Util.Source +open Util type atom = Atom.atom -type mixop = atom list list +type 'a mixop = + | Arg of 'a + | Atom of atom + | Brack of atom * 'a mixop * atom + | Infix of 'a mixop * atom * 'a mixop + | Seq of 'a mixop list + + +let rec map f mixop = + match mixop with + | Arg x -> Arg (f x) + | Atom at -> Atom at + | Brack (at1, mixop, at2) -> Brack (at1, map f mixop, at2) + | Infix (mixop1, at, mixop2) -> + let mixop1' = map f mixop1 in + let mixop2' = map f mixop2 in + Infix (mixop1', at, mixop2') + | Seq mixops -> Seq (List.map (map f) mixops) + +let rec fold f x mixop = + match mixop with + | Arg y -> f x y + | Atom _ -> x + | Brack (_, mixop, _) -> fold f x mixop + | Infix (mixop1, _, mixop2) -> fold f (fold f x mixop1) mixop2 + | Seq mixops -> List.fold_left (fold f) x mixops + +let rec map_atoms f mixop = + match mixop with + | Arg x -> Arg x + | Atom at -> Atom (f at) + | Brack (at1, mixop, at2) -> Brack (f at1, map_atoms f mixop, f at2) + | Infix (mixop1, at, mixop2) -> + Infix (map_atoms f mixop1, f at, map_atoms f mixop2) + | Seq mixops -> Seq (List.map (map_atoms f) mixops) + + +let arity mixop = fold (fun n _ -> n + 1) 0 mixop + +let apply mixop xs = + let rxs = ref xs in + let mixop' = + map (fun _ -> let xs = !rxs in rxs := List.tl xs; List.hd xs) mixop in + assert (!rxs = []); + mixop' + + +let (++) atomss1 atomss2 = + let atomss1', atoms1 = Lib.List.split_last atomss1 in + let atoms2, atomss2' = Lib.List.split_hd atomss2 in + atomss1' @ [atoms1 @ atoms2] @ atomss2' + +let rec head = function + | Arg _ | Seq [] -> None + | Atom atom | Brack (atom, _, _) | Infix (_, atom, _) -> Some atom + | Seq (mixop::mixops) -> + match head mixop with + | None -> head (Seq mixops) + | some -> some + +let rec flatten = function + | Arg _ -> [[]; []] + | Atom atom -> [[atom]] + | Brack (l, mixop, r) -> [[l]] ++ flatten mixop ++ [[r]] + | Infix (mixop1, atom, mixop2) -> flatten mixop1 ++ [[atom]] ++ flatten mixop2 + | Seq mixops -> List.fold_left (++) [[]] (List.map flatten mixops) let compare mixop1 mixop2 = - List.compare (List.compare Atom.compare) mixop1 mixop2 + List.compare (List.compare Atom.compare) (flatten mixop1) (flatten mixop2) let eq mixop1 mixop2 = compare mixop1 mixop2 = 0 +let rec to_string_with f s = function + | Arg x -> f x + | Seq mixops -> String.concat s (List.map (to_string_with f s) mixops) + | Atom atom -> Atom.to_string atom + | Brack (l, mixop, r) -> + Atom.to_string l ^ to_string_with f s mixop ^ Atom.to_string r + | Infix (mixop1, atom, mixop2) -> + to_string_with f s mixop1 ^ Atom.to_string atom ^ to_string_with f s mixop2 + +let is_arg = function Arg _ -> true | _ -> false let to_string = function - | [{it = Atom.Atom a; _}]::tail when List.for_all ((=) []) tail -> a - | mixop -> - let s = - String.concat "%" (List.map ( - fun atoms -> String.concat "" (List.map Atom.to_string atoms)) mixop - ) - in - "`" ^ s ^ "`" - -let name mixop = - String.concat "" (List.map Atom.name mixop) + | Seq (Atom a :: tail) when List.for_all is_arg tail -> Atom.to_string a + | mixop -> to_string_with (Fun.const "%") "" mixop diff --git a/spectec/test-frontend/TEST.md b/spectec/test-frontend/TEST.md index 60c4bfc6d4..3ce2962b94 100644 --- a/spectec/test-frontend/TEST.md +++ b/spectec/test-frontend/TEST.md @@ -87,7 +87,7 @@ def $concatn_(syntax X, X**, nat : nat) : X* ;; ../../../../specification/wasm-3.0/0.3-aux.seq.spectec:19.1-19.38 def $concatn_{syntax X, n : n}(syntax X, [], n) = [] ;; ../../../../specification/wasm-3.0/0.3-aux.seq.spectec:20.1-20.73 - def $concatn_{syntax X, `w*` : X*, n : n, `w'**` : X**}(syntax X, [w^n{w <- `w*`}] ++ w'^n{w' <- `w'*`}*{`w'*` <- `w'**`}, n) = w^n{w <- `w*`} ++ $concatn_(syntax X, w'^n{w' <- `w'*`}*{`w'*` <- `w'**`}, n) + def $concatn_{syntax X, n : n, `w*` : X*, `w'**` : X**}(syntax X, [w^n{w <- `w*`}] ++ w'^n{w' <- `w'*`}*{`w'*` <- `w'**`}, n) = w^n{w <- `w*`} ++ $concatn_(syntax X, w'^n{w' <- `w'*`}*{`w'*` <- `w'**`}, n) } ;; ../../../../specification/wasm-3.0/0.3-aux.seq.spectec @@ -178,22 +178,22 @@ def $ND : bool ;; ../../../../specification/wasm-3.0/1.1-syntax.values.spectec syntax bit = - | `%`{i : nat}(i : nat) + | `%`(i : nat) -- if ((i = 0) \/ (i = 1)) ;; ../../../../specification/wasm-3.0/1.1-syntax.values.spectec syntax byte = - | `%`{i : nat}(i : nat) + | `%`(i : nat) -- if ((i >= 0) /\ (i <= 255)) ;; ../../../../specification/wasm-3.0/1.1-syntax.values.spectec syntax uN{N : N}(N) = - | `%`{i : nat}(i : nat) + | `%`(i : nat) -- if ((i >= 0) /\ (i <= ((((2 ^ N) : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) ;; ../../../../specification/wasm-3.0/1.1-syntax.values.spectec syntax sN{N : N}(N) = - | `%`{i : int}(i : int) + | `%`(i : int) -- if ((((i >= - ((2 ^ (((N : nat <:> int) - (1 : nat <:> int)) : int <:> nat)) : nat <:> int)) /\ (i <= - (1 : nat <:> int))) \/ (i = (0 : nat <:> int))) \/ ((i >= + (1 : nat <:> int)) /\ (i <= (+ ((2 ^ (((N : nat <:> int) - (1 : nat <:> int)) : int <:> nat)) : nat <:> int) - (1 : nat <:> int))))) ;; ../../../../specification/wasm-3.0/1.1-syntax.values.spectec @@ -255,18 +255,18 @@ syntax exp = int ;; ../../../../specification/wasm-3.0/1.1-syntax.values.spectec syntax fNmag{N : N}(N) = - | NORM{m : m, exp : exp}(m : m, exp : exp) + | NORM(m : m, exp : exp) -- if ((m < (2 ^ $M(N))) /\ ((((2 : nat <:> int) - ((2 ^ ((($E(N) : nat <:> int) - (1 : nat <:> int)) : int <:> nat)) : nat <:> int)) <= exp) /\ (exp <= (((2 ^ ((($E(N) : nat <:> int) - (1 : nat <:> int)) : int <:> nat)) : nat <:> int) - (1 : nat <:> int))))) - | SUBNORM{m : m, exp : exp}(m : m) + | SUBNORM(m : m) {exp : exp} -- if ((m < (2 ^ $M(N))) /\ (((2 : nat <:> int) - ((2 ^ ((($E(N) : nat <:> int) - (1 : nat <:> int)) : int <:> nat)) : nat <:> int)) = exp)) | INF - | NAN{m : m}(m : m) + | NAN(m : m) -- if ((1 <= m) /\ (m < (2 ^ $M(N)))) ;; ../../../../specification/wasm-3.0/1.1-syntax.values.spectec syntax fN{N : N}(N) = - | POS{fNmag : fNmag(N)}(fNmag : fNmag(N)) - | NEG{fNmag : fNmag(N)}(fNmag : fNmag(N)) + | POS(fNmag(N)) + | NEG(fNmag(N)) ;; ../../../../specification/wasm-3.0/1.1-syntax.values.spectec syntax f32 = fN(32) @@ -302,12 +302,12 @@ syntax v128 = vN(128) ;; ../../../../specification/wasm-3.0/1.1-syntax.values.spectec syntax list{syntax X}(syntax X) = - | `%`{`X*` : X*}(X*{X <- `X*`} : X*) + | `%`(`X*` : X*) -- if (|X*{X <- `X*`}| < (2 ^ 32)) ;; ../../../../specification/wasm-3.0/1.1-syntax.values.spectec syntax char = - | `%`{i : nat}(i : nat) + | `%`(i : nat) -- if (((i >= 0) /\ (i <= 55295)) \/ ((i >= 57344) /\ (i <= 1114111))) ;; ../../../../specification/wasm-3.0/5.1-binary.values.spectec @@ -343,7 +343,7 @@ def $utf8(char*) : byte* ;; ../../../../specification/wasm-3.0/1.1-syntax.values.spectec syntax name = - | `%`{`char*` : char*}(char*{char <- `char*`} : char*) + | `%`(`char*` : char*) -- if (|$utf8(char*{char <- `char*`})| < (2 ^ 32)) ;; ../../../../specification/wasm-3.0/1.1-syntax.values.spectec @@ -387,11 +387,11 @@ syntax fieldidx = idx ;; ../../../../specification/wasm-3.0/1.1-syntax.values.spectec syntax externidx = - | FUNC{funcidx : funcidx}(funcidx : funcidx) - | GLOBAL{globalidx : globalidx}(globalidx : globalidx) - | TABLE{tableidx : tableidx}(tableidx : tableidx) - | MEM{memidx : memidx}(memidx : memidx) - | TAG{tagidx : tagidx}(tagidx : tagidx) + | FUNC(funcidx : funcidx) + | GLOBAL(globalidx : globalidx) + | TABLE(tableidx : tableidx) + | MEM(memidx : memidx) + | TAG(tagidx : tagidx) ;; ../../../../specification/wasm-3.0/1.1-syntax.values.spectec rec { @@ -466,15 +466,15 @@ def $tagsxx(externidx*) : tagidx* ;; ../../../../specification/wasm-3.0/1.1-syntax.values.spectec syntax free = { - TYPES{`typeidx*` : typeidx*} typeidx*, - FUNCS{`funcidx*` : funcidx*} funcidx*, - GLOBALS{`globalidx*` : globalidx*} globalidx*, - TABLES{`tableidx*` : tableidx*} tableidx*, - MEMS{`memidx*` : memidx*} memidx*, - ELEMS{`elemidx*` : elemidx*} elemidx*, - DATAS{`dataidx*` : dataidx*} dataidx*, - LOCALS{`localidx*` : localidx*} localidx*, - LABELS{`labelidx*` : labelidx*} labelidx* + TYPES typeidx*, + FUNCS funcidx*, + GLOBALS globalidx*, + TABLES tableidx*, + MEMS memidx*, + ELEMS elemidx*, + DATAS dataidx*, + LOCALS localidx*, + LABELS labelidx* } ;; ../../../../specification/wasm-3.0/1.1-syntax.values.spectec @@ -608,9 +608,9 @@ rec { ;; ../../../../specification/wasm-3.0/1.2-syntax.types.spectec:37.1-38.43 syntax typeuse = - | _IDX{typeidx : typeidx}(typeidx : typeidx) - | _DEF{rectype : rectype, n : n}(rectype : rectype, n : n) - | REC{n : n}(n : n) + | _IDX(typeidx : typeidx) + | _DEF(rectype : rectype, n : n) + | REC(n : n) ;; ../../../../specification/wasm-3.0/1.2-syntax.types.spectec:43.1-44.26 syntax heaptype = @@ -627,9 +627,9 @@ syntax heaptype = | EXTERN | NOEXTERN | BOT - | _IDX{typeidx : typeidx}(typeidx : typeidx) - | REC{n : n}(n : n) - | _DEF{rectype : rectype, n : n}(rectype : rectype, n : n) + | _IDX(typeidx : typeidx) + | _DEF(rectype : rectype, n : n) + | REC(n : n) ;; ../../../../specification/wasm-3.0/1.2-syntax.types.spectec:51.1-52.14 syntax valtype = @@ -638,18 +638,18 @@ syntax valtype = | F32 | F64 | V128 - | REF{`null?` : null?, heaptype : heaptype}(null?{null <- `null?`} : null?, heaptype : heaptype) + | REF(`null?` : null?, heaptype : heaptype) | BOT ;; ../../../../specification/wasm-3.0/1.2-syntax.types.spectec:92.1-92.66 syntax storagetype = - | BOT | I32 | I64 | F32 | F64 | V128 - | REF{`null?` : null?, heaptype : heaptype}(null?{null <- `null?`} : null?, heaptype : heaptype) + | REF(`null?` : null?, heaptype : heaptype) + | BOT | I8 | I16 @@ -658,35 +658,35 @@ syntax resulttype = list(syntax valtype) ;; ../../../../specification/wasm-3.0/1.2-syntax.types.spectec:112.1-112.61 syntax fieldtype = - | `%%`{`mut?` : mut?, storagetype : storagetype}(mut?{mut <- `mut?`} : mut?, storagetype : storagetype) + | `%%`(`mut?` : mut?, storagetype : storagetype) ;; ../../../../specification/wasm-3.0/1.2-syntax.types.spectec:114.1-117.34 syntax comptype = - | STRUCT{list : list(syntax fieldtype)}(list : list(syntax fieldtype)) - | ARRAY{fieldtype : fieldtype}(fieldtype : fieldtype) - | `FUNC%->%`{resulttype : resulttype}(resulttype : resulttype, resulttype) + | STRUCT(list(syntax fieldtype)) + | ARRAY(fieldtype : fieldtype) + | `FUNC%->%`(resulttype : resulttype, resulttype : resulttype) ;; ../../../../specification/wasm-3.0/1.2-syntax.types.spectec:119.1-120.33 syntax subtype = - | SUB{`final?` : final?, `typeuse*` : typeuse*, comptype : comptype}(final?{final <- `final?`} : final?, typeuse*{typeuse <- `typeuse*`} : typeuse*, comptype : comptype) + | SUB(`final?` : final?, `typeuse*` : typeuse*, comptype : comptype) ;; ../../../../specification/wasm-3.0/1.2-syntax.types.spectec:122.1-123.22 syntax rectype = - | REC{list : list(syntax subtype)}(list : list(syntax subtype)) + | REC(list(syntax subtype)) } ;; ../../../../specification/wasm-3.0/1.2-syntax.types.spectec syntax deftype = - | _DEF{rectype : rectype, n : n}(rectype : rectype, n : n) + | _DEF(rectype : rectype, n : n) ;; ../../../../specification/wasm-3.0/1.2-syntax.types.spectec syntax typevar = - | _IDX{typeidx : typeidx}(typeidx : typeidx) - | REC{n : n}(n : n) + | _IDX(typeidx : typeidx) + | REC(n : n) ;; ../../../../specification/wasm-3.0/1.2-syntax.types.spectec syntax reftype = - | REF{`null?` : null?, heaptype : heaptype}(null?{null <- `null?`} : null?, heaptype : heaptype) + | REF(`null?` : null?, heaptype : heaptype) ;; ../../../../specification/wasm-3.0/1.2-syntax.types.spectec syntax Inn = @@ -805,22 +805,22 @@ syntax Lnn = ;; ../../../../specification/wasm-3.0/1.2-syntax.types.spectec syntax limits = - | `[%..%]`{u64 : u64}(u64 : u64, u64?) + | `[%..%]`(u64 : u64, `u64?` : u64?) ;; ../../../../specification/wasm-3.0/1.2-syntax.types.spectec syntax tagtype = typeuse ;; ../../../../specification/wasm-3.0/1.2-syntax.types.spectec syntax globaltype = - | `%%`{`mut?` : mut?, valtype : valtype}(mut?{mut <- `mut?`} : mut?, valtype : valtype) + | `%%`(`mut?` : mut?, valtype : valtype) ;; ../../../../specification/wasm-3.0/1.2-syntax.types.spectec syntax memtype = - | `%%PAGE`{addrtype : addrtype, limits : limits}(addrtype : addrtype, limits : limits) + | `%%PAGE`(addrtype : addrtype, limits : limits) ;; ../../../../specification/wasm-3.0/1.2-syntax.types.spectec syntax tabletype = - | `%%%`{addrtype : addrtype, limits : limits, reftype : reftype}(addrtype : addrtype, limits : limits, reftype : reftype) + | `%%%`(addrtype : addrtype, limits : limits, reftype : reftype) ;; ../../../../specification/wasm-3.0/1.2-syntax.types.spectec syntax datatype = @@ -831,15 +831,15 @@ syntax elemtype = reftype ;; ../../../../specification/wasm-3.0/1.2-syntax.types.spectec syntax externtype = - | TAG{tagtype : tagtype}(tagtype : tagtype) - | GLOBAL{globaltype : globaltype}(globaltype : globaltype) - | MEM{memtype : memtype}(memtype : memtype) - | TABLE{tabletype : tabletype}(tabletype : tabletype) - | FUNC{typeuse : typeuse}(typeuse : typeuse) + | TAG(tagtype : tagtype) + | GLOBAL(globaltype : globaltype) + | MEM(memtype : memtype) + | TABLE(tabletype : tabletype) + | FUNC(typeuse : typeuse) ;; ../../../../specification/wasm-3.0/1.2-syntax.types.spectec syntax moduletype = - | `%->%`{`externtype*` : externtype*}(externtype*{externtype <- `externtype*`} : externtype*, externtype*) + | `%->%`(`externtype*` : externtype*, `externtype*` : externtype*) ;; ../../../../specification/wasm-3.0/1.2-syntax.types.spectec def $IN(N : N) : Inn @@ -1283,47 +1283,47 @@ def $subst_moduletype(moduletype : moduletype, typevar*, typeuse*) : moduletype ;; ../../../../specification/wasm-3.0/1.2-syntax.types.spectec def $subst_all_valtype(valtype : valtype, typeuse*) : valtype ;; ../../../../specification/wasm-3.0/1.2-syntax.types.spectec - def $subst_all_valtype{t : valtype, `tu*` : typeuse*, n : n, `i*` : nat*}(t, tu^n{tu <- `tu*`}) = $subst_valtype(t, _IDX_typevar(`%`_typeidx(i))^(i $sizenn2((Inn_2 : Inn <: numtype))) @@ -1678,15 +1678,15 @@ syntax cvtop__(numtype_1 : numtype, numtype_2 : numtype) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec syntax cvtop__{Inn_1 : Inn, Fnn_2 : Fnn}((Inn_1 : Inn <: numtype), (Fnn_2 : Fnn <: numtype)) = - | CONVERT{sx : sx}(sx : sx) + | CONVERT(sx : sx) | REINTERPRET -- if ($sizenn1((Inn_1 : Inn <: numtype)) = $sizenn2((Fnn_2 : Fnn <: numtype))) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec syntax cvtop__{Fnn_1 : Fnn, Inn_2 : Inn}((Fnn_1 : Fnn <: numtype), (Inn_2 : Inn <: numtype)) = - | TRUNC{sx : sx}(sx : sx) - | TRUNC_SAT{sx : sx}(sx : sx) + | TRUNC(sx : sx) + | TRUNC_SAT(sx : sx) | REINTERPRET -- if ($sizenn1((Fnn_1 : Fnn <: numtype)) = $sizenn2((Inn_2 : Inn <: numtype))) @@ -1701,12 +1701,12 @@ syntax cvtop__(numtype_1 : numtype, numtype_2 : numtype) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec syntax dim = - | `%`{i : nat}(i : nat) + | `%`(i : nat) -- if (((((i = 1) \/ (i = 2)) \/ (i = 4)) \/ (i = 8)) \/ (i = 16)) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec syntax shape = - | `%X%`{lanetype : lanetype, dim : dim}(lanetype : lanetype, dim : dim) + | `%X%`(lanetype : lanetype, dim : dim) -- if (($lsize(lanetype) * dim!`%`_dim.0) = 128) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec @@ -1726,12 +1726,12 @@ def $unpackshape(shape : shape) : numtype ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec syntax ishape = - | `%`{shape : shape, Jnn : Jnn}(shape : shape) + | `%`(shape : shape) {Jnn : Jnn} -- if ($lanetype(shape) = (Jnn : Jnn <: lanetype)) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec syntax bshape = - | `%`{shape : shape}(shape : shape) + | `%`(shape : shape) -- if ($lanetype(shape) = I8_lanetype) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec @@ -1789,21 +1789,21 @@ syntax vbinop_(shape : shape) syntax vbinop_{Jnn : Jnn, M : M}(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M))) = | ADD | SUB - | ADD_SAT{sx : sx}(sx : sx) + | ADD_SAT(sx : sx) -- if ($lsizenn((Jnn : Jnn <: lanetype)) <= 16) - | SUB_SAT{sx : sx}(sx : sx) + | SUB_SAT(sx : sx) -- if ($lsizenn((Jnn : Jnn <: lanetype)) <= 16) | MUL -- if ($lsizenn((Jnn : Jnn <: lanetype)) >= 16) - | `AVGRU` + | AVGRU -- if ($lsizenn((Jnn : Jnn <: lanetype)) <= 16) - | `Q15MULR_SATS` + | Q15MULR_SATS -- if ($lsizenn((Jnn : Jnn <: lanetype)) = 16) - | `RELAXED_Q15MULRS` + | RELAXED_Q15MULRS -- if ($lsizenn((Jnn : Jnn <: lanetype)) = 16) - | MIN{sx : sx}(sx : sx) + | MIN(sx : sx) -- if ($lsizenn((Jnn : Jnn <: lanetype)) <= 32) - | MAX{sx : sx}(sx : sx) + | MAX(sx : sx) -- if ($lsizenn((Jnn : Jnn <: lanetype)) <= 32) @@ -1844,13 +1844,13 @@ syntax vrelop_(shape : shape) syntax vrelop_{Jnn : Jnn, M : M}(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M))) = | EQ | NE - | LT{sx : sx}(sx : sx) + | LT(sx : sx) -- if (($lsizenn((Jnn : Jnn <: lanetype)) =/= 64) \/ (sx = S_sx)) - | GT{sx : sx}(sx : sx) + | GT(sx : sx) -- if (($lsizenn((Jnn : Jnn <: lanetype)) =/= 64) \/ (sx = S_sx)) - | LE{sx : sx}(sx : sx) + | LE(sx : sx) -- if (($lsizenn((Jnn : Jnn <: lanetype)) =/= 64) \/ (sx = S_sx)) - | GE{sx : sx}(sx : sx) + | GE(sx : sx) -- if (($lsizenn((Jnn : Jnn <: lanetype)) =/= 64) \/ (sx = S_sx)) @@ -1867,7 +1867,7 @@ syntax vrelop_(shape : shape) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec syntax vshiftop_{Jnn : Jnn, M : M}(`%`_ishape(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M)))) = | SHL - | SHR{sx : sx}(sx : sx) + | SHR(sx : sx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec syntax vswizzlop_{M : M}(`%`_bshape(`%X%`_shape(I8_lanetype, `%`_dim(M)))) = @@ -1876,82 +1876,82 @@ syntax vswizzlop_{M : M}(`%`_bshape(`%X%`_shape(I8_lanetype, `%`_dim(M)))) = ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec syntax vextunop__{Jnn_1 : Jnn, M_1 : M, Jnn_2 : Jnn, M_2 : M}(`%`_ishape(`%X%`_shape((Jnn_1 : Jnn <: lanetype), `%`_dim(M_1))), `%`_ishape(`%X%`_shape((Jnn_2 : Jnn <: lanetype), `%`_dim(M_2)))) = - | EXTADD_PAIRWISE{sx : sx}(sx : sx) + | EXTADD_PAIRWISE(sx : sx) -- if ((16 <= (2 * $lsizenn1((Jnn_1 : Jnn <: lanetype)))) /\ (((2 * $lsizenn1((Jnn_1 : Jnn <: lanetype))) = $lsizenn2((Jnn_2 : Jnn <: lanetype))) /\ ($lsizenn2((Jnn_2 : Jnn <: lanetype)) <= 32))) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec syntax vextbinop__{Jnn_1 : Jnn, M_1 : M, Jnn_2 : Jnn, M_2 : M}(`%`_ishape(`%X%`_shape((Jnn_1 : Jnn <: lanetype), `%`_dim(M_1))), `%`_ishape(`%X%`_shape((Jnn_2 : Jnn <: lanetype), `%`_dim(M_2)))) = - | EXTMUL{half : half, sx : sx}(half : half, sx : sx) + | EXTMUL(half : half, sx : sx) -- if (((2 * $lsizenn1((Jnn_1 : Jnn <: lanetype))) = $lsizenn2((Jnn_2 : Jnn <: lanetype))) /\ ($lsizenn2((Jnn_2 : Jnn <: lanetype)) >= 16)) - | `DOTS` + | DOTS -- if (((2 * $lsizenn1((Jnn_1 : Jnn <: lanetype))) = $lsizenn2((Jnn_2 : Jnn <: lanetype))) /\ ($lsizenn2((Jnn_2 : Jnn <: lanetype)) = 32)) - | `RELAXED_DOTS` + | RELAXED_DOTS -- if (((2 * $lsizenn1((Jnn_1 : Jnn <: lanetype))) = $lsizenn2((Jnn_2 : Jnn <: lanetype))) /\ ($lsizenn2((Jnn_2 : Jnn <: lanetype)) = 16)) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec syntax vextternop__{Jnn_1 : Jnn, M_1 : M, Jnn_2 : Jnn, M_2 : M}(`%`_ishape(`%X%`_shape((Jnn_1 : Jnn <: lanetype), `%`_dim(M_1))), `%`_ishape(`%X%`_shape((Jnn_2 : Jnn <: lanetype), `%`_dim(M_2)))) = - | `RELAXED_DOT_ADDS` + | RELAXED_DOT_ADDS -- if (((4 * $lsizenn1((Jnn_1 : Jnn <: lanetype))) = $lsizenn2((Jnn_2 : Jnn <: lanetype))) /\ ($lsizenn2((Jnn_2 : Jnn <: lanetype)) = 32)) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec syntax vcvtop__(shape_1 : shape, shape_2 : shape) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec syntax vcvtop__{Jnn_1 : Jnn, M_1 : M, Jnn_2 : Jnn, M_2 : M}(`%X%`_shape((Jnn_1 : Jnn <: lanetype), `%`_dim(M_1)), `%X%`_shape((Jnn_2 : Jnn <: lanetype), `%`_dim(M_2))) = - | EXTEND{half : half, sx : sx}(half : half, sx : sx) + | EXTEND(half : half, sx : sx) -- if ($lsizenn2((Jnn_2 : Jnn <: lanetype)) = (2 * $lsizenn1((Jnn_1 : Jnn <: lanetype)))) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec syntax vcvtop__{Jnn_1 : Jnn, M_1 : M, Fnn_2 : Fnn, M_2 : M}(`%X%`_shape((Jnn_1 : Jnn <: lanetype), `%`_dim(M_1)), `%X%`_shape((Fnn_2 : Fnn <: lanetype), `%`_dim(M_2))) = - | CONVERT{`half?` : half?, sx : sx}(half?{half <- `half?`} : half?, sx : sx) + | CONVERT(`half?` : half?, sx : sx) -- if (((($sizenn2((Fnn_2 : Fnn <: numtype)) = $lsizenn1((Jnn_1 : Jnn <: lanetype))) /\ ($lsizenn1((Jnn_1 : Jnn <: lanetype)) = 32)) /\ (half?{half <- `half?`} = ?())) \/ (($sizenn2((Fnn_2 : Fnn <: numtype)) = (2 * $lsizenn1((Jnn_1 : Jnn <: lanetype)))) /\ (half?{half <- `half?`} = ?(LOW_half)))) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec syntax vcvtop__{Fnn_1 : Fnn, M_1 : M, Jnn_2 : Jnn, M_2 : M}(`%X%`_shape((Fnn_1 : Fnn <: lanetype), `%`_dim(M_1)), `%X%`_shape((Jnn_2 : Jnn <: lanetype), `%`_dim(M_2))) = - | TRUNC_SAT{sx : sx, `zero?` : zero?}(sx : sx, zero?{zero <- `zero?`} : zero?) + | TRUNC_SAT(sx : sx, `zero?` : zero?) -- if (((($sizenn1((Fnn_1 : Fnn <: numtype)) = $lsizenn2((Jnn_2 : Jnn <: lanetype))) /\ ($lsizenn2((Jnn_2 : Jnn <: lanetype)) = 32)) /\ (zero?{zero <- `zero?`} = ?())) \/ (($sizenn1((Fnn_1 : Fnn <: numtype)) = (2 * $lsizenn2((Jnn_2 : Jnn <: lanetype)))) /\ (zero?{zero <- `zero?`} = ?(ZERO_zero)))) - | RELAXED_TRUNC{sx : sx, `zero?` : zero?}(sx : sx, zero?{zero <- `zero?`} : zero?) + | RELAXED_TRUNC(sx : sx, `zero?` : zero?) -- if (((($sizenn1((Fnn_1 : Fnn <: numtype)) = $lsizenn2((Jnn_2 : Jnn <: lanetype))) /\ ($lsizenn2((Jnn_2 : Jnn <: lanetype)) = 32)) /\ (zero?{zero <- `zero?`} = ?())) \/ (($sizenn1((Fnn_1 : Fnn <: numtype)) = (2 * $lsizenn2((Jnn_2 : Jnn <: lanetype)))) /\ (zero?{zero <- `zero?`} = ?(ZERO_zero)))) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec syntax vcvtop__{Fnn_1 : Fnn, M_1 : M, Fnn_2 : Fnn, M_2 : M}(`%X%`_shape((Fnn_1 : Fnn <: lanetype), `%`_dim(M_1)), `%X%`_shape((Fnn_2 : Fnn <: lanetype), `%`_dim(M_2))) = - | DEMOTE{zero : zero}(zero : zero) + | DEMOTE(zero : zero) -- if ($sizenn1((Fnn_1 : Fnn <: numtype)) = (2 * $sizenn2((Fnn_2 : Fnn <: numtype)))) - | `PROMOTELOW` + | PROMOTELOW -- if ((2 * $sizenn1((Fnn_1 : Fnn <: numtype))) = $sizenn2((Fnn_2 : Fnn <: numtype))) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec syntax memarg = { - ALIGN{u32 : u32} u32, - OFFSET{u64 : u64} u64 + ALIGN u32, + OFFSET u64 } ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec syntax loadop_{Inn : Inn}((Inn : Inn <: numtype)) = - | `%_%`{sz : sz, sx : sx}(sz : sz, sx : sx) + | `%_%`(sz : sz, sx : sx) -- if (sz!`%`_sz.0 < $sizenn((Inn : Inn <: numtype))) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec syntax storeop_{Inn : Inn}((Inn : Inn <: numtype)) = - | `%`{sz : sz}(sz : sz) + | `%`(sz : sz) -- if (sz!`%`_sz.0 < $sizenn((Inn : Inn <: numtype))) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec syntax vloadop_{vectype : vectype}(vectype) = - | `SHAPE%X%_%`{sz : sz, M : M, sx : sx}(sz : sz, M : M, sx : sx) + | `SHAPE%X%_%`(sz : sz, M : M, sx : sx) -- if (((sz!`%`_sz.0 * M) : nat <:> rat) = (($vsize(vectype) : nat <:> rat) / (2 : nat <:> rat))) - | SPLAT{sz : sz}(sz : sz) - | ZERO{sz : sz}(sz : sz) + | SPLAT(sz : sz) + | ZERO(sz : sz) -- if (sz!`%`_sz.0 >= 32) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec syntax blocktype = - | _RESULT{`valtype?` : valtype?}(valtype?{valtype <- `valtype?`} : valtype?) - | _IDX{typeidx : typeidx}(typeidx : typeidx) + | _RESULT(`valtype?` : valtype?) + | _IDX(typeidx : typeidx) ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax addr = nat @@ -1976,21 +1976,21 @@ rec { ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec:35.1-42.23 syntax addrref = - | REF.I31_NUM{u31 : u31}(u31 : u31) - | REF.STRUCT_ADDR{structaddr : structaddr}(structaddr : structaddr) - | REF.ARRAY_ADDR{arrayaddr : arrayaddr}(arrayaddr : arrayaddr) - | REF.FUNC_ADDR{funcaddr : funcaddr}(funcaddr : funcaddr) - | REF.EXN_ADDR{exnaddr : exnaddr}(exnaddr : exnaddr) - | REF.HOST_ADDR{hostaddr : hostaddr}(hostaddr : hostaddr) - | REF.EXTERN{addrref : addrref}(addrref : addrref) + | `REF.I31_NUM`(u31 : u31) + | `REF.STRUCT_ADDR`(structaddr : structaddr) + | `REF.ARRAY_ADDR`(arrayaddr : arrayaddr) + | `REF.FUNC_ADDR`(funcaddr : funcaddr) + | `REF.EXN_ADDR`(exnaddr : exnaddr) + | `REF.HOST_ADDR`(hostaddr : hostaddr) + | `REF.EXTERN`(addrref : addrref) } ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec syntax catch = - | CATCH{tagidx : tagidx, labelidx : labelidx}(tagidx : tagidx, labelidx : labelidx) - | CATCH_REF{tagidx : tagidx, labelidx : labelidx}(tagidx : tagidx, labelidx : labelidx) - | CATCH_ALL{labelidx : labelidx}(labelidx : labelidx) - | CATCH_ALL_REF{labelidx : labelidx}(labelidx : labelidx) + | CATCH(tagidx : tagidx, labelidx : labelidx) + | CATCH_REF(tagidx : tagidx, labelidx : labelidx) + | CATCH_ALL(labelidx : labelidx) + | CATCH_ALL_REF(labelidx : labelidx) ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax dataaddr = addr @@ -2012,51 +2012,51 @@ syntax tagaddr = addr ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax externaddr = - | TAG{tagaddr : tagaddr}(tagaddr : tagaddr) - | GLOBAL{globaladdr : globaladdr}(globaladdr : globaladdr) - | MEM{memaddr : memaddr}(memaddr : memaddr) - | TABLE{tableaddr : tableaddr}(tableaddr : tableaddr) - | FUNC{funcaddr : funcaddr}(funcaddr : funcaddr) + | TAG(tagaddr : tagaddr) + | GLOBAL(globaladdr : globaladdr) + | MEM(memaddr : memaddr) + | TABLE(tableaddr : tableaddr) + | FUNC(funcaddr : funcaddr) ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax exportinst = { - NAME{name : name} name, - ADDR{externaddr : externaddr} externaddr + NAME name, + ADDR externaddr } ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax moduleinst = { - TYPES{`deftype*` : deftype*} deftype*, - TAGS{`tagaddr*` : tagaddr*} tagaddr*, - GLOBALS{`globaladdr*` : globaladdr*} globaladdr*, - MEMS{`memaddr*` : memaddr*} memaddr*, - TABLES{`tableaddr*` : tableaddr*} tableaddr*, - FUNCS{`funcaddr*` : funcaddr*} funcaddr*, - DATAS{`dataaddr*` : dataaddr*} dataaddr*, - ELEMS{`elemaddr*` : elemaddr*} elemaddr*, - EXPORTS{`exportinst*` : exportinst*} exportinst* + TYPES deftype*, + TAGS tagaddr*, + GLOBALS globaladdr*, + MEMS memaddr*, + TABLES tableaddr*, + FUNCS funcaddr*, + DATAS dataaddr*, + ELEMS elemaddr*, + EXPORTS exportinst* } ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax val = - | CONST{numtype : numtype, num_ : num_(numtype)}(numtype : numtype, num_ : num_(numtype)) - | VCONST{vectype : vectype, vec_ : vec_(vectype)}(vectype : vectype, vec_ : vec_(vectype)) - | REF.NULL{heaptype : heaptype}(heaptype : heaptype) - | REF.I31_NUM{u31 : u31}(u31 : u31) - | REF.STRUCT_ADDR{structaddr : structaddr}(structaddr : structaddr) - | REF.ARRAY_ADDR{arrayaddr : arrayaddr}(arrayaddr : arrayaddr) - | REF.FUNC_ADDR{funcaddr : funcaddr}(funcaddr : funcaddr) - | REF.EXN_ADDR{exnaddr : exnaddr}(exnaddr : exnaddr) - | REF.HOST_ADDR{hostaddr : hostaddr}(hostaddr : hostaddr) - | REF.EXTERN{addrref : addrref}(addrref : addrref) + | CONST(numtype : numtype, num_(numtype)) + | VCONST(vectype : vectype, vec_(vectype)) + | `REF.I31_NUM`(u31 : u31) + | `REF.STRUCT_ADDR`(structaddr : structaddr) + | `REF.ARRAY_ADDR`(arrayaddr : arrayaddr) + | `REF.FUNC_ADDR`(funcaddr : funcaddr) + | `REF.EXN_ADDR`(exnaddr : exnaddr) + | `REF.HOST_ADDR`(hostaddr : hostaddr) + | `REF.EXTERN`(addrref : addrref) + | `REF.NULL`(heaptype : heaptype) ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax frame = { - LOCALS{`val?*` : val?*} val?*, - MODULE{moduleinst : moduleinst} moduleinst + LOCALS val?*, + MODULE moduleinst } ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec @@ -2067,120 +2067,120 @@ syntax instr = | NOP | UNREACHABLE | DROP - | SELECT{`valtype*?` : valtype*?}(valtype*{valtype <- `valtype*`}?{`valtype*` <- `valtype*?`} : valtype*?) - | BLOCK{blocktype : blocktype, `instr*` : instr*}(blocktype : blocktype, instr*{instr <- `instr*`} : instr*) - | LOOP{blocktype : blocktype, `instr*` : instr*}(blocktype : blocktype, instr*{instr <- `instr*`} : instr*) - | `IF%%ELSE%`{blocktype : blocktype, `instr*` : instr*}(blocktype : blocktype, instr*{instr <- `instr*`} : instr*, instr*) - | BR{labelidx : labelidx}(labelidx : labelidx) - | BR_IF{labelidx : labelidx}(labelidx : labelidx) - | BR_TABLE{`labelidx*` : labelidx*}(labelidx*{labelidx <- `labelidx*`} : labelidx*, labelidx) - | BR_ON_NULL{labelidx : labelidx}(labelidx : labelidx) - | BR_ON_NON_NULL{labelidx : labelidx}(labelidx : labelidx) - | BR_ON_CAST{labelidx : labelidx, reftype : reftype}(labelidx : labelidx, reftype : reftype, reftype) - | BR_ON_CAST_FAIL{labelidx : labelidx, reftype : reftype}(labelidx : labelidx, reftype : reftype, reftype) - | CALL{funcidx : funcidx}(funcidx : funcidx) - | CALL_REF{typeuse : typeuse}(typeuse : typeuse) - | CALL_INDIRECT{tableidx : tableidx, typeuse : typeuse}(tableidx : tableidx, typeuse : typeuse) + | SELECT(`valtype*?` : valtype*?) + | BLOCK(blocktype : blocktype, `instr*` : instr*) + | LOOP(blocktype : blocktype, `instr*` : instr*) + | `IF%%ELSE%`(blocktype : blocktype, `instr*` : instr*, `instr*` : instr*) + | BR(labelidx : labelidx) + | BR_IF(labelidx : labelidx) + | BR_TABLE(`labelidx*` : labelidx*, labelidx : labelidx) + | BR_ON_NULL(labelidx : labelidx) + | BR_ON_NON_NULL(labelidx : labelidx) + | BR_ON_CAST(labelidx : labelidx, reftype : reftype, reftype : reftype) + | BR_ON_CAST_FAIL(labelidx : labelidx, reftype : reftype, reftype : reftype) + | CALL(funcidx : funcidx) + | CALL_REF(typeuse : typeuse) + | CALL_INDIRECT(tableidx : tableidx, typeuse : typeuse) | RETURN - | RETURN_CALL{funcidx : funcidx}(funcidx : funcidx) - | RETURN_CALL_REF{typeuse : typeuse}(typeuse : typeuse) - | RETURN_CALL_INDIRECT{tableidx : tableidx, typeuse : typeuse}(tableidx : tableidx, typeuse : typeuse) - | THROW{tagidx : tagidx}(tagidx : tagidx) + | RETURN_CALL(funcidx : funcidx) + | RETURN_CALL_REF(typeuse : typeuse) + | RETURN_CALL_INDIRECT(tableidx : tableidx, typeuse : typeuse) + | THROW(tagidx : tagidx) | THROW_REF - | TRY_TABLE{blocktype : blocktype, list : list(syntax catch), `instr*` : instr*}(blocktype : blocktype, list : list(syntax catch), instr*{instr <- `instr*`} : instr*) - | LOCAL.GET{localidx : localidx}(localidx : localidx) - | LOCAL.SET{localidx : localidx}(localidx : localidx) - | LOCAL.TEE{localidx : localidx}(localidx : localidx) - | GLOBAL.GET{globalidx : globalidx}(globalidx : globalidx) - | GLOBAL.SET{globalidx : globalidx}(globalidx : globalidx) - | TABLE.GET{tableidx : tableidx}(tableidx : tableidx) - | TABLE.SET{tableidx : tableidx}(tableidx : tableidx) - | TABLE.SIZE{tableidx : tableidx}(tableidx : tableidx) - | TABLE.GROW{tableidx : tableidx}(tableidx : tableidx) - | TABLE.FILL{tableidx : tableidx}(tableidx : tableidx) - | TABLE.COPY{tableidx : tableidx}(tableidx : tableidx, tableidx) - | TABLE.INIT{tableidx : tableidx, elemidx : elemidx}(tableidx : tableidx, elemidx : elemidx) - | ELEM.DROP{elemidx : elemidx}(elemidx : elemidx) - | LOAD{numtype : numtype, `loadop_?` : loadop_(numtype)?, memidx : memidx, memarg : memarg}(numtype : numtype, loadop_?{loadop_ <- `loadop_?`} : loadop_(numtype)?, memidx : memidx, memarg : memarg) - | STORE{numtype : numtype, `storeop_?` : storeop_(numtype)?, memidx : memidx, memarg : memarg}(numtype : numtype, storeop_?{storeop_ <- `storeop_?`} : storeop_(numtype)?, memidx : memidx, memarg : memarg) - | VLOAD{vectype : vectype, `vloadop_?` : vloadop_(vectype)?, memidx : memidx, memarg : memarg}(vectype : vectype, vloadop_?{vloadop_ <- `vloadop_?`} : vloadop_(vectype)?, memidx : memidx, memarg : memarg) - | VLOAD_LANE{vectype : vectype, sz : sz, memidx : memidx, memarg : memarg, laneidx : laneidx}(vectype : vectype, sz : sz, memidx : memidx, memarg : memarg, laneidx : laneidx) - | VSTORE{vectype : vectype, memidx : memidx, memarg : memarg}(vectype : vectype, memidx : memidx, memarg : memarg) - | VSTORE_LANE{vectype : vectype, sz : sz, memidx : memidx, memarg : memarg, laneidx : laneidx}(vectype : vectype, sz : sz, memidx : memidx, memarg : memarg, laneidx : laneidx) - | MEMORY.SIZE{memidx : memidx}(memidx : memidx) - | MEMORY.GROW{memidx : memidx}(memidx : memidx) - | MEMORY.FILL{memidx : memidx}(memidx : memidx) - | MEMORY.COPY{memidx : memidx}(memidx : memidx, memidx) - | MEMORY.INIT{memidx : memidx, dataidx : dataidx}(memidx : memidx, dataidx : dataidx) - | DATA.DROP{dataidx : dataidx}(dataidx : dataidx) - | REF.NULL{heaptype : heaptype}(heaptype : heaptype) - | REF.IS_NULL - | REF.AS_NON_NULL - | REF.EQ - | REF.TEST{reftype : reftype}(reftype : reftype) - | REF.CAST{reftype : reftype}(reftype : reftype) - | REF.FUNC{funcidx : funcidx}(funcidx : funcidx) - | REF.I31 - | I31.GET{sx : sx}(sx : sx) - | STRUCT.NEW{typeidx : typeidx}(typeidx : typeidx) - | STRUCT.NEW_DEFAULT{typeidx : typeidx}(typeidx : typeidx) - | STRUCT.GET{`sx?` : sx?, typeidx : typeidx, u32 : u32}(sx?{sx <- `sx?`} : sx?, typeidx : typeidx, u32 : u32) - | STRUCT.SET{typeidx : typeidx, u32 : u32}(typeidx : typeidx, u32 : u32) - | ARRAY.NEW{typeidx : typeidx}(typeidx : typeidx) - | ARRAY.NEW_DEFAULT{typeidx : typeidx}(typeidx : typeidx) - | ARRAY.NEW_FIXED{typeidx : typeidx, u32 : u32}(typeidx : typeidx, u32 : u32) - | ARRAY.NEW_DATA{typeidx : typeidx, dataidx : dataidx}(typeidx : typeidx, dataidx : dataidx) - | ARRAY.NEW_ELEM{typeidx : typeidx, elemidx : elemidx}(typeidx : typeidx, elemidx : elemidx) - | ARRAY.GET{`sx?` : sx?, typeidx : typeidx}(sx?{sx <- `sx?`} : sx?, typeidx : typeidx) - | ARRAY.SET{typeidx : typeidx}(typeidx : typeidx) - | ARRAY.LEN - | ARRAY.FILL{typeidx : typeidx}(typeidx : typeidx) - | ARRAY.COPY{typeidx : typeidx}(typeidx : typeidx, typeidx) - | ARRAY.INIT_DATA{typeidx : typeidx, dataidx : dataidx}(typeidx : typeidx, dataidx : dataidx) - | ARRAY.INIT_ELEM{typeidx : typeidx, elemidx : elemidx}(typeidx : typeidx, elemidx : elemidx) - | EXTERN.CONVERT_ANY - | ANY.CONVERT_EXTERN - | CONST{numtype : numtype, num_ : num_(numtype)}(numtype : numtype, num_ : num_(numtype)) - | UNOP{numtype : numtype, unop_ : unop_(numtype)}(numtype : numtype, unop_ : unop_(numtype)) - | BINOP{numtype : numtype, binop_ : binop_(numtype)}(numtype : numtype, binop_ : binop_(numtype)) - | TESTOP{numtype : numtype, testop_ : testop_(numtype)}(numtype : numtype, testop_ : testop_(numtype)) - | RELOP{numtype : numtype, relop_ : relop_(numtype)}(numtype : numtype, relop_ : relop_(numtype)) - | CVTOP{numtype_1 : numtype, numtype_2 : numtype, cvtop__ : cvtop__(numtype_2, numtype_1)}(numtype_1 : numtype, numtype_2 : numtype, cvtop__ : cvtop__(numtype_2, numtype_1)) - | VCONST{vectype : vectype, vec_ : vec_(vectype)}(vectype : vectype, vec_ : vec_(vectype)) - | VVUNOP{vectype : vectype, vvunop : vvunop}(vectype : vectype, vvunop : vvunop) - | VVBINOP{vectype : vectype, vvbinop : vvbinop}(vectype : vectype, vvbinop : vvbinop) - | VVTERNOP{vectype : vectype, vvternop : vvternop}(vectype : vectype, vvternop : vvternop) - | VVTESTOP{vectype : vectype, vvtestop : vvtestop}(vectype : vectype, vvtestop : vvtestop) - | VUNOP{shape : shape, vunop_ : vunop_(shape)}(shape : shape, vunop_ : vunop_(shape)) - | VBINOP{shape : shape, vbinop_ : vbinop_(shape)}(shape : shape, vbinop_ : vbinop_(shape)) - | VTERNOP{shape : shape, vternop_ : vternop_(shape)}(shape : shape, vternop_ : vternop_(shape)) - | VTESTOP{shape : shape, vtestop_ : vtestop_(shape)}(shape : shape, vtestop_ : vtestop_(shape)) - | VRELOP{shape : shape, vrelop_ : vrelop_(shape)}(shape : shape, vrelop_ : vrelop_(shape)) - | VSHIFTOP{ishape : ishape, vshiftop_ : vshiftop_(ishape)}(ishape : ishape, vshiftop_ : vshiftop_(ishape)) - | VBITMASK{ishape : ishape}(ishape : ishape) - | VSWIZZLOP{bshape : bshape, vswizzlop_ : vswizzlop_(bshape)}(bshape : bshape, vswizzlop_ : vswizzlop_(bshape)) - | VSHUFFLE{bshape : bshape, `laneidx*` : laneidx*}(bshape : bshape, laneidx*{laneidx <- `laneidx*`} : laneidx*) + | TRY_TABLE(blocktype : blocktype, list(syntax catch), `instr*` : instr*) + | `LOCAL.GET`(localidx : localidx) + | `LOCAL.SET`(localidx : localidx) + | `LOCAL.TEE`(localidx : localidx) + | `GLOBAL.GET`(globalidx : globalidx) + | `GLOBAL.SET`(globalidx : globalidx) + | `TABLE.GET`(tableidx : tableidx) + | `TABLE.SET`(tableidx : tableidx) + | `TABLE.SIZE`(tableidx : tableidx) + | `TABLE.GROW`(tableidx : tableidx) + | `TABLE.FILL`(tableidx : tableidx) + | `TABLE.COPY`(tableidx : tableidx, tableidx : tableidx) + | `TABLE.INIT`(tableidx : tableidx, elemidx : elemidx) + | `ELEM.DROP`(elemidx : elemidx) + | LOAD(numtype : numtype, loadop_(numtype)?, memidx : memidx, memarg : memarg) + | STORE(numtype : numtype, storeop_(numtype)?, memidx : memidx, memarg : memarg) + | VLOAD(vectype : vectype, vloadop_(vectype)?, memidx : memidx, memarg : memarg) + | VLOAD_LANE(vectype : vectype, sz : sz, memidx : memidx, memarg : memarg, laneidx : laneidx) + | VSTORE(vectype : vectype, memidx : memidx, memarg : memarg) + | VSTORE_LANE(vectype : vectype, sz : sz, memidx : memidx, memarg : memarg, laneidx : laneidx) + | `MEMORY.SIZE`(memidx : memidx) + | `MEMORY.GROW`(memidx : memidx) + | `MEMORY.FILL`(memidx : memidx) + | `MEMORY.COPY`(memidx : memidx, memidx : memidx) + | `MEMORY.INIT`(memidx : memidx, dataidx : dataidx) + | `DATA.DROP`(dataidx : dataidx) + | `REF.NULL`(heaptype : heaptype) + | `REF.IS_NULL` + | `REF.AS_NON_NULL` + | `REF.EQ` + | `REF.TEST`(reftype : reftype) + | `REF.CAST`(reftype : reftype) + | `REF.FUNC`(funcidx : funcidx) + | `REF.I31` + | `I31.GET`(sx : sx) + | `STRUCT.NEW`(typeidx : typeidx) + | `STRUCT.NEW_DEFAULT`(typeidx : typeidx) + | `STRUCT.GET`(`sx?` : sx?, typeidx : typeidx, u32 : u32) + | `STRUCT.SET`(typeidx : typeidx, u32 : u32) + | `ARRAY.NEW`(typeidx : typeidx) + | `ARRAY.NEW_DEFAULT`(typeidx : typeidx) + | `ARRAY.NEW_FIXED`(typeidx : typeidx, u32 : u32) + | `ARRAY.NEW_DATA`(typeidx : typeidx, dataidx : dataidx) + | `ARRAY.NEW_ELEM`(typeidx : typeidx, elemidx : elemidx) + | `ARRAY.GET`(`sx?` : sx?, typeidx : typeidx) + | `ARRAY.SET`(typeidx : typeidx) + | `ARRAY.LEN` + | `ARRAY.FILL`(typeidx : typeidx) + | `ARRAY.COPY`(typeidx : typeidx, typeidx : typeidx) + | `ARRAY.INIT_DATA`(typeidx : typeidx, dataidx : dataidx) + | `ARRAY.INIT_ELEM`(typeidx : typeidx, elemidx : elemidx) + | `EXTERN.CONVERT_ANY` + | `ANY.CONVERT_EXTERN` + | CONST(numtype : numtype, num_(numtype)) + | UNOP(numtype : numtype, unop_(numtype)) + | BINOP(numtype : numtype, binop_(numtype)) + | TESTOP(numtype : numtype, testop_(numtype)) + | RELOP(numtype : numtype, relop_(numtype)) + | CVTOP(numtype_1 : numtype, numtype_2 : numtype, cvtop__(numtype_2, numtype_1)) + | VCONST(vectype : vectype, vec_(vectype)) + | VVUNOP(vectype : vectype, vvunop : vvunop) + | VVBINOP(vectype : vectype, vvbinop : vvbinop) + | VVTERNOP(vectype : vectype, vvternop : vvternop) + | VVTESTOP(vectype : vectype, vvtestop : vvtestop) + | VUNOP(shape : shape, vunop_(shape)) + | VBINOP(shape : shape, vbinop_(shape)) + | VTERNOP(shape : shape, vternop_(shape)) + | VTESTOP(shape : shape, vtestop_(shape)) + | VRELOP(shape : shape, vrelop_(shape)) + | VSHIFTOP(ishape : ishape, vshiftop_(ishape)) + | VBITMASK(ishape : ishape) + | VSWIZZLOP(bshape : bshape, vswizzlop_(bshape)) + | VSHUFFLE(bshape : bshape, `laneidx*` : laneidx*) -- if (`%`_dim(|laneidx*{laneidx <- `laneidx*`}|) = $dim(bshape!`%`_bshape.0)) - | VEXTUNOP{ishape_1 : ishape, ishape_2 : ishape, vextunop__ : vextunop__(ishape_2, ishape_1)}(ishape_1 : ishape, ishape_2 : ishape, vextunop__ : vextunop__(ishape_2, ishape_1)) - | VEXTBINOP{ishape_1 : ishape, ishape_2 : ishape, vextbinop__ : vextbinop__(ishape_2, ishape_1)}(ishape_1 : ishape, ishape_2 : ishape, vextbinop__ : vextbinop__(ishape_2, ishape_1)) - | VEXTTERNOP{ishape_1 : ishape, ishape_2 : ishape, vextternop__ : vextternop__(ishape_2, ishape_1)}(ishape_1 : ishape, ishape_2 : ishape, vextternop__ : vextternop__(ishape_2, ishape_1)) - | VNARROW{ishape_1 : ishape, ishape_2 : ishape, sx : sx}(ishape_1 : ishape, ishape_2 : ishape, sx : sx) + | VEXTUNOP(ishape_1 : ishape, ishape_2 : ishape, vextunop__(ishape_2, ishape_1)) + | VEXTBINOP(ishape_1 : ishape, ishape_2 : ishape, vextbinop__(ishape_2, ishape_1)) + | VEXTTERNOP(ishape_1 : ishape, ishape_2 : ishape, vextternop__(ishape_2, ishape_1)) + | VNARROW(ishape_1 : ishape, ishape_2 : ishape, sx : sx) -- if (($lsize($lanetype(ishape_2!`%`_ishape.0)) = (2 * $lsize($lanetype(ishape_1!`%`_ishape.0)))) /\ ((2 * $lsize($lanetype(ishape_1!`%`_ishape.0))) <= 32)) - | VCVTOP{shape_1 : shape, shape_2 : shape, vcvtop__ : vcvtop__(shape_2, shape_1)}(shape_1 : shape, shape_2 : shape, vcvtop__ : vcvtop__(shape_2, shape_1)) - | VSPLAT{shape : shape}(shape : shape) - | VEXTRACT_LANE{shape : shape, `sx?` : sx?, laneidx : laneidx}(shape : shape, sx?{sx <- `sx?`} : sx?, laneidx : laneidx) + | VCVTOP(shape_1 : shape, shape_2 : shape, vcvtop__(shape_2, shape_1)) + | VSPLAT(shape : shape) + | VEXTRACT_LANE(shape : shape, `sx?` : sx?, laneidx : laneidx) -- if ((sx?{sx <- `sx?`} = ?()) <=> ($lanetype(shape) <- [I32_lanetype I64_lanetype F32_lanetype F64_lanetype])) - | VREPLACE_LANE{shape : shape, laneidx : laneidx}(shape : shape, laneidx : laneidx) - | REF.I31_NUM{u31 : u31}(u31 : u31) - | REF.STRUCT_ADDR{structaddr : structaddr}(structaddr : structaddr) - | REF.ARRAY_ADDR{arrayaddr : arrayaddr}(arrayaddr : arrayaddr) - | REF.FUNC_ADDR{funcaddr : funcaddr}(funcaddr : funcaddr) - | REF.EXN_ADDR{exnaddr : exnaddr}(exnaddr : exnaddr) - | REF.HOST_ADDR{hostaddr : hostaddr}(hostaddr : hostaddr) - | REF.EXTERN{addrref : addrref}(addrref : addrref) - | `LABEL_%{%}%`{n : n, `instr*` : instr*}(n : n, instr*{instr <- `instr*`} : instr*, instr*) - | `FRAME_%{%}%`{n : n, frame : frame, `instr*` : instr*}(n : n, frame : frame, instr*{instr <- `instr*`} : instr*) - | `HANDLER_%{%}%`{n : n, `catch*` : catch*, `instr*` : instr*}(n : n, catch*{catch <- `catch*`} : catch*, instr*{instr <- `instr*`} : instr*) + | VREPLACE_LANE(shape : shape, laneidx : laneidx) + | `REF.I31_NUM`(u31 : u31) + | `REF.STRUCT_ADDR`(structaddr : structaddr) + | `REF.ARRAY_ADDR`(arrayaddr : arrayaddr) + | `REF.FUNC_ADDR`(funcaddr : funcaddr) + | `REF.EXN_ADDR`(exnaddr : exnaddr) + | `REF.HOST_ADDR`(hostaddr : hostaddr) + | `REF.EXTERN`(addrref : addrref) + | `LABEL_%{%}%`(n : n, `instr*` : instr*, `instr*` : instr*) + | `FRAME_%{%}%`(n : n, frame : frame, `instr*` : instr*) + | `HANDLER_%{%}%`(n : n, `catch*` : catch*, `instr*` : instr*) | TRAP } @@ -2195,9 +2195,9 @@ def $memarg0 : memarg ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec def $const(consttype : consttype, lit_ : lit_((consttype : consttype <: storagetype))) : instr ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec - def $const{numtype : numtype, c : lit_((numtype : numtype <: storagetype))}((numtype : numtype <: consttype), c) = CONST_instr(numtype, c) + def $const{numtype : numtype, c : lit_(((numtype : numtype <: consttype) : consttype <: storagetype))}((numtype : numtype <: consttype), c) = CONST_instr(numtype, c) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec - def $const{vectype : vectype, c : lit_((vectype : vectype <: storagetype))}((vectype : vectype <: consttype), c) = VCONST_instr(vectype, c) + def $const{vectype : vectype, c : lit_(((vectype : vectype <: consttype) : consttype <: storagetype))}((vectype : vectype <: consttype), c) = VCONST_instr(vectype, c) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec def $free_shape(shape : shape) : free @@ -2328,85 +2328,85 @@ def $free_instr(instr : instr) : free ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:493.1-493.66 def $free_instr{shape : shape, laneidx : laneidx}(VREPLACE_LANE_instr(shape, laneidx)) = $free_shape(shape) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:495.1-495.62 - def $free_instr{heaptype : heaptype}(REF.NULL_instr(heaptype)) = $free_heaptype(heaptype) + def $free_instr{heaptype : heaptype}(`REF.NULL`_instr(heaptype)) = $free_heaptype(heaptype) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:496.1-496.34 - def $free_instr(REF.IS_NULL_instr) = {TYPES [], FUNCS [], GLOBALS [], TABLES [], MEMS [], ELEMS [], DATAS [], LOCALS [], LABELS []} + def $free_instr(`REF.IS_NULL`_instr) = {TYPES [], FUNCS [], GLOBALS [], TABLES [], MEMS [], ELEMS [], DATAS [], LOCALS [], LABELS []} ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:497.1-497.38 - def $free_instr(REF.AS_NON_NULL_instr) = {TYPES [], FUNCS [], GLOBALS [], TABLES [], MEMS [], ELEMS [], DATAS [], LOCALS [], LABELS []} + def $free_instr(`REF.AS_NON_NULL`_instr) = {TYPES [], FUNCS [], GLOBALS [], TABLES [], MEMS [], ELEMS [], DATAS [], LOCALS [], LABELS []} ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:498.1-498.29 - def $free_instr(REF.EQ_instr) = {TYPES [], FUNCS [], GLOBALS [], TABLES [], MEMS [], ELEMS [], DATAS [], LOCALS [], LABELS []} + def $free_instr(`REF.EQ`_instr) = {TYPES [], FUNCS [], GLOBALS [], TABLES [], MEMS [], ELEMS [], DATAS [], LOCALS [], LABELS []} ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:499.1-499.59 - def $free_instr{reftype : reftype}(REF.TEST_instr(reftype)) = $free_reftype(reftype) + def $free_instr{reftype : reftype}(`REF.TEST`_instr(reftype)) = $free_reftype(reftype) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:500.1-500.59 - def $free_instr{reftype : reftype}(REF.CAST_instr(reftype)) = $free_reftype(reftype) + def $free_instr{reftype : reftype}(`REF.CAST`_instr(reftype)) = $free_reftype(reftype) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:501.1-501.59 - def $free_instr{funcidx : funcidx}(REF.FUNC_instr(funcidx)) = $free_funcidx(funcidx) + def $free_instr{funcidx : funcidx}(`REF.FUNC`_instr(funcidx)) = $free_funcidx(funcidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:502.1-502.30 - def $free_instr(REF.I31_instr) = {TYPES [], FUNCS [], GLOBALS [], TABLES [], MEMS [], ELEMS [], DATAS [], LOCALS [], LABELS []} + def $free_instr(`REF.I31`_instr) = {TYPES [], FUNCS [], GLOBALS [], TABLES [], MEMS [], ELEMS [], DATAS [], LOCALS [], LABELS []} ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:504.1-504.33 - def $free_instr{sx : sx}(I31.GET_instr(sx)) = {TYPES [], FUNCS [], GLOBALS [], TABLES [], MEMS [], ELEMS [], DATAS [], LOCALS [], LABELS []} + def $free_instr{sx : sx}(`I31.GET`_instr(sx)) = {TYPES [], FUNCS [], GLOBALS [], TABLES [], MEMS [], ELEMS [], DATAS [], LOCALS [], LABELS []} ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:506.1-506.41 - def $free_instr{typeidx : typeidx}(STRUCT.NEW_instr(typeidx)) = {TYPES [], FUNCS [], GLOBALS [], TABLES [], MEMS [], ELEMS [], DATAS [], LOCALS [], LABELS []} + def $free_instr{typeidx : typeidx}(`STRUCT.NEW`_instr(typeidx)) = {TYPES [], FUNCS [], GLOBALS [], TABLES [], MEMS [], ELEMS [], DATAS [], LOCALS [], LABELS []} ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:507.1-507.69 - def $free_instr{typeidx : typeidx}(STRUCT.NEW_DEFAULT_instr(typeidx)) = $free_typeidx(typeidx) + def $free_instr{typeidx : typeidx}(`STRUCT.NEW_DEFAULT`_instr(typeidx)) = $free_typeidx(typeidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:508.1-508.69 - def $free_instr{`sx?` : sx?, typeidx : typeidx, u32 : u32}(STRUCT.GET_instr(sx?{sx <- `sx?`}, typeidx, u32)) = $free_typeidx(typeidx) + def $free_instr{`sx?` : sx?, typeidx : typeidx, u32 : u32}(`STRUCT.GET`_instr(sx?{sx <- `sx?`}, typeidx, u32)) = $free_typeidx(typeidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:509.1-509.65 - def $free_instr{typeidx : typeidx, u32 : u32}(STRUCT.SET_instr(typeidx, u32)) = $free_typeidx(typeidx) + def $free_instr{typeidx : typeidx, u32 : u32}(`STRUCT.SET`_instr(typeidx, u32)) = $free_typeidx(typeidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:511.1-511.60 - def $free_instr{typeidx : typeidx}(ARRAY.NEW_instr(typeidx)) = $free_typeidx(typeidx) + def $free_instr{typeidx : typeidx}(`ARRAY.NEW`_instr(typeidx)) = $free_typeidx(typeidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:512.1-512.68 - def $free_instr{typeidx : typeidx}(ARRAY.NEW_DEFAULT_instr(typeidx)) = $free_typeidx(typeidx) + def $free_instr{typeidx : typeidx}(`ARRAY.NEW_DEFAULT`_instr(typeidx)) = $free_typeidx(typeidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:513.1-513.70 - def $free_instr{typeidx : typeidx, u32 : u32}(ARRAY.NEW_FIXED_instr(typeidx, u32)) = $free_typeidx(typeidx) + def $free_instr{typeidx : typeidx, u32 : u32}(`ARRAY.NEW_FIXED`_instr(typeidx, u32)) = $free_typeidx(typeidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:514.1-515.51 - def $free_instr{typeidx : typeidx, dataidx : dataidx}(ARRAY.NEW_DATA_instr(typeidx, dataidx)) = $free_typeidx(typeidx) +++ $free_dataidx(dataidx) + def $free_instr{typeidx : typeidx, dataidx : dataidx}(`ARRAY.NEW_DATA`_instr(typeidx, dataidx)) = $free_typeidx(typeidx) +++ $free_dataidx(dataidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:516.1-517.51 - def $free_instr{typeidx : typeidx, elemidx : elemidx}(ARRAY.NEW_ELEM_instr(typeidx, elemidx)) = $free_typeidx(typeidx) +++ $free_elemidx(elemidx) + def $free_instr{typeidx : typeidx, elemidx : elemidx}(`ARRAY.NEW_ELEM`_instr(typeidx, elemidx)) = $free_typeidx(typeidx) +++ $free_elemidx(elemidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:518.1-518.64 - def $free_instr{`sx?` : sx?, typeidx : typeidx}(ARRAY.GET_instr(sx?{sx <- `sx?`}, typeidx)) = $free_typeidx(typeidx) + def $free_instr{`sx?` : sx?, typeidx : typeidx}(`ARRAY.GET`_instr(sx?{sx <- `sx?`}, typeidx)) = $free_typeidx(typeidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:519.1-519.60 - def $free_instr{typeidx : typeidx}(ARRAY.SET_instr(typeidx)) = $free_typeidx(typeidx) + def $free_instr{typeidx : typeidx}(`ARRAY.SET`_instr(typeidx)) = $free_typeidx(typeidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:520.1-520.32 - def $free_instr(ARRAY.LEN_instr) = {TYPES [], FUNCS [], GLOBALS [], TABLES [], MEMS [], ELEMS [], DATAS [], LOCALS [], LABELS []} + def $free_instr(`ARRAY.LEN`_instr) = {TYPES [], FUNCS [], GLOBALS [], TABLES [], MEMS [], ELEMS [], DATAS [], LOCALS [], LABELS []} ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:521.1-521.61 - def $free_instr{typeidx : typeidx}(ARRAY.FILL_instr(typeidx)) = $free_typeidx(typeidx) + def $free_instr{typeidx : typeidx}(`ARRAY.FILL`_instr(typeidx)) = $free_typeidx(typeidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:522.1-523.55 - def $free_instr{typeidx_1 : typeidx, typeidx_2 : typeidx}(ARRAY.COPY_instr(typeidx_1, typeidx_2)) = $free_typeidx(typeidx_1) +++ $free_typeidx(typeidx_2) + def $free_instr{typeidx_1 : typeidx, typeidx_2 : typeidx}(`ARRAY.COPY`_instr(typeidx_1, typeidx_2)) = $free_typeidx(typeidx_1) +++ $free_typeidx(typeidx_2) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:524.1-525.51 - def $free_instr{typeidx : typeidx, dataidx : dataidx}(ARRAY.INIT_DATA_instr(typeidx, dataidx)) = $free_typeidx(typeidx) +++ $free_dataidx(dataidx) + def $free_instr{typeidx : typeidx, dataidx : dataidx}(`ARRAY.INIT_DATA`_instr(typeidx, dataidx)) = $free_typeidx(typeidx) +++ $free_dataidx(dataidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:526.1-527.51 - def $free_instr{typeidx : typeidx, elemidx : elemidx}(ARRAY.INIT_ELEM_instr(typeidx, elemidx)) = $free_typeidx(typeidx) +++ $free_elemidx(elemidx) + def $free_instr{typeidx : typeidx, elemidx : elemidx}(`ARRAY.INIT_ELEM`_instr(typeidx, elemidx)) = $free_typeidx(typeidx) +++ $free_elemidx(elemidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:529.1-529.41 - def $free_instr(EXTERN.CONVERT_ANY_instr) = {TYPES [], FUNCS [], GLOBALS [], TABLES [], MEMS [], ELEMS [], DATAS [], LOCALS [], LABELS []} + def $free_instr(`EXTERN.CONVERT_ANY`_instr) = {TYPES [], FUNCS [], GLOBALS [], TABLES [], MEMS [], ELEMS [], DATAS [], LOCALS [], LABELS []} ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:530.1-530.41 - def $free_instr(ANY.CONVERT_EXTERN_instr) = {TYPES [], FUNCS [], GLOBALS [], TABLES [], MEMS [], ELEMS [], DATAS [], LOCALS [], LABELS []} + def $free_instr(`ANY.CONVERT_EXTERN`_instr) = {TYPES [], FUNCS [], GLOBALS [], TABLES [], MEMS [], ELEMS [], DATAS [], LOCALS [], LABELS []} ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:532.1-532.63 - def $free_instr{localidx : localidx}(LOCAL.GET_instr(localidx)) = $free_localidx(localidx) + def $free_instr{localidx : localidx}(`LOCAL.GET`_instr(localidx)) = $free_localidx(localidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:533.1-533.63 - def $free_instr{localidx : localidx}(LOCAL.SET_instr(localidx)) = $free_localidx(localidx) + def $free_instr{localidx : localidx}(`LOCAL.SET`_instr(localidx)) = $free_localidx(localidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:534.1-534.63 - def $free_instr{localidx : localidx}(LOCAL.TEE_instr(localidx)) = $free_localidx(localidx) + def $free_instr{localidx : localidx}(`LOCAL.TEE`_instr(localidx)) = $free_localidx(localidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:536.1-536.67 - def $free_instr{globalidx : globalidx}(GLOBAL.GET_instr(globalidx)) = $free_globalidx(globalidx) + def $free_instr{globalidx : globalidx}(`GLOBAL.GET`_instr(globalidx)) = $free_globalidx(globalidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:537.1-537.67 - def $free_instr{globalidx : globalidx}(GLOBAL.SET_instr(globalidx)) = $free_globalidx(globalidx) + def $free_instr{globalidx : globalidx}(`GLOBAL.SET`_instr(globalidx)) = $free_globalidx(globalidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:539.1-539.63 - def $free_instr{tableidx : tableidx}(TABLE.GET_instr(tableidx)) = $free_tableidx(tableidx) + def $free_instr{tableidx : tableidx}(`TABLE.GET`_instr(tableidx)) = $free_tableidx(tableidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:540.1-540.63 - def $free_instr{tableidx : tableidx}(TABLE.SET_instr(tableidx)) = $free_tableidx(tableidx) + def $free_instr{tableidx : tableidx}(`TABLE.SET`_instr(tableidx)) = $free_tableidx(tableidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:541.1-541.64 - def $free_instr{tableidx : tableidx}(TABLE.SIZE_instr(tableidx)) = $free_tableidx(tableidx) + def $free_instr{tableidx : tableidx}(`TABLE.SIZE`_instr(tableidx)) = $free_tableidx(tableidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:542.1-542.64 - def $free_instr{tableidx : tableidx}(TABLE.GROW_instr(tableidx)) = $free_tableidx(tableidx) + def $free_instr{tableidx : tableidx}(`TABLE.GROW`_instr(tableidx)) = $free_tableidx(tableidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:543.1-543.64 - def $free_instr{tableidx : tableidx}(TABLE.FILL_instr(tableidx)) = $free_tableidx(tableidx) + def $free_instr{tableidx : tableidx}(`TABLE.FILL`_instr(tableidx)) = $free_tableidx(tableidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:544.1-545.59 - def $free_instr{tableidx_1 : tableidx, tableidx_2 : tableidx}(TABLE.COPY_instr(tableidx_1, tableidx_2)) = $free_tableidx(tableidx_1) +++ $free_tableidx(tableidx_2) + def $free_instr{tableidx_1 : tableidx, tableidx_2 : tableidx}(`TABLE.COPY`_instr(tableidx_1, tableidx_2)) = $free_tableidx(tableidx_1) +++ $free_tableidx(tableidx_2) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:546.1-547.53 - def $free_instr{tableidx : tableidx, elemidx : elemidx}(TABLE.INIT_instr(tableidx, elemidx)) = $free_tableidx(tableidx) +++ $free_elemidx(elemidx) + def $free_instr{tableidx : tableidx, elemidx : elemidx}(`TABLE.INIT`_instr(tableidx, elemidx)) = $free_tableidx(tableidx) +++ $free_elemidx(elemidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:548.1-548.60 - def $free_instr{elemidx : elemidx}(ELEM.DROP_instr(elemidx)) = $free_elemidx(elemidx) + def $free_instr{elemidx : elemidx}(`ELEM.DROP`_instr(elemidx)) = $free_elemidx(elemidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:550.1-551.49 def $free_instr{numtype : numtype, `loadop?` : loadop_(numtype)?, memidx : memidx, memarg : memarg}(LOAD_instr(numtype, loadop?{loadop <- `loadop?`}, memidx, memarg)) = $free_numtype(numtype) +++ $free_memidx(memidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:552.1-553.49 @@ -2420,17 +2420,17 @@ def $free_instr(instr : instr) : free ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:560.1-561.49 def $free_instr{vectype : vectype, sz : sz, memidx : memidx, memarg : memarg, laneidx : laneidx}(VSTORE_LANE_instr(vectype, sz, memidx, memarg, laneidx)) = $free_vectype(vectype) +++ $free_memidx(memidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:562.1-562.59 - def $free_instr{memidx : memidx}(MEMORY.SIZE_instr(memidx)) = $free_memidx(memidx) + def $free_instr{memidx : memidx}(`MEMORY.SIZE`_instr(memidx)) = $free_memidx(memidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:563.1-563.59 - def $free_instr{memidx : memidx}(MEMORY.GROW_instr(memidx)) = $free_memidx(memidx) + def $free_instr{memidx : memidx}(`MEMORY.GROW`_instr(memidx)) = $free_memidx(memidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:564.1-564.59 - def $free_instr{memidx : memidx}(MEMORY.FILL_instr(memidx)) = $free_memidx(memidx) + def $free_instr{memidx : memidx}(`MEMORY.FILL`_instr(memidx)) = $free_memidx(memidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:565.1-566.51 - def $free_instr{memidx_1 : memidx, memidx_2 : memidx}(MEMORY.COPY_instr(memidx_1, memidx_2)) = $free_memidx(memidx_1) +++ $free_memidx(memidx_2) + def $free_instr{memidx_1 : memidx, memidx_2 : memidx}(`MEMORY.COPY`_instr(memidx_1, memidx_2)) = $free_memidx(memidx_1) +++ $free_memidx(memidx_2) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:567.1-568.49 - def $free_instr{memidx : memidx, dataidx : dataidx}(MEMORY.INIT_instr(memidx, dataidx)) = $free_memidx(memidx) +++ $free_dataidx(dataidx) + def $free_instr{memidx : memidx, dataidx : dataidx}(`MEMORY.INIT`_instr(memidx, dataidx)) = $free_memidx(memidx) +++ $free_dataidx(dataidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:569.1-569.60 - def $free_instr{dataidx : dataidx}(DATA.DROP_instr(dataidx)) = $free_dataidx(dataidx) + def $free_instr{dataidx : dataidx}(`DATA.DROP`_instr(dataidx)) = $free_dataidx(dataidx) ;; ../../../../specification/wasm-3.0/1.3-syntax.instructions.spectec:418.1-418.31 def $free_block(instr*) : free @@ -2446,66 +2446,66 @@ def $free_expr(expr : expr) : free ;; ../../../../specification/wasm-3.0/1.4-syntax.modules.spectec syntax elemmode = - | ACTIVE{tableidx : tableidx, expr : expr}(tableidx : tableidx, expr : expr) + | ACTIVE(tableidx : tableidx, expr : expr) | PASSIVE | DECLARE ;; ../../../../specification/wasm-3.0/1.4-syntax.modules.spectec syntax datamode = - | ACTIVE{memidx : memidx, expr : expr}(memidx : memidx, expr : expr) + | ACTIVE(memidx : memidx, expr : expr) | PASSIVE ;; ../../../../specification/wasm-3.0/1.4-syntax.modules.spectec syntax type = - | TYPE{rectype : rectype}(rectype : rectype) + | TYPE(rectype : rectype) ;; ../../../../specification/wasm-3.0/1.4-syntax.modules.spectec syntax tag = - | TAG{tagtype : tagtype}(tagtype : tagtype) + | TAG(tagtype : tagtype) ;; ../../../../specification/wasm-3.0/1.4-syntax.modules.spectec syntax global = - | GLOBAL{globaltype : globaltype, expr : expr}(globaltype : globaltype, expr : expr) + | GLOBAL(globaltype : globaltype, expr : expr) ;; ../../../../specification/wasm-3.0/1.4-syntax.modules.spectec syntax mem = - | MEMORY{memtype : memtype}(memtype : memtype) + | MEMORY(memtype : memtype) ;; ../../../../specification/wasm-3.0/1.4-syntax.modules.spectec syntax table = - | TABLE{tabletype : tabletype, expr : expr}(tabletype : tabletype, expr : expr) + | TABLE(tabletype : tabletype, expr : expr) ;; ../../../../specification/wasm-3.0/1.4-syntax.modules.spectec syntax data = - | DATA{`byte*` : byte*, datamode : datamode}(byte*{byte <- `byte*`} : byte*, datamode : datamode) + | DATA(`byte*` : byte*, datamode : datamode) ;; ../../../../specification/wasm-3.0/1.4-syntax.modules.spectec syntax local = - | LOCAL{valtype : valtype}(valtype : valtype) + | LOCAL(valtype : valtype) ;; ../../../../specification/wasm-3.0/1.4-syntax.modules.spectec syntax func = - | FUNC{typeidx : typeidx, `local*` : local*, expr : expr}(typeidx : typeidx, local*{local <- `local*`} : local*, expr : expr) + | FUNC(typeidx : typeidx, `local*` : local*, expr : expr) ;; ../../../../specification/wasm-3.0/1.4-syntax.modules.spectec syntax elem = - | ELEM{reftype : reftype, `expr*` : expr*, elemmode : elemmode}(reftype : reftype, expr*{expr <- `expr*`} : expr*, elemmode : elemmode) + | ELEM(reftype : reftype, `expr*` : expr*, elemmode : elemmode) ;; ../../../../specification/wasm-3.0/1.4-syntax.modules.spectec syntax start = - | START{funcidx : funcidx}(funcidx : funcidx) + | START(funcidx : funcidx) ;; ../../../../specification/wasm-3.0/1.4-syntax.modules.spectec syntax import = - | IMPORT{name : name, externtype : externtype}(name : name, name, externtype : externtype) + | IMPORT(name : name, name : name, externtype : externtype) ;; ../../../../specification/wasm-3.0/1.4-syntax.modules.spectec syntax export = - | EXPORT{name : name, externidx : externidx}(name : name, externidx : externidx) + | EXPORT(name : name, externidx : externidx) ;; ../../../../specification/wasm-3.0/1.4-syntax.modules.spectec syntax module = - | MODULE{`type*` : type*, `import*` : import*, `tag*` : tag*, `global*` : global*, `mem*` : mem*, `table*` : table*, `func*` : func*, `data*` : data*, `elem*` : elem*, `start?` : start?, `export*` : export*}(type*{type <- `type*`} : type*, import*{import <- `import*`} : import*, tag*{tag <- `tag*`} : tag*, global*{global <- `global*`} : global*, mem*{mem <- `mem*`} : mem*, table*{table <- `table*`} : table*, func*{func <- `func*`} : func*, data*{data <- `data*`} : data*, elem*{elem <- `elem*`} : elem*, start?{start <- `start?`} : start?, export*{export <- `export*`} : export*) + | MODULE(`type*` : type*, `import*` : import*, `tag*` : tag*, `global*` : global*, `mem*` : mem*, `table*` : table*, `func*` : func*, `data*` : data*, `elem*` : elem*, `start?` : start?, `export*` : export*) ;; ../../../../specification/wasm-3.0/1.4-syntax.modules.spectec def $free_type(type : type) : free @@ -2605,28 +2605,28 @@ syntax init = ;; ../../../../specification/wasm-3.0/2.0-validation.contexts.spectec syntax localtype = - | `%%`{init : init, valtype : valtype}(init : init, valtype : valtype) + | `%%`(init : init, valtype : valtype) ;; ../../../../specification/wasm-3.0/2.0-validation.contexts.spectec syntax instrtype = - | `%->_%%`{resulttype : resulttype, `localidx*` : localidx*}(resulttype : resulttype, localidx*{localidx <- `localidx*`} : localidx*, resulttype) + | `%->_%%`(resulttype : resulttype, `localidx*` : localidx*, resulttype : resulttype) ;; ../../../../specification/wasm-3.0/2.0-validation.contexts.spectec syntax context = { - TYPES{`deftype*` : deftype*} deftype*, - RECS{`subtype*` : subtype*} subtype*, - TAGS{`tagtype*` : tagtype*} tagtype*, - GLOBALS{`globaltype*` : globaltype*} globaltype*, - MEMS{`memtype*` : memtype*} memtype*, - TABLES{`tabletype*` : tabletype*} tabletype*, - FUNCS{`deftype*` : deftype*} deftype*, - DATAS{`datatype*` : datatype*} datatype*, - ELEMS{`elemtype*` : elemtype*} elemtype*, - LOCALS{`localtype*` : localtype*} localtype*, - LABELS{`resulttype*` : resulttype*} resulttype*, - RETURN{`resulttype?` : resulttype?} resulttype?, - REFS{`funcidx*` : funcidx*} funcidx* + TYPES deftype*, + RECS subtype*, + TAGS tagtype*, + GLOBALS globaltype*, + MEMS memtype*, + TABLES tabletype*, + FUNCS deftype*, + DATAS datatype*, + ELEMS elemtype*, + LOCALS localtype*, + LABELS resulttype*, + RETURN resulttype?, + REFS funcidx* } ;; ../../../../specification/wasm-3.0/2.0-validation.contexts.spectec @@ -2696,11 +2696,11 @@ relation Vectype_ok: `%|-%:OK`(context, vectype) ;; ../../../../specification/wasm-3.0/2.1-validation.types.spectec syntax oktypeidx = - | OK{typeidx : typeidx}(typeidx : typeidx) + | OK(typeidx : typeidx) ;; ../../../../specification/wasm-3.0/2.1-validation.types.spectec syntax oktypeidxnat = - | OK{typeidx : typeidx, nat : nat}(typeidx : typeidx, nat : nat) + | OK(typeidx : typeidx, nat) ;; ../../../../specification/wasm-3.0/2.1-validation.types.spectec relation Packtype_ok: `%|-%:OK`(context, packtype) @@ -2857,7 +2857,7 @@ relation Comptype_ok: `%|-%:OK`(context, comptype) ;; ../../../../specification/wasm-3.0/2.1-validation.types.spectec:88.1-88.126 relation Subtype_ok: `%|-%:%`(context, subtype, oktypeidx) ;; ../../../../specification/wasm-3.0/2.1-validation.types.spectec:142.1-149.49 - rule _{C : context, `x*` : idx*, comptype : comptype, x_0 : idx, `x'**` : idx**, `comptype'*` : comptype*}: + rule _{C : context, `x*` : idx*, comptype : comptype, x_0 : idx, `comptype'*` : comptype*, `x'**` : idx**}: `%|-%:%`(C, SUB_subtype(FINAL_final?{}, _IDX_typeuse(x)*{x <- `x*`}, comptype), OK_oktypeidx(x_0)) -- if (|x*{x <- `x*`}| <= 1) -- (if (x!`%`_idx.0 < x_0!`%`_idx.0))*{x <- `x*`} @@ -2885,7 +2885,7 @@ relation Rectype_ok: `%|-%:%`(context, rectype, oktypeidx) ;; ../../../../specification/wasm-3.0/2.1-validation.types.spectec:90.1-90.126 relation Subtype_ok2: `%|-%:%`(context, subtype, oktypeidxnat) ;; ../../../../specification/wasm-3.0/2.1-validation.types.spectec:161.1-168.49 - rule _{C : context, `typeuse*` : typeuse*, compttype : comptype, x : idx, i : nat, `typeuse'**` : typeuse**, `comptype'*` : comptype*, comptype : comptype}: + rule _{C : context, `typeuse*` : typeuse*, compttype : comptype, x : idx, i : nat, `comptype'*` : comptype*, `typeuse'**` : typeuse**, comptype : comptype}: `%|-%:%`(C, SUB_subtype(FINAL_final?{}, typeuse*{typeuse <- `typeuse*`}, compttype), OK_oktypeidxnat(x, i)) -- if (|typeuse*{typeuse <- `typeuse*`}| <= 1) -- (if $before(typeuse, x, i))*{typeuse <- `typeuse*`} @@ -2908,7 +2908,7 @@ relation Rectype_ok2: `%|-%:%`(context, rectype, oktypeidxnat) ;; ../../../../specification/wasm-3.0/2.1-validation.types.spectec:92.1-92.102 relation Deftype_ok: `%|-%:OK`(context, deftype) ;; ../../../../specification/wasm-3.0/2.1-validation.types.spectec:192.1-196.14 - rule _{C : context, rectype : rectype, i : n, x : idx, `subtype*` : subtype*, n : n}: + rule _{C : context, rectype : rectype, i : n, x : idx, n : n, `subtype*` : subtype*}: `%|-%:OK`(C, _DEF_deftype(rectype, i)) -- Rectype_ok: `%|-%:%`(C, rectype, OK_oktypeidx(x)) -- if (rectype = REC_rectype(`%`_list(subtype^n{subtype <- `subtype*`}))) @@ -3318,7 +3318,7 @@ def $default_(valtype : valtype) : val? ;; ../../../../specification/wasm-3.0/4.1-execution.values.spectec def $default_{Vnn : Vnn}((Vnn : Vnn <: valtype)) = ?(VCONST_val(Vnn, `%`_vec_(0))) ;; ../../../../specification/wasm-3.0/4.1-execution.values.spectec - def $default_{ht : heaptype}(REF_valtype(?(NULL_null), ht)) = ?(REF.NULL_val(ht)) + def $default_{ht : heaptype}(REF_valtype(?(NULL_null), ht)) = ?(`REF.NULL`_val(ht)) ;; ../../../../specification/wasm-3.0/4.1-execution.values.spectec def $default_{ht : heaptype}(REF_valtype(?(), ht)) = ?() @@ -3507,254 +3507,254 @@ relation Instr_ok: `%|-%:%`(context, instr, instrtype) -- (Catch_ok: `%|-%:OK`(C, catch))*{catch <- `catch*`} ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:202.1-204.31 - rule ref.null{C : context, ht : heaptype}: - `%|-%:%`(C, REF.NULL_instr(ht), `%->_%%`_instrtype(`%`_resulttype([]), [], `%`_resulttype([REF_valtype(?(NULL_null), ht)]))) + rule `ref.null`{C : context, ht : heaptype}: + `%|-%:%`(C, `REF.NULL`_instr(ht), `%->_%%`_instrtype(`%`_resulttype([]), [], `%`_resulttype([REF_valtype(?(NULL_null), ht)]))) -- Heaptype_ok: `%|-%:OK`(C, ht) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:206.1-209.20 - rule ref.func{C : context, x : idx, dt : deftype}: - `%|-%:%`(C, REF.FUNC_instr(x), `%->_%%`_instrtype(`%`_resulttype([]), [], `%`_resulttype([REF_valtype(?(), (dt : deftype <: heaptype))]))) + rule `ref.func`{C : context, x : idx, dt : deftype}: + `%|-%:%`(C, `REF.FUNC`_instr(x), `%->_%%`_instrtype(`%`_resulttype([]), [], `%`_resulttype([REF_valtype(?(), (dt : deftype <: heaptype))]))) -- if (C.FUNCS_context[x!`%`_idx.0] = dt) -- if (x <- C.REFS_context) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:211.1-212.34 - rule ref.i31{C : context}: - `%|-%:%`(C, REF.I31_instr, `%->_%%`_instrtype(`%`_resulttype([I32_valtype]), [], `%`_resulttype([REF_valtype(?(), I31_heaptype)]))) + rule `ref.i31`{C : context}: + `%|-%:%`(C, `REF.I31`_instr, `%->_%%`_instrtype(`%`_resulttype([I32_valtype]), [], `%`_resulttype([REF_valtype(?(), I31_heaptype)]))) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:214.1-216.31 - rule ref.is_null{C : context, ht : heaptype}: - `%|-%:%`(C, REF.IS_NULL_instr, `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), ht)]), [], `%`_resulttype([I32_valtype]))) + rule `ref.is_null`{C : context, ht : heaptype}: + `%|-%:%`(C, `REF.IS_NULL`_instr, `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), ht)]), [], `%`_resulttype([I32_valtype]))) -- Heaptype_ok: `%|-%:OK`(C, ht) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:218.1-220.31 - rule ref.as_non_null{C : context, ht : heaptype}: - `%|-%:%`(C, REF.AS_NON_NULL_instr, `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), ht)]), [], `%`_resulttype([REF_valtype(?(), ht)]))) + rule `ref.as_non_null`{C : context, ht : heaptype}: + `%|-%:%`(C, `REF.AS_NON_NULL`_instr, `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), ht)]), [], `%`_resulttype([REF_valtype(?(), ht)]))) -- Heaptype_ok: `%|-%:OK`(C, ht) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:222.1-223.51 - rule ref.eq{C : context}: - `%|-%:%`(C, REF.EQ_instr, `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), EQ_heaptype) REF_valtype(?(NULL_null), EQ_heaptype)]), [], `%`_resulttype([I32_valtype]))) + rule `ref.eq`{C : context}: + `%|-%:%`(C, `REF.EQ`_instr, `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), EQ_heaptype) REF_valtype(?(NULL_null), EQ_heaptype)]), [], `%`_resulttype([I32_valtype]))) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:225.1-229.33 - rule ref.test{C : context, rt : reftype, rt' : reftype}: - `%|-%:%`(C, REF.TEST_instr(rt), `%->_%%`_instrtype(`%`_resulttype([(rt' : reftype <: valtype)]), [], `%`_resulttype([I32_valtype]))) + rule `ref.test`{C : context, rt : reftype, rt' : reftype}: + `%|-%:%`(C, `REF.TEST`_instr(rt), `%->_%%`_instrtype(`%`_resulttype([(rt' : reftype <: valtype)]), [], `%`_resulttype([I32_valtype]))) -- Reftype_ok: `%|-%:OK`(C, rt) -- Reftype_ok: `%|-%:OK`(C, rt') -- Reftype_sub: `%|-%<:%`(C, rt, rt') ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:231.1-235.33 - rule ref.cast{C : context, rt : reftype, rt' : reftype}: - `%|-%:%`(C, REF.CAST_instr(rt), `%->_%%`_instrtype(`%`_resulttype([(rt' : reftype <: valtype)]), [], `%`_resulttype([(rt : reftype <: valtype)]))) + rule `ref.cast`{C : context, rt : reftype, rt' : reftype}: + `%|-%:%`(C, `REF.CAST`_instr(rt), `%->_%%`_instrtype(`%`_resulttype([(rt' : reftype <: valtype)]), [], `%`_resulttype([(rt : reftype <: valtype)]))) -- Reftype_ok: `%|-%:OK`(C, rt) -- Reftype_ok: `%|-%:OK`(C, rt') -- Reftype_sub: `%|-%<:%`(C, rt, rt') ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:240.1-241.42 - rule i31.get{C : context, sx : sx}: - `%|-%:%`(C, I31.GET_instr(sx), `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), I31_heaptype)]), [], `%`_resulttype([I32_valtype]))) + rule `i31.get`{C : context, sx : sx}: + `%|-%:%`(C, `I31.GET`_instr(sx), `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), I31_heaptype)]), [], `%`_resulttype([I32_valtype]))) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:246.1-248.45 - rule struct.new{C : context, x : idx, `zt*` : storagetype*, `mut?*` : mut?*}: - `%|-%:%`(C, STRUCT.NEW_instr(x), `%->_%%`_instrtype(`%`_resulttype($unpack(zt)*{zt <- `zt*`}), [], `%`_resulttype([REF_valtype(?(), _IDX_heaptype(x))]))) + rule `struct.new`{C : context, x : idx, `zt*` : storagetype*, `mut?*` : mut?*}: + `%|-%:%`(C, `STRUCT.NEW`_instr(x), `%->_%%`_instrtype(`%`_resulttype($unpack(zt)*{zt <- `zt*`}), [], `%`_resulttype([REF_valtype(?(), _IDX_heaptype(x))]))) -- Expand: `%~~%`(C.TYPES_context[x!`%`_idx.0], STRUCT_comptype(`%`_list(`%%`_fieldtype(mut?{mut <- `mut?`}, zt)*{`mut?` <- `mut?*`, zt <- `zt*`}))) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:250.1-253.48 - rule struct.new_default{C : context, x : idx, `mut?*` : mut?*, `zt*` : storagetype*}: - `%|-%:%`(C, STRUCT.NEW_DEFAULT_instr(x), `%->_%%`_instrtype(`%`_resulttype([]), [], `%`_resulttype([REF_valtype(?(), _IDX_heaptype(x))]))) + rule `struct.new_default`{C : context, x : idx, `mut?*` : mut?*, `zt*` : storagetype*}: + `%|-%:%`(C, `STRUCT.NEW_DEFAULT`_instr(x), `%->_%%`_instrtype(`%`_resulttype([]), [], `%`_resulttype([REF_valtype(?(), _IDX_heaptype(x))]))) -- Expand: `%~~%`(C.TYPES_context[x!`%`_idx.0], STRUCT_comptype(`%`_list(`%%`_fieldtype(mut?{mut <- `mut?`}, zt)*{`mut?` <- `mut?*`, zt <- `zt*`}))) -- (Defaultable: `|-%DEFAULTABLE`($unpack(zt)))*{zt <- `zt*`} ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:258.1-262.39 - rule struct.get{C : context, `sx?` : sx?, x : idx, i : u32, zt : storagetype, `ft*` : fieldtype*, `mut?` : mut?}: - `%|-%:%`(C, STRUCT.GET_instr(sx?{sx <- `sx?`}, x, i), `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), _IDX_heaptype(x))]), [], `%`_resulttype([$unpack(zt)]))) + rule `struct.get`{C : context, `sx?` : sx?, x : idx, i : u32, zt : storagetype, `ft*` : fieldtype*, `mut?` : mut?}: + `%|-%:%`(C, `STRUCT.GET`_instr(sx?{sx <- `sx?`}, x, i), `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), _IDX_heaptype(x))]), [], `%`_resulttype([$unpack(zt)]))) -- Expand: `%~~%`(C.TYPES_context[x!`%`_idx.0], STRUCT_comptype(`%`_list(ft*{ft <- `ft*`}))) -- if (ft*{ft <- `ft*`}[i!`%`_u32.0] = `%%`_fieldtype(mut?{mut <- `mut?`}, zt)) -- if ((sx?{sx <- `sx?`} = ?()) <=> $is_packtype(zt)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:264.1-267.24 - rule struct.set{C : context, x : idx, i : u32, zt : storagetype, `ft*` : fieldtype*}: - `%|-%:%`(C, STRUCT.SET_instr(x, i), `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), _IDX_heaptype(x)) $unpack(zt)]), [], `%`_resulttype([]))) + rule `struct.set`{C : context, x : idx, i : u32, zt : storagetype, `ft*` : fieldtype*}: + `%|-%:%`(C, `STRUCT.SET`_instr(x, i), `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), _IDX_heaptype(x)) $unpack(zt)]), [], `%`_resulttype([]))) -- Expand: `%~~%`(C.TYPES_context[x!`%`_idx.0], STRUCT_comptype(`%`_list(ft*{ft <- `ft*`}))) -- if (ft*{ft <- `ft*`}[i!`%`_u32.0] = `%%`_fieldtype(?(MUT_mut), zt)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:272.1-274.43 - rule array.new{C : context, x : idx, zt : storagetype, `mut?` : mut?}: - `%|-%:%`(C, ARRAY.NEW_instr(x), `%->_%%`_instrtype(`%`_resulttype([$unpack(zt) I32_valtype]), [], `%`_resulttype([REF_valtype(?(), _IDX_heaptype(x))]))) + rule `array.new`{C : context, x : idx, zt : storagetype, `mut?` : mut?}: + `%|-%:%`(C, `ARRAY.NEW`_instr(x), `%->_%%`_instrtype(`%`_resulttype([$unpack(zt) I32_valtype]), [], `%`_resulttype([REF_valtype(?(), _IDX_heaptype(x))]))) -- Expand: `%~~%`(C.TYPES_context[x!`%`_idx.0], ARRAY_comptype(`%%`_fieldtype(mut?{mut <- `mut?`}, zt))) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:276.1-279.45 - rule array.new_default{C : context, x : idx, `mut?` : mut?, zt : storagetype}: - `%|-%:%`(C, ARRAY.NEW_DEFAULT_instr(x), `%->_%%`_instrtype(`%`_resulttype([I32_valtype]), [], `%`_resulttype([REF_valtype(?(), _IDX_heaptype(x))]))) + rule `array.new_default`{C : context, x : idx, `mut?` : mut?, zt : storagetype}: + `%|-%:%`(C, `ARRAY.NEW_DEFAULT`_instr(x), `%->_%%`_instrtype(`%`_resulttype([I32_valtype]), [], `%`_resulttype([REF_valtype(?(), _IDX_heaptype(x))]))) -- Expand: `%~~%`(C.TYPES_context[x!`%`_idx.0], ARRAY_comptype(`%%`_fieldtype(mut?{mut <- `mut?`}, zt))) -- Defaultable: `|-%DEFAULTABLE`($unpack(zt)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:281.1-283.43 - rule array.new_fixed{C : context, x : idx, n : n, zt : storagetype, `mut?` : mut?}: - `%|-%:%`(C, ARRAY.NEW_FIXED_instr(x, `%`_u32(n)), `%->_%%`_instrtype(`%`_resulttype($unpack(zt)^n{}), [], `%`_resulttype([REF_valtype(?(), _IDX_heaptype(x))]))) + rule `array.new_fixed`{C : context, x : idx, n : n, zt : storagetype, `mut?` : mut?}: + `%|-%:%`(C, `ARRAY.NEW_FIXED`_instr(x, `%`_u32(n)), `%->_%%`_instrtype(`%`_resulttype($unpack(zt)^n{}), [], `%`_resulttype([REF_valtype(?(), _IDX_heaptype(x))]))) -- Expand: `%~~%`(C.TYPES_context[x!`%`_idx.0], ARRAY_comptype(`%%`_fieldtype(mut?{mut <- `mut?`}, zt))) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:285.1-288.40 - rule array.new_elem{C : context, x : idx, y : idx, `mut?` : mut?, rt : reftype}: - `%|-%:%`(C, ARRAY.NEW_ELEM_instr(x, y), `%->_%%`_instrtype(`%`_resulttype([I32_valtype I32_valtype]), [], `%`_resulttype([REF_valtype(?(), _IDX_heaptype(x))]))) + rule `array.new_elem`{C : context, x : idx, y : idx, `mut?` : mut?, rt : reftype}: + `%|-%:%`(C, `ARRAY.NEW_ELEM`_instr(x, y), `%->_%%`_instrtype(`%`_resulttype([I32_valtype I32_valtype]), [], `%`_resulttype([REF_valtype(?(), _IDX_heaptype(x))]))) -- Expand: `%~~%`(C.TYPES_context[x!`%`_idx.0], ARRAY_comptype(`%%`_fieldtype(mut?{mut <- `mut?`}, (rt : reftype <: storagetype)))) -- Reftype_sub: `%|-%<:%`(C, C.ELEMS_context[y!`%`_idx.0], rt) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:290.1-294.24 - rule array.new_data{C : context, x : idx, y : idx, `mut?` : mut?, zt : storagetype, numtype : numtype, vectype : vectype}: - `%|-%:%`(C, ARRAY.NEW_DATA_instr(x, y), `%->_%%`_instrtype(`%`_resulttype([I32_valtype I32_valtype]), [], `%`_resulttype([REF_valtype(?(), _IDX_heaptype(x))]))) + rule `array.new_data`{C : context, x : idx, y : idx, `mut?` : mut?, zt : storagetype, numtype : numtype, vectype : vectype}: + `%|-%:%`(C, `ARRAY.NEW_DATA`_instr(x, y), `%->_%%`_instrtype(`%`_resulttype([I32_valtype I32_valtype]), [], `%`_resulttype([REF_valtype(?(), _IDX_heaptype(x))]))) -- Expand: `%~~%`(C.TYPES_context[x!`%`_idx.0], ARRAY_comptype(`%%`_fieldtype(mut?{mut <- `mut?`}, zt))) -- if (($unpack(zt) = (numtype : numtype <: valtype)) \/ ($unpack(zt) = (vectype : vectype <: valtype))) -- if (C.DATAS_context[y!`%`_idx.0] = OK_datatype) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:296.1-299.39 - rule array.get{C : context, `sx?` : sx?, x : idx, zt : storagetype, `mut?` : mut?}: - `%|-%:%`(C, ARRAY.GET_instr(sx?{sx <- `sx?`}, x), `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), _IDX_heaptype(x)) I32_valtype]), [], `%`_resulttype([$unpack(zt)]))) + rule `array.get`{C : context, `sx?` : sx?, x : idx, zt : storagetype, `mut?` : mut?}: + `%|-%:%`(C, `ARRAY.GET`_instr(sx?{sx <- `sx?`}, x), `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), _IDX_heaptype(x)) I32_valtype]), [], `%`_resulttype([$unpack(zt)]))) -- Expand: `%~~%`(C.TYPES_context[x!`%`_idx.0], ARRAY_comptype(`%%`_fieldtype(mut?{mut <- `mut?`}, zt))) -- if ((sx?{sx <- `sx?`} = ?()) <=> $is_packtype(zt)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:301.1-303.42 - rule array.set{C : context, x : idx, zt : storagetype}: - `%|-%:%`(C, ARRAY.SET_instr(x), `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), _IDX_heaptype(x)) I32_valtype $unpack(zt)]), [], `%`_resulttype([]))) + rule `array.set`{C : context, x : idx, zt : storagetype}: + `%|-%:%`(C, `ARRAY.SET`_instr(x), `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), _IDX_heaptype(x)) I32_valtype $unpack(zt)]), [], `%`_resulttype([]))) -- Expand: `%~~%`(C.TYPES_context[x!`%`_idx.0], ARRAY_comptype(`%%`_fieldtype(?(MUT_mut), zt))) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:305.1-306.43 - rule array.len{C : context}: - `%|-%:%`(C, ARRAY.LEN_instr, `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), ARRAY_heaptype)]), [], `%`_resulttype([I32_valtype]))) + rule `array.len`{C : context}: + `%|-%:%`(C, `ARRAY.LEN`_instr, `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), ARRAY_heaptype)]), [], `%`_resulttype([I32_valtype]))) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:308.1-310.42 - rule array.fill{C : context, x : idx, zt : storagetype}: - `%|-%:%`(C, ARRAY.FILL_instr(x), `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), _IDX_heaptype(x)) I32_valtype $unpack(zt) I32_valtype]), [], `%`_resulttype([]))) + rule `array.fill`{C : context, x : idx, zt : storagetype}: + `%|-%:%`(C, `ARRAY.FILL`_instr(x), `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), _IDX_heaptype(x)) I32_valtype $unpack(zt) I32_valtype]), [], `%`_resulttype([]))) -- Expand: `%~~%`(C.TYPES_context[x!`%`_idx.0], ARRAY_comptype(`%%`_fieldtype(?(MUT_mut), zt))) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:312.1-316.40 - rule array.copy{C : context, x_1 : idx, x_2 : idx, zt_1 : storagetype, `mut?` : mut?, zt_2 : storagetype}: - `%|-%:%`(C, ARRAY.COPY_instr(x_1, x_2), `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), _IDX_heaptype(x_1)) I32_valtype REF_valtype(?(NULL_null), _IDX_heaptype(x_2)) I32_valtype I32_valtype]), [], `%`_resulttype([]))) + rule `array.copy`{C : context, x_1 : idx, x_2 : idx, zt_1 : storagetype, `mut?` : mut?, zt_2 : storagetype}: + `%|-%:%`(C, `ARRAY.COPY`_instr(x_1, x_2), `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), _IDX_heaptype(x_1)) I32_valtype REF_valtype(?(NULL_null), _IDX_heaptype(x_2)) I32_valtype I32_valtype]), [], `%`_resulttype([]))) -- Expand: `%~~%`(C.TYPES_context[x_1!`%`_idx.0], ARRAY_comptype(`%%`_fieldtype(?(MUT_mut), zt_1))) -- Expand: `%~~%`(C.TYPES_context[x_2!`%`_idx.0], ARRAY_comptype(`%%`_fieldtype(mut?{mut <- `mut?`}, zt_2))) -- Storagetype_sub: `%|-%<:%`(C, zt_2, zt_1) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:318.1-321.44 - rule array.init_elem{C : context, x : idx, y : idx, zt : storagetype}: - `%|-%:%`(C, ARRAY.INIT_ELEM_instr(x, y), `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), _IDX_heaptype(x)) I32_valtype I32_valtype I32_valtype]), [], `%`_resulttype([]))) + rule `array.init_elem`{C : context, x : idx, y : idx, zt : storagetype}: + `%|-%:%`(C, `ARRAY.INIT_ELEM`_instr(x, y), `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), _IDX_heaptype(x)) I32_valtype I32_valtype I32_valtype]), [], `%`_resulttype([]))) -- Expand: `%~~%`(C.TYPES_context[x!`%`_idx.0], ARRAY_comptype(`%%`_fieldtype(?(MUT_mut), zt))) -- Storagetype_sub: `%|-%<:%`(C, (C.ELEMS_context[y!`%`_idx.0] : reftype <: storagetype), zt) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:323.1-327.24 - rule array.init_data{C : context, x : idx, y : idx, zt : storagetype, numtype : numtype, vectype : vectype}: - `%|-%:%`(C, ARRAY.INIT_DATA_instr(x, y), `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), _IDX_heaptype(x)) I32_valtype I32_valtype I32_valtype]), [], `%`_resulttype([]))) + rule `array.init_data`{C : context, x : idx, y : idx, zt : storagetype, numtype : numtype, vectype : vectype}: + `%|-%:%`(C, `ARRAY.INIT_DATA`_instr(x, y), `%->_%%`_instrtype(`%`_resulttype([REF_valtype(?(NULL_null), _IDX_heaptype(x)) I32_valtype I32_valtype I32_valtype]), [], `%`_resulttype([]))) -- Expand: `%~~%`(C.TYPES_context[x!`%`_idx.0], ARRAY_comptype(`%%`_fieldtype(?(MUT_mut), zt))) -- if (($unpack(zt) = (numtype : numtype <: valtype)) \/ ($unpack(zt) = (vectype : vectype <: valtype))) -- if (C.DATAS_context[y!`%`_idx.0] = OK_datatype) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:332.1-334.26 - rule extern.convert_any{C : context, `null_1?` : null?, `null_2?` : null?}: - `%|-%:%`(C, EXTERN.CONVERT_ANY_instr, `%->_%%`_instrtype(`%`_resulttype([REF_valtype(null_1?{null_1 <- `null_1?`}, ANY_heaptype)]), [], `%`_resulttype([REF_valtype(null_2?{null_2 <- `null_2?`}, EXTERN_heaptype)]))) + rule `extern.convert_any`{C : context, `null_1?` : null?, `null_2?` : null?}: + `%|-%:%`(C, `EXTERN.CONVERT_ANY`_instr, `%->_%%`_instrtype(`%`_resulttype([REF_valtype(null_1?{null_1 <- `null_1?`}, ANY_heaptype)]), [], `%`_resulttype([REF_valtype(null_2?{null_2 <- `null_2?`}, EXTERN_heaptype)]))) -- if (null_1?{null_1 <- `null_1?`} = null_2?{null_2 <- `null_2?`}) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:336.1-338.26 - rule any.convert_extern{C : context, `null_1?` : null?, `null_2?` : null?}: - `%|-%:%`(C, ANY.CONVERT_EXTERN_instr, `%->_%%`_instrtype(`%`_resulttype([REF_valtype(null_1?{null_1 <- `null_1?`}, EXTERN_heaptype)]), [], `%`_resulttype([REF_valtype(null_2?{null_2 <- `null_2?`}, ANY_heaptype)]))) + rule `any.convert_extern`{C : context, `null_1?` : null?, `null_2?` : null?}: + `%|-%:%`(C, `ANY.CONVERT_EXTERN`_instr, `%->_%%`_instrtype(`%`_resulttype([REF_valtype(null_1?{null_1 <- `null_1?`}, EXTERN_heaptype)]), [], `%`_resulttype([REF_valtype(null_2?{null_2 <- `null_2?`}, ANY_heaptype)]))) -- if (null_1?{null_1 <- `null_1?`} = null_2?{null_2 <- `null_2?`}) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:343.1-345.28 - rule local.get{C : context, x : idx, t : valtype}: - `%|-%:%`(C, LOCAL.GET_instr(x), `%->_%%`_instrtype(`%`_resulttype([]), [], `%`_resulttype([t]))) + rule `local.get`{C : context, x : idx, t : valtype}: + `%|-%:%`(C, `LOCAL.GET`_instr(x), `%->_%%`_instrtype(`%`_resulttype([]), [], `%`_resulttype([t]))) -- if (C.LOCALS_context[x!`%`_idx.0] = `%%`_localtype(SET_init, t)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:347.1-349.29 - rule local.set{C : context, x : idx, t : valtype, init : init}: - `%|-%:%`(C, LOCAL.SET_instr(x), `%->_%%`_instrtype(`%`_resulttype([t]), [x], `%`_resulttype([]))) + rule `local.set`{C : context, x : idx, t : valtype, init : init}: + `%|-%:%`(C, `LOCAL.SET`_instr(x), `%->_%%`_instrtype(`%`_resulttype([t]), [x], `%`_resulttype([]))) -- if (C.LOCALS_context[x!`%`_idx.0] = `%%`_localtype(init, t)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:351.1-353.29 - rule local.tee{C : context, x : idx, t : valtype, init : init}: - `%|-%:%`(C, LOCAL.TEE_instr(x), `%->_%%`_instrtype(`%`_resulttype([t]), [x], `%`_resulttype([t]))) + rule `local.tee`{C : context, x : idx, t : valtype, init : init}: + `%|-%:%`(C, `LOCAL.TEE`_instr(x), `%->_%%`_instrtype(`%`_resulttype([t]), [x], `%`_resulttype([t]))) -- if (C.LOCALS_context[x!`%`_idx.0] = `%%`_localtype(init, t)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:358.1-360.30 - rule global.get{C : context, x : idx, t : valtype, `mut?` : mut?}: - `%|-%:%`(C, GLOBAL.GET_instr(x), `%->_%%`_instrtype(`%`_resulttype([]), [], `%`_resulttype([t]))) + rule `global.get`{C : context, x : idx, t : valtype, `mut?` : mut?}: + `%|-%:%`(C, `GLOBAL.GET`_instr(x), `%->_%%`_instrtype(`%`_resulttype([]), [], `%`_resulttype([t]))) -- if (C.GLOBALS_context[x!`%`_idx.0] = `%%`_globaltype(mut?{mut <- `mut?`}, t)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:362.1-364.29 - rule global.set{C : context, x : idx, t : valtype}: - `%|-%:%`(C, GLOBAL.SET_instr(x), `%->_%%`_instrtype(`%`_resulttype([t]), [], `%`_resulttype([]))) + rule `global.set`{C : context, x : idx, t : valtype}: + `%|-%:%`(C, `GLOBAL.SET`_instr(x), `%->_%%`_instrtype(`%`_resulttype([t]), [], `%`_resulttype([]))) -- if (C.GLOBALS_context[x!`%`_idx.0] = `%%`_globaltype(?(MUT_mut), t)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:369.1-371.32 - rule table.get{C : context, x : idx, at : addrtype, rt : reftype, lim : limits}: - `%|-%:%`(C, TABLE.GET_instr(x), `%->_%%`_instrtype(`%`_resulttype([(at : addrtype <: valtype)]), [], `%`_resulttype([(rt : reftype <: valtype)]))) + rule `table.get`{C : context, x : idx, at : addrtype, rt : reftype, lim : limits}: + `%|-%:%`(C, `TABLE.GET`_instr(x), `%->_%%`_instrtype(`%`_resulttype([(at : addrtype <: valtype)]), [], `%`_resulttype([(rt : reftype <: valtype)]))) -- if (C.TABLES_context[x!`%`_idx.0] = `%%%`_tabletype(at, lim, rt)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:373.1-375.32 - rule table.set{C : context, x : idx, at : addrtype, rt : reftype, lim : limits}: - `%|-%:%`(C, TABLE.SET_instr(x), `%->_%%`_instrtype(`%`_resulttype([(at : addrtype <: valtype) (rt : reftype <: valtype)]), [], `%`_resulttype([]))) + rule `table.set`{C : context, x : idx, at : addrtype, rt : reftype, lim : limits}: + `%|-%:%`(C, `TABLE.SET`_instr(x), `%->_%%`_instrtype(`%`_resulttype([(at : addrtype <: valtype) (rt : reftype <: valtype)]), [], `%`_resulttype([]))) -- if (C.TABLES_context[x!`%`_idx.0] = `%%%`_tabletype(at, lim, rt)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:377.1-379.32 - rule table.size{C : context, x : idx, at : addrtype, lim : limits, rt : reftype}: - `%|-%:%`(C, TABLE.SIZE_instr(x), `%->_%%`_instrtype(`%`_resulttype([]), [], `%`_resulttype([(at : addrtype <: valtype)]))) + rule `table.size`{C : context, x : idx, at : addrtype, lim : limits, rt : reftype}: + `%|-%:%`(C, `TABLE.SIZE`_instr(x), `%->_%%`_instrtype(`%`_resulttype([]), [], `%`_resulttype([(at : addrtype <: valtype)]))) -- if (C.TABLES_context[x!`%`_idx.0] = `%%%`_tabletype(at, lim, rt)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:381.1-383.32 - rule table.grow{C : context, x : idx, rt : reftype, at : addrtype, lim : limits}: - `%|-%:%`(C, TABLE.GROW_instr(x), `%->_%%`_instrtype(`%`_resulttype([(rt : reftype <: valtype) (at : addrtype <: valtype)]), [], `%`_resulttype([I32_valtype]))) + rule `table.grow`{C : context, x : idx, rt : reftype, at : addrtype, lim : limits}: + `%|-%:%`(C, `TABLE.GROW`_instr(x), `%->_%%`_instrtype(`%`_resulttype([(rt : reftype <: valtype) (at : addrtype <: valtype)]), [], `%`_resulttype([I32_valtype]))) -- if (C.TABLES_context[x!`%`_idx.0] = `%%%`_tabletype(at, lim, rt)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:385.1-387.32 - rule table.fill{C : context, x : idx, at : addrtype, rt : reftype, lim : limits}: - `%|-%:%`(C, TABLE.FILL_instr(x), `%->_%%`_instrtype(`%`_resulttype([(at : addrtype <: valtype) (rt : reftype <: valtype) (at : addrtype <: valtype)]), [], `%`_resulttype([]))) + rule `table.fill`{C : context, x : idx, at : addrtype, rt : reftype, lim : limits}: + `%|-%:%`(C, `TABLE.FILL`_instr(x), `%->_%%`_instrtype(`%`_resulttype([(at : addrtype <: valtype) (rt : reftype <: valtype) (at : addrtype <: valtype)]), [], `%`_resulttype([]))) -- if (C.TABLES_context[x!`%`_idx.0] = `%%%`_tabletype(at, lim, rt)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:389.1-393.36 - rule table.copy{C : context, x_1 : idx, x_2 : idx, at_1 : addrtype, at_2 : addrtype, lim_1 : limits, rt_1 : reftype, lim_2 : limits, rt_2 : reftype}: - `%|-%:%`(C, TABLE.COPY_instr(x_1, x_2), `%->_%%`_instrtype(`%`_resulttype([(at_1 : addrtype <: valtype) (at_2 : addrtype <: valtype) ($minat(at_1, at_2) : addrtype <: valtype)]), [], `%`_resulttype([]))) + rule `table.copy`{C : context, x_1 : idx, x_2 : idx, at_1 : addrtype, at_2 : addrtype, lim_1 : limits, rt_1 : reftype, lim_2 : limits, rt_2 : reftype}: + `%|-%:%`(C, `TABLE.COPY`_instr(x_1, x_2), `%->_%%`_instrtype(`%`_resulttype([(at_1 : addrtype <: valtype) (at_2 : addrtype <: valtype) ($minat(at_1, at_2) : addrtype <: valtype)]), [], `%`_resulttype([]))) -- if (C.TABLES_context[x_1!`%`_idx.0] = `%%%`_tabletype(at_1, lim_1, rt_1)) -- if (C.TABLES_context[x_2!`%`_idx.0] = `%%%`_tabletype(at_2, lim_2, rt_2)) -- Reftype_sub: `%|-%<:%`(C, rt_2, rt_1) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:395.1-399.36 - rule table.init{C : context, x : idx, y : idx, at : addrtype, lim : limits, rt_1 : reftype, rt_2 : reftype}: - `%|-%:%`(C, TABLE.INIT_instr(x, y), `%->_%%`_instrtype(`%`_resulttype([(at : addrtype <: valtype) I32_valtype I32_valtype]), [], `%`_resulttype([]))) + rule `table.init`{C : context, x : idx, y : idx, at : addrtype, lim : limits, rt_1 : reftype, rt_2 : reftype}: + `%|-%:%`(C, `TABLE.INIT`_instr(x, y), `%->_%%`_instrtype(`%`_resulttype([(at : addrtype <: valtype) I32_valtype I32_valtype]), [], `%`_resulttype([]))) -- if (C.TABLES_context[x!`%`_idx.0] = `%%%`_tabletype(at, lim, rt_1)) -- if (C.ELEMS_context[y!`%`_idx.0] = rt_2) -- Reftype_sub: `%|-%<:%`(C, rt_2, rt_1) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:401.1-403.24 - rule elem.drop{C : context, x : idx, rt : reftype}: - `%|-%:%`(C, ELEM.DROP_instr(x), `%->_%%`_instrtype(`%`_resulttype([]), [], `%`_resulttype([]))) + rule `elem.drop`{C : context, x : idx, rt : reftype}: + `%|-%:%`(C, `ELEM.DROP`_instr(x), `%->_%%`_instrtype(`%`_resulttype([]), [], `%`_resulttype([]))) -- if (C.ELEMS_context[x!`%`_idx.0] = rt) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:416.1-418.32 - rule memory.size{C : context, x : idx, at : addrtype, lim : limits}: - `%|-%:%`(C, MEMORY.SIZE_instr(x), `%->_%%`_instrtype(`%`_resulttype([]), [], `%`_resulttype([(at : addrtype <: valtype)]))) + rule `memory.size`{C : context, x : idx, at : addrtype, lim : limits}: + `%|-%:%`(C, `MEMORY.SIZE`_instr(x), `%->_%%`_instrtype(`%`_resulttype([]), [], `%`_resulttype([(at : addrtype <: valtype)]))) -- if (C.MEMS_context[x!`%`_idx.0] = `%%PAGE`_memtype(at, lim)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:420.1-422.32 - rule memory.grow{C : context, x : idx, at : addrtype, lim : limits}: - `%|-%:%`(C, MEMORY.GROW_instr(x), `%->_%%`_instrtype(`%`_resulttype([(at : addrtype <: valtype)]), [], `%`_resulttype([(at : addrtype <: valtype)]))) + rule `memory.grow`{C : context, x : idx, at : addrtype, lim : limits}: + `%|-%:%`(C, `MEMORY.GROW`_instr(x), `%->_%%`_instrtype(`%`_resulttype([(at : addrtype <: valtype)]), [], `%`_resulttype([(at : addrtype <: valtype)]))) -- if (C.MEMS_context[x!`%`_idx.0] = `%%PAGE`_memtype(at, lim)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:424.1-426.32 - rule memory.fill{C : context, x : idx, at : addrtype, lim : limits}: - `%|-%:%`(C, MEMORY.FILL_instr(x), `%->_%%`_instrtype(`%`_resulttype([(at : addrtype <: valtype) I32_valtype (at : addrtype <: valtype)]), [], `%`_resulttype([]))) + rule `memory.fill`{C : context, x : idx, at : addrtype, lim : limits}: + `%|-%:%`(C, `MEMORY.FILL`_instr(x), `%->_%%`_instrtype(`%`_resulttype([(at : addrtype <: valtype) I32_valtype (at : addrtype <: valtype)]), [], `%`_resulttype([]))) -- if (C.MEMS_context[x!`%`_idx.0] = `%%PAGE`_memtype(at, lim)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:428.1-431.38 - rule memory.copy{C : context, x_1 : idx, x_2 : idx, at_1 : addrtype, at_2 : addrtype, lim_1 : limits, lim_2 : limits}: - `%|-%:%`(C, MEMORY.COPY_instr(x_1, x_2), `%->_%%`_instrtype(`%`_resulttype([(at_1 : addrtype <: valtype) (at_2 : addrtype <: valtype) ($minat(at_1, at_2) : addrtype <: valtype)]), [], `%`_resulttype([]))) + rule `memory.copy`{C : context, x_1 : idx, x_2 : idx, at_1 : addrtype, at_2 : addrtype, lim_1 : limits, lim_2 : limits}: + `%|-%:%`(C, `MEMORY.COPY`_instr(x_1, x_2), `%->_%%`_instrtype(`%`_resulttype([(at_1 : addrtype <: valtype) (at_2 : addrtype <: valtype) ($minat(at_1, at_2) : addrtype <: valtype)]), [], `%`_resulttype([]))) -- if (C.MEMS_context[x_1!`%`_idx.0] = `%%PAGE`_memtype(at_1, lim_1)) -- if (C.MEMS_context[x_2!`%`_idx.0] = `%%PAGE`_memtype(at_2, lim_2)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:433.1-436.24 - rule memory.init{C : context, x : idx, y : idx, at : addrtype, lim : limits}: - `%|-%:%`(C, MEMORY.INIT_instr(x, y), `%->_%%`_instrtype(`%`_resulttype([(at : addrtype <: valtype) I32_valtype I32_valtype]), [], `%`_resulttype([]))) + rule `memory.init`{C : context, x : idx, y : idx, at : addrtype, lim : limits}: + `%|-%:%`(C, `MEMORY.INIT`_instr(x, y), `%->_%%`_instrtype(`%`_resulttype([(at : addrtype <: valtype) I32_valtype I32_valtype]), [], `%`_resulttype([]))) -- if (C.MEMS_context[x!`%`_idx.0] = `%%PAGE`_memtype(at, lim)) -- if (C.DATAS_context[y!`%`_idx.0] = OK_datatype) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:438.1-440.24 - rule data.drop{C : context, x : idx}: - `%|-%:%`(C, DATA.DROP_instr(x), `%->_%%`_instrtype(`%`_resulttype([]), [], `%`_resulttype([]))) + rule `data.drop`{C : context, x : idx}: + `%|-%:%`(C, `DATA.DROP`_instr(x), `%->_%%`_instrtype(`%`_resulttype([]), [], `%`_resulttype([]))) -- if (C.DATAS_context[x!`%`_idx.0] = OK_datatype) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec:451.1-454.44 @@ -3992,48 +3992,48 @@ relation Instr_const: `%|-%CONST`(context, instr) `%|-%CONST`(C, VCONST_instr(vt, c_vt)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec - rule ref.null{C : context, ht : heaptype}: - `%|-%CONST`(C, REF.NULL_instr(ht)) + rule `ref.null`{C : context, ht : heaptype}: + `%|-%CONST`(C, `REF.NULL`_instr(ht)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec - rule ref.i31{C : context}: - `%|-%CONST`(C, REF.I31_instr) + rule `ref.i31`{C : context}: + `%|-%CONST`(C, `REF.I31`_instr) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec - rule ref.func{C : context, x : idx}: - `%|-%CONST`(C, REF.FUNC_instr(x)) + rule `ref.func`{C : context, x : idx}: + `%|-%CONST`(C, `REF.FUNC`_instr(x)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec - rule struct.new{C : context, x : idx}: - `%|-%CONST`(C, STRUCT.NEW_instr(x)) + rule `struct.new`{C : context, x : idx}: + `%|-%CONST`(C, `STRUCT.NEW`_instr(x)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec - rule struct.new_default{C : context, x : idx}: - `%|-%CONST`(C, STRUCT.NEW_DEFAULT_instr(x)) + rule `struct.new_default`{C : context, x : idx}: + `%|-%CONST`(C, `STRUCT.NEW_DEFAULT`_instr(x)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec - rule array.new{C : context, x : idx}: - `%|-%CONST`(C, ARRAY.NEW_instr(x)) + rule `array.new`{C : context, x : idx}: + `%|-%CONST`(C, `ARRAY.NEW`_instr(x)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec - rule array.new_default{C : context, x : idx}: - `%|-%CONST`(C, ARRAY.NEW_DEFAULT_instr(x)) + rule `array.new_default`{C : context, x : idx}: + `%|-%CONST`(C, `ARRAY.NEW_DEFAULT`_instr(x)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec - rule array.new_fixed{C : context, x : idx, n : n}: - `%|-%CONST`(C, ARRAY.NEW_FIXED_instr(x, `%`_u32(n))) + rule `array.new_fixed`{C : context, x : idx, n : n}: + `%|-%CONST`(C, `ARRAY.NEW_FIXED`_instr(x, `%`_u32(n))) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec - rule any.convert_extern{C : context}: - `%|-%CONST`(C, ANY.CONVERT_EXTERN_instr) + rule `any.convert_extern`{C : context}: + `%|-%CONST`(C, `ANY.CONVERT_EXTERN`_instr) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec - rule extern.convert_any{C : context}: - `%|-%CONST`(C, EXTERN.CONVERT_ANY_instr) + rule `extern.convert_any`{C : context}: + `%|-%CONST`(C, `EXTERN.CONVERT_ANY`_instr) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec - rule global.get{C : context, x : idx, t : valtype}: - `%|-%CONST`(C, GLOBAL.GET_instr(x)) + rule `global.get`{C : context, x : idx, t : valtype}: + `%|-%CONST`(C, `GLOBAL.GET`_instr(x)) -- if (C.GLOBALS_context[x!`%`_idx.0] = `%%`_globaltype(?(), t)) ;; ../../../../specification/wasm-3.0/2.3-validation.instructions.spectec @@ -4246,7 +4246,7 @@ relation Types_ok: `%|-%:%`(context, type*, deftype*) ;; ../../../../specification/wasm-3.0/2.4-validation.modules.spectec syntax nonfuncs = - | `%%%%`{`global*` : global*, `mem*` : mem*, `table*` : table*, `elem*` : elem*}(global*{global <- `global*`} : global*, mem*{mem <- `mem*`} : mem*, table*{table <- `table*`} : table*, elem*{elem <- `elem*`} : elem*) + | `%%%%`(`global*` : global*, `mem*` : mem*, `table*` : table*, `elem*` : elem*) ;; ../../../../specification/wasm-3.0/2.4-validation.modules.spectec def $funcidx_nonfuncs(nonfuncs : nonfuncs) : funcidx* @@ -4281,12 +4281,12 @@ relation Module_ok: `|-%:%`(module, moduletype) ;; ../../../../specification/wasm-3.0/3.0-numerics.relaxed.spectec syntax relaxed2 = - | `%`{i : nat}(i : nat) + | `%`(i : nat) -- if ((i = 0) \/ (i = 1)) ;; ../../../../specification/wasm-3.0/3.0-numerics.relaxed.spectec syntax relaxed4 = - | `%`{i : nat}(i : nat) + | `%`(i : nat) -- if ((((i = 0) \/ (i = 1)) \/ (i = 2)) \/ (i = 3)) ;; ../../../../specification/wasm-3.0/3.0-numerics.relaxed.spectec @@ -4938,7 +4938,7 @@ def $zeroop(shape_1 : shape, shape_2 : shape, vcvtop__ : vcvtop__(shape_1, shape ;; ../../../../specification/wasm-3.0/3.2-numerics.vector.spectec def $zeroop{Fnn_1 : Fnn, M_1 : M, Fnn_2 : Fnn, M_2 : M, zero : zero}(`%X%`_shape((Fnn_1 : Fnn <: lanetype), `%`_dim(M_1)), `%X%`_shape((Fnn_2 : Fnn <: lanetype), `%`_dim(M_2)), DEMOTE_vcvtop__(zero)) = ?(zero) ;; ../../../../specification/wasm-3.0/3.2-numerics.vector.spectec - def $zeroop{Fnn_1 : Fnn, M_1 : M, Fnn_2 : Fnn, M_2 : M}(`%X%`_shape((Fnn_1 : Fnn <: lanetype), `%`_dim(M_1)), `%X%`_shape((Fnn_2 : Fnn <: lanetype), `%`_dim(M_2)), `PROMOTELOW`_vcvtop__) = ?() + def $zeroop{Fnn_1 : Fnn, M_1 : M, Fnn_2 : Fnn, M_2 : M}(`%X%`_shape((Fnn_1 : Fnn <: lanetype), `%`_dim(M_1)), `%X%`_shape((Fnn_2 : Fnn <: lanetype), `%`_dim(M_2)), PROMOTELOW_vcvtop__) = ?() ;; ../../../../specification/wasm-3.0/3.2-numerics.vector.spectec def $halfop(shape_1 : shape, shape_2 : shape, vcvtop__ : vcvtop__(shape_1, shape_2)) : half? @@ -4953,7 +4953,7 @@ def $halfop(shape_1 : shape, shape_2 : shape, vcvtop__ : vcvtop__(shape_1, shape ;; ../../../../specification/wasm-3.0/3.2-numerics.vector.spectec def $halfop{Fnn_1 : Fnn, M_1 : M, Fnn_2 : Fnn, M_2 : M, zero : zero}(`%X%`_shape((Fnn_1 : Fnn <: lanetype), `%`_dim(M_1)), `%X%`_shape((Fnn_2 : Fnn <: lanetype), `%`_dim(M_2)), DEMOTE_vcvtop__(zero)) = ?() ;; ../../../../specification/wasm-3.0/3.2-numerics.vector.spectec - def $halfop{Fnn_1 : Fnn, M_1 : M, Fnn_2 : Fnn, M_2 : M}(`%X%`_shape((Fnn_1 : Fnn <: lanetype), `%`_dim(M_1)), `%X%`_shape((Fnn_2 : Fnn <: lanetype), `%`_dim(M_2)), `PROMOTELOW`_vcvtop__) = ?(LOW_half) + def $halfop{Fnn_1 : Fnn, M_1 : M, Fnn_2 : Fnn, M_2 : M}(`%X%`_shape((Fnn_1 : Fnn <: lanetype), `%`_dim(M_1)), `%X%`_shape((Fnn_2 : Fnn <: lanetype), `%`_dim(M_2)), PROMOTELOW_vcvtop__) = ?(LOW_half) ;; ../../../../specification/wasm-3.0/3.2-numerics.vector.spectec def $half(half : half, nat : nat, nat : nat) : nat @@ -5170,11 +5170,11 @@ def $vbinop_(shape : shape, vbinop_ : vbinop_(shape), vec_ : vec_(V128_Vnn), vec ;; ../../../../specification/wasm-3.0/3.2-numerics.vector.spectec def $vbinop_{Jnn : Jnn, M : M, sx : sx, v_1 : vec_(V128_Vnn), v_2 : vec_(V128_Vnn)}(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M)), MAX_vbinop_(sx), v_1, v_2) = $ivbinopsx_(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M)), def $imax_, sx, v_1, v_2) ;; ../../../../specification/wasm-3.0/3.2-numerics.vector.spectec - def $vbinop_{Jnn : Jnn, M : M, v_1 : vec_(V128_Vnn), v_2 : vec_(V128_Vnn)}(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M)), `AVGRU`_vbinop_, v_1, v_2) = $ivbinopsx_(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M)), def $iavgr_, U_sx, v_1, v_2) + def $vbinop_{Jnn : Jnn, M : M, v_1 : vec_(V128_Vnn), v_2 : vec_(V128_Vnn)}(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M)), AVGRU_vbinop_, v_1, v_2) = $ivbinopsx_(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M)), def $iavgr_, U_sx, v_1, v_2) ;; ../../../../specification/wasm-3.0/3.2-numerics.vector.spectec - def $vbinop_{Jnn : Jnn, M : M, v_1 : vec_(V128_Vnn), v_2 : vec_(V128_Vnn)}(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M)), `Q15MULR_SATS`_vbinop_, v_1, v_2) = $ivbinopsx_(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M)), def $iq15mulr_sat_, S_sx, v_1, v_2) + def $vbinop_{Jnn : Jnn, M : M, v_1 : vec_(V128_Vnn), v_2 : vec_(V128_Vnn)}(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M)), Q15MULR_SATS_vbinop_, v_1, v_2) = $ivbinopsx_(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M)), def $iq15mulr_sat_, S_sx, v_1, v_2) ;; ../../../../specification/wasm-3.0/3.2-numerics.vector.spectec - def $vbinop_{Jnn : Jnn, M : M, v_1 : vec_(V128_Vnn), v_2 : vec_(V128_Vnn)}(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M)), `RELAXED_Q15MULRS`_vbinop_, v_1, v_2) = $ivbinopsxnd_(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M)), def $irelaxed_q15mulr_, S_sx, v_1, v_2) + def $vbinop_{Jnn : Jnn, M : M, v_1 : vec_(V128_Vnn), v_2 : vec_(V128_Vnn)}(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M)), RELAXED_Q15MULRS_vbinop_, v_1, v_2) = $ivbinopsxnd_(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M)), def $irelaxed_q15mulr_, S_sx, v_1, v_2) ;; ../../../../specification/wasm-3.0/3.2-numerics.vector.spectec def $vbinop_{Fnn : Fnn, M : M, v_1 : vec_(V128_Vnn), v_2 : vec_(V128_Vnn)}(`%X%`_shape((Fnn : Fnn <: lanetype), `%`_dim(M)), ADD_vbinop_, v_1, v_2) = $fvbinop_(`%X%`_shape((Fnn : Fnn <: lanetype), `%`_dim(M)), def $fadd_, v_1, v_2) ;; ../../../../specification/wasm-3.0/3.2-numerics.vector.spectec @@ -5250,7 +5250,7 @@ def $lcvtop__(shape_1 : shape, shape_2 : shape, vcvtop__ : vcvtop__(shape_1, sha def $lcvtop__{Fnn_1 : Fnn, M_1 : M, Fnn_2 : Fnn, M_2 : M, c_1 : lane_($lanetype(`%X%`_shape((Fnn_1 : Fnn <: lanetype), `%`_dim(M_1)))), `c*` : fN($lsizenn2((Fnn_2 : Fnn <: lanetype)))*}(`%X%`_shape((Fnn_1 : Fnn <: lanetype), `%`_dim(M_1)), `%X%`_shape((Fnn_2 : Fnn <: lanetype), `%`_dim(M_2)), DEMOTE_vcvtop__(ZERO_zero), c_1) = c*{c <- `c*`} -- if (c*{c <- `c*`} = $demote__($lsizenn1((Fnn_1 : Fnn <: lanetype)), $lsizenn2((Fnn_2 : Fnn <: lanetype)), c_1)) ;; ../../../../specification/wasm-3.0/3.2-numerics.vector.spectec - def $lcvtop__{Fnn_1 : Fnn, M_1 : M, Fnn_2 : Fnn, M_2 : M, c_1 : lane_($lanetype(`%X%`_shape((Fnn_1 : Fnn <: lanetype), `%`_dim(M_1)))), `c*` : fN($lsizenn2((Fnn_2 : Fnn <: lanetype)))*}(`%X%`_shape((Fnn_1 : Fnn <: lanetype), `%`_dim(M_1)), `%X%`_shape((Fnn_2 : Fnn <: lanetype), `%`_dim(M_2)), `PROMOTELOW`_vcvtop__, c_1) = c*{c <- `c*`} + def $lcvtop__{Fnn_1 : Fnn, M_1 : M, Fnn_2 : Fnn, M_2 : M, c_1 : lane_($lanetype(`%X%`_shape((Fnn_1 : Fnn <: lanetype), `%`_dim(M_1)))), `c*` : fN($lsizenn2((Fnn_2 : Fnn <: lanetype)))*}(`%X%`_shape((Fnn_1 : Fnn <: lanetype), `%`_dim(M_1)), `%X%`_shape((Fnn_2 : Fnn <: lanetype), `%`_dim(M_2)), PROMOTELOW_vcvtop__, c_1) = c*{c <- `c*`} -- if (c*{c <- `c*`} = $promote__($lsizenn1((Fnn_1 : Fnn <: lanetype)), $lsizenn2((Fnn_2 : Fnn <: lanetype)), c_1)) ;; ../../../../specification/wasm-3.0/3.2-numerics.vector.spectec @@ -5359,43 +5359,43 @@ def $vextbinop__(ishape_1 : ishape, ishape_2 : ishape, vextbinop__ : vextbinop__ ;; ../../../../specification/wasm-3.0/3.2-numerics.vector.spectec def $vextbinop__{Jnn_1 : Jnn, M_1 : M, Jnn_2 : Jnn, M_2 : M, half : half, sx : sx, v_1 : vec_(V128_Vnn), v_2 : vec_(V128_Vnn)}(`%`_ishape(`%X%`_shape((Jnn_1 : Jnn <: lanetype), `%`_dim(M_1))), `%`_ishape(`%X%`_shape((Jnn_2 : Jnn <: lanetype), `%`_dim(M_2))), EXTMUL_vextbinop__(half, sx), v_1, v_2) = $ivextbinop__(`%X%`_shape((Jnn_1 : Jnn <: lanetype), `%`_dim(M_1)), `%X%`_shape((Jnn_2 : Jnn <: lanetype), `%`_dim(M_2)), def $ivmul_, sx, sx, `%`_laneidx($half(half, 0, M_2)), `%`_laneidx(M_2), v_1, v_2) ;; ../../../../specification/wasm-3.0/3.2-numerics.vector.spectec - def $vextbinop__{Jnn_1 : Jnn, M_1 : M, Jnn_2 : Jnn, M_2 : M, v_1 : vec_(V128_Vnn), v_2 : vec_(V128_Vnn)}(`%`_ishape(`%X%`_shape((Jnn_1 : Jnn <: lanetype), `%`_dim(M_1))), `%`_ishape(`%X%`_shape((Jnn_2 : Jnn <: lanetype), `%`_dim(M_2))), `DOTS`_vextbinop__, v_1, v_2) = $ivextbinop__(`%X%`_shape((Jnn_1 : Jnn <: lanetype), `%`_dim(M_1)), `%X%`_shape((Jnn_2 : Jnn <: lanetype), `%`_dim(M_2)), def $ivdot_, S_sx, S_sx, `%`_laneidx(0), `%`_laneidx(M_1), v_1, v_2) + def $vextbinop__{Jnn_1 : Jnn, M_1 : M, Jnn_2 : Jnn, M_2 : M, v_1 : vec_(V128_Vnn), v_2 : vec_(V128_Vnn)}(`%`_ishape(`%X%`_shape((Jnn_1 : Jnn <: lanetype), `%`_dim(M_1))), `%`_ishape(`%X%`_shape((Jnn_2 : Jnn <: lanetype), `%`_dim(M_2))), DOTS_vextbinop__, v_1, v_2) = $ivextbinop__(`%X%`_shape((Jnn_1 : Jnn <: lanetype), `%`_dim(M_1)), `%X%`_shape((Jnn_2 : Jnn <: lanetype), `%`_dim(M_2)), def $ivdot_, S_sx, S_sx, `%`_laneidx(0), `%`_laneidx(M_1), v_1, v_2) ;; ../../../../specification/wasm-3.0/3.2-numerics.vector.spectec - def $vextbinop__{Jnn_1 : Jnn, M_1 : M, Jnn_2 : Jnn, M_2 : M, v_1 : vec_(V128_Vnn), v_2 : vec_(V128_Vnn)}(`%`_ishape(`%X%`_shape((Jnn_1 : Jnn <: lanetype), `%`_dim(M_1))), `%`_ishape(`%X%`_shape((Jnn_2 : Jnn <: lanetype), `%`_dim(M_2))), `RELAXED_DOTS`_vextbinop__, v_1, v_2) = $ivextbinop__(`%X%`_shape((Jnn_1 : Jnn <: lanetype), `%`_dim(M_1)), `%X%`_shape((Jnn_2 : Jnn <: lanetype), `%`_dim(M_2)), def $ivdot_sat_, S_sx, $relaxed2($R_idot, syntax sx, S_sx, U_sx), `%`_laneidx(0), `%`_laneidx(M_1), v_1, v_2) + def $vextbinop__{Jnn_1 : Jnn, M_1 : M, Jnn_2 : Jnn, M_2 : M, v_1 : vec_(V128_Vnn), v_2 : vec_(V128_Vnn)}(`%`_ishape(`%X%`_shape((Jnn_1 : Jnn <: lanetype), `%`_dim(M_1))), `%`_ishape(`%X%`_shape((Jnn_2 : Jnn <: lanetype), `%`_dim(M_2))), RELAXED_DOTS_vextbinop__, v_1, v_2) = $ivextbinop__(`%X%`_shape((Jnn_1 : Jnn <: lanetype), `%`_dim(M_1)), `%X%`_shape((Jnn_2 : Jnn <: lanetype), `%`_dim(M_2)), def $ivdot_sat_, S_sx, $relaxed2($R_idot, syntax sx, S_sx, U_sx), `%`_laneidx(0), `%`_laneidx(M_1), v_1, v_2) ;; ../../../../specification/wasm-3.0/3.2-numerics.vector.spectec def $vextternop__(ishape_1 : ishape, ishape_2 : ishape, vextternop__ : vextternop__(ishape_1, ishape_2), vec_ : vec_(V128_Vnn), vec_ : vec_(V128_Vnn), vec_ : vec_(V128_Vnn)) : vec_(V128_Vnn) ;; ../../../../specification/wasm-3.0/3.2-numerics.vector.spectec - def $vextternop__{Jnn_1 : Jnn, M_1 : M, Jnn_2 : Jnn, M_2 : M, c_1 : vec_(V128_Vnn), c_2 : vec_(V128_Vnn), c_3 : vec_(V128_Vnn), c : vec_(V128_Vnn), Jnn : Jnn, M : M, c' : vec_(V128_Vnn), c'' : vec_(V128_Vnn)}(`%`_ishape(`%X%`_shape((Jnn_1 : Jnn <: lanetype), `%`_dim(M_1))), `%`_ishape(`%X%`_shape((Jnn_2 : Jnn <: lanetype), `%`_dim(M_2))), `RELAXED_DOT_ADDS`_vextternop__, c_1, c_2, c_3) = c + def $vextternop__{Jnn_1 : Jnn, M_1 : M, Jnn_2 : Jnn, M_2 : M, c_1 : vec_(V128_Vnn), c_2 : vec_(V128_Vnn), c_3 : vec_(V128_Vnn), c : vec_(V128_Vnn), Jnn : Jnn, M : M, c' : vec_(V128_Vnn), c'' : vec_(V128_Vnn)}(`%`_ishape(`%X%`_shape((Jnn_1 : Jnn <: lanetype), `%`_dim(M_1))), `%`_ishape(`%X%`_shape((Jnn_2 : Jnn <: lanetype), `%`_dim(M_2))), RELAXED_DOT_ADDS_vextternop__, c_1, c_2, c_3) = c -- if ($jsizenn(Jnn) = (2 * $lsizenn1((Jnn_1 : Jnn <: lanetype)))) -- if (M = (2 * M_2)) - -- if (c' = $vextbinop__(`%`_ishape(`%X%`_shape((Jnn_1 : Jnn <: lanetype), `%`_dim(M_1))), `%`_ishape(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M))), `RELAXED_DOTS`_vextbinop__, c_1, c_2)) + -- if (c' = $vextbinop__(`%`_ishape(`%X%`_shape((Jnn_1 : Jnn <: lanetype), `%`_dim(M_1))), `%`_ishape(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M))), RELAXED_DOTS_vextbinop__, c_1, c_2)) -- if (c'' = $vextunop__(`%`_ishape(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M))), `%`_ishape(`%X%`_shape((Jnn_2 : Jnn <: lanetype), `%`_dim(M_2))), EXTADD_PAIRWISE_vextunop__(S_sx), c')) -- if (c <- $vbinop_(`%X%`_shape((Jnn_2 : Jnn <: lanetype), `%`_dim(M_2)), ADD_vbinop_, c'', c_3)) ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax num = - | CONST{numtype : numtype, num_ : num_(numtype)}(numtype : numtype, num_ : num_(numtype)) + | CONST(numtype : numtype, num_(numtype)) ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax vec = - | VCONST{vectype : vectype, vec_ : vec_(vectype)}(vectype : vectype, vec_ : vec_(vectype)) + | VCONST(vectype : vectype, vec_(vectype)) ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax ref = - | REF.I31_NUM{u31 : u31}(u31 : u31) - | REF.STRUCT_ADDR{structaddr : structaddr}(structaddr : structaddr) - | REF.ARRAY_ADDR{arrayaddr : arrayaddr}(arrayaddr : arrayaddr) - | REF.FUNC_ADDR{funcaddr : funcaddr}(funcaddr : funcaddr) - | REF.EXN_ADDR{exnaddr : exnaddr}(exnaddr : exnaddr) - | REF.HOST_ADDR{hostaddr : hostaddr}(hostaddr : hostaddr) - | REF.EXTERN{addrref : addrref}(addrref : addrref) - | REF.NULL{heaptype : heaptype}(heaptype : heaptype) + | `REF.I31_NUM`(u31 : u31) + | `REF.STRUCT_ADDR`(structaddr : structaddr) + | `REF.ARRAY_ADDR`(arrayaddr : arrayaddr) + | `REF.FUNC_ADDR`(funcaddr : funcaddr) + | `REF.EXN_ADDR`(exnaddr : exnaddr) + | `REF.HOST_ADDR`(hostaddr : hostaddr) + | `REF.EXTERN`(addrref : addrref) + | `REF.NULL`(heaptype : heaptype) ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax result = - | _VALS{`val*` : val*}(val*{val <- `val*`} : val*) - | `(REF.EXN_ADDR%)THROW_REF`{exnaddr : exnaddr}(exnaddr : exnaddr) + | _VALS(`val*` : val*) + | `(REF.EXN_ADDR%)THROW_REF`(exnaddr : exnaddr) | TRAP ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec @@ -5404,118 +5404,118 @@ syntax hostfunc = ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax funccode = - | FUNC{typeidx : typeidx, `local*` : local*, expr : expr}(typeidx : typeidx, local*{local <- `local*`} : local*, expr : expr) + | FUNC(typeidx : typeidx, `local*` : local*, expr : expr) | `...` ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax taginst = { - TYPE{tagtype : tagtype} tagtype + TYPE tagtype } ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax globalinst = { - TYPE{globaltype : globaltype} globaltype, - VALUE{val : val} val + TYPE globaltype, + VALUE val } ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax meminst = { - TYPE{memtype : memtype} memtype, - BYTES{`byte*` : byte*} byte* + TYPE memtype, + BYTES byte* } ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax tableinst = { - TYPE{tabletype : tabletype} tabletype, - REFS{`ref*` : ref*} ref* + TYPE tabletype, + REFS ref* } ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax funcinst = { - TYPE{deftype : deftype} deftype, - MODULE{moduleinst : moduleinst} moduleinst, - CODE{funccode : funccode} funccode + TYPE deftype, + MODULE moduleinst, + CODE funccode } ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax datainst = { - BYTES{`byte*` : byte*} byte* + BYTES byte* } ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax eleminst = { - TYPE{elemtype : elemtype} elemtype, - REFS{`ref*` : ref*} ref* + TYPE elemtype, + REFS ref* } ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax packval = - | PACK{packtype : packtype, iN : iN($psizenn(packtype))}(packtype : packtype, iN : iN($psizenn(packtype))) + | PACK(packtype : packtype, iN($psizenn(packtype))) ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax fieldval = - | CONST{numtype : numtype, num_ : num_(numtype)}(numtype : numtype, num_ : num_(numtype)) - | VCONST{vectype : vectype, vec_ : vec_(vectype)}(vectype : vectype, vec_ : vec_(vectype)) - | REF.NULL{heaptype : heaptype}(heaptype : heaptype) - | REF.I31_NUM{u31 : u31}(u31 : u31) - | REF.STRUCT_ADDR{structaddr : structaddr}(structaddr : structaddr) - | REF.ARRAY_ADDR{arrayaddr : arrayaddr}(arrayaddr : arrayaddr) - | REF.FUNC_ADDR{funcaddr : funcaddr}(funcaddr : funcaddr) - | REF.EXN_ADDR{exnaddr : exnaddr}(exnaddr : exnaddr) - | REF.HOST_ADDR{hostaddr : hostaddr}(hostaddr : hostaddr) - | REF.EXTERN{addrref : addrref}(addrref : addrref) - | PACK{packtype : packtype, iN : iN($psizenn(packtype))}(packtype : packtype, iN : iN($psizenn(packtype))) + | CONST(numtype : numtype, num_(numtype)) + | VCONST(vectype : vectype, vec_(vectype)) + | `REF.I31_NUM`(u31 : u31) + | `REF.STRUCT_ADDR`(structaddr : structaddr) + | `REF.ARRAY_ADDR`(arrayaddr : arrayaddr) + | `REF.FUNC_ADDR`(funcaddr : funcaddr) + | `REF.EXN_ADDR`(exnaddr : exnaddr) + | `REF.HOST_ADDR`(hostaddr : hostaddr) + | `REF.EXTERN`(addrref : addrref) + | `REF.NULL`(heaptype : heaptype) + | PACK(packtype : packtype, iN($psizenn(packtype))) ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax structinst = { - TYPE{deftype : deftype} deftype, - FIELDS{`fieldval*` : fieldval*} fieldval* + TYPE deftype, + FIELDS fieldval* } ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax arrayinst = { - TYPE{deftype : deftype} deftype, - FIELDS{`fieldval*` : fieldval*} fieldval* + TYPE deftype, + FIELDS fieldval* } ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax exninst = { - TAG{tagaddr : tagaddr} tagaddr, - FIELDS{`val*` : val*} val* + TAG tagaddr, + FIELDS val* } ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax store = { - TAGS{`taginst*` : taginst*} taginst*, - GLOBALS{`globalinst*` : globalinst*} globalinst*, - MEMS{`meminst*` : meminst*} meminst*, - TABLES{`tableinst*` : tableinst*} tableinst*, - FUNCS{`funcinst*` : funcinst*} funcinst*, - DATAS{`datainst*` : datainst*} datainst*, - ELEMS{`eleminst*` : eleminst*} eleminst*, - STRUCTS{`structinst*` : structinst*} structinst*, - ARRAYS{`arrayinst*` : arrayinst*} arrayinst*, - EXNS{`exninst*` : exninst*} exninst* + TAGS taginst*, + GLOBALS globalinst*, + MEMS meminst*, + TABLES tableinst*, + FUNCS funcinst*, + DATAS datainst*, + ELEMS eleminst*, + STRUCTS structinst*, + ARRAYS arrayinst*, + EXNS exninst* } ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax state = - | `%;%`{store : store, frame : frame}(store : store, frame : frame) + | `%;%`(store : store, frame : frame) ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec syntax config = - | `%;%`{state : state, `instr*` : instr*}(state : state, instr*{instr <- `instr*`} : instr*) + | `%;%`(state : state, `instr*` : instr*) ;; ../../../../specification/wasm-3.0/4.0-execution.configurations.spectec def $Ki : nat @@ -5823,40 +5823,40 @@ rec { relation Ref_ok: `%|-%:%`(store, ref, reftype) ;; ../../../../specification/wasm-3.0/4.1-execution.values.spectec:35.1-37.35 rule null{s : store, ht : heaptype, ht' : heaptype}: - `%|-%:%`(s, REF.NULL_ref(ht), REF_reftype(?(NULL_null), ht')) + `%|-%:%`(s, `REF.NULL`_ref(ht), REF_reftype(?(NULL_null), ht')) -- Heaptype_sub: `%|-%<:%`({TYPES [], RECS [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], RETURN ?(), REFS []}, ht', ht) ;; ../../../../specification/wasm-3.0/4.1-execution.values.spectec:39.1-40.33 rule i31{s : store, i : u31}: - `%|-%:%`(s, REF.I31_NUM_ref(i), REF_reftype(?(), I31_heaptype)) + `%|-%:%`(s, `REF.I31_NUM`_ref(i), REF_reftype(?(), I31_heaptype)) ;; ../../../../specification/wasm-3.0/4.1-execution.values.spectec:42.1-44.31 rule struct{s : store, a : addr, dt : deftype}: - `%|-%:%`(s, REF.STRUCT_ADDR_ref(a), REF_reftype(?(), (dt : deftype <: heaptype))) + `%|-%:%`(s, `REF.STRUCT_ADDR`_ref(a), REF_reftype(?(), (dt : deftype <: heaptype))) -- if (s.STRUCTS_store[a].TYPE_structinst = dt) ;; ../../../../specification/wasm-3.0/4.1-execution.values.spectec:46.1-48.30 rule array{s : store, a : addr, dt : deftype}: - `%|-%:%`(s, REF.ARRAY_ADDR_ref(a), REF_reftype(?(), (dt : deftype <: heaptype))) + `%|-%:%`(s, `REF.ARRAY_ADDR`_ref(a), REF_reftype(?(), (dt : deftype <: heaptype))) -- if (s.ARRAYS_store[a].TYPE_arrayinst = dt) ;; ../../../../specification/wasm-3.0/4.1-execution.values.spectec:50.1-52.29 rule func{s : store, a : addr, dt : deftype}: - `%|-%:%`(s, REF.FUNC_ADDR_ref(a), REF_reftype(?(), (dt : deftype <: heaptype))) + `%|-%:%`(s, `REF.FUNC_ADDR`_ref(a), REF_reftype(?(), (dt : deftype <: heaptype))) -- if (s.FUNCS_store[a].TYPE_funcinst = dt) ;; ../../../../specification/wasm-3.0/4.1-execution.values.spectec:54.1-56.24 rule exn{s : store, a : addr, exn : exninst}: - `%|-%:%`(s, REF.EXN_ADDR_ref(a), REF_reftype(?(), EXN_heaptype)) + `%|-%:%`(s, `REF.EXN_ADDR`_ref(a), REF_reftype(?(), EXN_heaptype)) -- if (s.EXNS_store[a] = exn) ;; ../../../../specification/wasm-3.0/4.1-execution.values.spectec:58.1-59.35 rule host{s : store, a : addr}: - `%|-%:%`(s, REF.HOST_ADDR_ref(a), REF_reftype(?(), ANY_heaptype)) + `%|-%:%`(s, `REF.HOST_ADDR`_ref(a), REF_reftype(?(), ANY_heaptype)) ;; ../../../../specification/wasm-3.0/4.1-execution.values.spectec:61.1-63.38 rule extern{s : store, addrref : addrref}: - `%|-%:%`(s, REF.EXTERN_ref(addrref), REF_reftype(?(), EXTERN_heaptype)) + `%|-%:%`(s, `REF.EXTERN`_ref(addrref), REF_reftype(?(), EXTERN_heaptype)) -- Ref_ok: `%|-%:%`(s, (addrref : addrref <: ref), REF_reftype(?(), ANY_heaptype)) ;; ../../../../specification/wasm-3.0/4.1-execution.values.spectec:65.1-68.34 @@ -6025,7 +6025,7 @@ relation Step_pure: `%~>%`(instr*, instr*) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `br_on_null-null`{val : val, l : labelidx, ht : heaptype}: `%~>%`([(val : val <: instr) BR_ON_NULL_instr(l)], [BR_instr(l)]) - -- if (val = REF.NULL_val(ht)) + -- if (val = `REF.NULL`_val(ht)) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `br_on_null-addr`{val : val, l : labelidx}: @@ -6035,7 +6035,7 @@ relation Step_pure: `%~>%`(instr*, instr*) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `br_on_non_null-null`{val : val, l : labelidx, ht : heaptype}: `%~>%`([(val : val <: instr) BR_ON_NON_NULL_instr(l)], []) - -- if (val = REF.NULL_val(ht)) + -- if (val = `REF.NULL`_val(ht)) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `br_on_non_null-addr`{val : val, l : labelidx}: @@ -6044,11 +6044,11 @@ relation Step_pure: `%~>%`(instr*, instr*) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule call_indirect{x : idx, yy : typeuse}: - `%~>%`([CALL_INDIRECT_instr(x, yy)], [TABLE.GET_instr(x) REF.CAST_instr(REF_reftype(?(NULL_null), (yy : typeuse <: heaptype))) CALL_REF_instr(yy)]) + `%~>%`([CALL_INDIRECT_instr(x, yy)], [`TABLE.GET`_instr(x) `REF.CAST`_instr(REF_reftype(?(NULL_null), (yy : typeuse <: heaptype))) CALL_REF_instr(yy)]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule return_call_indirect{x : idx, yy : typeuse}: - `%~>%`([RETURN_CALL_INDIRECT_instr(x, yy)], [TABLE.GET_instr(x) REF.CAST_instr(REF_reftype(?(NULL_null), (yy : typeuse <: heaptype))) RETURN_CALL_REF_instr(yy)]) + `%~>%`([RETURN_CALL_INDIRECT_instr(x, yy)], [`TABLE.GET`_instr(x) `REF.CAST`_instr(REF_reftype(?(NULL_null), (yy : typeuse <: heaptype))) RETURN_CALL_REF_instr(yy)]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `frame-vals`{n : n, f : frame, `val*` : val*}: @@ -6084,76 +6084,76 @@ relation Step_pure: `%~>%`(instr*, instr*) `%~>%`([`FRAME_%{%}%`_instr(n, f, [TRAP_instr])], [TRAP_instr]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec - rule local.tee{val : val, x : idx}: - `%~>%`([(val : val <: instr) LOCAL.TEE_instr(x)], [(val : val <: instr) (val : val <: instr) LOCAL.SET_instr(x)]) + rule `local.tee`{val : val, x : idx}: + `%~>%`([(val : val <: instr) `LOCAL.TEE`_instr(x)], [(val : val <: instr) (val : val <: instr) `LOCAL.SET`_instr(x)]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec - rule ref.i31{i : num_(I32_numtype)}: - `%~>%`([CONST_instr(I32_numtype, i) REF.I31_instr], [REF.I31_NUM_instr($wrap__(32, 31, i))]) + rule `ref.i31`{i : num_(I32_numtype)}: + `%~>%`([CONST_instr(I32_numtype, i) `REF.I31`_instr], [`REF.I31_NUM`_instr($wrap__(32, 31, i))]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `ref.is_null-true`{ref : ref, ht : heaptype}: - `%~>%`([(ref : ref <: instr) REF.IS_NULL_instr], [CONST_instr(I32_numtype, `%`_num_(1))]) - -- if (ref = REF.NULL_ref(ht)) + `%~>%`([(ref : ref <: instr) `REF.IS_NULL`_instr], [CONST_instr(I32_numtype, `%`_num_(1))]) + -- if (ref = `REF.NULL`_ref(ht)) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `ref.is_null-false`{ref : ref}: - `%~>%`([(ref : ref <: instr) REF.IS_NULL_instr], [CONST_instr(I32_numtype, `%`_num_(0))]) + `%~>%`([(ref : ref <: instr) `REF.IS_NULL`_instr], [CONST_instr(I32_numtype, `%`_num_(0))]) -- otherwise ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `ref.as_non_null-null`{ref : ref, ht : heaptype}: - `%~>%`([(ref : ref <: instr) REF.AS_NON_NULL_instr], [TRAP_instr]) - -- if (ref = REF.NULL_ref(ht)) + `%~>%`([(ref : ref <: instr) `REF.AS_NON_NULL`_instr], [TRAP_instr]) + -- if (ref = `REF.NULL`_ref(ht)) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `ref.as_non_null-addr`{ref : ref}: - `%~>%`([(ref : ref <: instr) REF.AS_NON_NULL_instr], [(ref : ref <: instr)]) + `%~>%`([(ref : ref <: instr) `REF.AS_NON_NULL`_instr], [(ref : ref <: instr)]) -- otherwise ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `ref.eq-null`{ref_1 : ref, ref_2 : ref, ht_1 : heaptype, ht_2 : heaptype}: - `%~>%`([(ref_1 : ref <: instr) (ref_2 : ref <: instr) REF.EQ_instr], [CONST_instr(I32_numtype, `%`_num_(1))]) - -- if ((ref_1 = REF.NULL_ref(ht_1)) /\ (ref_2 = REF.NULL_ref(ht_2))) + `%~>%`([(ref_1 : ref <: instr) (ref_2 : ref <: instr) `REF.EQ`_instr], [CONST_instr(I32_numtype, `%`_num_(1))]) + -- if ((ref_1 = `REF.NULL`_ref(ht_1)) /\ (ref_2 = `REF.NULL`_ref(ht_2))) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `ref.eq-true`{ref_1 : ref, ref_2 : ref}: - `%~>%`([(ref_1 : ref <: instr) (ref_2 : ref <: instr) REF.EQ_instr], [CONST_instr(I32_numtype, `%`_num_(1))]) + `%~>%`([(ref_1 : ref <: instr) (ref_2 : ref <: instr) `REF.EQ`_instr], [CONST_instr(I32_numtype, `%`_num_(1))]) -- otherwise -- if (ref_1 = ref_2) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `ref.eq-false`{ref_1 : ref, ref_2 : ref}: - `%~>%`([(ref_1 : ref <: instr) (ref_2 : ref <: instr) REF.EQ_instr], [CONST_instr(I32_numtype, `%`_num_(0))]) + `%~>%`([(ref_1 : ref <: instr) (ref_2 : ref <: instr) `REF.EQ`_instr], [CONST_instr(I32_numtype, `%`_num_(0))]) -- otherwise ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `i31.get-null`{ht : heaptype, sx : sx}: - `%~>%`([REF.NULL_instr(ht) I31.GET_instr(sx)], [TRAP_instr]) + `%~>%`([`REF.NULL`_instr(ht) `I31.GET`_instr(sx)], [TRAP_instr]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `i31.get-num`{i : u31, sx : sx}: - `%~>%`([REF.I31_NUM_instr(i) I31.GET_instr(sx)], [CONST_instr(I32_numtype, $extend__(31, 32, sx, i))]) + `%~>%`([`REF.I31_NUM`_instr(i) `I31.GET`_instr(sx)], [CONST_instr(I32_numtype, $extend__(31, 32, sx, i))]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec - rule array.new{val : val, n : n, x : idx}: - `%~>%`([(val : val <: instr) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.NEW_instr(x)], (val : val <: instr)^n{} ++ [ARRAY.NEW_FIXED_instr(x, `%`_u32(n))]) + rule `array.new`{val : val, n : n, x : idx}: + `%~>%`([(val : val <: instr) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.NEW`_instr(x)], (val : val <: instr)^n{} ++ [`ARRAY.NEW_FIXED`_instr(x, `%`_u32(n))]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `extern.convert_any-null`{ht : heaptype}: - `%~>%`([REF.NULL_instr(ht) EXTERN.CONVERT_ANY_instr], [REF.NULL_instr(EXTERN_heaptype)]) + `%~>%`([`REF.NULL`_instr(ht) `EXTERN.CONVERT_ANY`_instr], [`REF.NULL`_instr(EXTERN_heaptype)]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `extern.convert_any-addr`{addrref : addrref}: - `%~>%`([(addrref : addrref <: instr) EXTERN.CONVERT_ANY_instr], [REF.EXTERN_instr(addrref)]) + `%~>%`([(addrref : addrref <: instr) `EXTERN.CONVERT_ANY`_instr], [`REF.EXTERN`_instr(addrref)]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `any.convert_extern-null`{ht : heaptype}: - `%~>%`([REF.NULL_instr(ht) ANY.CONVERT_EXTERN_instr], [REF.NULL_instr(ANY_heaptype)]) + `%~>%`([`REF.NULL`_instr(ht) `ANY.CONVERT_EXTERN`_instr], [`REF.NULL`_instr(ANY_heaptype)]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `any.convert_extern-addr`{addrref : addrref}: - `%~>%`([REF.EXTERN_instr(addrref) ANY.CONVERT_EXTERN_instr], [(addrref : addrref <: instr)]) + `%~>%`([`REF.EXTERN`_instr(addrref) `ANY.CONVERT_EXTERN`_instr], [(addrref : addrref <: instr)]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `unop-val`{nt : numtype, c_1 : num_(nt), unop : unop_(nt), c : num_(nt)}: @@ -6332,12 +6332,12 @@ def $blocktype_(state : state, blocktype : blocktype) : instrtype ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec relation Step_read: `%~>%`(config, instr*) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec - rule block{z : state, `val*` : val*, m : m, bt : blocktype, `instr*` : instr*, n : n, `t_1*` : valtype*, `t_2*` : valtype*}: + rule block{z : state, m : m, `val*` : val*, bt : blocktype, `instr*` : instr*, n : n, `t_1*` : valtype*, `t_2*` : valtype*}: `%~>%`(`%;%`_config(z, (val : val <: instr)^m{val <- `val*`} ++ [BLOCK_instr(bt, instr*{instr <- `instr*`})]), [`LABEL_%{%}%`_instr(n, [], (val : val <: instr)^m{val <- `val*`} ++ instr*{instr <- `instr*`})]) -- if ($blocktype_(z, bt) = `%->_%%`_instrtype(`%`_resulttype(t_1^m{t_1 <- `t_1*`}), [], `%`_resulttype(t_2^n{t_2 <- `t_2*`}))) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec - rule loop{z : state, `val*` : val*, m : m, bt : blocktype, `instr*` : instr*, `t_1*` : valtype*, `t_2*` : valtype*, n : n}: + rule loop{z : state, m : m, `val*` : val*, bt : blocktype, `instr*` : instr*, `t_1*` : valtype*, n : n, `t_2*` : valtype*}: `%~>%`(`%;%`_config(z, (val : val <: instr)^m{val <- `val*`} ++ [LOOP_instr(bt, instr*{instr <- `instr*`})]), [`LABEL_%{%}%`_instr(m, [LOOP_instr(bt, instr*{instr <- `instr*`})], (val : val <: instr)^m{val <- `val*`} ++ instr*{instr <- `instr*`})]) -- if ($blocktype_(z, bt) = `%->_%%`_instrtype(`%`_resulttype(t_1^m{t_1 <- `t_1*`}), [], `%`_resulttype(t_2^n{t_2 <- `t_2*`}))) @@ -6365,16 +6365,16 @@ relation Step_read: `%~>%`(config, instr*) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule call{z : state, x : idx, a : addr}: - `%~>%`(`%;%`_config(z, [CALL_instr(x)]), [REF.FUNC_ADDR_instr(a) CALL_REF_instr(($funcinst(z)[a].TYPE_funcinst : deftype <: typeuse))]) + `%~>%`(`%;%`_config(z, [CALL_instr(x)]), [`REF.FUNC_ADDR`_instr(a) CALL_REF_instr(($funcinst(z)[a].TYPE_funcinst : deftype <: typeuse))]) -- if ($moduleinst(z).FUNCS_moduleinst[x!`%`_idx.0] = a) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `call_ref-null`{z : state, ht : heaptype, yy : typeuse}: - `%~>%`(`%;%`_config(z, [REF.NULL_instr(ht) CALL_REF_instr(yy)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [`REF.NULL`_instr(ht) CALL_REF_instr(yy)]), [TRAP_instr]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec - rule `call_ref-func`{z : state, `val*` : val*, n : n, a : addr, yy : typeuse, m : m, f : frame, `instr*` : instr*, fi : funcinst, `t_1*` : valtype*, `t_2*` : valtype*, x : idx, `t*` : valtype*}: - `%~>%`(`%;%`_config(z, (val : val <: instr)^n{val <- `val*`} ++ [REF.FUNC_ADDR_instr(a) CALL_REF_instr(yy)]), [`FRAME_%{%}%`_instr(m, f, [`LABEL_%{%}%`_instr(m, [], instr*{instr <- `instr*`})])]) + rule `call_ref-func`{z : state, n : n, `val*` : val*, a : addr, yy : typeuse, m : m, f : frame, `instr*` : instr*, fi : funcinst, `t_1*` : valtype*, `t_2*` : valtype*, x : idx, `t*` : valtype*}: + `%~>%`(`%;%`_config(z, (val : val <: instr)^n{val <- `val*`} ++ [`REF.FUNC_ADDR`_instr(a) CALL_REF_instr(yy)]), [`FRAME_%{%}%`_instr(m, f, [`LABEL_%{%}%`_instr(m, [], instr*{instr <- `instr*`})])]) -- if ($funcinst(z)[a] = fi) -- Expand: `%~~%`(fi.TYPE_funcinst, `FUNC%->%`_comptype(`%`_resulttype(t_1^n{t_1 <- `t_1*`}), `%`_resulttype(t_2^m{t_2 <- `t_2*`}))) -- if (fi.CODE_funcinst = FUNC_funccode(x, LOCAL_local(t)*{t <- `t*`}, instr*{instr <- `instr*`})) @@ -6382,7 +6382,7 @@ relation Step_read: `%~>%`(config, instr*) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule return_call{z : state, x : idx, a : addr}: - `%~>%`(`%;%`_config(z, [RETURN_CALL_instr(x)]), [REF.FUNC_ADDR_instr(a) RETURN_CALL_REF_instr(($funcinst(z)[a].TYPE_funcinst : deftype <: typeuse))]) + `%~>%`(`%;%`_config(z, [RETURN_CALL_instr(x)]), [`REF.FUNC_ADDR`_instr(a) RETURN_CALL_REF_instr(($funcinst(z)[a].TYPE_funcinst : deftype <: typeuse))]) -- if ($moduleinst(z).FUNCS_moduleinst[x!`%`_idx.0] = a) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec @@ -6395,142 +6395,142 @@ relation Step_read: `%~>%`(config, instr*) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `return_call_ref-frame-null`{z : state, k : n, f : frame, `val*` : val*, ht : heaptype, yy : typeuse, `instr*` : instr*}: - `%~>%`(`%;%`_config(z, [`FRAME_%{%}%`_instr(k, f, (val : val <: instr)*{val <- `val*`} ++ [REF.NULL_instr(ht)] ++ [RETURN_CALL_REF_instr(yy)] ++ instr*{instr <- `instr*`})]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [`FRAME_%{%}%`_instr(k, f, (val : val <: instr)*{val <- `val*`} ++ [`REF.NULL`_instr(ht)] ++ [RETURN_CALL_REF_instr(yy)] ++ instr*{instr <- `instr*`})]), [TRAP_instr]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec - rule `return_call_ref-frame-addr`{z : state, k : n, f : frame, `val'*` : val*, `val*` : val*, n : n, a : addr, yy : typeuse, `instr*` : instr*, `t_1*` : valtype*, `t_2*` : valtype*, m : m}: - `%~>%`(`%;%`_config(z, [`FRAME_%{%}%`_instr(k, f, (val' : val <: instr)*{val' <- `val'*`} ++ (val : val <: instr)^n{val <- `val*`} ++ [REF.FUNC_ADDR_instr(a)] ++ [RETURN_CALL_REF_instr(yy)] ++ instr*{instr <- `instr*`})]), (val : val <: instr)^n{val <- `val*`} ++ [REF.FUNC_ADDR_instr(a) CALL_REF_instr(yy)]) + rule `return_call_ref-frame-addr`{z : state, k : n, f : frame, `val'*` : val*, n : n, `val*` : val*, a : addr, yy : typeuse, `instr*` : instr*, `t_1*` : valtype*, m : m, `t_2*` : valtype*}: + `%~>%`(`%;%`_config(z, [`FRAME_%{%}%`_instr(k, f, (val' : val <: instr)*{val' <- `val'*`} ++ (val : val <: instr)^n{val <- `val*`} ++ [`REF.FUNC_ADDR`_instr(a)] ++ [RETURN_CALL_REF_instr(yy)] ++ instr*{instr <- `instr*`})]), (val : val <: instr)^n{val <- `val*`} ++ [`REF.FUNC_ADDR`_instr(a) CALL_REF_instr(yy)]) -- Expand: `%~~%`($funcinst(z)[a].TYPE_funcinst, `FUNC%->%`_comptype(`%`_resulttype(t_1^n{t_1 <- `t_1*`}), `%`_resulttype(t_2^m{t_2 <- `t_2*`}))) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `throw_ref-null`{z : state, ht : heaptype}: - `%~>%`(`%;%`_config(z, [REF.NULL_instr(ht) THROW_REF_instr]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [`REF.NULL`_instr(ht) THROW_REF_instr]), [TRAP_instr]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `throw_ref-instrs`{z : state, `val*` : val*, a : addr, `instr*` : instr*}: - `%~>%`(`%;%`_config(z, (val : val <: instr)*{val <- `val*`} ++ [REF.EXN_ADDR_instr(a)] ++ [THROW_REF_instr] ++ instr*{instr <- `instr*`}), [REF.EXN_ADDR_instr(a) THROW_REF_instr]) + `%~>%`(`%;%`_config(z, (val : val <: instr)*{val <- `val*`} ++ [`REF.EXN_ADDR`_instr(a)] ++ [THROW_REF_instr] ++ instr*{instr <- `instr*`}), [`REF.EXN_ADDR`_instr(a) THROW_REF_instr]) -- if ((val*{val <- `val*`} =/= []) \/ (instr*{instr <- `instr*`} =/= [])) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `throw_ref-label`{z : state, n : n, `instr'*` : instr*, a : addr}: - `%~>%`(`%;%`_config(z, [`LABEL_%{%}%`_instr(n, instr'*{instr' <- `instr'*`}, [REF.EXN_ADDR_instr(a) THROW_REF_instr])]), [REF.EXN_ADDR_instr(a) THROW_REF_instr]) + `%~>%`(`%;%`_config(z, [`LABEL_%{%}%`_instr(n, instr'*{instr' <- `instr'*`}, [`REF.EXN_ADDR`_instr(a) THROW_REF_instr])]), [`REF.EXN_ADDR`_instr(a) THROW_REF_instr]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `throw_ref-frame`{z : state, n : n, f : frame, a : addr}: - `%~>%`(`%;%`_config(z, [`FRAME_%{%}%`_instr(n, f, [REF.EXN_ADDR_instr(a) THROW_REF_instr])]), [REF.EXN_ADDR_instr(a) THROW_REF_instr]) + `%~>%`(`%;%`_config(z, [`FRAME_%{%}%`_instr(n, f, [`REF.EXN_ADDR`_instr(a) THROW_REF_instr])]), [`REF.EXN_ADDR`_instr(a) THROW_REF_instr]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `throw_ref-handler-empty`{z : state, n : n, a : addr}: - `%~>%`(`%;%`_config(z, [`HANDLER_%{%}%`_instr(n, [], [REF.EXN_ADDR_instr(a) THROW_REF_instr])]), [REF.EXN_ADDR_instr(a) THROW_REF_instr]) + `%~>%`(`%;%`_config(z, [`HANDLER_%{%}%`_instr(n, [], [`REF.EXN_ADDR`_instr(a) THROW_REF_instr])]), [`REF.EXN_ADDR`_instr(a) THROW_REF_instr]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `throw_ref-handler-catch`{z : state, n : n, x : idx, l : labelidx, `catch'*` : catch*, a : addr, `val*` : val*}: - `%~>%`(`%;%`_config(z, [`HANDLER_%{%}%`_instr(n, [CATCH_catch(x, l)] ++ catch'*{catch' <- `catch'*`}, [REF.EXN_ADDR_instr(a) THROW_REF_instr])]), (val : val <: instr)*{val <- `val*`} ++ [BR_instr(l)]) + `%~>%`(`%;%`_config(z, [`HANDLER_%{%}%`_instr(n, [CATCH_catch(x, l)] ++ catch'*{catch' <- `catch'*`}, [`REF.EXN_ADDR`_instr(a) THROW_REF_instr])]), (val : val <: instr)*{val <- `val*`} ++ [BR_instr(l)]) -- if ($exninst(z)[a].TAG_exninst = $tagaddr(z)[x!`%`_idx.0]) -- if (val*{val <- `val*`} = $exninst(z)[a].FIELDS_exninst) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `throw_ref-handler-catch_ref`{z : state, n : n, x : idx, l : labelidx, `catch'*` : catch*, a : addr, `val*` : val*}: - `%~>%`(`%;%`_config(z, [`HANDLER_%{%}%`_instr(n, [CATCH_REF_catch(x, l)] ++ catch'*{catch' <- `catch'*`}, [REF.EXN_ADDR_instr(a) THROW_REF_instr])]), (val : val <: instr)*{val <- `val*`} ++ [REF.EXN_ADDR_instr(a) BR_instr(l)]) + `%~>%`(`%;%`_config(z, [`HANDLER_%{%}%`_instr(n, [CATCH_REF_catch(x, l)] ++ catch'*{catch' <- `catch'*`}, [`REF.EXN_ADDR`_instr(a) THROW_REF_instr])]), (val : val <: instr)*{val <- `val*`} ++ [`REF.EXN_ADDR`_instr(a) BR_instr(l)]) -- if ($exninst(z)[a].TAG_exninst = $tagaddr(z)[x!`%`_idx.0]) -- if (val*{val <- `val*`} = $exninst(z)[a].FIELDS_exninst) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `throw_ref-handler-catch_all`{z : state, n : n, l : labelidx, `catch'*` : catch*, a : addr}: - `%~>%`(`%;%`_config(z, [`HANDLER_%{%}%`_instr(n, [CATCH_ALL_catch(l)] ++ catch'*{catch' <- `catch'*`}, [REF.EXN_ADDR_instr(a) THROW_REF_instr])]), [BR_instr(l)]) + `%~>%`(`%;%`_config(z, [`HANDLER_%{%}%`_instr(n, [CATCH_ALL_catch(l)] ++ catch'*{catch' <- `catch'*`}, [`REF.EXN_ADDR`_instr(a) THROW_REF_instr])]), [BR_instr(l)]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `throw_ref-handler-catch_all_ref`{z : state, n : n, l : labelidx, `catch'*` : catch*, a : addr}: - `%~>%`(`%;%`_config(z, [`HANDLER_%{%}%`_instr(n, [CATCH_ALL_REF_catch(l)] ++ catch'*{catch' <- `catch'*`}, [REF.EXN_ADDR_instr(a) THROW_REF_instr])]), [REF.EXN_ADDR_instr(a) BR_instr(l)]) + `%~>%`(`%;%`_config(z, [`HANDLER_%{%}%`_instr(n, [CATCH_ALL_REF_catch(l)] ++ catch'*{catch' <- `catch'*`}, [`REF.EXN_ADDR`_instr(a) THROW_REF_instr])]), [`REF.EXN_ADDR`_instr(a) BR_instr(l)]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `throw_ref-handler-next`{z : state, n : n, catch : catch, `catch'*` : catch*, a : addr}: - `%~>%`(`%;%`_config(z, [`HANDLER_%{%}%`_instr(n, [catch] ++ catch'*{catch' <- `catch'*`}, [REF.EXN_ADDR_instr(a) THROW_REF_instr])]), [`HANDLER_%{%}%`_instr(n, catch'*{catch' <- `catch'*`}, [REF.EXN_ADDR_instr(a) THROW_REF_instr])]) + `%~>%`(`%;%`_config(z, [`HANDLER_%{%}%`_instr(n, [catch] ++ catch'*{catch' <- `catch'*`}, [`REF.EXN_ADDR`_instr(a) THROW_REF_instr])]), [`HANDLER_%{%}%`_instr(n, catch'*{catch' <- `catch'*`}, [`REF.EXN_ADDR`_instr(a) THROW_REF_instr])]) -- otherwise ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec - rule try_table{z : state, `val*` : val*, m : m, bt : blocktype, `catch*` : catch*, `instr*` : instr*, n : n, `t_1*` : valtype*, `t_2*` : valtype*}: + rule try_table{z : state, m : m, `val*` : val*, bt : blocktype, `catch*` : catch*, `instr*` : instr*, n : n, `t_1*` : valtype*, `t_2*` : valtype*}: `%~>%`(`%;%`_config(z, (val : val <: instr)^m{val <- `val*`} ++ [TRY_TABLE_instr(bt, `%`_list(catch*{catch <- `catch*`}), instr*{instr <- `instr*`})]), [`HANDLER_%{%}%`_instr(n, catch*{catch <- `catch*`}, [`LABEL_%{%}%`_instr(n, [], (val : val <: instr)^m{val <- `val*`} ++ instr*{instr <- `instr*`})])]) -- if ($blocktype_(z, bt) = `%->_%%`_instrtype(`%`_resulttype(t_1^m{t_1 <- `t_1*`}), [], `%`_resulttype(t_2^n{t_2 <- `t_2*`}))) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec - rule local.get{z : state, x : idx, val : val}: - `%~>%`(`%;%`_config(z, [LOCAL.GET_instr(x)]), [(val : val <: instr)]) + rule `local.get`{z : state, x : idx, val : val}: + `%~>%`(`%;%`_config(z, [`LOCAL.GET`_instr(x)]), [(val : val <: instr)]) -- if ($local(z, x) = ?(val)) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec - rule global.get{z : state, x : idx, val : val}: - `%~>%`(`%;%`_config(z, [GLOBAL.GET_instr(x)]), [(val : val <: instr)]) + rule `global.get`{z : state, x : idx, val : val}: + `%~>%`(`%;%`_config(z, [`GLOBAL.GET`_instr(x)]), [(val : val <: instr)]) -- if ($global(z, x).VALUE_globalinst = val) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `table.get-oob`{z : state, at : addrtype, i : num_((at : addrtype <: numtype)), x : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) TABLE.GET_instr(x)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) `TABLE.GET`_instr(x)]), [TRAP_instr]) -- if (i!`%`_num_.0 >= |$table(z, x).REFS_tableinst|) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `table.get-val`{z : state, at : addrtype, i : num_((at : addrtype <: numtype)), x : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) TABLE.GET_instr(x)]), [($table(z, x).REFS_tableinst[i!`%`_num_.0] : ref <: instr)]) + `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) `TABLE.GET`_instr(x)]), [($table(z, x).REFS_tableinst[i!`%`_num_.0] : ref <: instr)]) -- if (i!`%`_num_.0 < |$table(z, x).REFS_tableinst|) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec - rule table.size{z : state, x : idx, at : addrtype, n : n, lim : limits, rt : reftype}: - `%~>%`(`%;%`_config(z, [TABLE.SIZE_instr(x)]), [CONST_instr((at : addrtype <: numtype), `%`_num_(n))]) + rule `table.size`{z : state, x : idx, at : addrtype, n : n, lim : limits, rt : reftype}: + `%~>%`(`%;%`_config(z, [`TABLE.SIZE`_instr(x)]), [CONST_instr((at : addrtype <: numtype), `%`_num_(n))]) -- if (|$table(z, x).REFS_tableinst| = n) -- if ($table(z, x).TYPE_tableinst = `%%%`_tabletype(at, lim, rt)) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `table.fill-oob`{z : state, at : addrtype, i : num_((at : addrtype <: numtype)), val : val, n : n, x : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) (val : val <: instr) CONST_instr((at : addrtype <: numtype), `%`_num_(n)) TABLE.FILL_instr(x)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) (val : val <: instr) CONST_instr((at : addrtype <: numtype), `%`_num_(n)) `TABLE.FILL`_instr(x)]), [TRAP_instr]) -- if ((i!`%`_num_.0 + n) > |$table(z, x).REFS_tableinst|) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `table.fill-zero`{z : state, at : addrtype, i : num_((at : addrtype <: numtype)), val : val, n : n, x : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) (val : val <: instr) CONST_instr((at : addrtype <: numtype), `%`_num_(n)) TABLE.FILL_instr(x)]), []) + `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) (val : val <: instr) CONST_instr((at : addrtype <: numtype), `%`_num_(n)) `TABLE.FILL`_instr(x)]), []) -- otherwise -- if (n = 0) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `table.fill-succ`{z : state, at : addrtype, i : num_((at : addrtype <: numtype)), val : val, n : n, x : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) (val : val <: instr) CONST_instr((at : addrtype <: numtype), `%`_num_(n)) TABLE.FILL_instr(x)]), [CONST_instr((at : addrtype <: numtype), i) (val : val <: instr) TABLE.SET_instr(x) CONST_instr((at : addrtype <: numtype), `%`_num_((i!`%`_num_.0 + 1))) (val : val <: instr) CONST_instr((at : addrtype <: numtype), `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) TABLE.FILL_instr(x)]) + `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) (val : val <: instr) CONST_instr((at : addrtype <: numtype), `%`_num_(n)) `TABLE.FILL`_instr(x)]), [CONST_instr((at : addrtype <: numtype), i) (val : val <: instr) `TABLE.SET`_instr(x) CONST_instr((at : addrtype <: numtype), `%`_num_((i!`%`_num_.0 + 1))) (val : val <: instr) CONST_instr((at : addrtype <: numtype), `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) `TABLE.FILL`_instr(x)]) -- otherwise ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `table.copy-oob`{z : state, at_1 : addrtype, i_1 : num_((at_1 : addrtype <: numtype)), at_2 : addrtype, i_2 : num_((at_2 : addrtype <: numtype)), at' : addrtype, n : n, x_1 : idx, x_2 : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at_1 : addrtype <: numtype), i_1) CONST_instr((at_2 : addrtype <: numtype), i_2) CONST_instr((at' : addrtype <: numtype), `%`_num_(n)) TABLE.COPY_instr(x_1, x_2)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [CONST_instr((at_1 : addrtype <: numtype), i_1) CONST_instr((at_2 : addrtype <: numtype), i_2) CONST_instr((at' : addrtype <: numtype), `%`_num_(n)) `TABLE.COPY`_instr(x_1, x_2)]), [TRAP_instr]) -- if (((i_1!`%`_num_.0 + n) > |$table(z, x_1).REFS_tableinst|) \/ ((i_2!`%`_num_.0 + n) > |$table(z, x_2).REFS_tableinst|)) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `table.copy-zero`{z : state, at_1 : addrtype, i_1 : num_((at_1 : addrtype <: numtype)), at_2 : addrtype, i_2 : num_((at_2 : addrtype <: numtype)), at' : addrtype, n : n, x : idx, y : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at_1 : addrtype <: numtype), i_1) CONST_instr((at_2 : addrtype <: numtype), i_2) CONST_instr((at' : addrtype <: numtype), `%`_num_(n)) TABLE.COPY_instr(x, y)]), []) + `%~>%`(`%;%`_config(z, [CONST_instr((at_1 : addrtype <: numtype), i_1) CONST_instr((at_2 : addrtype <: numtype), i_2) CONST_instr((at' : addrtype <: numtype), `%`_num_(n)) `TABLE.COPY`_instr(x, y)]), []) -- otherwise -- if (n = 0) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `table.copy-le`{z : state, at_1 : addrtype, i_1 : num_((at_1 : addrtype <: numtype)), at_2 : addrtype, i_2 : num_((at_2 : addrtype <: numtype)), at' : addrtype, n : n, x : idx, y : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at_1 : addrtype <: numtype), i_1) CONST_instr((at_2 : addrtype <: numtype), i_2) CONST_instr((at' : addrtype <: numtype), `%`_num_(n)) TABLE.COPY_instr(x, y)]), [CONST_instr((at_1 : addrtype <: numtype), i_1) CONST_instr((at_2 : addrtype <: numtype), i_2) TABLE.GET_instr(y) TABLE.SET_instr(x) CONST_instr((at_1 : addrtype <: numtype), `%`_num_((i_1!`%`_num_.0 + 1))) CONST_instr((at_2 : addrtype <: numtype), `%`_num_((i_2!`%`_num_.0 + 1))) CONST_instr((at' : addrtype <: numtype), `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) TABLE.COPY_instr(x, y)]) + `%~>%`(`%;%`_config(z, [CONST_instr((at_1 : addrtype <: numtype), i_1) CONST_instr((at_2 : addrtype <: numtype), i_2) CONST_instr((at' : addrtype <: numtype), `%`_num_(n)) `TABLE.COPY`_instr(x, y)]), [CONST_instr((at_1 : addrtype <: numtype), i_1) CONST_instr((at_2 : addrtype <: numtype), i_2) `TABLE.GET`_instr(y) `TABLE.SET`_instr(x) CONST_instr((at_1 : addrtype <: numtype), `%`_num_((i_1!`%`_num_.0 + 1))) CONST_instr((at_2 : addrtype <: numtype), `%`_num_((i_2!`%`_num_.0 + 1))) CONST_instr((at' : addrtype <: numtype), `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) `TABLE.COPY`_instr(x, y)]) -- otherwise -- if (i_1!`%`_num_.0 <= i_2!`%`_num_.0) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `table.copy-gt`{z : state, at_1 : addrtype, i_1 : num_((at_1 : addrtype <: numtype)), at_2 : addrtype, i_2 : num_((at_2 : addrtype <: numtype)), at' : addrtype, n : n, x : idx, y : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at_1 : addrtype <: numtype), i_1) CONST_instr((at_2 : addrtype <: numtype), i_2) CONST_instr((at' : addrtype <: numtype), `%`_num_(n)) TABLE.COPY_instr(x, y)]), [CONST_instr((at_1 : addrtype <: numtype), `%`_num_(((((i_1!`%`_num_.0 + n) : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) CONST_instr((at_2 : addrtype <: numtype), `%`_num_(((((i_2!`%`_num_.0 + n) : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) TABLE.GET_instr(y) TABLE.SET_instr(x) CONST_instr((at_1 : addrtype <: numtype), i_1) CONST_instr((at_2 : addrtype <: numtype), i_2) CONST_instr((at' : addrtype <: numtype), `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) TABLE.COPY_instr(x, y)]) + `%~>%`(`%;%`_config(z, [CONST_instr((at_1 : addrtype <: numtype), i_1) CONST_instr((at_2 : addrtype <: numtype), i_2) CONST_instr((at' : addrtype <: numtype), `%`_num_(n)) `TABLE.COPY`_instr(x, y)]), [CONST_instr((at_1 : addrtype <: numtype), `%`_num_(((((i_1!`%`_num_.0 + n) : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) CONST_instr((at_2 : addrtype <: numtype), `%`_num_(((((i_2!`%`_num_.0 + n) : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) `TABLE.GET`_instr(y) `TABLE.SET`_instr(x) CONST_instr((at_1 : addrtype <: numtype), i_1) CONST_instr((at_2 : addrtype <: numtype), i_2) CONST_instr((at' : addrtype <: numtype), `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) `TABLE.COPY`_instr(x, y)]) -- otherwise ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `table.init-oob`{z : state, at : addrtype, i : num_((at : addrtype <: numtype)), j : num_(I32_numtype), n : n, x : idx, y : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) TABLE.INIT_instr(x, y)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) `TABLE.INIT`_instr(x, y)]), [TRAP_instr]) -- if (((i!`%`_num_.0 + n) > |$table(z, x).REFS_tableinst|) \/ ((j!`%`_num_.0 + n) > |$elem(z, y).REFS_eleminst|)) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `table.init-zero`{z : state, at : addrtype, i : num_((at : addrtype <: numtype)), j : num_(I32_numtype), n : n, x : idx, y : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) TABLE.INIT_instr(x, y)]), []) + `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) `TABLE.INIT`_instr(x, y)]), []) -- otherwise -- if (n = 0) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `table.init-succ`{z : state, at : addrtype, i : num_((at : addrtype <: numtype)), j : num_(I32_numtype), n : n, x : idx, y : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) TABLE.INIT_instr(x, y)]), [CONST_instr((at : addrtype <: numtype), i) ($elem(z, y).REFS_eleminst[j!`%`_num_.0] : ref <: instr) TABLE.SET_instr(x) CONST_instr((at : addrtype <: numtype), `%`_num_((i!`%`_num_.0 + 1))) CONST_instr(I32_numtype, `%`_num_((j!`%`_num_.0 + 1))) CONST_instr(I32_numtype, `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) TABLE.INIT_instr(x, y)]) + `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) `TABLE.INIT`_instr(x, y)]), [CONST_instr((at : addrtype <: numtype), i) ($elem(z, y).REFS_eleminst[j!`%`_num_.0] : ref <: instr) `TABLE.SET`_instr(x) CONST_instr((at : addrtype <: numtype), `%`_num_((i!`%`_num_.0 + 1))) CONST_instr(I32_numtype, `%`_num_((j!`%`_num_.0 + 1))) CONST_instr(I32_numtype, `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) `TABLE.INIT`_instr(x, y)]) -- otherwise ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec @@ -6569,9 +6569,9 @@ relation Step_read: `%~>%`(config, instr*) -- if (((i!`%`_num_.0 + ao.OFFSET_memarg!`%`_u64.0) + ((((M * K) : nat <:> rat) / (8 : nat <:> rat)) : rat <:> nat)) > |$mem(z, x).BYTES_meminst|) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec - rule `vload-pack-val`{z : state, at : addrtype, i : num_((at : addrtype <: numtype)), M : M, K : K, sx : sx, x : idx, ao : memarg, c : vec_(V128_Vnn), `j*` : iN(M)*, `k*` : nat*, Jnn : Jnn}: + rule `vload-pack-val`{z : state, at : addrtype, i : num_((at : addrtype <: numtype)), M : M, K : K, sx : sx, x : idx, ao : memarg, c : vec_(V128_Vnn), `j*` : iN(M)*, Jnn : Jnn}: `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) VLOAD_instr(V128_vectype, ?(`SHAPE%X%_%`_vloadop_(`%`_sz(M), K, sx)), x, ao)]), [VCONST_instr(V128_vectype, c)]) - -- (if ($ibytes_(M, j) = $mem(z, x).BYTES_meminst[((i!`%`_num_.0 + ao.OFFSET_memarg!`%`_u64.0) + ((((k * M) : nat <:> rat) / (8 : nat <:> rat)) : rat <:> nat)) : (((M : nat <:> rat) / (8 : nat <:> rat)) : rat <:> nat)]))^(k rat) / (8 : nat <:> rat)) : rat <:> nat)) : (((M : nat <:> rat) / (8 : nat <:> rat)) : rat <:> nat)]))^(k%`(config, instr*) -- if (c = $inv_lanes_(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M)), $lanes_(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M)), c_1)[[j!`%`_laneidx.0] = `%`_lane_(k!`%`_iN.0)])) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec - rule memory.size{z : state, x : idx, at : addrtype, n : n, lim : limits}: - `%~>%`(`%;%`_config(z, [MEMORY.SIZE_instr(x)]), [CONST_instr((at : addrtype <: numtype), `%`_num_(n))]) + rule `memory.size`{z : state, x : idx, at : addrtype, n : n, lim : limits}: + `%~>%`(`%;%`_config(z, [`MEMORY.SIZE`_instr(x)]), [CONST_instr((at : addrtype <: numtype), `%`_num_(n))]) -- if ((n * (64 * $Ki)) = |$mem(z, x).BYTES_meminst|) -- if ($mem(z, x).TYPE_meminst = `%%PAGE`_memtype(at, lim)) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `memory.fill-oob`{z : state, at : addrtype, i : num_((at : addrtype <: numtype)), val : val, n : n, x : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) (val : val <: instr) CONST_instr((at : addrtype <: numtype), `%`_num_(n)) MEMORY.FILL_instr(x)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) (val : val <: instr) CONST_instr((at : addrtype <: numtype), `%`_num_(n)) `MEMORY.FILL`_instr(x)]), [TRAP_instr]) -- if ((i!`%`_num_.0 + n) > |$mem(z, x).BYTES_meminst|) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `memory.fill-zero`{z : state, at : addrtype, i : num_((at : addrtype <: numtype)), val : val, n : n, x : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) (val : val <: instr) CONST_instr((at : addrtype <: numtype), `%`_num_(n)) MEMORY.FILL_instr(x)]), []) + `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) (val : val <: instr) CONST_instr((at : addrtype <: numtype), `%`_num_(n)) `MEMORY.FILL`_instr(x)]), []) -- otherwise -- if (n = 0) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `memory.fill-succ`{z : state, at : addrtype, i : num_((at : addrtype <: numtype)), val : val, n : n, x : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) (val : val <: instr) CONST_instr((at : addrtype <: numtype), `%`_num_(n)) MEMORY.FILL_instr(x)]), [CONST_instr((at : addrtype <: numtype), i) (val : val <: instr) STORE_instr(I32_numtype, ?(`%`_storeop_(`%`_sz(8))), x, $memarg0) CONST_instr((at : addrtype <: numtype), `%`_num_((i!`%`_num_.0 + 1))) (val : val <: instr) CONST_instr((at : addrtype <: numtype), `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) MEMORY.FILL_instr(x)]) + `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) (val : val <: instr) CONST_instr((at : addrtype <: numtype), `%`_num_(n)) `MEMORY.FILL`_instr(x)]), [CONST_instr((at : addrtype <: numtype), i) (val : val <: instr) STORE_instr(I32_numtype, ?(`%`_storeop_(`%`_sz(8))), x, $memarg0) CONST_instr((at : addrtype <: numtype), `%`_num_((i!`%`_num_.0 + 1))) (val : val <: instr) CONST_instr((at : addrtype <: numtype), `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) `MEMORY.FILL`_instr(x)]) -- otherwise ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `memory.copy-oob`{z : state, at_1 : addrtype, i_1 : num_((at_1 : addrtype <: numtype)), at_2 : addrtype, i_2 : num_((at_2 : addrtype <: numtype)), at' : addrtype, n : n, x_1 : idx, x_2 : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at_1 : addrtype <: numtype), i_1) CONST_instr((at_2 : addrtype <: numtype), i_2) CONST_instr((at' : addrtype <: numtype), `%`_num_(n)) MEMORY.COPY_instr(x_1, x_2)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [CONST_instr((at_1 : addrtype <: numtype), i_1) CONST_instr((at_2 : addrtype <: numtype), i_2) CONST_instr((at' : addrtype <: numtype), `%`_num_(n)) `MEMORY.COPY`_instr(x_1, x_2)]), [TRAP_instr]) -- if (((i_1!`%`_num_.0 + n) > |$mem(z, x_1).BYTES_meminst|) \/ ((i_2!`%`_num_.0 + n) > |$mem(z, x_2).BYTES_meminst|)) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `memory.copy-zero`{z : state, at_1 : addrtype, i_1 : num_((at_1 : addrtype <: numtype)), at_2 : addrtype, i_2 : num_((at_2 : addrtype <: numtype)), at' : addrtype, n : n, x_1 : idx, x_2 : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at_1 : addrtype <: numtype), i_1) CONST_instr((at_2 : addrtype <: numtype), i_2) CONST_instr((at' : addrtype <: numtype), `%`_num_(n)) MEMORY.COPY_instr(x_1, x_2)]), []) + `%~>%`(`%;%`_config(z, [CONST_instr((at_1 : addrtype <: numtype), i_1) CONST_instr((at_2 : addrtype <: numtype), i_2) CONST_instr((at' : addrtype <: numtype), `%`_num_(n)) `MEMORY.COPY`_instr(x_1, x_2)]), []) -- otherwise -- if (n = 0) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `memory.copy-le`{z : state, at_1 : addrtype, i_1 : num_((at_1 : addrtype <: numtype)), at_2 : addrtype, i_2 : num_((at_2 : addrtype <: numtype)), at' : addrtype, n : n, x_1 : idx, x_2 : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at_1 : addrtype <: numtype), i_1) CONST_instr((at_2 : addrtype <: numtype), i_2) CONST_instr((at' : addrtype <: numtype), `%`_num_(n)) MEMORY.COPY_instr(x_1, x_2)]), [CONST_instr((at_1 : addrtype <: numtype), i_1) CONST_instr((at_2 : addrtype <: numtype), i_2) LOAD_instr(I32_numtype, ?(`%_%`_loadop_(`%`_sz(8), U_sx)), x_2, $memarg0) STORE_instr(I32_numtype, ?(`%`_storeop_(`%`_sz(8))), x_1, $memarg0) CONST_instr((at_1 : addrtype <: numtype), `%`_num_((i_1!`%`_num_.0 + 1))) CONST_instr((at_2 : addrtype <: numtype), `%`_num_((i_2!`%`_num_.0 + 1))) CONST_instr((at' : addrtype <: numtype), `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) MEMORY.COPY_instr(x_1, x_2)]) + `%~>%`(`%;%`_config(z, [CONST_instr((at_1 : addrtype <: numtype), i_1) CONST_instr((at_2 : addrtype <: numtype), i_2) CONST_instr((at' : addrtype <: numtype), `%`_num_(n)) `MEMORY.COPY`_instr(x_1, x_2)]), [CONST_instr((at_1 : addrtype <: numtype), i_1) CONST_instr((at_2 : addrtype <: numtype), i_2) LOAD_instr(I32_numtype, ?(`%_%`_loadop_(`%`_sz(8), U_sx)), x_2, $memarg0) STORE_instr(I32_numtype, ?(`%`_storeop_(`%`_sz(8))), x_1, $memarg0) CONST_instr((at_1 : addrtype <: numtype), `%`_num_((i_1!`%`_num_.0 + 1))) CONST_instr((at_2 : addrtype <: numtype), `%`_num_((i_2!`%`_num_.0 + 1))) CONST_instr((at' : addrtype <: numtype), `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) `MEMORY.COPY`_instr(x_1, x_2)]) -- otherwise -- if (i_1!`%`_num_.0 <= i_2!`%`_num_.0) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `memory.copy-gt`{z : state, at_1 : addrtype, i_1 : num_((at_1 : addrtype <: numtype)), at_2 : addrtype, i_2 : num_((at_2 : addrtype <: numtype)), at' : addrtype, n : n, x_1 : idx, x_2 : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at_1 : addrtype <: numtype), i_1) CONST_instr((at_2 : addrtype <: numtype), i_2) CONST_instr((at' : addrtype <: numtype), `%`_num_(n)) MEMORY.COPY_instr(x_1, x_2)]), [CONST_instr((at_1 : addrtype <: numtype), `%`_num_(((((i_1!`%`_num_.0 + n) : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) CONST_instr((at_2 : addrtype <: numtype), `%`_num_(((((i_2!`%`_num_.0 + n) : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) LOAD_instr(I32_numtype, ?(`%_%`_loadop_(`%`_sz(8), U_sx)), x_2, $memarg0) STORE_instr(I32_numtype, ?(`%`_storeop_(`%`_sz(8))), x_1, $memarg0) CONST_instr((at_1 : addrtype <: numtype), i_1) CONST_instr((at_2 : addrtype <: numtype), i_2) CONST_instr((at' : addrtype <: numtype), `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) MEMORY.COPY_instr(x_1, x_2)]) + `%~>%`(`%;%`_config(z, [CONST_instr((at_1 : addrtype <: numtype), i_1) CONST_instr((at_2 : addrtype <: numtype), i_2) CONST_instr((at' : addrtype <: numtype), `%`_num_(n)) `MEMORY.COPY`_instr(x_1, x_2)]), [CONST_instr((at_1 : addrtype <: numtype), `%`_num_(((((i_1!`%`_num_.0 + n) : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) CONST_instr((at_2 : addrtype <: numtype), `%`_num_(((((i_2!`%`_num_.0 + n) : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) LOAD_instr(I32_numtype, ?(`%_%`_loadop_(`%`_sz(8), U_sx)), x_2, $memarg0) STORE_instr(I32_numtype, ?(`%`_storeop_(`%`_sz(8))), x_1, $memarg0) CONST_instr((at_1 : addrtype <: numtype), i_1) CONST_instr((at_2 : addrtype <: numtype), i_2) CONST_instr((at' : addrtype <: numtype), `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) `MEMORY.COPY`_instr(x_1, x_2)]) -- otherwise ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `memory.init-oob`{z : state, at : addrtype, i : num_((at : addrtype <: numtype)), j : num_(I32_numtype), n : n, x : idx, y : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) MEMORY.INIT_instr(x, y)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) `MEMORY.INIT`_instr(x, y)]), [TRAP_instr]) -- if (((i!`%`_num_.0 + n) > |$mem(z, x).BYTES_meminst|) \/ ((j!`%`_num_.0 + n) > |$data(z, y).BYTES_datainst|)) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `memory.init-zero`{z : state, at : addrtype, i : num_((at : addrtype <: numtype)), j : num_(I32_numtype), n : n, x : idx, y : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) MEMORY.INIT_instr(x, y)]), []) + `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) `MEMORY.INIT`_instr(x, y)]), []) -- otherwise -- if (n = 0) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `memory.init-succ`{z : state, at : addrtype, i : num_((at : addrtype <: numtype)), j : num_(I32_numtype), n : n, x : idx, y : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) MEMORY.INIT_instr(x, y)]), [CONST_instr((at : addrtype <: numtype), i) CONST_instr(I32_numtype, `%`_num_($data(z, y).BYTES_datainst[j!`%`_num_.0]!`%`_byte.0)) STORE_instr(I32_numtype, ?(`%`_storeop_(`%`_sz(8))), x, $memarg0) CONST_instr((at : addrtype <: numtype), `%`_num_((i!`%`_num_.0 + 1))) CONST_instr(I32_numtype, `%`_num_((j!`%`_num_.0 + 1))) CONST_instr(I32_numtype, `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) MEMORY.INIT_instr(x, y)]) + `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) `MEMORY.INIT`_instr(x, y)]), [CONST_instr((at : addrtype <: numtype), i) CONST_instr(I32_numtype, `%`_num_($data(z, y).BYTES_datainst[j!`%`_num_.0]!`%`_byte.0)) STORE_instr(I32_numtype, ?(`%`_storeop_(`%`_sz(8))), x, $memarg0) CONST_instr((at : addrtype <: numtype), `%`_num_((i!`%`_num_.0 + 1))) CONST_instr(I32_numtype, `%`_num_((j!`%`_num_.0 + 1))) CONST_instr(I32_numtype, `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) `MEMORY.INIT`_instr(x, y)]) -- otherwise ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `ref.null-idx`{z : state, x : idx}: - `%~>%`(`%;%`_config(z, [REF.NULL_instr(_IDX_heaptype(x))]), [REF.NULL_instr(($type(z, x) : deftype <: heaptype))]) + `%~>%`(`%;%`_config(z, [`REF.NULL`_instr(_IDX_heaptype(x))]), [`REF.NULL`_instr(($type(z, x) : deftype <: heaptype))]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec - rule ref.func{z : state, x : idx}: - `%~>%`(`%;%`_config(z, [REF.FUNC_instr(x)]), [REF.FUNC_ADDR_instr($moduleinst(z).FUNCS_moduleinst[x!`%`_idx.0])]) + rule `ref.func`{z : state, x : idx}: + `%~>%`(`%;%`_config(z, [`REF.FUNC`_instr(x)]), [`REF.FUNC_ADDR`_instr($moduleinst(z).FUNCS_moduleinst[x!`%`_idx.0])]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `ref.test-true`{s : store, f : frame, ref : ref, rt : reftype, rt' : reftype}: - `%~>%`(`%;%`_config(`%;%`_state(s, f), [(ref : ref <: instr) REF.TEST_instr(rt)]), [CONST_instr(I32_numtype, `%`_num_(1))]) + `%~>%`(`%;%`_config(`%;%`_state(s, f), [(ref : ref <: instr) `REF.TEST`_instr(rt)]), [CONST_instr(I32_numtype, `%`_num_(1))]) -- Ref_ok: `%|-%:%`(s, ref, rt') -- Reftype_sub: `%|-%<:%`({TYPES [], RECS [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], RETURN ?(), REFS []}, rt', $inst_reftype(f.MODULE_frame, rt)) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `ref.test-false`{s : store, f : frame, ref : ref, rt : reftype}: - `%~>%`(`%;%`_config(`%;%`_state(s, f), [(ref : ref <: instr) REF.TEST_instr(rt)]), [CONST_instr(I32_numtype, `%`_num_(0))]) + `%~>%`(`%;%`_config(`%;%`_state(s, f), [(ref : ref <: instr) `REF.TEST`_instr(rt)]), [CONST_instr(I32_numtype, `%`_num_(0))]) -- otherwise ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `ref.cast-succeed`{s : store, f : frame, ref : ref, rt : reftype, rt' : reftype}: - `%~>%`(`%;%`_config(`%;%`_state(s, f), [(ref : ref <: instr) REF.CAST_instr(rt)]), [(ref : ref <: instr)]) + `%~>%`(`%;%`_config(`%;%`_state(s, f), [(ref : ref <: instr) `REF.CAST`_instr(rt)]), [(ref : ref <: instr)]) -- Ref_ok: `%|-%:%`(s, ref, rt') -- Reftype_sub: `%|-%<:%`({TYPES [], RECS [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], RETURN ?(), REFS []}, rt', $inst_reftype(f.MODULE_frame, rt)) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `ref.cast-fail`{s : store, f : frame, ref : ref, rt : reftype}: - `%~>%`(`%;%`_config(`%;%`_state(s, f), [(ref : ref <: instr) REF.CAST_instr(rt)]), [TRAP_instr]) + `%~>%`(`%;%`_config(`%;%`_state(s, f), [(ref : ref <: instr) `REF.CAST`_instr(rt)]), [TRAP_instr]) -- otherwise ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec - rule struct.new_default{z : state, x : idx, `val*` : val*, `mut?*` : mut?*, `zt*` : storagetype*}: - `%~>%`(`%;%`_config(z, [STRUCT.NEW_DEFAULT_instr(x)]), (val : val <: instr)*{val <- `val*`} ++ [STRUCT.NEW_instr(x)]) + rule `struct.new_default`{z : state, x : idx, `val*` : val*, `mut?*` : mut?*, `zt*` : storagetype*}: + `%~>%`(`%;%`_config(z, [`STRUCT.NEW_DEFAULT`_instr(x)]), (val : val <: instr)*{val <- `val*`} ++ [`STRUCT.NEW`_instr(x)]) -- Expand: `%~~%`($type(z, x), STRUCT_comptype(`%`_list(`%%`_fieldtype(mut?{mut <- `mut?`}, zt)*{`mut?` <- `mut?*`, zt <- `zt*`}))) -- (if ($default_($unpack(zt)) = ?(val)))*{val <- `val*`, zt <- `zt*`} ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `struct.get-null`{z : state, ht : heaptype, `sx?` : sx?, x : idx, i : u32}: - `%~>%`(`%;%`_config(z, [REF.NULL_instr(ht) STRUCT.GET_instr(sx?{sx <- `sx?`}, x, i)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [`REF.NULL`_instr(ht) `STRUCT.GET`_instr(sx?{sx <- `sx?`}, x, i)]), [TRAP_instr]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `struct.get-struct`{z : state, a : addr, `sx?` : sx?, x : idx, i : u32, `zt*` : storagetype*, `mut?*` : mut?*}: - `%~>%`(`%;%`_config(z, [REF.STRUCT_ADDR_instr(a) STRUCT.GET_instr(sx?{sx <- `sx?`}, x, i)]), [($unpackfield_(zt*{zt <- `zt*`}[i!`%`_u32.0], sx?{sx <- `sx?`}, $structinst(z)[a].FIELDS_structinst[i!`%`_u32.0]) : val <: instr)]) + `%~>%`(`%;%`_config(z, [`REF.STRUCT_ADDR`_instr(a) `STRUCT.GET`_instr(sx?{sx <- `sx?`}, x, i)]), [($unpackfield_(zt*{zt <- `zt*`}[i!`%`_u32.0], sx?{sx <- `sx?`}, $structinst(z)[a].FIELDS_structinst[i!`%`_u32.0]) : val <: instr)]) -- Expand: `%~~%`($type(z, x), STRUCT_comptype(`%`_list(`%%`_fieldtype(mut?{mut <- `mut?`}, zt)*{`mut?` <- `mut?*`, zt <- `zt*`}))) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec - rule array.new_default{z : state, n : n, x : idx, val : val, `mut?` : mut?, zt : storagetype}: - `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.NEW_DEFAULT_instr(x)]), (val : val <: instr)^n{} ++ [ARRAY.NEW_FIXED_instr(x, `%`_u32(n))]) + rule `array.new_default`{z : state, n : n, x : idx, val : val, `mut?` : mut?, zt : storagetype}: + `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.NEW_DEFAULT`_instr(x)]), (val : val <: instr)^n{} ++ [`ARRAY.NEW_FIXED`_instr(x, `%`_u32(n))]) -- Expand: `%~~%`($type(z, x), ARRAY_comptype(`%%`_fieldtype(mut?{mut <- `mut?`}, zt))) -- if ($default_($unpack(zt)) = ?(val)) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.new_elem-oob`{z : state, i : num_(I32_numtype), n : n, x : idx, y : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.NEW_ELEM_instr(x, y)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.NEW_ELEM`_instr(x, y)]), [TRAP_instr]) -- if ((i!`%`_num_.0 + n) > |$elem(z, y).REFS_eleminst|) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.new_elem-alloc`{z : state, i : num_(I32_numtype), n : n, x : idx, y : idx, `ref*` : ref*}: - `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.NEW_ELEM_instr(x, y)]), (ref : ref <: instr)^n{ref <- `ref*`} ++ [ARRAY.NEW_FIXED_instr(x, `%`_u32(n))]) + `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.NEW_ELEM`_instr(x, y)]), (ref : ref <: instr)^n{ref <- `ref*`} ++ [`ARRAY.NEW_FIXED`_instr(x, `%`_u32(n))]) -- if (ref^n{ref <- `ref*`} = $elem(z, y).REFS_eleminst[i!`%`_num_.0 : n]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.new_data-oob`{z : state, i : num_(I32_numtype), n : n, x : idx, y : idx, `mut?` : mut?, zt : storagetype}: - `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.NEW_DATA_instr(x, y)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.NEW_DATA`_instr(x, y)]), [TRAP_instr]) -- Expand: `%~~%`($type(z, x), ARRAY_comptype(`%%`_fieldtype(mut?{mut <- `mut?`}, zt))) -- if ((i!`%`_num_.0 + ((((n * $zsize(zt)) : nat <:> rat) / (8 : nat <:> rat)) : rat <:> nat)) > |$data(z, y).BYTES_datainst|) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.new_data-num`{z : state, i : num_(I32_numtype), n : n, x : idx, y : idx, zt : storagetype, `c*` : lit_(zt)*, `mut?` : mut?}: - `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.NEW_DATA_instr(x, y)]), $const($cunpack(zt), $cunpacknum_(zt, c))^n{c <- `c*`} ++ [ARRAY.NEW_FIXED_instr(x, `%`_u32(n))]) + `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.NEW_DATA`_instr(x, y)]), $const($cunpack(zt), $cunpacknum_(zt, c))^n{c <- `c*`} ++ [`ARRAY.NEW_FIXED`_instr(x, `%`_u32(n))]) -- Expand: `%~~%`($type(z, x), ARRAY_comptype(`%%`_fieldtype(mut?{mut <- `mut?`}, zt))) -- if ($concatn_(syntax byte, $zbytes_(zt, c)^n{c <- `c*`}, ((($zsize(zt) : nat <:> rat) / (8 : nat <:> rat)) : rat <:> nat)) = $data(z, y).BYTES_datainst[i!`%`_num_.0 : ((((n * $zsize(zt)) : nat <:> rat) / (8 : nat <:> rat)) : rat <:> nat)]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.get-null`{z : state, ht : heaptype, i : num_(I32_numtype), `sx?` : sx?, x : idx}: - `%~>%`(`%;%`_config(z, [REF.NULL_instr(ht) CONST_instr(I32_numtype, i) ARRAY.GET_instr(sx?{sx <- `sx?`}, x)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [`REF.NULL`_instr(ht) CONST_instr(I32_numtype, i) `ARRAY.GET`_instr(sx?{sx <- `sx?`}, x)]), [TRAP_instr]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.get-oob`{z : state, a : addr, i : num_(I32_numtype), `sx?` : sx?, x : idx}: - `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, i) ARRAY.GET_instr(sx?{sx <- `sx?`}, x)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [`REF.ARRAY_ADDR`_instr(a) CONST_instr(I32_numtype, i) `ARRAY.GET`_instr(sx?{sx <- `sx?`}, x)]), [TRAP_instr]) -- if (i!`%`_num_.0 >= |$arrayinst(z)[a].FIELDS_arrayinst|) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.get-array`{z : state, a : addr, i : num_(I32_numtype), `sx?` : sx?, x : idx, zt : storagetype, `mut?` : mut?}: - `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, i) ARRAY.GET_instr(sx?{sx <- `sx?`}, x)]), [($unpackfield_(zt, sx?{sx <- `sx?`}, $arrayinst(z)[a].FIELDS_arrayinst[i!`%`_num_.0]) : val <: instr)]) + `%~>%`(`%;%`_config(z, [`REF.ARRAY_ADDR`_instr(a) CONST_instr(I32_numtype, i) `ARRAY.GET`_instr(sx?{sx <- `sx?`}, x)]), [($unpackfield_(zt, sx?{sx <- `sx?`}, $arrayinst(z)[a].FIELDS_arrayinst[i!`%`_num_.0]) : val <: instr)]) -- Expand: `%~~%`($type(z, x), ARRAY_comptype(`%%`_fieldtype(mut?{mut <- `mut?`}, zt))) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.len-null`{z : state, ht : heaptype}: - `%~>%`(`%;%`_config(z, [REF.NULL_instr(ht) ARRAY.LEN_instr]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [`REF.NULL`_instr(ht) `ARRAY.LEN`_instr]), [TRAP_instr]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.len-array`{z : state, a : addr}: - `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) ARRAY.LEN_instr]), [CONST_instr(I32_numtype, `%`_num_(|$arrayinst(z)[a].FIELDS_arrayinst|))]) + `%~>%`(`%;%`_config(z, [`REF.ARRAY_ADDR`_instr(a) `ARRAY.LEN`_instr]), [CONST_instr(I32_numtype, `%`_num_(|$arrayinst(z)[a].FIELDS_arrayinst|))]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.fill-null`{z : state, ht : heaptype, i : num_(I32_numtype), val : val, n : n, x : idx}: - `%~>%`(`%;%`_config(z, [REF.NULL_instr(ht) CONST_instr(I32_numtype, i) (val : val <: instr) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.FILL_instr(x)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [`REF.NULL`_instr(ht) CONST_instr(I32_numtype, i) (val : val <: instr) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.FILL`_instr(x)]), [TRAP_instr]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.fill-oob`{z : state, a : addr, i : num_(I32_numtype), val : val, n : n, x : idx}: - `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, i) (val : val <: instr) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.FILL_instr(x)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [`REF.ARRAY_ADDR`_instr(a) CONST_instr(I32_numtype, i) (val : val <: instr) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.FILL`_instr(x)]), [TRAP_instr]) -- if ((i!`%`_num_.0 + n) > |$arrayinst(z)[a].FIELDS_arrayinst|) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.fill-zero`{z : state, a : addr, i : num_(I32_numtype), val : val, n : n, x : idx}: - `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, i) (val : val <: instr) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.FILL_instr(x)]), []) + `%~>%`(`%;%`_config(z, [`REF.ARRAY_ADDR`_instr(a) CONST_instr(I32_numtype, i) (val : val <: instr) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.FILL`_instr(x)]), []) -- otherwise -- if (n = 0) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.fill-succ`{z : state, a : addr, i : num_(I32_numtype), val : val, n : n, x : idx}: - `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, i) (val : val <: instr) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.FILL_instr(x)]), [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, i) (val : val <: instr) ARRAY.SET_instr(x) REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, `%`_num_((i!`%`_num_.0 + 1))) (val : val <: instr) CONST_instr(I32_numtype, `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) ARRAY.FILL_instr(x)]) + `%~>%`(`%;%`_config(z, [`REF.ARRAY_ADDR`_instr(a) CONST_instr(I32_numtype, i) (val : val <: instr) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.FILL`_instr(x)]), [`REF.ARRAY_ADDR`_instr(a) CONST_instr(I32_numtype, i) (val : val <: instr) `ARRAY.SET`_instr(x) `REF.ARRAY_ADDR`_instr(a) CONST_instr(I32_numtype, `%`_num_((i!`%`_num_.0 + 1))) (val : val <: instr) CONST_instr(I32_numtype, `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) `ARRAY.FILL`_instr(x)]) -- otherwise ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.copy-null1`{z : state, ht_1 : heaptype, i_1 : num_(I32_numtype), ref : ref, i_2 : num_(I32_numtype), n : n, x_1 : idx, x_2 : idx}: - `%~>%`(`%;%`_config(z, [REF.NULL_instr(ht_1) CONST_instr(I32_numtype, i_1) (ref : ref <: instr) CONST_instr(I32_numtype, i_2) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.COPY_instr(x_1, x_2)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [`REF.NULL`_instr(ht_1) CONST_instr(I32_numtype, i_1) (ref : ref <: instr) CONST_instr(I32_numtype, i_2) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.COPY`_instr(x_1, x_2)]), [TRAP_instr]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.copy-null2`{z : state, ref : ref, i_1 : num_(I32_numtype), ht_2 : heaptype, i_2 : num_(I32_numtype), n : n, x_1 : idx, x_2 : idx}: - `%~>%`(`%;%`_config(z, [(ref : ref <: instr) CONST_instr(I32_numtype, i_1) REF.NULL_instr(ht_2) CONST_instr(I32_numtype, i_2) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.COPY_instr(x_1, x_2)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [(ref : ref <: instr) CONST_instr(I32_numtype, i_1) `REF.NULL`_instr(ht_2) CONST_instr(I32_numtype, i_2) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.COPY`_instr(x_1, x_2)]), [TRAP_instr]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.copy-oob1`{z : state, a_1 : addr, i_1 : num_(I32_numtype), a_2 : addr, i_2 : num_(I32_numtype), n : n, x_1 : idx, x_2 : idx}: - `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a_1) CONST_instr(I32_numtype, i_1) REF.ARRAY_ADDR_instr(a_2) CONST_instr(I32_numtype, i_2) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.COPY_instr(x_1, x_2)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [`REF.ARRAY_ADDR`_instr(a_1) CONST_instr(I32_numtype, i_1) `REF.ARRAY_ADDR`_instr(a_2) CONST_instr(I32_numtype, i_2) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.COPY`_instr(x_1, x_2)]), [TRAP_instr]) -- if ((i_1!`%`_num_.0 + n) > |$arrayinst(z)[a_1].FIELDS_arrayinst|) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.copy-oob2`{z : state, a_1 : addr, i_1 : num_(I32_numtype), a_2 : addr, i_2 : num_(I32_numtype), n : n, x_1 : idx, x_2 : idx}: - `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a_1) CONST_instr(I32_numtype, i_1) REF.ARRAY_ADDR_instr(a_2) CONST_instr(I32_numtype, i_2) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.COPY_instr(x_1, x_2)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [`REF.ARRAY_ADDR`_instr(a_1) CONST_instr(I32_numtype, i_1) `REF.ARRAY_ADDR`_instr(a_2) CONST_instr(I32_numtype, i_2) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.COPY`_instr(x_1, x_2)]), [TRAP_instr]) -- if ((i_2!`%`_num_.0 + n) > |$arrayinst(z)[a_2].FIELDS_arrayinst|) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.copy-zero`{z : state, a_1 : addr, i_1 : num_(I32_numtype), a_2 : addr, i_2 : num_(I32_numtype), n : n, x_1 : idx, x_2 : idx}: - `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a_1) CONST_instr(I32_numtype, i_1) REF.ARRAY_ADDR_instr(a_2) CONST_instr(I32_numtype, i_2) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.COPY_instr(x_1, x_2)]), []) + `%~>%`(`%;%`_config(z, [`REF.ARRAY_ADDR`_instr(a_1) CONST_instr(I32_numtype, i_1) `REF.ARRAY_ADDR`_instr(a_2) CONST_instr(I32_numtype, i_2) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.COPY`_instr(x_1, x_2)]), []) -- otherwise -- if (n = 0) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.copy-le`{z : state, a_1 : addr, i_1 : num_(I32_numtype), a_2 : addr, i_2 : num_(I32_numtype), n : n, x_1 : idx, x_2 : idx, `sx?` : sx?, `mut?` : mut?, zt_2 : storagetype}: - `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a_1) CONST_instr(I32_numtype, i_1) REF.ARRAY_ADDR_instr(a_2) CONST_instr(I32_numtype, i_2) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.COPY_instr(x_1, x_2)]), [REF.ARRAY_ADDR_instr(a_1) CONST_instr(I32_numtype, i_1) REF.ARRAY_ADDR_instr(a_2) CONST_instr(I32_numtype, i_2) ARRAY.GET_instr(sx?{sx <- `sx?`}, x_2) ARRAY.SET_instr(x_1) REF.ARRAY_ADDR_instr(a_1) CONST_instr(I32_numtype, `%`_num_((i_1!`%`_num_.0 + 1))) REF.ARRAY_ADDR_instr(a_2) CONST_instr(I32_numtype, `%`_num_((i_2!`%`_num_.0 + 1))) CONST_instr(I32_numtype, `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) ARRAY.COPY_instr(x_1, x_2)]) + `%~>%`(`%;%`_config(z, [`REF.ARRAY_ADDR`_instr(a_1) CONST_instr(I32_numtype, i_1) `REF.ARRAY_ADDR`_instr(a_2) CONST_instr(I32_numtype, i_2) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.COPY`_instr(x_1, x_2)]), [`REF.ARRAY_ADDR`_instr(a_1) CONST_instr(I32_numtype, i_1) `REF.ARRAY_ADDR`_instr(a_2) CONST_instr(I32_numtype, i_2) `ARRAY.GET`_instr(sx?{sx <- `sx?`}, x_2) `ARRAY.SET`_instr(x_1) `REF.ARRAY_ADDR`_instr(a_1) CONST_instr(I32_numtype, `%`_num_((i_1!`%`_num_.0 + 1))) `REF.ARRAY_ADDR`_instr(a_2) CONST_instr(I32_numtype, `%`_num_((i_2!`%`_num_.0 + 1))) CONST_instr(I32_numtype, `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) `ARRAY.COPY`_instr(x_1, x_2)]) -- otherwise -- Expand: `%~~%`($type(z, x_2), ARRAY_comptype(`%%`_fieldtype(mut?{mut <- `mut?`}, zt_2))) -- if ((i_1!`%`_num_.0 <= i_2!`%`_num_.0) /\ (sx?{sx <- `sx?`} = $sx(zt_2))) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.copy-gt`{z : state, a_1 : addr, i_1 : num_(I32_numtype), a_2 : addr, i_2 : num_(I32_numtype), n : n, x_1 : idx, x_2 : idx, `sx?` : sx?, `mut?` : mut?, zt_2 : storagetype}: - `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a_1) CONST_instr(I32_numtype, i_1) REF.ARRAY_ADDR_instr(a_2) CONST_instr(I32_numtype, i_2) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.COPY_instr(x_1, x_2)]), [REF.ARRAY_ADDR_instr(a_1) CONST_instr(I32_numtype, `%`_num_(((((i_1!`%`_num_.0 + n) : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) REF.ARRAY_ADDR_instr(a_2) CONST_instr(I32_numtype, `%`_num_(((((i_2!`%`_num_.0 + n) : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) ARRAY.GET_instr(sx?{sx <- `sx?`}, x_2) ARRAY.SET_instr(x_1) REF.ARRAY_ADDR_instr(a_1) CONST_instr(I32_numtype, i_1) REF.ARRAY_ADDR_instr(a_2) CONST_instr(I32_numtype, i_2) CONST_instr(I32_numtype, `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) ARRAY.COPY_instr(x_1, x_2)]) + `%~>%`(`%;%`_config(z, [`REF.ARRAY_ADDR`_instr(a_1) CONST_instr(I32_numtype, i_1) `REF.ARRAY_ADDR`_instr(a_2) CONST_instr(I32_numtype, i_2) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.COPY`_instr(x_1, x_2)]), [`REF.ARRAY_ADDR`_instr(a_1) CONST_instr(I32_numtype, `%`_num_(((((i_1!`%`_num_.0 + n) : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) `REF.ARRAY_ADDR`_instr(a_2) CONST_instr(I32_numtype, `%`_num_(((((i_2!`%`_num_.0 + n) : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) `ARRAY.GET`_instr(sx?{sx <- `sx?`}, x_2) `ARRAY.SET`_instr(x_1) `REF.ARRAY_ADDR`_instr(a_1) CONST_instr(I32_numtype, i_1) `REF.ARRAY_ADDR`_instr(a_2) CONST_instr(I32_numtype, i_2) CONST_instr(I32_numtype, `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) `ARRAY.COPY`_instr(x_1, x_2)]) -- otherwise -- Expand: `%~~%`($type(z, x_2), ARRAY_comptype(`%%`_fieldtype(mut?{mut <- `mut?`}, zt_2))) -- if (sx?{sx <- `sx?`} = $sx(zt_2)) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.init_elem-null`{z : state, ht : heaptype, i : num_(I32_numtype), j : num_(I32_numtype), n : n, x : idx, y : idx}: - `%~>%`(`%;%`_config(z, [REF.NULL_instr(ht) CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.INIT_ELEM_instr(x, y)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [`REF.NULL`_instr(ht) CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.INIT_ELEM`_instr(x, y)]), [TRAP_instr]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.init_elem-oob1`{z : state, a : addr, i : num_(I32_numtype), j : num_(I32_numtype), n : n, x : idx, y : idx}: - `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.INIT_ELEM_instr(x, y)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [`REF.ARRAY_ADDR`_instr(a) CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.INIT_ELEM`_instr(x, y)]), [TRAP_instr]) -- if ((i!`%`_num_.0 + n) > |$arrayinst(z)[a].FIELDS_arrayinst|) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.init_elem-oob2`{z : state, a : addr, i : num_(I32_numtype), j : num_(I32_numtype), n : n, x : idx, y : idx}: - `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.INIT_ELEM_instr(x, y)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [`REF.ARRAY_ADDR`_instr(a) CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.INIT_ELEM`_instr(x, y)]), [TRAP_instr]) -- if ((j!`%`_num_.0 + n) > |$elem(z, y).REFS_eleminst|) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.init_elem-zero`{z : state, a : addr, i : num_(I32_numtype), j : num_(I32_numtype), n : n, x : idx, y : idx}: - `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.INIT_ELEM_instr(x, y)]), []) + `%~>%`(`%;%`_config(z, [`REF.ARRAY_ADDR`_instr(a) CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.INIT_ELEM`_instr(x, y)]), []) -- otherwise -- if (n = 0) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.init_elem-succ`{z : state, a : addr, i : num_(I32_numtype), j : num_(I32_numtype), n : n, x : idx, y : idx, ref : ref}: - `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.INIT_ELEM_instr(x, y)]), [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, i) (ref : ref <: instr) ARRAY.SET_instr(x) REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, `%`_num_((i!`%`_num_.0 + 1))) CONST_instr(I32_numtype, `%`_num_((j!`%`_num_.0 + 1))) CONST_instr(I32_numtype, `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) ARRAY.INIT_ELEM_instr(x, y)]) + `%~>%`(`%;%`_config(z, [`REF.ARRAY_ADDR`_instr(a) CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.INIT_ELEM`_instr(x, y)]), [`REF.ARRAY_ADDR`_instr(a) CONST_instr(I32_numtype, i) (ref : ref <: instr) `ARRAY.SET`_instr(x) `REF.ARRAY_ADDR`_instr(a) CONST_instr(I32_numtype, `%`_num_((i!`%`_num_.0 + 1))) CONST_instr(I32_numtype, `%`_num_((j!`%`_num_.0 + 1))) CONST_instr(I32_numtype, `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) `ARRAY.INIT_ELEM`_instr(x, y)]) -- otherwise -- if (ref = $elem(z, y).REFS_eleminst[j!`%`_num_.0]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.init_data-null`{z : state, ht : heaptype, i : num_(I32_numtype), j : num_(I32_numtype), n : n, x : idx, y : idx}: - `%~>%`(`%;%`_config(z, [REF.NULL_instr(ht) CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.INIT_DATA_instr(x, y)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [`REF.NULL`_instr(ht) CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.INIT_DATA`_instr(x, y)]), [TRAP_instr]) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.init_data-oob1`{z : state, a : addr, i : num_(I32_numtype), j : num_(I32_numtype), n : n, x : idx, y : idx}: - `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.INIT_DATA_instr(x, y)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [`REF.ARRAY_ADDR`_instr(a) CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.INIT_DATA`_instr(x, y)]), [TRAP_instr]) -- if ((i!`%`_num_.0 + n) > |$arrayinst(z)[a].FIELDS_arrayinst|) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.init_data-oob2`{z : state, a : addr, i : num_(I32_numtype), j : num_(I32_numtype), n : n, x : idx, y : idx, `mut?` : mut?, zt : storagetype}: - `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.INIT_DATA_instr(x, y)]), [TRAP_instr]) + `%~>%`(`%;%`_config(z, [`REF.ARRAY_ADDR`_instr(a) CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.INIT_DATA`_instr(x, y)]), [TRAP_instr]) -- Expand: `%~~%`($type(z, x), ARRAY_comptype(`%%`_fieldtype(mut?{mut <- `mut?`}, zt))) -- if ((j!`%`_num_.0 + ((((n * $zsize(zt)) : nat <:> rat) / (8 : nat <:> rat)) : rat <:> nat)) > |$data(z, y).BYTES_datainst|) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.init_data-zero`{z : state, a : addr, i : num_(I32_numtype), j : num_(I32_numtype), n : n, x : idx, y : idx}: - `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.INIT_DATA_instr(x, y)]), []) + `%~>%`(`%;%`_config(z, [`REF.ARRAY_ADDR`_instr(a) CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.INIT_DATA`_instr(x, y)]), []) -- otherwise -- if (n = 0) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec rule `array.init_data-num`{z : state, a : addr, i : num_(I32_numtype), j : num_(I32_numtype), n : n, x : idx, y : idx, zt : storagetype, c : lit_(zt), `mut?` : mut?}: - `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) ARRAY.INIT_DATA_instr(x, y)]), [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, i) $const($cunpack(zt), $cunpacknum_(zt, c)) ARRAY.SET_instr(x) REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, `%`_num_((i!`%`_num_.0 + 1))) CONST_instr(I32_numtype, `%`_num_((j!`%`_num_.0 + ((($zsize(zt) : nat <:> rat) / (8 : nat <:> rat)) : rat <:> nat)))) CONST_instr(I32_numtype, `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) ARRAY.INIT_DATA_instr(x, y)]) + `%~>%`(`%;%`_config(z, [`REF.ARRAY_ADDR`_instr(a) CONST_instr(I32_numtype, i) CONST_instr(I32_numtype, j) CONST_instr(I32_numtype, `%`_num_(n)) `ARRAY.INIT_DATA`_instr(x, y)]), [`REF.ARRAY_ADDR`_instr(a) CONST_instr(I32_numtype, i) $const($cunpack(zt), $cunpacknum_(zt, c)) `ARRAY.SET`_instr(x) `REF.ARRAY_ADDR`_instr(a) CONST_instr(I32_numtype, `%`_num_((i!`%`_num_.0 + 1))) CONST_instr(I32_numtype, `%`_num_((j!`%`_num_.0 + ((($zsize(zt) : nat <:> rat) / (8 : nat <:> rat)) : rat <:> nat)))) CONST_instr(I32_numtype, `%`_num_((((n : nat <:> int) - (1 : nat <:> int)) : int <:> nat))) `ARRAY.INIT_DATA`_instr(x, y)]) -- otherwise -- Expand: `%~~%`($type(z, x), ARRAY_comptype(`%%`_fieldtype(mut?{mut <- `mut?`}, zt))) -- if ($zbytes_(zt, c) = $data(z, y).BYTES_datainst[j!`%`_num_.0 : ((($zsize(zt) : nat <:> rat) / (8 : nat <:> rat)) : rat <:> nat)]) @@ -6910,42 +6910,42 @@ relation Step: `%~>%`(config, config) -- Step: `%~>%`(`%;%`_config(`%;%`_state(s, f'), instr*{instr <- `instr*`}), `%;%`_config(`%;%`_state(s', f''), instr'*{instr' <- `instr'*`})) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec:227.1-231.49 - rule throw{z : state, `val*` : val*, n : n, x : idx, exn : exninst, a : addr, `t*` : valtype*}: - `%~>%`(`%;%`_config(z, (val : val <: instr)^n{val <- `val*`} ++ [THROW_instr(x)]), `%;%`_config($add_exninst(z, [exn]), [REF.EXN_ADDR_instr(a) THROW_REF_instr])) + rule throw{z : state, n : n, `val*` : val*, x : idx, exn : exninst, a : addr, `t*` : valtype*}: + `%~>%`(`%;%`_config(z, (val : val <: instr)^n{val <- `val*`} ++ [THROW_instr(x)]), `%;%`_config($add_exninst(z, [exn]), [`REF.EXN_ADDR`_instr(a) THROW_REF_instr])) -- Expand: `%~~%`($as_deftype($tag(z, x).TYPE_taginst), `FUNC%->%`_comptype(`%`_resulttype(t^n{t <- `t*`}), `%`_resulttype([]))) -- if (a = |$exninst(z)|) -- if (exn = {TAG $tagaddr(z)[x!`%`_idx.0], FIELDS val^n{val <- `val*`}}) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec:302.1-303.56 - rule local.set{z : state, val : val, x : idx}: - `%~>%`(`%;%`_config(z, [(val : val <: instr) LOCAL.SET_instr(x)]), `%;%`_config($with_local(z, x, val), [])) + rule `local.set`{z : state, val : val, x : idx}: + `%~>%`(`%;%`_config(z, [(val : val <: instr) `LOCAL.SET`_instr(x)]), `%;%`_config($with_local(z, x, val), [])) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec:315.1-316.58 - rule global.set{z : state, val : val, x : idx}: - `%~>%`(`%;%`_config(z, [(val : val <: instr) GLOBAL.SET_instr(x)]), `%;%`_config($with_global(z, x, val), [])) + rule `global.set`{z : state, val : val, x : idx}: + `%~>%`(`%;%`_config(z, [(val : val <: instr) `GLOBAL.SET`_instr(x)]), `%;%`_config($with_global(z, x, val), [])) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec:329.1-331.33 rule `table.set-oob`{z : state, at : addrtype, i : num_((at : addrtype <: numtype)), ref : ref, x : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) (ref : ref <: instr) TABLE.SET_instr(x)]), `%;%`_config(z, [TRAP_instr])) + `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) (ref : ref <: instr) `TABLE.SET`_instr(x)]), `%;%`_config(z, [TRAP_instr])) -- if (i!`%`_num_.0 >= |$table(z, x).REFS_tableinst|) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec:333.1-335.32 rule `table.set-val`{z : state, at : addrtype, i : num_((at : addrtype <: numtype)), ref : ref, x : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) (ref : ref <: instr) TABLE.SET_instr(x)]), `%;%`_config($with_table(z, x, i!`%`_num_.0, ref), [])) + `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), i) (ref : ref <: instr) `TABLE.SET`_instr(x)]), `%;%`_config($with_table(z, x, i!`%`_num_.0, ref), [])) -- if (i!`%`_num_.0 < |$table(z, x).REFS_tableinst|) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec:344.1-347.46 rule `table.grow-succeed`{z : state, ref : ref, at : addrtype, n : n, x : idx, ti : tableinst}: - `%~>%`(`%;%`_config(z, [(ref : ref <: instr) CONST_instr((at : addrtype <: numtype), `%`_num_(n)) TABLE.GROW_instr(x)]), `%;%`_config($with_tableinst(z, x, ti), [CONST_instr((at : addrtype <: numtype), `%`_num_(|$table(z, x).REFS_tableinst|))])) + `%~>%`(`%;%`_config(z, [(ref : ref <: instr) CONST_instr((at : addrtype <: numtype), `%`_num_(n)) `TABLE.GROW`_instr(x)]), `%;%`_config($with_tableinst(z, x, ti), [CONST_instr((at : addrtype <: numtype), `%`_num_(|$table(z, x).REFS_tableinst|))])) -- if (ti = $growtable($table(z, x), n, ref)) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec:349.1-350.87 rule `table.grow-fail`{z : state, ref : ref, at : addrtype, n : n, x : idx}: - `%~>%`(`%;%`_config(z, [(ref : ref <: instr) CONST_instr((at : addrtype <: numtype), `%`_num_(n)) TABLE.GROW_instr(x)]), `%;%`_config(z, [CONST_instr((at : addrtype <: numtype), `%`_num_($inv_signed_($size((at : addrtype <: numtype)), - (1 : nat <:> int))))])) + `%~>%`(`%;%`_config(z, [(ref : ref <: instr) CONST_instr((at : addrtype <: numtype), `%`_num_(n)) `TABLE.GROW`_instr(x)]), `%;%`_config(z, [CONST_instr((at : addrtype <: numtype), `%`_num_($inv_signed_($size((at : addrtype <: numtype)), - (1 : nat <:> int))))])) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec:410.1-411.51 - rule elem.drop{z : state, x : idx}: - `%~>%`(`%;%`_config(z, [ELEM.DROP_instr(x)]), `%;%`_config($with_elem(z, x, []), [])) + rule `elem.drop`{z : state, x : idx}: + `%~>%`(`%;%`_config(z, [`ELEM.DROP`_instr(x)]), `%;%`_config($with_elem(z, x, []), [])) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec:494.1-497.60 rule `store-num-oob`{z : state, at : addrtype, i : num_((at : addrtype <: numtype)), nt : numtype, c : num_(nt), x : idx, ao : memarg}: @@ -6991,51 +6991,51 @@ relation Step: `%~>%`(config, config) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec:546.1-549.37 rule `memory.grow-succeed`{z : state, at : addrtype, n : n, x : idx, mi : meminst}: - `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), `%`_num_(n)) MEMORY.GROW_instr(x)]), `%;%`_config($with_meminst(z, x, mi), [CONST_instr((at : addrtype <: numtype), `%`_num_((((|$mem(z, x).BYTES_meminst| : nat <:> rat) / ((64 * $Ki) : nat <:> rat)) : rat <:> nat)))])) + `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), `%`_num_(n)) `MEMORY.GROW`_instr(x)]), `%;%`_config($with_meminst(z, x, mi), [CONST_instr((at : addrtype <: numtype), `%`_num_((((|$mem(z, x).BYTES_meminst| : nat <:> rat) / ((64 * $Ki) : nat <:> rat)) : rat <:> nat)))])) -- if (mi = $growmem($mem(z, x), n)) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec:551.1-552.84 rule `memory.grow-fail`{z : state, at : addrtype, n : n, x : idx}: - `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), `%`_num_(n)) MEMORY.GROW_instr(x)]), `%;%`_config(z, [CONST_instr((at : addrtype <: numtype), `%`_num_($inv_signed_($size((at : addrtype <: numtype)), - (1 : nat <:> int))))])) + `%~>%`(`%;%`_config(z, [CONST_instr((at : addrtype <: numtype), `%`_num_(n)) `MEMORY.GROW`_instr(x)]), `%;%`_config(z, [CONST_instr((at : addrtype <: numtype), `%`_num_($inv_signed_($size((at : addrtype <: numtype)), - (1 : nat <:> int))))])) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec:612.1-613.51 - rule data.drop{z : state, x : idx}: - `%~>%`(`%;%`_config(z, [DATA.DROP_instr(x)]), `%;%`_config($with_data(z, x, []), [])) + rule `data.drop`{z : state, x : idx}: + `%~>%`(`%;%`_config(z, [`DATA.DROP`_instr(x)]), `%;%`_config($with_data(z, x, []), [])) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec:693.1-697.65 - rule struct.new{z : state, `val*` : val*, n : n, x : idx, si : structinst, a : addr, `mut?*` : mut?*, `zt*` : storagetype*}: - `%~>%`(`%;%`_config(z, (val : val <: instr)^n{val <- `val*`} ++ [STRUCT.NEW_instr(x)]), `%;%`_config($add_structinst(z, [si]), [REF.STRUCT_ADDR_instr(a)])) + rule `struct.new`{z : state, n : n, `val*` : val*, x : idx, si : structinst, a : addr, `mut?*` : mut?*, `zt*` : storagetype*}: + `%~>%`(`%;%`_config(z, (val : val <: instr)^n{val <- `val*`} ++ [`STRUCT.NEW`_instr(x)]), `%;%`_config($add_structinst(z, [si]), [`REF.STRUCT_ADDR`_instr(a)])) -- Expand: `%~~%`($type(z, x), STRUCT_comptype(`%`_list(`%%`_fieldtype(mut?{mut <- `mut?`}, zt)^n{`mut?` <- `mut?*`, zt <- `zt*`}))) -- if (a = |$structinst(z)|) -- if (si = {TYPE $type(z, x), FIELDS $packfield_(zt, val)^n{val <- `val*`, zt <- `zt*`}}) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec:714.1-715.53 rule `struct.set-null`{z : state, ht : heaptype, val : val, x : idx, i : u32}: - `%~>%`(`%;%`_config(z, [REF.NULL_instr(ht) (val : val <: instr) STRUCT.SET_instr(x, i)]), `%;%`_config(z, [TRAP_instr])) + `%~>%`(`%;%`_config(z, [`REF.NULL`_instr(ht) (val : val <: instr) `STRUCT.SET`_instr(x, i)]), `%;%`_config(z, [TRAP_instr])) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec:717.1-720.46 rule `struct.set-struct`{z : state, a : addr, val : val, x : idx, i : u32, `zt*` : storagetype*, `mut?*` : mut?*}: - `%~>%`(`%;%`_config(z, [REF.STRUCT_ADDR_instr(a) (val : val <: instr) STRUCT.SET_instr(x, i)]), `%;%`_config($with_struct(z, a, i!`%`_u32.0, $packfield_(zt*{zt <- `zt*`}[i!`%`_u32.0], val)), [])) + `%~>%`(`%;%`_config(z, [`REF.STRUCT_ADDR`_instr(a) (val : val <: instr) `STRUCT.SET`_instr(x, i)]), `%;%`_config($with_struct(z, a, i!`%`_u32.0, $packfield_(zt*{zt <- `zt*`}[i!`%`_u32.0], val)), [])) -- Expand: `%~~%`($type(z, x), STRUCT_comptype(`%`_list(`%%`_fieldtype(mut?{mut <- `mut?`}, zt)*{`mut?` <- `mut?*`, zt <- `zt*`}))) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec:733.1-738.65 - rule array.new_fixed{z : state, `val*` : val*, n : n, x : idx, ai : arrayinst, a : addr, `mut?` : mut?, zt : storagetype}: - `%~>%`(`%;%`_config(z, (val : val <: instr)^n{val <- `val*`} ++ [ARRAY.NEW_FIXED_instr(x, `%`_u32(n))]), `%;%`_config($add_arrayinst(z, [ai]), [REF.ARRAY_ADDR_instr(a)])) + rule `array.new_fixed`{z : state, n : n, `val*` : val*, x : idx, ai : arrayinst, a : addr, `mut?` : mut?, zt : storagetype}: + `%~>%`(`%;%`_config(z, (val : val <: instr)^n{val <- `val*`} ++ [`ARRAY.NEW_FIXED`_instr(x, `%`_u32(n))]), `%;%`_config($add_arrayinst(z, [ai]), [`REF.ARRAY_ADDR`_instr(a)])) -- Expand: `%~~%`($type(z, x), ARRAY_comptype(`%%`_fieldtype(mut?{mut <- `mut?`}, zt))) -- if ((a = |$arrayinst(z)|) /\ (ai = {TYPE $type(z, x), FIELDS $packfield_(zt, val)^n{val <- `val*`}})) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec:778.1-779.64 rule `array.set-null`{z : state, ht : heaptype, i : num_(I32_numtype), val : val, x : idx}: - `%~>%`(`%;%`_config(z, [REF.NULL_instr(ht) CONST_instr(I32_numtype, i) (val : val <: instr) ARRAY.SET_instr(x)]), `%;%`_config(z, [TRAP_instr])) + `%~>%`(`%;%`_config(z, [`REF.NULL`_instr(ht) CONST_instr(I32_numtype, i) (val : val <: instr) `ARRAY.SET`_instr(x)]), `%;%`_config(z, [TRAP_instr])) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec:781.1-783.39 rule `array.set-oob`{z : state, a : addr, i : num_(I32_numtype), val : val, x : idx}: - `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, i) (val : val <: instr) ARRAY.SET_instr(x)]), `%;%`_config(z, [TRAP_instr])) + `%~>%`(`%;%`_config(z, [`REF.ARRAY_ADDR`_instr(a) CONST_instr(I32_numtype, i) (val : val <: instr) `ARRAY.SET`_instr(x)]), `%;%`_config(z, [TRAP_instr])) -- if (i!`%`_num_.0 >= |$arrayinst(z)[a].FIELDS_arrayinst|) ;; ../../../../specification/wasm-3.0/4.3-execution.instructions.spectec:785.1-788.44 rule `array.set-array`{z : state, a : addr, i : num_(I32_numtype), val : val, x : idx, zt : storagetype, `mut?` : mut?}: - `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, i) (val : val <: instr) ARRAY.SET_instr(x)]), `%;%`_config($with_array(z, a, i!`%`_num_.0, $packfield_(zt, val)), [])) + `%~>%`(`%;%`_config(z, [`REF.ARRAY_ADDR`_instr(a) CONST_instr(I32_numtype, i) (val : val <: instr) `ARRAY.SET`_instr(x)]), `%;%`_config($with_array(z, a, i!`%`_num_.0, $packfield_(zt, val)), [])) -- Expand: `%~~%`($type(z, x), ARRAY_comptype(`%%`_fieldtype(mut?{mut <- `mut?`}, zt))) } @@ -7231,7 +7231,7 @@ def $allocexports(moduleinst : moduleinst, export*) : exportinst* ;; ../../../../specification/wasm-3.0/4.4-execution.modules.spectec def $allocmodule(store : store, module : module, externaddr*, val*, ref*, ref**) : (store, moduleinst) ;; ../../../../specification/wasm-3.0/4.4-execution.modules.spectec - def $allocmodule{s : store, module : module, `externaddr*` : externaddr*, `val_G*` : val*, `ref_T*` : ref*, `ref_E**` : ref**, s_7 : store, moduleinst : moduleinst, `type*` : type*, `import*` : import*, `tag*` : tag*, `global*` : global*, `mem*` : mem*, `table*` : table*, `func*` : func*, `data*` : data*, `elem*` : elem*, `start?` : start?, `export*` : export*, `tagtype*` : tagtype*, `globaltype*` : globaltype*, `expr_G*` : expr*, `memtype*` : memtype*, `tabletype*` : tabletype*, `expr_T*` : expr*, `x*` : idx*, `local**` : local**, `expr_F*` : expr*, `byte**` : byte**, `datamode*` : datamode*, `elemtype*` : elemtype*, `expr_E**` : expr**, `elemmode*` : elemmode*, `aa_I*` : tagaddr*, `ga_I*` : globaladdr*, `ma_I*` : memaddr*, `ta_I*` : tableaddr*, `fa_I*` : funcaddr*, `dt*` : deftype*, `fa*` : nat*, `i_F*` : nat*, s_1 : store, `aa*` : tagaddr*, s_2 : store, `ga*` : globaladdr*, s_3 : store, `ma*` : memaddr*, s_4 : store, `ta*` : tableaddr*, s_5 : store, `da*` : dataaddr*, s_6 : store, `ea*` : elemaddr*, `xi*` : exportinst*}(s, module, externaddr*{externaddr <- `externaddr*`}, val_G*{val_G <- `val_G*`}, ref_T*{ref_T <- `ref_T*`}, ref_E*{ref_E <- `ref_E*`}*{`ref_E*` <- `ref_E**`}) = (s_7, moduleinst) + def $allocmodule{s : store, module : module, `externaddr*` : externaddr*, `val_G*` : val*, `ref_T*` : ref*, `ref_E**` : ref**, s_7 : store, moduleinst : moduleinst, `type*` : type*, `import*` : import*, `tag*` : tag*, `global*` : global*, `mem*` : mem*, `table*` : table*, `func*` : func*, `data*` : data*, `elem*` : elem*, `start?` : start?, `export*` : export*, `tagtype*` : tagtype*, `expr_G*` : expr*, `globaltype*` : globaltype*, `memtype*` : memtype*, `expr_T*` : expr*, `tabletype*` : tabletype*, `expr_F*` : expr*, `local**` : local**, `x*` : idx*, `byte**` : byte**, `datamode*` : datamode*, `elemmode*` : elemmode*, `elemtype*` : elemtype*, `expr_E**` : expr**, `aa_I*` : tagaddr*, `ga_I*` : globaladdr*, `ma_I*` : memaddr*, `ta_I*` : tableaddr*, `fa_I*` : funcaddr*, `dt*` : deftype*, `fa*` : nat*, s_1 : store, `aa*` : tagaddr*, s_2 : store, `ga*` : globaladdr*, s_3 : store, `ma*` : memaddr*, s_4 : store, `ta*` : tableaddr*, s_5 : store, `da*` : dataaddr*, s_6 : store, `ea*` : elemaddr*, `xi*` : exportinst*}(s, module, externaddr*{externaddr <- `externaddr*`}, val_G*{val_G <- `val_G*`}, ref_T*{ref_T <- `ref_T*`}, ref_E*{ref_E <- `ref_E*`}*{`ref_E*` <- `ref_E**`}) = (s_7, moduleinst) -- if (module = MODULE_module(type*{type <- `type*`}, import*{import <- `import*`}, tag*{tag <- `tag*`}, global*{global <- `global*`}, mem*{mem <- `mem*`}, table*{table <- `table*`}, func*{func <- `func*`}, data*{data <- `data*`}, elem*{elem <- `elem*`}, start?{start <- `start?`}, export*{export <- `export*`})) -- if (tag*{tag <- `tag*`} = TAG_tag(tagtype)*{tagtype <- `tagtype*`}) -- if (global*{global <- `global*`} = GLOBAL_global(globaltype, expr_G)*{expr_G <- `expr_G*`, globaltype <- `globaltype*`}) @@ -7246,7 +7246,7 @@ def $allocmodule(store : store, module : module, externaddr*, val*, ref*, ref**) -- if (ta_I*{ta_I <- `ta_I*`} = $tablesxa(externaddr*{externaddr <- `externaddr*`})) -- if (fa_I*{fa_I <- `fa_I*`} = $funcsxa(externaddr*{externaddr <- `externaddr*`})) -- if (dt*{dt <- `dt*`} = $alloctypes(type*{type <- `type*`})) - -- if (fa*{fa <- `fa*`} = (|s.FUNCS_store| + i_F)^(i_F<|func*{func <- `func*`}|){i_F <- `i_F*`}) + -- if (fa*{fa <- `fa*`} = (|s.FUNCS_store| + i_F)^(i_F<|func*{func <- `func*`}|){}) -- if ((s_1, aa*{aa <- `aa*`}) = $alloctags(s, $subst_all_tagtype(tagtype, (dt : deftype <: typeuse)*{dt <- `dt*`})*{tagtype <- `tagtype*`})) -- if ((s_2, ga*{ga <- `ga*`}) = $allocglobals(s_1, $subst_all_globaltype(globaltype, (dt : deftype <: typeuse)*{dt <- `dt*`})*{globaltype <- `globaltype*`}, val_G*{val_G <- `val_G*`})) -- if ((s_3, ma*{ma <- `ma*`}) = $allocmems(s_2, $subst_all_memtype(memtype, (dt : deftype <: typeuse)*{dt <- `dt*`})*{memtype <- `memtype*`})) @@ -7260,18 +7260,18 @@ def $allocmodule(store : store, module : module, externaddr*, val*, ref*, ref**) ;; ../../../../specification/wasm-3.0/4.4-execution.modules.spectec def $rundata_(dataidx : dataidx, data : data) : instr* ;; ../../../../specification/wasm-3.0/4.4-execution.modules.spectec - def $rundata_{x : idx, `b*` : byte*, n : n}(x, DATA_data(b^n{b <- `b*`}, PASSIVE_datamode)) = [] + def $rundata_{x : idx, n : n, `b*` : byte*}(x, DATA_data(b^n{b <- `b*`}, PASSIVE_datamode)) = [] ;; ../../../../specification/wasm-3.0/4.4-execution.modules.spectec - def $rundata_{x : idx, `b*` : byte*, n : n, y : idx, `instr*` : instr*}(x, DATA_data(b^n{b <- `b*`}, ACTIVE_datamode(y, instr*{instr <- `instr*`}))) = instr*{instr <- `instr*`} ++ [CONST_instr(I32_numtype, `%`_num_(0)) CONST_instr(I32_numtype, `%`_num_(n)) MEMORY.INIT_instr(y, x) DATA.DROP_instr(x)] + def $rundata_{x : idx, n : n, `b*` : byte*, y : idx, `instr*` : instr*}(x, DATA_data(b^n{b <- `b*`}, ACTIVE_datamode(y, instr*{instr <- `instr*`}))) = instr*{instr <- `instr*`} ++ [CONST_instr(I32_numtype, `%`_num_(0)) CONST_instr(I32_numtype, `%`_num_(n)) `MEMORY.INIT`_instr(y, x) `DATA.DROP`_instr(x)] ;; ../../../../specification/wasm-3.0/4.4-execution.modules.spectec def $runelem_(elemidx : elemidx, elem : elem) : instr* ;; ../../../../specification/wasm-3.0/4.4-execution.modules.spectec - def $runelem_{x : idx, rt : reftype, `e*` : expr*, n : n}(x, ELEM_elem(rt, e^n{e <- `e*`}, PASSIVE_elemmode)) = [] + def $runelem_{x : idx, rt : reftype, n : n, `e*` : expr*}(x, ELEM_elem(rt, e^n{e <- `e*`}, PASSIVE_elemmode)) = [] ;; ../../../../specification/wasm-3.0/4.4-execution.modules.spectec - def $runelem_{x : idx, rt : reftype, `e*` : expr*, n : n}(x, ELEM_elem(rt, e^n{e <- `e*`}, DECLARE_elemmode)) = [ELEM.DROP_instr(x)] + def $runelem_{x : idx, rt : reftype, n : n, `e*` : expr*}(x, ELEM_elem(rt, e^n{e <- `e*`}, DECLARE_elemmode)) = [`ELEM.DROP`_instr(x)] ;; ../../../../specification/wasm-3.0/4.4-execution.modules.spectec - def $runelem_{x : idx, rt : reftype, `e*` : expr*, n : n, y : idx, `instr*` : instr*}(x, ELEM_elem(rt, e^n{e <- `e*`}, ACTIVE_elemmode(y, instr*{instr <- `instr*`}))) = instr*{instr <- `instr*`} ++ [CONST_instr(I32_numtype, `%`_num_(0)) CONST_instr(I32_numtype, `%`_num_(n)) TABLE.INIT_instr(y, x) ELEM.DROP_instr(x)] + def $runelem_{x : idx, rt : reftype, n : n, `e*` : expr*, y : idx, `instr*` : instr*}(x, ELEM_elem(rt, e^n{e <- `e*`}, ACTIVE_elemmode(y, instr*{instr <- `instr*`}))) = instr*{instr <- `instr*`} ++ [CONST_instr(I32_numtype, `%`_num_(0)) CONST_instr(I32_numtype, `%`_num_(n)) `TABLE.INIT`_instr(y, x) `ELEM.DROP`_instr(x)] ;; ../../../../specification/wasm-3.0/4.4-execution.modules.spectec rec { @@ -7291,7 +7291,7 @@ def $evalglobals(state : state, globaltype*, expr*) : (state, val*) ;; ../../../../specification/wasm-3.0/4.4-execution.modules.spectec def $instantiate(store : store, module : module, externaddr*) : config ;; ../../../../specification/wasm-3.0/4.4-execution.modules.spectec - def $instantiate{s : store, module : module, `externaddr*` : externaddr*, s' : store, moduleinst : moduleinst, `instr_E*` : instr*, `instr_D*` : instr*, `instr_S?` : instr?, `xt_I*` : externtype*, `xt_E*` : externtype*, `type*` : type*, `import*` : import*, `tag*` : tag*, `global*` : global*, `mem*` : mem*, `table*` : table*, `func*` : func*, `data*` : data*, `elem*` : elem*, `start?` : start?, `export*` : export*, `globaltype*` : globaltype*, `expr_G*` : expr*, `tabletype*` : tabletype*, `expr_T*` : expr*, `byte**` : byte**, `datamode*` : datamode*, `reftype*` : reftype*, `expr_E**` : expr**, `elemmode*` : elemmode*, `x?` : idx?, moduleinst_0 : moduleinst, `i_F*` : nat*, z : state, z' : state, `val_G*` : val*, `ref_T*` : ref*, `ref_E**` : ref**, `i_D*` : nat*, `i_E*` : nat*}(s, module, externaddr*{externaddr <- `externaddr*`}) = `%;%`_config(`%;%`_state(s', {LOCALS [], MODULE moduleinst}), instr_E*{instr_E <- `instr_E*`} ++ instr_D*{instr_D <- `instr_D*`} ++ lift(instr_S?{instr_S <- `instr_S?`})) + def $instantiate{s : store, module : module, `externaddr*` : externaddr*, s' : store, moduleinst : moduleinst, `instr_E*` : instr*, `instr_D*` : instr*, `instr_S?` : instr?, `xt_I*` : externtype*, `xt_E*` : externtype*, `type*` : type*, `import*` : import*, `tag*` : tag*, `global*` : global*, `mem*` : mem*, `table*` : table*, `func*` : func*, `data*` : data*, `elem*` : elem*, `start?` : start?, `export*` : export*, `expr_G*` : expr*, `globaltype*` : globaltype*, `expr_T*` : expr*, `tabletype*` : tabletype*, `byte**` : byte**, `datamode*` : datamode*, `elemmode*` : elemmode*, `expr_E**` : expr**, `reftype*` : reftype*, `x?` : idx?, moduleinst_0 : moduleinst, z : state, z' : state, `val_G*` : val*, `ref_T*` : ref*, `ref_E**` : ref**, i_D : nat, i_E : nat}(s, module, externaddr*{externaddr <- `externaddr*`}) = `%;%`_config(`%;%`_state(s', {LOCALS [], MODULE moduleinst}), instr_E*{instr_E <- `instr_E*`} ++ instr_D*{instr_D <- `instr_D*`} ++ lift(instr_S?{instr_S <- `instr_S?`})) -- Module_ok: `|-%:%`(module, `%->%`_moduletype(xt_I*{xt_I <- `xt_I*`}, xt_E*{xt_E <- `xt_E*`})) -- (Externaddr_ok: `%|-%:%`(s, externaddr, xt_I))*{externaddr <- `externaddr*`, xt_I <- `xt_I*`} -- if (module = MODULE_module(type*{type <- `type*`}, import*{import <- `import*`}, tag*{tag <- `tag*`}, global*{global <- `global*`}, mem*{mem <- `mem*`}, table*{table <- `table*`}, func*{func <- `func*`}, data*{data <- `data*`}, elem*{elem <- `elem*`}, start?{start <- `start?`}, export*{export <- `export*`})) @@ -7300,20 +7300,20 @@ def $instantiate(store : store, module : module, externaddr*) : config -- if (data*{data <- `data*`} = DATA_data(byte*{byte <- `byte*`}, datamode)*{`byte*` <- `byte**`, datamode <- `datamode*`}) -- if (elem*{elem <- `elem*`} = ELEM_elem(reftype, expr_E*{expr_E <- `expr_E*`}, elemmode)*{elemmode <- `elemmode*`, `expr_E*` <- `expr_E**`, reftype <- `reftype*`}) -- if (start?{start <- `start?`} = START_start(x)?{x <- `x?`}) - -- if (moduleinst_0 = {TYPES $alloctypes(type*{type <- `type*`}), TAGS [], GLOBALS $globalsxa(externaddr*{externaddr <- `externaddr*`}), MEMS [], TABLES [], FUNCS $funcsxa(externaddr*{externaddr <- `externaddr*`}) ++ (|s.FUNCS_store| + i_F)^(i_F<|func*{func <- `func*`}|){i_F <- `i_F*`}, DATAS [], ELEMS [], EXPORTS []}) + -- if (moduleinst_0 = {TYPES $alloctypes(type*{type <- `type*`}), TAGS [], GLOBALS $globalsxa(externaddr*{externaddr <- `externaddr*`}), MEMS [], TABLES [], FUNCS $funcsxa(externaddr*{externaddr <- `externaddr*`}) ++ (|s.FUNCS_store| + i_F)^(i_F<|func*{func <- `func*`}|){}, DATAS [], ELEMS [], EXPORTS []}) -- if (z = `%;%`_state(s, {LOCALS [], MODULE moduleinst_0})) -- if ((z', val_G*{val_G <- `val_G*`}) = $evalglobals(z, globaltype*{globaltype <- `globaltype*`}, expr_G*{expr_G <- `expr_G*`})) -- (Eval_expr: `%;%~>*%;%`(z', expr_T, z', [(ref_T : ref <: val)]))*{expr_T <- `expr_T*`, ref_T <- `ref_T*`} -- (Eval_expr: `%;%~>*%;%`(z', expr_E, z', [(ref_E : ref <: val)]))*{expr_E <- `expr_E*`, ref_E <- `ref_E*`}*{`expr_E*` <- `expr_E**`, `ref_E*` <- `ref_E**`} -- if ((s', moduleinst) = $allocmodule(s, module, externaddr*{externaddr <- `externaddr*`}, val_G*{val_G <- `val_G*`}, ref_T*{ref_T <- `ref_T*`}, ref_E*{ref_E <- `ref_E*`}*{`ref_E*` <- `ref_E**`})) - -- if (instr_D*{instr_D <- `instr_D*`} = $concat_(syntax instr, $rundata_(`%`_dataidx(i_D), data*{data <- `data*`}[i_D])^(i_D<|data*{data <- `data*`}|){i_D <- `i_D*`})) - -- if (instr_E*{instr_E <- `instr_E*`} = $concat_(syntax instr, $runelem_(`%`_elemidx(i_E), elem*{elem <- `elem*`}[i_E])^(i_E<|elem*{elem <- `elem*`}|){i_E <- `i_E*`})) + -- if (instr_D*{instr_D <- `instr_D*`} = $concat_(syntax instr, $rundata_(`%`_dataidx(i_D), data*{data <- `data*`}[i_D])^(i_D<|data*{data <- `data*`}|){})) + -- if (instr_E*{instr_E <- `instr_E*`} = $concat_(syntax instr, $runelem_(`%`_elemidx(i_E), elem*{elem <- `elem*`}[i_E])^(i_E<|elem*{elem <- `elem*`}|){})) -- if (instr_S?{instr_S <- `instr_S?`} = CALL_instr(x)?{x <- `x?`}) ;; ../../../../specification/wasm-3.0/4.4-execution.modules.spectec def $invoke(store : store, funcaddr : funcaddr, val*) : config ;; ../../../../specification/wasm-3.0/4.4-execution.modules.spectec - def $invoke{s : store, funcaddr : funcaddr, `val*` : val*, `t_1*` : valtype*, `t_2*` : valtype*}(s, funcaddr, val*{val <- `val*`}) = `%;%`_config(`%;%`_state(s, {LOCALS [], MODULE {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], EXPORTS []}}), (val : val <: instr)*{val <- `val*`} ++ [REF.FUNC_ADDR_instr(funcaddr) CALL_REF_instr((s.FUNCS_store[funcaddr].TYPE_funcinst : deftype <: typeuse))]) + def $invoke{s : store, funcaddr : funcaddr, `val*` : val*, `t_1*` : valtype*, `t_2*` : valtype*}(s, funcaddr, val*{val <- `val*`}) = `%;%`_config(`%;%`_state(s, {LOCALS [], MODULE {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], EXPORTS []}}), (val : val <: instr)*{val <- `val*`} ++ [`REF.FUNC_ADDR`_instr(funcaddr) CALL_REF_instr((s.FUNCS_store[funcaddr].TYPE_funcinst : deftype <: typeuse))]) -- Expand: `%~~%`(s.FUNCS_store[funcaddr].TYPE_funcinst, `FUNC%->%`_comptype(`%`_resulttype(t_1*{t_1 <- `t_1*`}), `%`_resulttype(t_2*{t_2 <- `t_2*`}))) -- (Val_ok: `%|-%:%`(s, val, t_1))*{t_1 <- `t_1*`, val <- `val*`} @@ -7331,7 +7331,7 @@ grammar BuN(N : N) : uN(N) prod{n : n} `%`_byte(n):Bbyte => `%`_uN(n) -- if ((n < (2 ^ 7)) /\ (n < (2 ^ N))) ;; ../../../../specification/wasm-3.0/5.1-binary.values.spectec:11.5-11.82 - prod{n : n, m : m} {{`%`_byte(n):Bbyte} {`%`_uN(m):BuN((((N : nat <:> int) - (7 : nat <:> int)) : int <:> nat))}} => `%`_uN((((2 ^ 7) * m) + (((n : nat <:> int) - ((2 ^ 7) : nat <:> int)) : int <:> nat))) + prod{m : m, n : n} {{`%`_byte(n):Bbyte} {`%`_uN(m):BuN((((N : nat <:> int) - (7 : nat <:> int)) : int <:> nat))}} => `%`_uN((((2 ^ 7) * m) + (((n : nat <:> int) - ((2 ^ 7) : nat <:> int)) : int <:> nat))) -- if ((n >= (2 ^ 7)) /\ (N > 7)) } @@ -7347,7 +7347,7 @@ grammar BsN(N : N) : sN(N) prod{n : n} `%`_byte(n):Bbyte => `%`_sN(((n : nat <:> int) - ((2 ^ 7) : nat <:> int))) -- if ((((2 ^ 6) <= n) /\ (n < (2 ^ 7))) /\ ((n : nat <:> int) >= (((2 ^ 7) : nat <:> int) - ((2 ^ (((N : nat <:> int) - (1 : nat <:> int)) : int <:> nat)) : nat <:> int)))) ;; ../../../../specification/wasm-3.0/5.1-binary.values.spectec:16.5-16.82 - prod{n : n, i : sN((((N : nat <:> int) - (7 : nat <:> int)) : int <:> nat))} {{`%`_byte(n):Bbyte} {i:BsN((((N : nat <:> int) - (7 : nat <:> int)) : int <:> nat))}} => `%`_sN(((((2 ^ 7) * (i!`%`_sN.0 : int <:> nat)) + (((n : nat <:> int) - ((2 ^ 7) : nat <:> int)) : int <:> nat)) : nat <:> int)) + prod{i : sN((((N : nat <:> int) - (7 : nat <:> int)) : int <:> nat)), n : n} {{`%`_byte(n):Bbyte} {i:BsN((((N : nat <:> int) - (7 : nat <:> int)) : int <:> nat))}} => `%`_sN(((((2 ^ 7) * (i!`%`_sN.0 : int <:> nat)) + (((n : nat <:> int) - ((2 ^ 7) : nat <:> int)) : int <:> nat)) : nat <:> int)) -- if ((n >= (2 ^ 7)) /\ (N > 7)) } @@ -7404,7 +7404,7 @@ grammar Blist(syntax el, grammar BX : el) : el* ;; ../../../../specification/wasm-3.0/5.1-binary.values.spectec grammar Bname : name ;; ../../../../specification/wasm-3.0/5.1-binary.values.spectec - prod{`b*` : byte*, name : name} b*{b <- `b*`}:Blist(syntax byte, grammar Bbyte) => name + prod{name : name, `b*` : byte*} b*{b <- `b*`}:Blist(syntax byte, grammar Bbyte) => name -- if ($utf8(name!`%`_name.0) = b*{b <- `b*`}) ;; ../../../../specification/wasm-3.0/5.1-binary.values.spectec @@ -7568,7 +7568,7 @@ grammar Bstoragetype : storagetype ;; ../../../../specification/wasm-3.0/5.2-binary.types.spectec grammar Bfieldtype : fieldtype ;; ../../../../specification/wasm-3.0/5.2-binary.types.spectec - prod{zt : storagetype, `mut?` : mut?} {{zt:Bstoragetype} {mut?{mut <- `mut?`}:Bmut}} => `%%`_fieldtype(mut?{mut <- `mut?`}, zt) + prod{`mut?` : mut?, zt : storagetype} {{zt:Bstoragetype} {mut?{mut <- `mut?`}:Bmut}} => `%%`_fieldtype(mut?{mut <- `mut?`}, zt) ;; ../../../../specification/wasm-3.0/5.2-binary.types.spectec grammar Bcomptype : comptype @@ -7614,7 +7614,7 @@ grammar Btagtype : tagtype ;; ../../../../specification/wasm-3.0/5.2-binary.types.spectec grammar Bglobaltype : globaltype ;; ../../../../specification/wasm-3.0/5.2-binary.types.spectec - prod{t : valtype, `mut?` : mut?} {{t:Bvaltype} {mut?{mut <- `mut?`}:Bmut}} => `%%`_globaltype(mut?{mut <- `mut?`}, t) + prod{`mut?` : mut?, t : valtype} {{t:Bvaltype} {mut?{mut <- `mut?`}:Bmut}} => `%%`_globaltype(mut?{mut <- `mut?`}, t) ;; ../../../../specification/wasm-3.0/5.2-binary.types.spectec grammar Bmemtype : memtype @@ -7624,7 +7624,7 @@ grammar Bmemtype : memtype ;; ../../../../specification/wasm-3.0/5.2-binary.types.spectec grammar Btabletype : tabletype ;; ../../../../specification/wasm-3.0/5.2-binary.types.spectec - prod{rt : reftype, at : addrtype, lim : limits} {{rt:Breftype} {(at, lim):Blimits}} => `%%%`_tabletype(at, lim, rt) + prod{at : addrtype, lim : limits, rt : reftype} {{rt:Breftype} {(at, lim):Blimits}} => `%%%`_tabletype(at, lim, rt) ;; ../../../../specification/wasm-3.0/5.2-binary.types.spectec grammar Bexterntype : externtype @@ -7683,7 +7683,7 @@ grammar Bmemarg : memidxop prod{n : n, m : m} {{`%`_u32(n):Bu32} {`%`_u64(m):Bu64}} => (`%`_memidx(0), {ALIGN `%`_u32(n), OFFSET `%`_u64(m)}) -- if (n < (2 ^ 6)) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec - prod{n : n, x : idx, m : m} {{`%`_u32(n):Bu32} {x:Bmemidx} {`%`_u64(m):Bu64}} => (x, {ALIGN `%`_u32((((n : nat <:> int) - ((2 ^ 6) : nat <:> int)) : int <:> nat)), OFFSET `%`_u64(m)}) + prod{x : idx, n : n, m : m} {{`%`_u32(n):Bu32} {x:Bmemidx} {`%`_u64(m):Bu64}} => (x, {ALIGN `%`_u32((((n : nat <:> int) - ((2 ^ 6) : nat <:> int)) : int <:> nat)), OFFSET `%`_u64(m)}) -- if (((2 ^ 6) <= n) /\ (n < (2 ^ 7))) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec @@ -7729,11 +7729,11 @@ grammar Binstr : instr ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:46.5-46.30 prod{x : idx} {{0x10} {x:Bfuncidx}} => CALL_instr(x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:47.5-47.60 - prod{y : idx, x : idx} {{0x11} {y:Btypeidx} {x:Btableidx}} => CALL_INDIRECT_instr(x, _IDX_typeuse(y)) + prod{x : idx, y : idx} {{0x11} {y:Btypeidx} {x:Btableidx}} => CALL_INDIRECT_instr(x, _IDX_typeuse(y)) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:48.5-48.37 prod{x : idx} {{0x12} {x:Bfuncidx}} => RETURN_CALL_instr(x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:49.5-49.67 - prod{y : idx, x : idx} {{0x13} {y:Btypeidx} {x:Btableidx}} => RETURN_CALL_INDIRECT_instr(x, _IDX_typeuse(y)) + prod{x : idx, y : idx} {{0x13} {y:Btypeidx} {x:Btableidx}} => RETURN_CALL_INDIRECT_instr(x, _IDX_typeuse(y)) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:50.5-50.41 prod{x : idx} {{0x14} {x:Btypeidx}} => CALL_REF_instr(_IDX_typeuse(x)) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:51.5-51.48 @@ -7745,35 +7745,35 @@ grammar Binstr : instr ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:54.5-54.41 prod{l : labelidx} {{0xD6} {l:Blabelidx}} => BR_ON_NON_NULL_instr(l) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:55.5-56.100 - prod{`null_1?` : null?, `null_2?` : null?, l : labelidx, ht_1 : heaptype, ht_2 : heaptype} {{0xFB} {`%`_u32(24):Bu32} {(null_1?{null_1 <- `null_1?`}, null_2?{null_2 <- `null_2?`}):Bcastop} {l:Blabelidx} {ht_1:Bheaptype} {ht_2:Bheaptype}} => BR_ON_CAST_instr(l, REF_reftype(null_1?{null_1 <- `null_1?`}, ht_1), REF_reftype(null_2?{null_2 <- `null_2?`}, ht_2)) + prod{l : labelidx, `null_1?` : null?, ht_1 : heaptype, `null_2?` : null?, ht_2 : heaptype} {{0xFB} {`%`_u32(24):Bu32} {(null_1?{null_1 <- `null_1?`}, null_2?{null_2 <- `null_2?`}):Bcastop} {l:Blabelidx} {ht_1:Bheaptype} {ht_2:Bheaptype}} => BR_ON_CAST_instr(l, REF_reftype(null_1?{null_1 <- `null_1?`}, ht_1), REF_reftype(null_2?{null_2 <- `null_2?`}, ht_2)) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:57.5-58.105 - prod{`null_1?` : null?, `null_2?` : null?, l : labelidx, ht_1 : heaptype, ht_2 : heaptype} {{0xFB} {`%`_u32(25):Bu32} {(null_1?{null_1 <- `null_1?`}, null_2?{null_2 <- `null_2?`}):Bcastop} {l:Blabelidx} {ht_1:Bheaptype} {ht_2:Bheaptype}} => BR_ON_CAST_FAIL_instr(l, REF_reftype(null_1?{null_1 <- `null_1?`}, ht_1), REF_reftype(null_2?{null_2 <- `null_2?`}, ht_2)) + prod{l : labelidx, `null_1?` : null?, ht_1 : heaptype, `null_2?` : null?, ht_2 : heaptype} {{0xFB} {`%`_u32(25):Bu32} {(null_1?{null_1 <- `null_1?`}, null_2?{null_2 <- `null_2?`}):Bcastop} {l:Blabelidx} {ht_1:Bheaptype} {ht_2:Bheaptype}} => BR_ON_CAST_FAIL_instr(l, REF_reftype(null_1?{null_1 <- `null_1?`}, ht_1), REF_reftype(null_2?{null_2 <- `null_2?`}, ht_2)) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:71.5-71.36 - prod{x : idx} {{0x20} {x:Blocalidx}} => LOCAL.GET_instr(x) + prod{x : idx} {{0x20} {x:Blocalidx}} => `LOCAL.GET`_instr(x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:72.5-72.36 - prod{x : idx} {{0x21} {x:Blocalidx}} => LOCAL.SET_instr(x) + prod{x : idx} {{0x21} {x:Blocalidx}} => `LOCAL.SET`_instr(x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:73.5-73.36 - prod{x : idx} {{0x22} {x:Blocalidx}} => LOCAL.TEE_instr(x) + prod{x : idx} {{0x22} {x:Blocalidx}} => `LOCAL.TEE`_instr(x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:77.5-77.38 - prod{x : idx} {{0x23} {x:Bglobalidx}} => GLOBAL.GET_instr(x) + prod{x : idx} {{0x23} {x:Bglobalidx}} => `GLOBAL.GET`_instr(x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:78.5-78.38 - prod{x : idx} {{0x24} {x:Bglobalidx}} => GLOBAL.SET_instr(x) + prod{x : idx} {{0x24} {x:Bglobalidx}} => `GLOBAL.SET`_instr(x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:85.5-85.36 - prod{x : idx} {{0x25} {x:Btableidx}} => TABLE.GET_instr(x) + prod{x : idx} {{0x25} {x:Btableidx}} => `TABLE.GET`_instr(x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:86.5-86.36 - prod{x : idx} {{0x26} {x:Btableidx}} => TABLE.SET_instr(x) + prod{x : idx} {{0x26} {x:Btableidx}} => `TABLE.SET`_instr(x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:87.5-87.58 - prod{y : idx, x : idx} {{0xFC} {`%`_u32(12):Bu32} {y:Belemidx} {x:Btableidx}} => TABLE.INIT_instr(x, y) + prod{x : idx, y : idx} {{0xFC} {`%`_u32(12):Bu32} {y:Belemidx} {x:Btableidx}} => `TABLE.INIT`_instr(x, y) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:88.5-88.43 - prod{x : idx} {{0xFC} {`%`_u32(13):Bu32} {x:Belemidx}} => ELEM.DROP_instr(x) + prod{x : idx} {{0xFC} {`%`_u32(13):Bu32} {x:Belemidx}} => `ELEM.DROP`_instr(x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:89.5-89.67 - prod{x_1 : idx, x_2 : idx} {{0xFC} {`%`_u32(14):Bu32} {x_1:Btableidx} {x_2:Btableidx}} => TABLE.COPY_instr(x_1, x_2) + prod{x_1 : idx, x_2 : idx} {{0xFC} {`%`_u32(14):Bu32} {x_1:Btableidx} {x_2:Btableidx}} => `TABLE.COPY`_instr(x_1, x_2) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:90.5-90.45 - prod{x : idx} {{0xFC} {`%`_u32(15):Bu32} {x:Btableidx}} => TABLE.GROW_instr(x) + prod{x : idx} {{0xFC} {`%`_u32(15):Bu32} {x:Btableidx}} => `TABLE.GROW`_instr(x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:91.5-91.45 - prod{x : idx} {{0xFC} {`%`_u32(16):Bu32} {x:Btableidx}} => TABLE.SIZE_instr(x) + prod{x : idx} {{0xFC} {`%`_u32(16):Bu32} {x:Btableidx}} => `TABLE.SIZE`_instr(x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:92.5-92.45 - prod{x : idx} {{0xFC} {`%`_u32(17):Bu32} {x:Btableidx}} => TABLE.FILL_instr(x) + prod{x : idx} {{0xFC} {`%`_u32(17):Bu32} {x:Btableidx}} => `TABLE.FILL`_instr(x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:105.5-105.41 prod{x : idx, ao : memarg} {{0x28} {(x, ao):Bmemarg}} => LOAD_instr(I32_numtype, ?(), x, ao) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:106.5-106.41 @@ -7821,85 +7821,85 @@ grammar Binstr : instr ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:127.5-127.46 prod{x : idx, ao : memarg} {{0x3E} {(x, ao):Bmemarg}} => STORE_instr(I64_numtype, ?(`%`_storeop_(`%`_sz(32))), x, ao) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:128.5-128.36 - prod{x : idx} {{0x3F} {x:Bmemidx}} => MEMORY.SIZE_instr(x) + prod{x : idx} {{0x3F} {x:Bmemidx}} => `MEMORY.SIZE`_instr(x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:129.5-129.36 - prod{x : idx} {{0x40} {x:Bmemidx}} => MEMORY.GROW_instr(x) + prod{x : idx} {{0x40} {x:Bmemidx}} => `MEMORY.GROW`_instr(x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:130.5-130.56 - prod{y : idx, x : idx} {{0xFC} {`%`_u32(8):Bu32} {y:Bdataidx} {x:Bmemidx}} => MEMORY.INIT_instr(x, y) + prod{x : idx, y : idx} {{0xFC} {`%`_u32(8):Bu32} {y:Bdataidx} {x:Bmemidx}} => `MEMORY.INIT`_instr(x, y) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:131.5-131.42 - prod{x : idx} {{0xFC} {`%`_u32(9):Bu32} {x:Bdataidx}} => DATA.DROP_instr(x) + prod{x : idx} {{0xFC} {`%`_u32(9):Bu32} {x:Bdataidx}} => `DATA.DROP`_instr(x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:132.5-132.64 - prod{x_1 : idx, x_2 : idx} {{0xFC} {`%`_u32(10):Bu32} {x_1:Bmemidx} {x_2:Bmemidx}} => MEMORY.COPY_instr(x_1, x_2) + prod{x_1 : idx, x_2 : idx} {{0xFC} {`%`_u32(10):Bu32} {x_1:Bmemidx} {x_2:Bmemidx}} => `MEMORY.COPY`_instr(x_1, x_2) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:133.5-133.44 - prod{x : idx} {{0xFC} {`%`_u32(11):Bu32} {x:Bmemidx}} => MEMORY.FILL_instr(x) + prod{x : idx} {{0xFC} {`%`_u32(11):Bu32} {x:Bmemidx}} => `MEMORY.FILL`_instr(x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:140.5-140.37 - prod{ht : heaptype} {{0xD0} {ht:Bheaptype}} => REF.NULL_instr(ht) + prod{ht : heaptype} {{0xD0} {ht:Bheaptype}} => `REF.NULL`_instr(ht) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:141.5-141.24 - prod 0xD1 => REF.IS_NULL_instr + prod 0xD1 => `REF.IS_NULL`_instr ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:142.5-142.34 - prod{x : idx} {{0xD2} {x:Bfuncidx}} => REF.FUNC_instr(x) + prod{x : idx} {{0xD2} {x:Bfuncidx}} => `REF.FUNC`_instr(x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:143.5-143.19 - prod 0xD3 => REF.EQ_instr + prod 0xD3 => `REF.EQ`_instr ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:144.5-144.28 - prod 0xD4 => REF.AS_NON_NULL_instr + prod 0xD4 => `REF.AS_NON_NULL`_instr ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:145.5-145.51 - prod{ht : heaptype} {{0xFB} {`%`_u32(20):Bu32} {ht:Bheaptype}} => REF.TEST_instr(REF_reftype(?(), ht)) + prod{ht : heaptype} {{0xFB} {`%`_u32(20):Bu32} {ht:Bheaptype}} => `REF.TEST`_instr(REF_reftype(?(), ht)) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:146.5-146.56 - prod{ht : heaptype} {{0xFB} {`%`_u32(21):Bu32} {ht:Bheaptype}} => REF.TEST_instr(REF_reftype(?(NULL_null), ht)) + prod{ht : heaptype} {{0xFB} {`%`_u32(21):Bu32} {ht:Bheaptype}} => `REF.TEST`_instr(REF_reftype(?(NULL_null), ht)) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:147.5-147.51 - prod{ht : heaptype} {{0xFB} {`%`_u32(22):Bu32} {ht:Bheaptype}} => REF.CAST_instr(REF_reftype(?(), ht)) + prod{ht : heaptype} {{0xFB} {`%`_u32(22):Bu32} {ht:Bheaptype}} => `REF.CAST`_instr(REF_reftype(?(), ht)) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:148.5-148.56 - prod{ht : heaptype} {{0xFB} {`%`_u32(23):Bu32} {ht:Bheaptype}} => REF.CAST_instr(REF_reftype(?(NULL_null), ht)) + prod{ht : heaptype} {{0xFB} {`%`_u32(23):Bu32} {ht:Bheaptype}} => `REF.CAST`_instr(REF_reftype(?(NULL_null), ht)) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:152.5-152.43 - prod{x : idx} {{0xFB} {`%`_u32(0):Bu32} {x:Btypeidx}} => STRUCT.NEW_instr(x) + prod{x : idx} {{0xFB} {`%`_u32(0):Bu32} {x:Btypeidx}} => `STRUCT.NEW`_instr(x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:153.5-153.51 - prod{x : idx} {{0xFB} {`%`_u32(1):Bu32} {x:Btypeidx}} => STRUCT.NEW_DEFAULT_instr(x) + prod{x : idx} {{0xFB} {`%`_u32(1):Bu32} {x:Btypeidx}} => `STRUCT.NEW_DEFAULT`_instr(x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:154.5-154.52 - prod{x : idx, i : u32} {{0xFB} {`%`_u32(2):Bu32} {x:Btypeidx} {i:Bu32}} => STRUCT.GET_instr(?(), x, i) + prod{x : idx, i : u32} {{0xFB} {`%`_u32(2):Bu32} {x:Btypeidx} {i:Bu32}} => `STRUCT.GET`_instr(?(), x, i) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:155.5-155.54 - prod{x : idx, i : u32} {{0xFB} {`%`_u32(3):Bu32} {x:Btypeidx} {i:Bu32}} => STRUCT.GET_instr(?(S_sx), x, i) + prod{x : idx, i : u32} {{0xFB} {`%`_u32(3):Bu32} {x:Btypeidx} {i:Bu32}} => `STRUCT.GET`_instr(?(S_sx), x, i) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:156.5-156.54 - prod{x : idx, i : u32} {{0xFB} {`%`_u32(4):Bu32} {x:Btypeidx} {i:Bu32}} => STRUCT.GET_instr(?(U_sx), x, i) + prod{x : idx, i : u32} {{0xFB} {`%`_u32(4):Bu32} {x:Btypeidx} {i:Bu32}} => `STRUCT.GET`_instr(?(U_sx), x, i) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:157.5-157.52 - prod{x : idx, i : u32} {{0xFB} {`%`_u32(5):Bu32} {x:Btypeidx} {i:Bu32}} => STRUCT.SET_instr(x, i) + prod{x : idx, i : u32} {{0xFB} {`%`_u32(5):Bu32} {x:Btypeidx} {i:Bu32}} => `STRUCT.SET`_instr(x, i) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:161.5-161.42 - prod{x : idx} {{0xFB} {`%`_u32(6):Bu32} {x:Btypeidx}} => ARRAY.NEW_instr(x) + prod{x : idx} {{0xFB} {`%`_u32(6):Bu32} {x:Btypeidx}} => `ARRAY.NEW`_instr(x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:162.5-162.50 - prod{x : idx} {{0xFB} {`%`_u32(7):Bu32} {x:Btypeidx}} => ARRAY.NEW_DEFAULT_instr(x) + prod{x : idx} {{0xFB} {`%`_u32(7):Bu32} {x:Btypeidx}} => `ARRAY.NEW_DEFAULT`_instr(x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:163.5-163.57 - prod{x : idx, n : n} {{0xFB} {`%`_u32(8):Bu32} {x:Btypeidx} {`%`_u32(n):Bu32}} => ARRAY.NEW_FIXED_instr(x, `%`_u32(n)) + prod{x : idx, n : n} {{0xFB} {`%`_u32(8):Bu32} {x:Btypeidx} {`%`_u32(n):Bu32}} => `ARRAY.NEW_FIXED`_instr(x, `%`_u32(n)) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:164.5-164.60 - prod{x : idx, y : idx} {{0xFB} {`%`_u32(9):Bu32} {x:Btypeidx} {y:Bdataidx}} => ARRAY.NEW_DATA_instr(x, y) + prod{x : idx, y : idx} {{0xFB} {`%`_u32(9):Bu32} {x:Btypeidx} {y:Bdataidx}} => `ARRAY.NEW_DATA`_instr(x, y) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:165.5-165.61 - prod{x : idx, y : idx} {{0xFB} {`%`_u32(10):Bu32} {x:Btypeidx} {y:Belemidx}} => ARRAY.NEW_ELEM_instr(x, y) + prod{x : idx, y : idx} {{0xFB} {`%`_u32(10):Bu32} {x:Btypeidx} {y:Belemidx}} => `ARRAY.NEW_ELEM`_instr(x, y) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:166.5-166.43 - prod{x : idx} {{0xFB} {`%`_u32(11):Bu32} {x:Btypeidx}} => ARRAY.GET_instr(?(), x) + prod{x : idx} {{0xFB} {`%`_u32(11):Bu32} {x:Btypeidx}} => `ARRAY.GET`_instr(?(), x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:167.5-167.45 - prod{x : idx} {{0xFB} {`%`_u32(12):Bu32} {x:Btypeidx}} => ARRAY.GET_instr(?(S_sx), x) + prod{x : idx} {{0xFB} {`%`_u32(12):Bu32} {x:Btypeidx}} => `ARRAY.GET`_instr(?(S_sx), x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:168.5-168.45 - prod{x : idx} {{0xFB} {`%`_u32(13):Bu32} {x:Btypeidx}} => ARRAY.GET_instr(?(U_sx), x) + prod{x : idx} {{0xFB} {`%`_u32(13):Bu32} {x:Btypeidx}} => `ARRAY.GET`_instr(?(U_sx), x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:169.5-169.43 - prod{x : idx} {{0xFB} {`%`_u32(14):Bu32} {x:Btypeidx}} => ARRAY.SET_instr(x) + prod{x : idx} {{0xFB} {`%`_u32(14):Bu32} {x:Btypeidx}} => `ARRAY.SET`_instr(x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:170.5-170.30 - prod {{0xFB} {`%`_u32(15):Bu32}} => ARRAY.LEN_instr + prod {{0xFB} {`%`_u32(15):Bu32}} => `ARRAY.LEN`_instr ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:171.5-171.44 - prod{x : idx} {{0xFB} {`%`_u32(16):Bu32} {x:Btypeidx}} => ARRAY.FILL_instr(x) + prod{x : idx} {{0xFB} {`%`_u32(16):Bu32} {x:Btypeidx}} => `ARRAY.FILL`_instr(x) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:172.5-172.65 - prod{x_1 : idx, x_2 : idx} {{0xFB} {`%`_u32(17):Bu32} {x_1:Btypeidx} {x_2:Btypeidx}} => ARRAY.COPY_instr(x_1, x_2) + prod{x_1 : idx, x_2 : idx} {{0xFB} {`%`_u32(17):Bu32} {x_1:Btypeidx} {x_2:Btypeidx}} => `ARRAY.COPY`_instr(x_1, x_2) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:173.5-173.62 - prod{x : idx, y : idx} {{0xFB} {`%`_u32(18):Bu32} {x:Btypeidx} {y:Bdataidx}} => ARRAY.INIT_DATA_instr(x, y) + prod{x : idx, y : idx} {{0xFB} {`%`_u32(18):Bu32} {x:Btypeidx} {y:Bdataidx}} => `ARRAY.INIT_DATA`_instr(x, y) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:174.5-174.62 - prod{x : idx, y : idx} {{0xFB} {`%`_u32(19):Bu32} {x:Btypeidx} {y:Belemidx}} => ARRAY.INIT_ELEM_instr(x, y) + prod{x : idx, y : idx} {{0xFB} {`%`_u32(19):Bu32} {x:Btypeidx} {y:Belemidx}} => `ARRAY.INIT_ELEM`_instr(x, y) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:178.5-178.39 - prod {{0xFB} {`%`_u32(26):Bu32}} => ANY.CONVERT_EXTERN_instr + prod {{0xFB} {`%`_u32(26):Bu32}} => `ANY.CONVERT_EXTERN`_instr ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:179.5-179.39 - prod {{0xFB} {`%`_u32(27):Bu32}} => EXTERN.CONVERT_ANY_instr + prod {{0xFB} {`%`_u32(27):Bu32}} => `EXTERN.CONVERT_ANY`_instr ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:183.5-183.28 - prod {{0xFB} {`%`_u32(28):Bu32}} => REF.I31_instr + prod {{0xFB} {`%`_u32(28):Bu32}} => `REF.I31`_instr ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:184.5-184.30 - prod {{0xFB} {`%`_u32(29):Bu32}} => I31.GET_instr(S_sx) + prod {{0xFB} {`%`_u32(29):Bu32}} => `I31.GET`_instr(S_sx) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:185.5-185.30 - prod {{0xFB} {`%`_u32(30):Bu32}} => I31.GET_instr(U_sx) + prod {{0xFB} {`%`_u32(30):Bu32}} => `I31.GET`_instr(U_sx) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:192.5-192.31 prod{i : i32} {{0x41} {i:Bi32}} => CONST_instr(I32_numtype, i) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:193.5-193.31 @@ -8411,7 +8411,7 @@ grammar Binstr : instr ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:567.5-567.45 prod {{0xFD} {`%`_u32(121):Bu32}} => VBINOP_instr(`%X%`_shape(I8_lanetype, `%`_dim(16)), MAX_vbinop_(U_sx)) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:568.5-568.46 - prod {{0xFD} {`%`_u32(123):Bu32}} => VBINOP_instr(`%X%`_shape(I8_lanetype, `%`_dim(16)), `AVGRU`_vbinop_) + prod {{0xFD} {`%`_u32(123):Bu32}} => VBINOP_instr(`%X%`_shape(I8_lanetype, `%`_dim(16)), AVGRU_vbinop_) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:572.5-572.70 prod {{0xFD} {`%`_u32(124):Bu32}} => VEXTUNOP_instr(`%`_ishape(`%X%`_shape(I16_lanetype, `%`_dim(8))), `%`_ishape(`%X%`_shape(I8_lanetype, `%`_dim(16))), EXTADD_PAIRWISE_vextunop__(S_sx)) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:573.5-573.70 @@ -8421,7 +8421,7 @@ grammar Binstr : instr ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:578.5-578.42 prod {{0xFD} {`%`_u32(129):Bu32}} => VUNOP_instr(`%X%`_shape(I16_lanetype, `%`_dim(8)), NEG_vunop_) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:582.5-582.53 - prod {{0xFD} {`%`_u32(130):Bu32}} => VBINOP_instr(`%X%`_shape(I16_lanetype, `%`_dim(8)), `Q15MULR_SATS`_vbinop_) + prod {{0xFD} {`%`_u32(130):Bu32}} => VBINOP_instr(`%X%`_shape(I16_lanetype, `%`_dim(8)), Q15MULR_SATS_vbinop_) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:583.5-583.43 prod {{0xFD} {`%`_u32(142):Bu32}} => VBINOP_instr(`%X%`_shape(I16_lanetype, `%`_dim(8)), ADD_vbinop_) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:584.5-584.49 @@ -8445,9 +8445,9 @@ grammar Binstr : instr ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:593.5-593.45 prod {{0xFD} {`%`_u32(153):Bu32}} => VBINOP_instr(`%X%`_shape(I16_lanetype, `%`_dim(8)), MAX_vbinop_(U_sx)) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:594.5-594.46 - prod {{0xFD} {`%`_u32(155):Bu32}} => VBINOP_instr(`%X%`_shape(I16_lanetype, `%`_dim(8)), `AVGRU`_vbinop_) + prod {{0xFD} {`%`_u32(155):Bu32}} => VBINOP_instr(`%X%`_shape(I16_lanetype, `%`_dim(8)), AVGRU_vbinop_) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:595.5-595.57 - prod {{0xFD} {`%`_u32(273):Bu32}} => VBINOP_instr(`%X%`_shape(I16_lanetype, `%`_dim(8)), `RELAXED_Q15MULRS`_vbinop_) + prod {{0xFD} {`%`_u32(273):Bu32}} => VBINOP_instr(`%X%`_shape(I16_lanetype, `%`_dim(8)), RELAXED_Q15MULRS_vbinop_) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:599.5-599.49 prod {{0xFD} {`%`_u32(131):Bu32}} => VTESTOP_instr(`%X%`_shape(I16_lanetype, `%`_dim(8)), ALL_TRUE_vtestop_) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:603.5-603.41 @@ -8479,7 +8479,7 @@ grammar Binstr : instr ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:628.5-628.67 prod {{0xFD} {`%`_u32(159):Bu32}} => VEXTBINOP_instr(`%`_ishape(`%X%`_shape(I16_lanetype, `%`_dim(8))), `%`_ishape(`%X%`_shape(I8_lanetype, `%`_dim(16))), EXTMUL_vextbinop__(HIGH_half, U_sx)) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:629.5-629.67 - prod {{0xFD} {`%`_u32(274):Bu32}} => VEXTBINOP_instr(`%`_ishape(`%X%`_shape(I16_lanetype, `%`_dim(8))), `%`_ishape(`%X%`_shape(I8_lanetype, `%`_dim(16))), `RELAXED_DOTS`_vextbinop__) + prod {{0xFD} {`%`_u32(274):Bu32}} => VEXTBINOP_instr(`%`_ishape(`%X%`_shape(I16_lanetype, `%`_dim(8))), `%`_ishape(`%X%`_shape(I8_lanetype, `%`_dim(16))), RELAXED_DOTS_vextbinop__) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:633.5-633.70 prod {{0xFD} {`%`_u32(126):Bu32}} => VEXTUNOP_instr(`%`_ishape(`%X%`_shape(I32_lanetype, `%`_dim(4))), `%`_ishape(`%X%`_shape(I16_lanetype, `%`_dim(8))), EXTADD_PAIRWISE_vextunop__(S_sx)) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:634.5-634.70 @@ -8521,7 +8521,7 @@ grammar Binstr : instr ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:670.5-670.45 prod {{0xFD} {`%`_u32(185):Bu32}} => VBINOP_instr(`%X%`_shape(I32_lanetype, `%`_dim(4)), MAX_vbinop_(U_sx)) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:674.5-674.59 - prod {{0xFD} {`%`_u32(186):Bu32}} => VEXTBINOP_instr(`%`_ishape(`%X%`_shape(I32_lanetype, `%`_dim(4))), `%`_ishape(`%X%`_shape(I16_lanetype, `%`_dim(8))), `DOTS`_vextbinop__) + prod {{0xFD} {`%`_u32(186):Bu32}} => VEXTBINOP_instr(`%`_ishape(`%X%`_shape(I32_lanetype, `%`_dim(4))), `%`_ishape(`%X%`_shape(I16_lanetype, `%`_dim(8))), DOTS_vextbinop__) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:675.5-675.66 prod {{0xFD} {`%`_u32(188):Bu32}} => VEXTBINOP_instr(`%`_ishape(`%X%`_shape(I32_lanetype, `%`_dim(4))), `%`_ishape(`%X%`_shape(I16_lanetype, `%`_dim(8))), EXTMUL_vextbinop__(LOW_half, S_sx)) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:676.5-676.67 @@ -8531,7 +8531,7 @@ grammar Binstr : instr ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:678.5-678.67 prod {{0xFD} {`%`_u32(191):Bu32}} => VEXTBINOP_instr(`%`_ishape(`%X%`_shape(I32_lanetype, `%`_dim(4))), `%`_ishape(`%X%`_shape(I16_lanetype, `%`_dim(8))), EXTMUL_vextbinop__(HIGH_half, U_sx)) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:682.5-682.72 - prod {{0xFD} {`%`_u32(275):Bu32}} => VEXTTERNOP_instr(`%`_ishape(`%X%`_shape(I32_lanetype, `%`_dim(4))), `%`_ishape(`%X%`_shape(I16_lanetype, `%`_dim(8))), `RELAXED_DOT_ADDS`_vextternop__) + prod {{0xFD} {`%`_u32(275):Bu32}} => VEXTTERNOP_instr(`%`_ishape(`%X%`_shape(I32_lanetype, `%`_dim(4))), `%`_ishape(`%X%`_shape(I16_lanetype, `%`_dim(8))), RELAXED_DOT_ADDS_vextternop__) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:686.5-686.42 prod {{0xFD} {`%`_u32(192):Bu32}} => VUNOP_instr(`%X%`_shape(I64_lanetype, `%`_dim(2)), ABS_vunop_) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:687.5-687.42 @@ -8667,7 +8667,7 @@ grammar Binstr : instr ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:794.5-794.61 prod {{0xFD} {`%`_u32(94):Bu32}} => VCVTOP_instr(`%X%`_shape(F32_lanetype, `%`_dim(4)), `%X%`_shape(F64_lanetype, `%`_dim(2)), DEMOTE_vcvtop__(ZERO_zero)) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:795.5-795.61 - prod {{0xFD} {`%`_u32(95):Bu32}} => VCVTOP_instr(`%X%`_shape(F64_lanetype, `%`_dim(2)), `%X%`_shape(F32_lanetype, `%`_dim(4)), `PROMOTELOW`_vcvtop__) + prod {{0xFD} {`%`_u32(95):Bu32}} => VCVTOP_instr(`%X%`_shape(F64_lanetype, `%`_dim(2)), `%X%`_shape(F32_lanetype, `%`_dim(4)), PROMOTELOW_vcvtop__) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:796.5-796.62 prod {{0xFD} {`%`_u32(248):Bu32}} => VCVTOP_instr(`%X%`_shape(I32_lanetype, `%`_dim(4)), `%X%`_shape(F32_lanetype, `%`_dim(4)), TRUNC_SAT_vcvtop__(S_sx, ?())) ;; ../../../../specification/wasm-3.0/5.3-binary.instructions.spectec:797.5-797.62 @@ -8702,7 +8702,7 @@ grammar Bexpr : expr ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec grammar Bsection_(N : N, syntax en, grammar BX : en*) : en* ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec - prod{len : nat, `en*` : en*} {{`%`_byte(N):Bbyte} {`%`_u32(len):Bu32} {en*{en <- `en*`}:BX}} => en*{en <- `en*`} + prod{`en*` : en*, len : nat} {{`%`_byte(N):Bbyte} {`%`_u32(len):Bu32} {en*{en <- `en*`}:BX}} => en*{en <- `en*`} -- if (len = 0) ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec prod eps => [] @@ -8710,12 +8710,12 @@ grammar Bsection_(N : N, syntax en, grammar BX : en*) : en* ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec grammar Bcustom : ()* ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec - prod {{Bname} {Bbyte*{}}} => [()] + prod {{Bname} {Bbyte*{}}} => [] ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec grammar Bcustomsec : () ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec - prod Bsection_(0, syntax (), grammar Bcustom) => () + prod Bsection_(0, syntax (), grammar Bcustom) => ((), ()).1 ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec grammar Btype : type @@ -8745,7 +8745,7 @@ grammar Bfuncsec : typeidx* ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec grammar Btable : table ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec - prod{tt : tabletype, ht : heaptype, at : addrtype, lim : limits} tt:Btabletype => TABLE_table(tt, [REF.NULL_instr(ht)]) + prod{tt : tabletype, ht : heaptype, at : addrtype, lim : limits} tt:Btabletype => TABLE_table(tt, [`REF.NULL`_instr(ht)]) -- if (tt = `%%%`_tabletype(at, lim, REF_reftype(NULL_null?{}, ht))) ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec prod{tt : tabletype, e : expr} {{0x40} {0x00} {tt:Btabletype} {e:Bexpr}} => TABLE_table(tt, e) @@ -8806,19 +8806,19 @@ grammar Belemkind : reftype ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec grammar Belem : elem ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec - prod{e_o : expr, `y*` : idx*} {{`%`_u32(0):Bu32} {e_o:Bexpr} {y*{y <- `y*`}:Blist(syntax funcidx, grammar Bfuncidx)}} => ELEM_elem(REF_reftype(?(), FUNC_heaptype), [REF.FUNC_instr(y)*{y <- `y*`}], ACTIVE_elemmode(`%`_tableidx(0), e_o)) + prod{`y*` : idx*, e_o : expr} {{`%`_u32(0):Bu32} {e_o:Bexpr} {y*{y <- `y*`}:Blist(syntax funcidx, grammar Bfuncidx)}} => ELEM_elem(REF_reftype(?(), FUNC_heaptype), [`REF.FUNC`_instr(y)*{y <- `y*`}], ACTIVE_elemmode(`%`_tableidx(0), e_o)) ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec - prod{rt : reftype, `y*` : idx*} {{`%`_u32(1):Bu32} {rt:Belemkind} {y*{y <- `y*`}:Blist(syntax funcidx, grammar Bfuncidx)}} => ELEM_elem(rt, [REF.FUNC_instr(y)*{y <- `y*`}], PASSIVE_elemmode) + prod{rt : reftype, `y*` : idx*} {{`%`_u32(1):Bu32} {rt:Belemkind} {y*{y <- `y*`}:Blist(syntax funcidx, grammar Bfuncidx)}} => ELEM_elem(rt, [`REF.FUNC`_instr(y)*{y <- `y*`}], PASSIVE_elemmode) ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec - prod{x : idx, e : expr, rt : reftype, `y*` : idx*} {{`%`_u32(2):Bu32} {x:Btableidx} {e:Bexpr} {rt:Belemkind} {y*{y <- `y*`}:Blist(syntax funcidx, grammar Bfuncidx)}} => ELEM_elem(rt, [REF.FUNC_instr(y)*{y <- `y*`}], ACTIVE_elemmode(x, e)) + prod{rt : reftype, `y*` : idx*, x : idx, e : expr} {{`%`_u32(2):Bu32} {x:Btableidx} {e:Bexpr} {rt:Belemkind} {y*{y <- `y*`}:Blist(syntax funcidx, grammar Bfuncidx)}} => ELEM_elem(rt, [`REF.FUNC`_instr(y)*{y <- `y*`}], ACTIVE_elemmode(x, e)) ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec - prod{rt : reftype, `y*` : idx*} {{`%`_u32(3):Bu32} {rt:Belemkind} {y*{y <- `y*`}:Blist(syntax funcidx, grammar Bfuncidx)}} => ELEM_elem(rt, [REF.FUNC_instr(y)*{y <- `y*`}], DECLARE_elemmode) + prod{rt : reftype, `y*` : idx*} {{`%`_u32(3):Bu32} {rt:Belemkind} {y*{y <- `y*`}:Blist(syntax funcidx, grammar Bfuncidx)}} => ELEM_elem(rt, [`REF.FUNC`_instr(y)*{y <- `y*`}], DECLARE_elemmode) ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec - prod{e_O : expr, `e*` : expr*} {{`%`_u32(4):Bu32} {e_O:Bexpr} {e*{e <- `e*`}:Blist(syntax expr, grammar Bexpr)}} => ELEM_elem(REF_reftype(?(NULL_null), FUNC_heaptype), e*{e <- `e*`}, ACTIVE_elemmode(`%`_tableidx(0), e_O)) + prod{`e*` : expr*, e_O : expr} {{`%`_u32(4):Bu32} {e_O:Bexpr} {e*{e <- `e*`}:Blist(syntax expr, grammar Bexpr)}} => ELEM_elem(REF_reftype(?(NULL_null), FUNC_heaptype), e*{e <- `e*`}, ACTIVE_elemmode(`%`_tableidx(0), e_O)) ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec prod{rt : reftype, `e*` : expr*} {{`%`_u32(5):Bu32} {rt:Breftype} {e*{e <- `e*`}:Blist(syntax expr, grammar Bexpr)}} => ELEM_elem(rt, e*{e <- `e*`}, PASSIVE_elemmode) ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec - prod{x : idx, e_O : expr, `e*` : expr*} {{`%`_u32(6):Bu32} {x:Btableidx} {e_O:Bexpr} {e*{e <- `e*`}:Blist(syntax expr, grammar Bexpr)}} => ELEM_elem(REF_reftype(?(NULL_null), FUNC_heaptype), e*{e <- `e*`}, ACTIVE_elemmode(x, e_O)) + prod{`e*` : expr*, x : idx, e_O : expr} {{`%`_u32(6):Bu32} {x:Btableidx} {e_O:Bexpr} {e*{e <- `e*`}:Blist(syntax expr, grammar Bexpr)}} => ELEM_elem(REF_reftype(?(NULL_null), FUNC_heaptype), e*{e <- `e*`}, ACTIVE_elemmode(x, e_O)) ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec prod{rt : reftype, `e*` : expr*} {{`%`_u32(7):Bu32} {rt:Breftype} {e*{e <- `e*`}:Blist(syntax expr, grammar Bexpr)}} => ELEM_elem(rt, e*{e <- `e*`}, DECLARE_elemmode) @@ -8833,7 +8833,7 @@ syntax code = (local*, expr) ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec grammar Blocals : local* ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec - prod{n : n, t : valtype} {{`%`_u32(n):Bu32} {t:Bvaltype}} => LOCAL_local(t)^n{} + prod{t : valtype, n : n} {{`%`_u32(n):Bu32} {t:Bvaltype}} => LOCAL_local(t)^n{} ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec grammar Bfunc : code @@ -8844,7 +8844,7 @@ grammar Bfunc : code ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec grammar Bcode : code ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec - prod{len : nat, code : code} {{`%`_u32(len):Bu32} {code:Bfunc}} => code + prod{code : code, len : nat} {{`%`_u32(len):Bu32} {code:Bfunc}} => code -- if (len = 0) ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec @@ -8855,11 +8855,11 @@ grammar Bcodesec : code* ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec grammar Bdata : data ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec - prod{e : expr, `b*` : byte*} {{`%`_u32(0):Bu32} {e:Bexpr} {b*{b <- `b*`}:Blist(syntax byte, grammar Bbyte)}} => DATA_data(b*{b <- `b*`}, ACTIVE_datamode(`%`_memidx(0), e)) + prod{`b*` : byte*, e : expr} {{`%`_u32(0):Bu32} {e:Bexpr} {b*{b <- `b*`}:Blist(syntax byte, grammar Bbyte)}} => DATA_data(b*{b <- `b*`}, ACTIVE_datamode(`%`_memidx(0), e)) ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec prod{`b*` : byte*} {{`%`_u32(1):Bu32} {b*{b <- `b*`}:Blist(syntax byte, grammar Bbyte)}} => DATA_data(b*{b <- `b*`}, PASSIVE_datamode) ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec - prod{x : idx, e : expr, `b*` : byte*} {{`%`_u32(2):Bu32} {x:Bmemidx} {e:Bexpr} {b*{b <- `b*`}:Blist(syntax byte, grammar Bbyte)}} => DATA_data(b*{b <- `b*`}, ACTIVE_datamode(x, e)) + prod{`b*` : byte*, x : idx, e : expr} {{`%`_u32(2):Bu32} {x:Bmemidx} {e:Bexpr} {b*{b <- `b*`}:Blist(syntax byte, grammar Bbyte)}} => DATA_data(b*{b <- `b*`}, ACTIVE_datamode(x, e)) ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec grammar Bdatasec : data* @@ -8892,17 +8892,17 @@ grammar Btagsec : tag* ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec grammar Bmagic : () ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec - prod {{0x00} {0x61} {0x73} {0x6D}} => () + prod {{0x00} {0x61} {0x73} {0x6D}} => ((), ()).1 ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec grammar Bversion : () ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec - prod {{0x01} {0x00} {0x00} {0x00}} => () + prod {{0x01} {0x00} {0x00} {0x00}} => ((), ()).1 ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec grammar Bmodule : module ;; ../../../../specification/wasm-3.0/5.4-binary.modules.spectec - prod{`type*` : type*, `import*` : import*, `typeidx*` : typeidx*, `table*` : table*, `mem*` : mem*, `tag*` : tag*, `global*` : global*, `export*` : export*, `start?` : start?, `elem*` : elem*, `n?` : n?, `local**` : local**, `expr*` : expr*, `data*` : data*, `func*` : func*} {{Bmagic} {Bversion} {Bcustomsec*{}} {type*{type <- `type*`}:Btypesec} {Bcustomsec*{}} {import*{import <- `import*`}:Bimportsec} {Bcustomsec*{}} {typeidx*{typeidx <- `typeidx*`}:Bfuncsec} {Bcustomsec*{}} {table*{table <- `table*`}:Btablesec} {Bcustomsec*{}} {mem*{mem <- `mem*`}:Bmemsec} {Bcustomsec*{}} {tag*{tag <- `tag*`}:Btagsec} {Bcustomsec*{}} {global*{global <- `global*`}:Bglobalsec} {Bcustomsec*{}} {export*{export <- `export*`}:Bexportsec} {Bcustomsec*{}} {start?{start <- `start?`}:Bstartsec} {Bcustomsec*{}} {elem*{elem <- `elem*`}:Belemsec} {Bcustomsec*{}} {`%`_u32(n)?{n <- `n?`}:Bdatacntsec} {Bcustomsec*{}} {(local*{local <- `local*`}, expr)*{expr <- `expr*`, `local*` <- `local**`}:Bcodesec} {Bcustomsec*{}} {data*{data <- `data*`}:Bdatasec} {Bcustomsec*{}}} => MODULE_module(type*{type <- `type*`}, import*{import <- `import*`}, tag*{tag <- `tag*`}, global*{global <- `global*`}, mem*{mem <- `mem*`}, table*{table <- `table*`}, func*{func <- `func*`}, data*{data <- `data*`}, elem*{elem <- `elem*`}, start?{start <- `start?`}, export*{export <- `export*`}) + prod{`type*` : type*, `import*` : import*, `tag*` : tag*, `global*` : global*, `mem*` : mem*, `table*` : table*, `func*` : func*, `data*` : data*, `elem*` : elem*, `start?` : start?, `export*` : export*, `typeidx*` : typeidx*, `n?` : n?, `expr*` : expr*, `local**` : local**} {Bmagic Bversion {Bcustomsec*{}} {type*{type <- `type*`}:Btypesec} {Bcustomsec*{}} {import*{import <- `import*`}:Bimportsec} {Bcustomsec*{}} {typeidx*{typeidx <- `typeidx*`}:Bfuncsec} {Bcustomsec*{}} {table*{table <- `table*`}:Btablesec} {Bcustomsec*{}} {mem*{mem <- `mem*`}:Bmemsec} {Bcustomsec*{}} {tag*{tag <- `tag*`}:Btagsec} {Bcustomsec*{}} {global*{global <- `global*`}:Bglobalsec} {Bcustomsec*{}} {export*{export <- `export*`}:Bexportsec} {Bcustomsec*{}} {start?{start <- `start?`}:Bstartsec} {Bcustomsec*{}} {elem*{elem <- `elem*`}:Belemsec} {Bcustomsec*{}} {`%`_u32(n)?{n <- `n?`}:Bdatacntsec} {Bcustomsec*{}} {(local*{local <- `local*`}, expr)*{expr <- `expr*`, `local*` <- `local**`}:Bcodesec} {Bcustomsec*{}} {data*{data <- `data*`}:Bdatasec} {Bcustomsec*{}}} => MODULE_module(type*{type <- `type*`}, import*{import <- `import*`}, tag*{tag <- `tag*`}, global*{global <- `global*`}, mem*{mem <- `mem*`}, table*{table <- `table*`}, func*{func <- `func*`}, data*{data <- `data*`}, elem*{elem <- `elem*`}, start?{start <- `start?`}, export*{export <- `export*`}) -- (if (n = |data*{data <- `data*`}|))?{n <- `n?`} -- if ((n?{n <- `n?`} =/= ?()) \/ ($dataidx_funcs(func*{func <- `func*`}) = [])) -- (if (func = FUNC_func(typeidx, local*{local <- `local*`}, expr)))*{expr <- `expr*`, func <- `func*`, `local*` <- `local**`, typeidx <- `typeidx*`} @@ -9089,7 +9089,7 @@ grammar Tstring : byte* ;; ../../../../specification/wasm-3.0/6.1-text.values.spectec grammar Tname : name ;; ../../../../specification/wasm-3.0/6.1-text.values.spectec - prod{`b*` : byte*, `c*` : char*} b*{b <- `b*`}:Tstring => `%`_name(c*{c <- `c*`}) + prod{`c*` : char*, `b*` : byte*} b*{b <- `b*`}:Tstring => `%`_name(c*{c <- `c*`}) -- if (b*{b <- `b*`} = $utf8(c*{c <- `c*`})) ;; ../../../../specification/wasm-3.0/6.1-text.values.spectec @@ -9382,18 +9382,18 @@ grammar Tlist(syntax el, grammar TX : el) : el* ;; ../../../../specification/wasm-3.0/6.1-text.values.spectec syntax idctxt = { - TYPES{`name?*` : name?*} name?*, - TAGS{`name?*` : name?*} name?*, - GLOBALS{`name?*` : name?*} name?*, - MEMS{`name?*` : name?*} name?*, - TABLES{`name?*` : name?*} name?*, - FUNCS{`name?*` : name?*} name?*, - DATAS{`name?*` : name?*} name?*, - ELEMS{`name?*` : name?*} name?*, - LOCALS{`name?*` : name?*} name?*, - LABELS{`name?*` : name?*} name?*, - FIELDS{`name?**` : name?**} name?**, - TYPEDEFS{`deftype?*` : deftype?*} deftype?* + TYPES name?*, + TAGS name?*, + GLOBALS name?*, + MEMS name?*, + TABLES name?*, + FUNCS name?*, + DATAS name?*, + ELEMS name?*, + LOCALS name?*, + LABELS name?*, + FIELDS name?**, + TYPEDEFS deftype?* } ;; ../../../../specification/wasm-3.0/6.1-text.values.spectec @@ -9406,8 +9406,8 @@ rec { def $concat_idctxt(idctxt*) : idctxt ;; ../../../../specification/wasm-3.0/6.1-text.values.spectec:155.1-155.29 def $concat_idctxt([]) = {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []} - ;; ../../../../specification/wasm-3.0/6.1-text.values.spectec:156.1-156.52 - def $concat_idctxt{I : I, I' : I}([I I']) = I +++ $concat_idctxt(I'*{}) + ;; ../../../../specification/wasm-3.0/6.1-text.values.spectec:156.1-156.53 + def $concat_idctxt{I : I, `I'*` : I*}([I] ++ I'*{I' <- `I'*`}) = I +++ $concat_idctxt(I'*{I' <- `I'*`}) } ;; ../../../../specification/wasm-3.0/6.1-text.values.spectec @@ -9433,7 +9433,7 @@ grammar Tidx_(ids : name?*) : idx ;; ../../../../specification/wasm-3.0/6.1-text.values.spectec prod{x : idx} x:Tu32 => x ;; ../../../../specification/wasm-3.0/6.1-text.values.spectec - prod{id : name, x : idx} id:Tid => x + prod{x : idx, id : name} id:Tid => x -- if (ids[x!`%`_idx.0] = ?(id)) ;; ../../../../specification/wasm-3.0/6.1-text.values.spectec @@ -9597,12 +9597,12 @@ grammar Tfieldtype_(I : I) : fieldtype ;; ../../../../specification/wasm-3.0/6.2-text.types.spectec grammar Tfield_(I : I) : (fieldtype, name?) ;; ../../../../specification/wasm-3.0/6.2-text.types.spectec - prod{`id?` : char?, ft : fieldtype} {{"("} {"field"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {ft:Tfieldtype_(I)} {")"}} => (ft, ?(`%`_name(lift(id?{id <- `id?`})))) + prod{ft : fieldtype, `id?` : char?} {{"("} {"field"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {ft:Tfieldtype_(I)} {")"}} => (ft, ?(`%`_name(lift(id?{id <- `id?`})))) ;; ../../../../specification/wasm-3.0/6.2-text.types.spectec grammar Tparam_(I : I) : (valtype, name?) ;; ../../../../specification/wasm-3.0/6.2-text.types.spectec - prod{`id?` : char?, t : valtype} {{"("} {"param"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {t:Tvaltype_(I)} {")"}} => (t, ?(`%`_name(lift(id?{id <- `id?`})))) + prod{t : valtype, `id?` : char?} {{"("} {"param"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {t:Tvaltype_(I)} {")"}} => (t, ?(`%`_name(lift(id?{id <- `id?`})))) ;; ../../../../specification/wasm-3.0/6.2-text.types.spectec grammar Tresult_(I : I) : valtype @@ -9616,7 +9616,7 @@ grammar Tcomptype_(I : I) : (comptype, idctxt) ;; ../../../../specification/wasm-3.0/6.2-text.types.spectec prod{ft : fieldtype} {{"("} {"array"} {ft:Tfieldtype_(I)} {")"}} => (ARRAY_comptype(ft), {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) ;; ../../../../specification/wasm-3.0/6.2-text.types.spectec - prod{`t_1*` : valtype*, `id?*` : char?*, `t_2*` : valtype*} {{"("} {"func"} {(t_1, ?(`%`_name(lift(id?{id <- `id?`}))))*{`id?` <- `id?*`, t_1 <- `t_1*`}:Tlist(syntax (valtype, name?), grammar Tparam_(I))} {t_2*{t_2 <- `t_2*`}:Tlist(syntax valtype, grammar Tresult_(I))} {")"}} => (`FUNC%->%`_comptype(`%`_resulttype(t_1*{t_1 <- `t_1*`}), `%`_resulttype(t_2*{t_2 <- `t_2*`})), {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) + prod{`t_1*` : valtype*, `t_2*` : valtype*, `id?*` : char?*} {{"("} {"func"} {(t_1, ?(`%`_name(lift(id?{id <- `id?`}))))*{`id?` <- `id?*`, t_1 <- `t_1*`}:Tlist(syntax (valtype, name?), grammar Tparam_(I))} {t_2*{t_2 <- `t_2*`}:Tlist(syntax valtype, grammar Tresult_(I))} {")"}} => (`FUNC%->%`_comptype(`%`_resulttype(t_1*{t_1 <- `t_1*`}), `%`_resulttype(t_2*{t_2 <- `t_2*`})), {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) ;; ../../../../specification/wasm-3.0/6.2-text.types.spectec grammar Tfinal : final @@ -9631,7 +9631,7 @@ grammar Tsubtype_(I : I) : (subtype, idctxt) ;; ../../../../specification/wasm-3.0/6.2-text.types.spectec grammar Ttypedef_(I : I) : (subtype, idctxt) ;; ../../../../specification/wasm-3.0/6.2-text.types.spectec - prod{`id?` : char?, st : subtype, I' : I} {{"("} {"type"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {(st, I'):Tsubtype_(I)} {")"}} => (st, I' +++ {TYPES [?(`%`_name(lift(id?{id <- `id?`})))], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) + prod{st : subtype, I' : I, `id?` : char?} {{"("} {"type"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {(st, I'):Tsubtype_(I)} {")"}} => (st, I' +++ {TYPES [?(`%`_name(lift(id?{id <- `id?`})))], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) ;; ../../../../specification/wasm-3.0/6.2-text.types.spectec grammar Trectype_(I : I) : (rectype, idctxt) @@ -9660,7 +9660,7 @@ grammar Ttypeuse_(I : I) : (typeidx, idctxt) -- if (st*{st <- `st*`}[i] = SUB_subtype(?(FINAL_final), [], `FUNC%->%`_comptype(`%`_resulttype(t_1*{t_1 <- `t_1*`}), `%`_resulttype(t_2*{t_2 <- `t_2*`})))) -- if (I' = {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS ?(`%`_name([]))^|t_1*{t_1 <- `t_1*`}|{}, LABELS [], FIELDS [], TYPEDEFS []}) ;; ../../../../specification/wasm-3.0/6.2-text.types.spectec - prod{x : idx, `t_1*` : valtype*, `id?*` : char?*, `t_2*` : valtype*, I' : I, `st*` : subtype*, i : n} {{"("} {"type"} {x:Ttypeidx_(I)} {")"} {(t_1, ?(`%`_name(lift(id?{id <- `id?`}))))*{`id?` <- `id?*`, t_1 <- `t_1*`}:Tparam_(I)*{}} {t_2*{t_2 <- `t_2*`}:Tresult_(I)*{}}} => (x, I') + prod{x : idx, I' : I, `id?*` : char?*, `t_1*` : valtype*, `t_2*` : valtype*, `st*` : subtype*, i : n} {{"("} {"type"} {x:Ttypeidx_(I)} {")"} {(t_1, ?(`%`_name(lift(id?{id <- `id?`}))))*{`id?` <- `id?*`, t_1 <- `t_1*`}:Tparam_(I)*{}} {t_2*{t_2 <- `t_2*`}:Tresult_(I)*{}}} => (x, I') -- if (I.TYPEDEFS_I[x!`%`_idx.0] = ?(_DEF_deftype(REC_rectype(`%`_list(st*{st <- `st*`})), i))) -- if (st*{st <- `st*`}[i] = SUB_subtype(?(FINAL_final), [], `FUNC%->%`_comptype(`%`_resulttype(t_1*{t_1 <- `t_1*`}), `%`_resulttype(t_2*{t_2 <- `t_2*`})))) -- if (I' = {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS ?(`%`_name(lift(id?{id <- `id?`})))*{`id?` <- `id?*`}, LABELS [], FIELDS [], TYPEDEFS []}) @@ -9691,15 +9691,15 @@ grammar Ttabletype_(I : I) : tabletype ;; ../../../../specification/wasm-3.0/6.2-text.types.spectec grammar Texterntype_(I : I) : (externtype, idctxt) ;; ../../../../specification/wasm-3.0/6.2-text.types.spectec - prod{`id?` : char?, jt : tagtype} {{"("} {"tag"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {jt:Ttagtype_(I)} {")"}} => (TAG_externtype(jt), {TYPES [], TAGS [?(`%`_name(lift(id?{id <- `id?`})))], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) + prod{jt : tagtype, `id?` : char?} {{"("} {"tag"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {jt:Ttagtype_(I)} {")"}} => (TAG_externtype(jt), {TYPES [], TAGS [?(`%`_name(lift(id?{id <- `id?`})))], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) ;; ../../../../specification/wasm-3.0/6.2-text.types.spectec - prod{`id?` : char?, gt : globaltype} {{"("} {"global"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {gt:Tglobaltype_(I)} {")"}} => (GLOBAL_externtype(gt), {TYPES [], TAGS [], GLOBALS [?(`%`_name(lift(id?{id <- `id?`})))], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) + prod{gt : globaltype, `id?` : char?} {{"("} {"global"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {gt:Tglobaltype_(I)} {")"}} => (GLOBAL_externtype(gt), {TYPES [], TAGS [], GLOBALS [?(`%`_name(lift(id?{id <- `id?`})))], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) ;; ../../../../specification/wasm-3.0/6.2-text.types.spectec - prod{`id?` : char?, mt : memtype} {{"("} {"memory"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {mt:Tmemtype_(I)} {")"}} => (MEM_externtype(mt), {TYPES [], TAGS [], GLOBALS [], MEMS [?(`%`_name(lift(id?{id <- `id?`})))], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) + prod{mt : memtype, `id?` : char?} {{"("} {"memory"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {mt:Tmemtype_(I)} {")"}} => (MEM_externtype(mt), {TYPES [], TAGS [], GLOBALS [], MEMS [?(`%`_name(lift(id?{id <- `id?`})))], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) ;; ../../../../specification/wasm-3.0/6.2-text.types.spectec - prod{`id?` : char?, tt : tabletype} {{"("} {"table"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {tt:Ttabletype_(I)} {")"}} => (TABLE_externtype(tt), {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [?(`%`_name(lift(id?{id <- `id?`})))], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) + prod{tt : tabletype, `id?` : char?} {{"("} {"table"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {tt:Ttabletype_(I)} {")"}} => (TABLE_externtype(tt), {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [?(`%`_name(lift(id?{id <- `id?`})))], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) ;; ../../../../specification/wasm-3.0/6.2-text.types.spectec - prod{`id?` : char?, x : idx, I' : I} {{"("} {"func"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {(x, I'):Ttypeuse_(I)} {")"}} => (FUNC_externtype(_IDX_typeuse(x)), {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [?(`%`_name(lift(id?{id <- `id?`})))], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) + prod{x : idx, `id?` : char?, I' : I} {{"("} {"func"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {(x, I'):Ttypeuse_(I)} {")"}} => (FUNC_externtype(_IDX_typeuse(x)), {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [?(`%`_name(lift(id?{id <- `id?`})))], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec grammar Tlabel_(I : I) : (name?, I) @@ -9804,31 +9804,31 @@ grammar Tplaininstr_(I : I) : instr ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec prod "throw_ref" => THROW_REF_instr ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"local.get"} {x:Tlocalidx_(I)}} => LOCAL.GET_instr(x) + prod{x : idx} {{"local.get"} {x:Tlocalidx_(I)}} => `LOCAL.GET`_instr(x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"local.set"} {x:Tlocalidx_(I)}} => LOCAL.SET_instr(x) + prod{x : idx} {{"local.set"} {x:Tlocalidx_(I)}} => `LOCAL.SET`_instr(x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"local.tee"} {x:Tlocalidx_(I)}} => LOCAL.TEE_instr(x) + prod{x : idx} {{"local.tee"} {x:Tlocalidx_(I)}} => `LOCAL.TEE`_instr(x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"global.get"} {x:Tglobalidx_(I)}} => GLOBAL.GET_instr(x) + prod{x : idx} {{"global.get"} {x:Tglobalidx_(I)}} => `GLOBAL.GET`_instr(x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"global.set"} {x:Tglobalidx_(I)}} => GLOBAL.SET_instr(x) + prod{x : idx} {{"global.set"} {x:Tglobalidx_(I)}} => `GLOBAL.SET`_instr(x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"table.get"} {x:Ttableidx_(I)}} => TABLE.GET_instr(x) + prod{x : idx} {{"table.get"} {x:Ttableidx_(I)}} => `TABLE.GET`_instr(x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"table.set"} {x:Ttableidx_(I)}} => TABLE.SET_instr(x) + prod{x : idx} {{"table.set"} {x:Ttableidx_(I)}} => `TABLE.SET`_instr(x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"table.size"} {x:Ttableidx_(I)}} => TABLE.SIZE_instr(x) + prod{x : idx} {{"table.size"} {x:Ttableidx_(I)}} => `TABLE.SIZE`_instr(x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"table.grow"} {x:Ttableidx_(I)}} => TABLE.GROW_instr(x) + prod{x : idx} {{"table.grow"} {x:Ttableidx_(I)}} => `TABLE.GROW`_instr(x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"table.fill"} {x:Ttableidx_(I)}} => TABLE.FILL_instr(x) + prod{x : idx} {{"table.fill"} {x:Ttableidx_(I)}} => `TABLE.FILL`_instr(x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x_1 : idx, x_2 : idx} {{"table.copy"} {x_1:Ttableidx_(I)} {x_2:Ttableidx_(I)}} => TABLE.COPY_instr(x_1, x_2) + prod{x_1 : idx, x_2 : idx} {{"table.copy"} {x_1:Ttableidx_(I)} {x_2:Ttableidx_(I)}} => `TABLE.COPY`_instr(x_1, x_2) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx, y : idx} {{"table.init"} {x:Ttableidx_(I)} {y:Telemidx_(I)}} => TABLE.INIT_instr(x, y) + prod{x : idx, y : idx} {{"table.init"} {x:Ttableidx_(I)} {y:Telemidx_(I)}} => `TABLE.INIT`_instr(x, y) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"elem.drop"} {x:Telemidx_(I)}} => ELEM.DROP_instr(x) + prod{x : idx} {{"elem.drop"} {x:Telemidx_(I)}} => `ELEM.DROP`_instr(x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec prod{x : idx, ao : memarg} {{"i32.load"} {x:Tmemidx_(I)} {ao:Tmemarg_(4)}} => LOAD_instr(I32_numtype, ?(), x, ao) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec @@ -9920,81 +9920,81 @@ grammar Tplaininstr_(I : I) : instr ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec prod{x : idx, ao : memarg, i : laneidx} {{"v128.store64_lane"} {x:Tmemidx_(I)} {ao:Tmemarg_(8)} {i:Tlaneidx}} => VSTORE_LANE_instr(V128_vectype, `%`_sz(64), x, ao, i) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"memory.size"} {x:Tmemidx_(I)}} => MEMORY.SIZE_instr(x) + prod{x : idx} {{"memory.size"} {x:Tmemidx_(I)}} => `MEMORY.SIZE`_instr(x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"memory.grow"} {x:Tmemidx_(I)}} => MEMORY.GROW_instr(x) + prod{x : idx} {{"memory.grow"} {x:Tmemidx_(I)}} => `MEMORY.GROW`_instr(x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"memory.fill"} {x:Tmemidx_(I)}} => MEMORY.FILL_instr(x) + prod{x : idx} {{"memory.fill"} {x:Tmemidx_(I)}} => `MEMORY.FILL`_instr(x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x_1 : idx, x_2 : idx} {{"memory.copy"} {x_1:Tmemidx_(I)} {x_2:Tmemidx_(I)}} => MEMORY.COPY_instr(x_1, x_2) + prod{x_1 : idx, x_2 : idx} {{"memory.copy"} {x_1:Tmemidx_(I)} {x_2:Tmemidx_(I)}} => `MEMORY.COPY`_instr(x_1, x_2) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx, y : idx} {{"memory.init"} {x:Tmemidx_(I)} {y:Tdataidx_(I)}} => MEMORY.INIT_instr(x, y) + prod{x : idx, y : idx} {{"memory.init"} {x:Tmemidx_(I)} {y:Tdataidx_(I)}} => `MEMORY.INIT`_instr(x, y) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"data.drop"} {x:Tdataidx_(I)}} => DATA.DROP_instr(x) + prod{x : idx} {{"data.drop"} {x:Tdataidx_(I)}} => `DATA.DROP`_instr(x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{ht : heaptype} {{"ref.null"} {ht:Theaptype_(I)}} => REF.NULL_instr(ht) + prod{ht : heaptype} {{"ref.null"} {ht:Theaptype_(I)}} => `REF.NULL`_instr(ht) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"ref.func"} {x:Tfuncidx_(I)}} => REF.FUNC_instr(x) + prod{x : idx} {{"ref.func"} {x:Tfuncidx_(I)}} => `REF.FUNC`_instr(x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod "ref.is_null" => REF.IS_NULL_instr + prod "ref.is_null" => `REF.IS_NULL`_instr ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod "ref.as_non_null" => REF.AS_NON_NULL_instr + prod "ref.as_non_null" => `REF.AS_NON_NULL`_instr ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod "ref.eq" => REF.EQ_instr + prod "ref.eq" => `REF.EQ`_instr ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{rt : reftype} {{"ref.test"} {rt:Treftype_(I)}} => REF.TEST_instr(rt) + prod{rt : reftype} {{"ref.test"} {rt:Treftype_(I)}} => `REF.TEST`_instr(rt) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{rt : reftype} {{"ref.cast"} {rt:Treftype_(I)}} => REF.CAST_instr(rt) + prod{rt : reftype} {{"ref.cast"} {rt:Treftype_(I)}} => `REF.CAST`_instr(rt) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod "ref.i31" => REF.I31_instr + prod "ref.i31" => `REF.I31`_instr ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod "i31.get_s" => I31.GET_instr(S_sx) + prod "i31.get_s" => `I31.GET`_instr(S_sx) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod "i31.get_u" => I31.GET_instr(U_sx) + prod "i31.get_u" => `I31.GET`_instr(U_sx) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"struct.new"} {x:Ttypeidx_(I)}} => STRUCT.NEW_instr(x) + prod{x : idx} {{"struct.new"} {x:Ttypeidx_(I)}} => `STRUCT.NEW`_instr(x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"struct.new_default"} {x:Ttypeidx_(I)}} => STRUCT.NEW_DEFAULT_instr(x) + prod{x : idx} {{"struct.new_default"} {x:Ttypeidx_(I)}} => `STRUCT.NEW_DEFAULT`_instr(x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx, i : fieldidx} {{"struct.get"} {x:Ttypeidx_(I)} {i:Tfieldidx__(I, x)}} => STRUCT.GET_instr(?(), x, i) + prod{x : idx, i : fieldidx} {{"struct.get"} {x:Ttypeidx_(I)} {i:Tfieldidx__(I, x)}} => `STRUCT.GET`_instr(?(), x, i) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx, i : fieldidx} {{"struct.get_s"} {x:Ttypeidx_(I)} {i:Tfieldidx__(I, x)}} => STRUCT.GET_instr(?(S_sx), x, i) + prod{x : idx, i : fieldidx} {{"struct.get_s"} {x:Ttypeidx_(I)} {i:Tfieldidx__(I, x)}} => `STRUCT.GET`_instr(?(S_sx), x, i) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx, i : fieldidx} {{"struct.get_u"} {x:Ttypeidx_(I)} {i:Tfieldidx__(I, x)}} => STRUCT.GET_instr(?(U_sx), x, i) + prod{x : idx, i : fieldidx} {{"struct.get_u"} {x:Ttypeidx_(I)} {i:Tfieldidx__(I, x)}} => `STRUCT.GET`_instr(?(U_sx), x, i) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx, i : fieldidx} {{"struct.set"} {x:Ttypeidx_(I)} {i:Tfieldidx__(I, x)}} => STRUCT.SET_instr(x, i) + prod{x : idx, i : fieldidx} {{"struct.set"} {x:Ttypeidx_(I)} {i:Tfieldidx__(I, x)}} => `STRUCT.SET`_instr(x, i) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"array.new"} {x:Ttypeidx_(I)}} => ARRAY.NEW_instr(x) + prod{x : idx} {{"array.new"} {x:Ttypeidx_(I)}} => `ARRAY.NEW`_instr(x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"array.new_default"} {x:Ttypeidx_(I)}} => ARRAY.NEW_DEFAULT_instr(x) + prod{x : idx} {{"array.new_default"} {x:Ttypeidx_(I)}} => `ARRAY.NEW_DEFAULT`_instr(x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx, n : n} {{"array.new_fixed"} {x:Ttypeidx_(I)} {`%`_u32(n):Tu32}} => ARRAY.NEW_FIXED_instr(x, `%`_u32(n)) + prod{x : idx, n : n} {{"array.new_fixed"} {x:Ttypeidx_(I)} {`%`_u32(n):Tu32}} => `ARRAY.NEW_FIXED`_instr(x, `%`_u32(n)) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx, y : idx} {{"array.new_data"} {x:Ttypeidx_(I)} {y:Tdataidx_(I)}} => ARRAY.NEW_DATA_instr(x, y) + prod{x : idx, y : idx} {{"array.new_data"} {x:Ttypeidx_(I)} {y:Tdataidx_(I)}} => `ARRAY.NEW_DATA`_instr(x, y) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx, y : idx} {{"array.new_elem"} {x:Ttypeidx_(I)} {y:Telemidx_(I)}} => ARRAY.NEW_ELEM_instr(x, y) + prod{x : idx, y : idx} {{"array.new_elem"} {x:Ttypeidx_(I)} {y:Telemidx_(I)}} => `ARRAY.NEW_ELEM`_instr(x, y) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"array.get"} {x:Ttypeidx_(I)}} => ARRAY.GET_instr(?(), x) + prod{x : idx} {{"array.get"} {x:Ttypeidx_(I)}} => `ARRAY.GET`_instr(?(), x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"array.get_s"} {x:Ttypeidx_(I)}} => ARRAY.GET_instr(?(S_sx), x) + prod{x : idx} {{"array.get_s"} {x:Ttypeidx_(I)}} => `ARRAY.GET`_instr(?(S_sx), x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"array.get_u"} {x:Ttypeidx_(I)}} => ARRAY.GET_instr(?(U_sx), x) + prod{x : idx} {{"array.get_u"} {x:Ttypeidx_(I)}} => `ARRAY.GET`_instr(?(U_sx), x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"array.set"} {x:Ttypeidx_(I)}} => ARRAY.SET_instr(x) + prod{x : idx} {{"array.set"} {x:Ttypeidx_(I)}} => `ARRAY.SET`_instr(x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod "array.len" => ARRAY.LEN_instr + prod "array.len" => `ARRAY.LEN`_instr ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx} {{"array.fill"} {x:Ttypeidx_(I)}} => ARRAY.FILL_instr(x) + prod{x : idx} {{"array.fill"} {x:Ttypeidx_(I)}} => `ARRAY.FILL`_instr(x) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x_1 : idx, x_2 : idx} {{"array.copy"} {x_1:Ttypeidx_(I)} {x_2:Ttypeidx_(I)}} => ARRAY.COPY_instr(x_1, x_2) + prod{x_1 : idx, x_2 : idx} {{"array.copy"} {x_1:Ttypeidx_(I)} {x_2:Ttypeidx_(I)}} => `ARRAY.COPY`_instr(x_1, x_2) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx, y : idx} {{"array.init_data"} {x:Ttypeidx_(I)} {y:Tdataidx_(I)}} => ARRAY.INIT_DATA_instr(x, y) + prod{x : idx, y : idx} {{"array.init_data"} {x:Ttypeidx_(I)} {y:Tdataidx_(I)}} => `ARRAY.INIT_DATA`_instr(x, y) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod{x : idx, y : idx} {{"array.init_elem"} {x:Ttypeidx_(I)} {y:Telemidx_(I)}} => ARRAY.INIT_ELEM_instr(x, y) + prod{x : idx, y : idx} {{"array.init_elem"} {x:Ttypeidx_(I)} {y:Telemidx_(I)}} => `ARRAY.INIT_ELEM`_instr(x, y) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod "any.convert_extern" => ANY.CONVERT_EXTERN_instr + prod "any.convert_extern" => `ANY.CONVERT_EXTERN`_instr ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod "extern.convert_any" => EXTERN.CONVERT_ANY_instr + prod "extern.convert_any" => `EXTERN.CONVERT_ANY`_instr ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec prod{c : u32} {{"i32.const"} {c:Ti32}} => CONST_instr(I32_numtype, c) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec @@ -10516,7 +10516,7 @@ grammar Tplaininstr_(I : I) : instr ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec prod "i8x16.max_u" => VBINOP_instr(`%X%`_shape(I8_lanetype, `%`_dim(16)), MAX_vbinop_(U_sx)) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod "i8x16.avgr_u" => VBINOP_instr(`%X%`_shape(I8_lanetype, `%`_dim(16)), `AVGRU`_vbinop_) + prod "i8x16.avgr_u" => VBINOP_instr(`%X%`_shape(I8_lanetype, `%`_dim(16)), AVGRU_vbinop_) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec prod "i16x8.add" => VBINOP_instr(`%X%`_shape(I16_lanetype, `%`_dim(8)), ADD_vbinop_) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec @@ -10540,11 +10540,11 @@ grammar Tplaininstr_(I : I) : instr ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec prod "i16x8.max_u" => VBINOP_instr(`%X%`_shape(I16_lanetype, `%`_dim(8)), MAX_vbinop_(U_sx)) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod "i16x8.avgr_u" => VBINOP_instr(`%X%`_shape(I16_lanetype, `%`_dim(8)), `AVGRU`_vbinop_) + prod "i16x8.avgr_u" => VBINOP_instr(`%X%`_shape(I16_lanetype, `%`_dim(8)), AVGRU_vbinop_) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod "i16x8.q15mulr_sat_s" => VBINOP_instr(`%X%`_shape(I16_lanetype, `%`_dim(8)), `Q15MULR_SATS`_vbinop_) + prod "i16x8.q15mulr_sat_s" => VBINOP_instr(`%X%`_shape(I16_lanetype, `%`_dim(8)), Q15MULR_SATS_vbinop_) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod "i16x8.relaxed_q15mulr_s" => VBINOP_instr(`%X%`_shape(I16_lanetype, `%`_dim(8)), `RELAXED_Q15MULRS`_vbinop_) + prod "i16x8.relaxed_q15mulr_s" => VBINOP_instr(`%X%`_shape(I16_lanetype, `%`_dim(8)), RELAXED_Q15MULRS_vbinop_) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec prod "i32x4.add" => VBINOP_instr(`%X%`_shape(I32_lanetype, `%`_dim(4)), ADD_vbinop_) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec @@ -10710,7 +10710,7 @@ grammar Tplaininstr_(I : I) : instr ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec prod "f32x4.convert_i32x4_u" => VCVTOP_instr(`%X%`_shape(F32_lanetype, `%`_dim(4)), `%X%`_shape(I32_lanetype, `%`_dim(4)), CONVERT_vcvtop__(?(), U_sx)) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod "f64x2.promote_low_f32x4" => VCVTOP_instr(`%X%`_shape(F64_lanetype, `%`_dim(2)), `%X%`_shape(F32_lanetype, `%`_dim(4)), `PROMOTELOW`_vcvtop__) + prod "f64x2.promote_low_f32x4" => VCVTOP_instr(`%X%`_shape(F64_lanetype, `%`_dim(2)), `%X%`_shape(F32_lanetype, `%`_dim(4)), PROMOTELOW_vcvtop__) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec prod "f64x2.convert_low_i32x4_s" => VCVTOP_instr(`%X%`_shape(F64_lanetype, `%`_dim(2)), `%X%`_shape(I32_lanetype, `%`_dim(4)), CONVERT_vcvtop__(?(LOW_half), S_sx)) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec @@ -10740,7 +10740,7 @@ grammar Tplaininstr_(I : I) : instr ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec prod "i32x4.extmul_high_i16x8_u" => VEXTBINOP_instr(`%`_ishape(`%X%`_shape(I32_lanetype, `%`_dim(4))), `%`_ishape(`%X%`_shape(I16_lanetype, `%`_dim(8))), EXTMUL_vextbinop__(HIGH_half, U_sx)) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec - prod "i32x4.dot_i16x8_s" => VEXTBINOP_instr(`%`_ishape(`%X%`_shape(I32_lanetype, `%`_dim(4))), `%`_ishape(`%X%`_shape(I16_lanetype, `%`_dim(8))), `DOTS`_vextbinop__) + prod "i32x4.dot_i16x8_s" => VEXTBINOP_instr(`%`_ishape(`%X%`_shape(I32_lanetype, `%`_dim(4))), `%`_ishape(`%X%`_shape(I16_lanetype, `%`_dim(8))), DOTS_vextbinop__) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec prod "i64x2.extmul_low_i32x4_s" => VEXTBINOP_instr(`%`_ishape(`%X%`_shape(I64_lanetype, `%`_dim(2))), `%`_ishape(`%X%`_shape(I32_lanetype, `%`_dim(4))), EXTMUL_vextbinop__(LOW_half, S_sx)) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec @@ -10770,16 +10770,16 @@ grammar Tinstrs_(I : I) : instr* ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec:88.1-90.65 grammar Tblockinstr_(I : I) : instr ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec:63.5-67.35 - prod{`id?` : char?, I' : I, bt : blocktype, `in*` : instr*, `id'?` : char?} {{"block"} {(?(`%`_name(lift(id?{id <- `id?`}))), I'):Tlabel_(I)} {bt:Tblocktype_(I)} {in*{in <- `in*`}:Tinstrs_(I')} {"end"} {?(`%`_name(lift(id'?{id' <- `id'?`}))):Tid?{}}} => BLOCK_instr(bt, in*{in <- `in*`}) + prod{bt : blocktype, `in*` : instr*, `id?` : char?, I' : I, `id'?` : char?} {{"block"} {(?(`%`_name(lift(id?{id <- `id?`}))), I'):Tlabel_(I)} {bt:Tblocktype_(I)} {in*{in <- `in*`}:Tinstrs_(I')} {"end"} {?(`%`_name(lift(id'?{id' <- `id'?`}))):Tid?{}}} => BLOCK_instr(bt, in*{in <- `in*`}) -- if ((id'?{id' <- `id'?`} = ?()) \/ (id'?{id' <- `id'?`} = id?{id <- `id?`})) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec:68.5-72.35 - prod{`id?` : char?, I' : I, bt : blocktype, `in*` : instr*, `id'?` : char?} {{"loop"} {(?(`%`_name(lift(id?{id <- `id?`}))), I'):Tlabel_(I)} {bt:Tblocktype_(I)} {in*{in <- `in*`}:Tinstrs_(I')} {"end"} {?(`%`_name(lift(id'?{id' <- `id'?`}))):Tid?{}}} => LOOP_instr(bt, in*{in <- `in*`}) + prod{bt : blocktype, `in*` : instr*, `id?` : char?, I' : I, `id'?` : char?} {{"loop"} {(?(`%`_name(lift(id?{id <- `id?`}))), I'):Tlabel_(I)} {bt:Tblocktype_(I)} {in*{in <- `in*`}:Tinstrs_(I')} {"end"} {?(`%`_name(lift(id'?{id' <- `id'?`}))):Tid?{}}} => LOOP_instr(bt, in*{in <- `in*`}) -- if ((id'?{id' <- `id'?`} = ?()) \/ (id'?{id' <- `id'?`} = id?{id <- `id?`})) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec:73.5-79.71 - prod{`id?` : char?, I' : I, bt : blocktype, `in_1*` : instr*, `id_1?` : char?, `in_2*` : instr*, `id_2?` : char?} {{"if"} {(?(`%`_name(lift(id?{id <- `id?`}))), I'):Tlabel_(I)} {bt:Tblocktype_(I)} {in_1*{in_1 <- `in_1*`}:Tinstrs_(I')} {"else"} {?(`%`_name(lift(id_1?{id_1 <- `id_1?`}))):Tid?{}} {in_2*{in_2 <- `in_2*`}:Tinstrs_(I')} {"end"} {?(`%`_name(lift(id_2?{id_2 <- `id_2?`}))):Tid?{}}} => `IF%%ELSE%`_instr(bt, in_1*{in_1 <- `in_1*`}, in_2*{in_2 <- `in_2*`}) + prod{bt : blocktype, `in_1*` : instr*, `in_2*` : instr*, `id?` : char?, I' : I, `id_1?` : char?, `id_2?` : char?} {{"if"} {(?(`%`_name(lift(id?{id <- `id?`}))), I'):Tlabel_(I)} {bt:Tblocktype_(I)} {in_1*{in_1 <- `in_1*`}:Tinstrs_(I')} {"else"} {?(`%`_name(lift(id_1?{id_1 <- `id_1?`}))):Tid?{}} {in_2*{in_2 <- `in_2*`}:Tinstrs_(I')} {"end"} {?(`%`_name(lift(id_2?{id_2 <- `id_2?`}))):Tid?{}}} => `IF%%ELSE%`_instr(bt, in_1*{in_1 <- `in_1*`}, in_2*{in_2 <- `in_2*`}) -- if (((id_1?{id_1 <- `id_1?`} = ?()) \/ (id_1?{id_1 <- `id_1?`} = id?{id <- `id?`})) /\ ((id_2?{id_2 <- `id_2?`} = ?()) \/ (id_2?{id_2 <- `id_2?`} = id?{id <- `id?`}))) ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec:80.5-85.35 - prod{`id?` : char?, I' : I, bt : blocktype, `c*` : catch*, `in*` : instr*, `id'?` : char?} {{"try_table"} {(?(`%`_name(lift(id?{id <- `id?`}))), I'):Tlabel_(I)} {bt:Tblocktype_(I)} {c*{c <- `c*`}:Tcatch_(I)*{}} {in*{in <- `in*`}:Tinstrs_(I')} {"end"} {?(`%`_name(lift(id'?{id' <- `id'?`}))):Tid?{}}} => TRY_TABLE_instr(bt, `%`_list(c*{c <- `c*`}), in*{in <- `in*`}) + prod{bt : blocktype, `c*` : catch*, `in*` : instr*, `id?` : char?, I' : I, `id'?` : char?} {{"try_table"} {(?(`%`_name(lift(id?{id <- `id?`}))), I'):Tlabel_(I)} {bt:Tblocktype_(I)} {c*{c <- `c*`}:Tcatch_(I)*{}} {in*{in <- `in*`}:Tinstrs_(I')} {"end"} {?(`%`_name(lift(id'?{id' <- `id'?`}))):Tid?{}}} => TRY_TABLE_instr(bt, `%`_list(c*{c <- `c*`}), in*{in <- `in*`}) -- if ((id'?{id' <- `id'?`} = ?()) \/ (id'?{id' <- `id'?`} = id?{id <- `id?`})) } @@ -10788,384 +10788,384 @@ grammar Texpr_(I : I) : expr ;; ../../../../specification/wasm-3.0/6.3-text.instructions.spectec prod{`in*` : instr*} in*{in <- `in*`}:Tinstrs_(I) => in*{in <- `in*`} -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Ttype_(I : I) : (type, idctxt) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec - prod{qt : rectype, I' : I, I'' : I, `st*` : subtype*, n : n, `i*` : nat*} (qt, I'):Trectype_(I) => (TYPE_type(qt), I' +++ I'') + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec + prod{qt : rectype, I' : I, I'' : I, n : n, `st*` : subtype*} (qt, I'):Trectype_(I) => (TYPE_type(qt), I' +++ I'') -- if (qt = REC_rectype(`%`_list(st^n{st <- `st*`}))) - -- if (I'' = {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS ?(_DEF_deftype(qt, i))^(i (TAG_tag(jt), {TYPES [], TAGS [?(`%`_name(lift(id?{id <- `id?`})))], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec + prod{jt : tagtype, `id?` : char?} {{"("} {"tag"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {jt:Ttagtype_(I)} {")"}} => (TAG_tag(jt), {TYPES [], TAGS [?(`%`_name(lift(id?{id <- `id?`})))], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Tglobal_(I : I) : (global, idctxt) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec - prod{`id?` : char?, gt : globaltype, e : expr} {{"("} {"global"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {gt:Tglobaltype_(I)} {e:Texpr_(I)} {")"}} => (GLOBAL_global(gt, e), {TYPES [], TAGS [], GLOBALS [?(`%`_name(lift(id?{id <- `id?`})))], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec + prod{gt : globaltype, e : expr, `id?` : char?} {{"("} {"global"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {gt:Tglobaltype_(I)} {e:Texpr_(I)} {")"}} => (GLOBAL_global(gt, e), {TYPES [], TAGS [], GLOBALS [?(`%`_name(lift(id?{id <- `id?`})))], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Tmem_(I : I) : (mem, idctxt) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec - prod{`id?` : char?, mt : memtype} {{"("} {"memory"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {mt:Tmemtype_(I)} {")"}} => (MEMORY_mem(mt), {TYPES [], TAGS [], GLOBALS [], MEMS [?(`%`_name(lift(id?{id <- `id?`})))], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec + prod{mt : memtype, `id?` : char?} {{"("} {"memory"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {mt:Tmemtype_(I)} {")"}} => (MEMORY_mem(mt), {TYPES [], TAGS [], GLOBALS [], MEMS [?(`%`_name(lift(id?{id <- `id?`})))], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Ttable_(I : I) : (table, idctxt) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec - prod{`id?` : char?, tt : tabletype, e : expr} {{"("} {"table"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {tt:Ttabletype_(I)} {e:Texpr_(I)} {")"}} => (TABLE_table(tt, e), {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [?(`%`_name(lift(id?{id <- `id?`})))], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec + prod{tt : tabletype, e : expr, `id?` : char?} {{"("} {"table"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {tt:Ttabletype_(I)} {e:Texpr_(I)} {")"}} => (TABLE_table(tt, e), {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [?(`%`_name(lift(id?{id <- `id?`})))], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Tlocal_(I : I) : (local*, idctxt) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec - prod{`id?` : char?, t : valtype} {{"("} {"local"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {t:Tvaltype_(I)} {")"}} => ([LOCAL_local(t)], {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [?(`%`_name(lift(id?{id <- `id?`})))], LABELS [], FIELDS [], TYPEDEFS []}) + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec + prod{t : valtype, `id?` : char?} {{"("} {"local"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {t:Tvaltype_(I)} {")"}} => ([LOCAL_local(t)], {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [?(`%`_name(lift(id?{id <- `id?`})))], LABELS [], FIELDS [], TYPEDEFS []}) -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Tfunc_(I : I) : (func, idctxt) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec - prod{`id?` : char?, x : idx, I_1 : I, `loc**` : local**, `I_2*` : I*, e : expr, I' : I} {{"("} {"func"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {(x, I_1):Ttypeuse_(I)} {(loc*{loc <- `loc*`}, I_2):Tlocal_(I)*{I_2 <- `I_2*`, `loc*` <- `loc**`}} {e:Texpr_(I')} {")"}} => (FUNC_func(x, $concat_(syntax local, loc*{loc <- `loc*`}*{`loc*` <- `loc**`}), e), {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [?(`%`_name(lift(id?{id <- `id?`})))], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec + prod{x : idx, `loc**` : local**, e : expr, `id?` : char?, I_1 : I, `I_2*` : I*, I' : I} {{"("} {"func"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {(x, I_1):Ttypeuse_(I)} {(loc*{loc <- `loc*`}, I_2):Tlocal_(I)*{I_2 <- `I_2*`, `loc*` <- `loc**`}} {e:Texpr_(I')} {")"}} => (FUNC_func(x, $concat_(syntax local, loc*{loc <- `loc*`}*{`loc*` <- `loc**`}), e), {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [?(`%`_name(lift(id?{id <- `id?`})))], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) -- if (I' = I +++ I_1 +++ $concat_idctxt(I_2*{I_2 <- `I_2*`})) -- Idctxt_ok: `|-%:OK`(I') -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Tdatastring : byte* - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`b**` : byte**} b*{b <- `b*`}*{`b*` <- `b**`}:Tstring*{} => $concat_(syntax byte, b*{b <- `b*`}*{`b*` <- `b**`}) -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Tmemuse_(I : I) : memidx - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{x : idx} {{"("} {"memory"} {x:Tmemidx_(I)} {")"}} => x -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Toffset_(I : I) : expr - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{e : expr} {{"("} {"offset"} {e:Texpr_(I)} {")"}} => e -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Tdata_(I : I) : (data, idctxt) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec - prod{`id?` : char?, `b*` : byte*} {{"("} {"data"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {b*{b <- `b*`}:Tdatastring} {")"}} => (DATA_data(b*{b <- `b*`}, PASSIVE_datamode), {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [?(`%`_name(lift(id?{id <- `id?`})))], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec - prod{`id?` : char?, x : idx, e : expr, `b*` : byte*} {{"("} {"data"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {x:Tmemuse_(I)} {e:Toffset_(I)} {b*{b <- `b*`}:Tdatastring} {")"}} => (DATA_data(b*{b <- `b*`}, ACTIVE_datamode(x, e)), {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [?(`%`_name(lift(id?{id <- `id?`})))], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec + prod{`b*` : byte*, `id?` : char?} {{"("} {"data"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {b*{b <- `b*`}:Tdatastring} {")"}} => (DATA_data(b*{b <- `b*`}, PASSIVE_datamode), {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [?(`%`_name(lift(id?{id <- `id?`})))], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec + prod{`b*` : byte*, x : idx, e : expr, `id?` : char?} {{"("} {"data"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {x:Tmemuse_(I)} {e:Toffset_(I)} {b*{b <- `b*`}:Tdatastring} {")"}} => (DATA_data(b*{b <- `b*`}, ACTIVE_datamode(x, e)), {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [?(`%`_name(lift(id?{id <- `id?`})))], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Telemlist_(I : I) : (reftype, expr*) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{rt : reftype, `e*` : expr*} {{rt:Treftype_(I)} {e*{e <- `e*`}:Tlist(syntax expr, grammar Texpr_(I))}} => (rt, e*{e <- `e*`}) -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Ttableuse_(I : I) : tableidx - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{x : idx} {{"("} {"table"} {x:Ttableidx_(I)} {")"}} => x -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Telem_(I : I) : (elem, idctxt) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec - prod{`id?` : char?, rt : reftype, `e*` : expr*} {{"("} {"elem"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {(rt, e*{e <- `e*`}):Telemlist_(I)} {")"}} => (ELEM_elem(rt, e*{e <- `e*`}, PASSIVE_elemmode), {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [?(`%`_name(lift(id?{id <- `id?`})))], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec - prod{`id?` : char?, x : idx, e' : expr, rt : reftype, `e*` : expr*} {{"("} {"elem"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {x:Ttableuse_(I)} {e':Toffset_(I)} {(rt, e*{e <- `e*`}):Telemlist_(I)} {")"}} => (ELEM_elem(rt, e*{e <- `e*`}, ACTIVE_elemmode(x, e')), {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [?(`%`_name(lift(id?{id <- `id?`})))], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec - prod{`id?` : char?, rt : reftype, `e*` : expr*} {{"("} {"elem"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {"declare"} {(rt, e*{e <- `e*`}):Telemlist_(I)} {")"}} => (ELEM_elem(rt, e*{e <- `e*`}, DECLARE_elemmode), {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [?(`%`_name(lift(id?{id <- `id?`})))], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) - -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec + prod{rt : reftype, `e*` : expr*, `id?` : char?} {{"("} {"elem"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {(rt, e*{e <- `e*`}):Telemlist_(I)} {")"}} => (ELEM_elem(rt, e*{e <- `e*`}, PASSIVE_elemmode), {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [?(`%`_name(lift(id?{id <- `id?`})))], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec + prod{rt : reftype, `e*` : expr*, x : idx, e' : expr, `id?` : char?} {{"("} {"elem"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {x:Ttableuse_(I)} {e':Toffset_(I)} {(rt, e*{e <- `e*`}):Telemlist_(I)} {")"}} => (ELEM_elem(rt, e*{e <- `e*`}, ACTIVE_elemmode(x, e')), {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [?(`%`_name(lift(id?{id <- `id?`})))], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec + prod{rt : reftype, `e*` : expr*, `id?` : char?} {{"("} {"elem"} {?(`%`_name(lift(id?{id <- `id?`}))):Tid?{}} {"declare"} {(rt, e*{e <- `e*`}):Telemlist_(I)} {")"}} => (ELEM_elem(rt, e*{e <- `e*`}, DECLARE_elemmode), {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [?(`%`_name(lift(id?{id <- `id?`})))], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) + +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Telemexpr_(I : I) : expr - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{e : expr} {{"("} {"item"} {e:Texpr_(I)} {")"}} => e -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Tstart_(I : I) : (start, idctxt) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{x : idx} {{"("} {"start"} {x:Tfuncidx_(I)} {")"}} => (START_start(x), {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Timport_(I : I) : (import, idctxt) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{nm_1 : name, nm_2 : name, xt : externtype, I' : I} {{"("} {"import"} {nm_1:Tname} {nm_2:Tname} {(xt, I'):Texterntype_(I)} {")"}} => (IMPORT_import(nm_1, nm_2, xt), I') -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Texport_(I : I) : (export, idctxt) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{nm : name, xx : externidx} {{"("} {"export"} {nm:Tname} {xx:Texternidx_(I)} {")"}} => (EXPORT_export(nm, xx), {TYPES [], TAGS [], GLOBALS [], MEMS [], TABLES [], FUNCS [], DATAS [], ELEMS [], LOCALS [], LABELS [], FIELDS [], TYPEDEFS []}) -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Texportdots : () - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : ()} ``:{{"("} {"export"} {Tname} {")"}} => (``, ()).1 -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Timportdots : () - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : ()} ``:{{"("} {"import"} {Tname} {Tname} {")"}} => (``, ()).1 -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec def $dots : () -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Texporttagdots_(I : I) : () - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : ()} ``:{{Texportdots*{}} {Ttagtype_(I)}} => (``, ()).1 - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : ()} ``:{{Texportdots*{}} Timportdots {Ttagtype_(I)}} => (``, ()).1 -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Texportglobaldots_(I : I) : () - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : ()} ``:{{Texportdots*{}} {Tglobaltype_(I)} {Texpr_(I)}} => (``, ()).1 - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : ()} ``:{{Texportdots*{}} Timportdots {Tglobaltype_(I)}} => (``, ()).1 -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Texportmemdots_(I : I) : () - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : ()} ``:{{Texportdots*{}} {Tmemtype_(I)}} => (``, ()).1 - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : ()} ``:{{Texportdots*{}} {Taddrtype?{}} {"("} {"data"} {Tdatastring} {")"}} => (``, ()).1 - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : ()} ``:{{Texportdots*{}} Timportdots {Tmemtype_(I)}} => (``, ()).1 -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Texporttabledots_(I : I) : () - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : ()} ``:{{Texportdots*{}} {Ttabletype_(I)} {Texpr_(I)?{}}} => (``, ()).1 - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : ()} ``:{{Texportdots*{}} {Taddrtype?{}} {Treftype_(I)} {"("} {"elem"} {Telemlist_(I)} {")"}} => (``, ()).1 - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : ()} ``:{{Texportdots*{}} Timportdots {Ttabletype_(I)}} => (``, ()).1 -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Texportfuncdots_(I : I) : () - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : ()} ``:{{Texportdots*{}} {Ttypeuse_(I)} {Tlocal_(I)*{}} {Texpr_(I)}} => (``, ()).1 - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : ()} ``:{{Texportdots*{}} Timportdots {Ttypeuse_(I)}} => (``, ()).1 -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Texporttag_(I : I) : () -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Texportglobal_(I : I) : () -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Texportmem_(I : I) : () -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Texporttable_(I : I) : () -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Texportfunc_(I : I) : () -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Tdatamem_(I : I) : () -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Telemtable_(I : I) : () -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec syntax decl = - | TYPE{rectype : rectype}(rectype : rectype) - | IMPORT{name : name, externtype : externtype}(name : name, name, externtype : externtype) - | TAG{tagtype : tagtype}(tagtype : tagtype) - | GLOBAL{globaltype : globaltype, expr : expr}(globaltype : globaltype, expr : expr) - | MEMORY{memtype : memtype}(memtype : memtype) - | TABLE{tabletype : tabletype, expr : expr}(tabletype : tabletype, expr : expr) - | FUNC{typeidx : typeidx, `local*` : local*, expr : expr}(typeidx : typeidx, local*{local <- `local*`} : local*, expr : expr) - | DATA{`byte*` : byte*, datamode : datamode}(byte*{byte <- `byte*`} : byte*, datamode : datamode) - | ELEM{reftype : reftype, `expr*` : expr*, elemmode : elemmode}(reftype : reftype, expr*{expr <- `expr*`} : expr*, elemmode : elemmode) - | START{funcidx : funcidx}(funcidx : funcidx) - | EXPORT{name : name, externidx : externidx}(name : name, externidx : externidx) - -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + | TYPE(rectype : rectype) + | IMPORT(name : name, name : name, externtype : externtype) + | TAG(tagtype : tagtype) + | GLOBAL(globaltype : globaltype, expr : expr) + | MEMORY(memtype : memtype) + | TABLE(tabletype : tabletype, expr : expr) + | FUNC(typeidx : typeidx, `local*` : local*, expr : expr) + | DATA(`byte*` : byte*, datamode : datamode) + | ELEM(reftype : reftype, `expr*` : expr*, elemmode : elemmode) + | START(funcidx : funcidx) + | EXPORT(name : name, externidx : externidx) + +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec rec { -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:258.1-258.76 +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:258.1-258.76 def $typesd(decl*) : type* - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:270.1-270.23 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:270.1-270.23 def $typesd([]) = [] - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:271.1-271.48 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:271.1-271.48 def $typesd{type : type, `decl'*` : decl*}([(type : type <: decl)] ++ decl'*{decl' <- `decl'*`}) = [type] ++ $typesd(decl'*{decl' <- `decl'*`}) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:272.1-272.57 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:272.1-272.57 def $typesd{decl : decl, `decl'*` : decl*}([decl] ++ decl'*{decl' <- `decl'*`}) = $typesd(decl'*{decl' <- `decl'*`}) -- otherwise } -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec rec { -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:259.1-259.78 +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:259.1-259.78 def $importsd(decl*) : import* - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:274.1-274.25 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:274.1-274.25 def $importsd([]) = [] - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:275.1-275.56 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:275.1-275.56 def $importsd{import : import, `decl'*` : decl*}([(import : import <: decl)] ++ decl'*{decl' <- `decl'*`}) = [import] ++ $importsd(decl'*{decl' <- `decl'*`}) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:276.1-276.61 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:276.1-276.61 def $importsd{decl : decl, `decl'*` : decl*}([decl] ++ decl'*{decl' <- `decl'*`}) = $importsd(decl'*{decl' <- `decl'*`}) -- otherwise } -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec rec { -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:260.1-260.75 +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:260.1-260.75 def $tagsd(decl*) : tag* - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:278.1-278.22 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:278.1-278.22 def $tagsd([]) = [] - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:279.1-279.44 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:279.1-279.44 def $tagsd{tag : tag, `decl'*` : decl*}([(tag : tag <: decl)] ++ decl'*{decl' <- `decl'*`}) = [tag] ++ $tagsd(decl'*{decl' <- `decl'*`}) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:280.1-280.55 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:280.1-280.55 def $tagsd{decl : decl, `decl'*` : decl*}([decl] ++ decl'*{decl' <- `decl'*`}) = $tagsd(decl'*{decl' <- `decl'*`}) -- otherwise } -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec rec { -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:261.1-261.78 +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:261.1-261.78 def $globalsd(decl*) : global* - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:282.1-282.25 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:282.1-282.25 def $globalsd([]) = [] - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:283.1-283.56 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:283.1-283.56 def $globalsd{global : global, `decl'*` : decl*}([(global : global <: decl)] ++ decl'*{decl' <- `decl'*`}) = [global] ++ $globalsd(decl'*{decl' <- `decl'*`}) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:284.1-284.61 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:284.1-284.61 def $globalsd{decl : decl, `decl'*` : decl*}([decl] ++ decl'*{decl' <- `decl'*`}) = $globalsd(decl'*{decl' <- `decl'*`}) -- otherwise } -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec rec { -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:262.1-262.75 +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:262.1-262.75 def $memsd(decl*) : mem* - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:286.1-286.22 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:286.1-286.22 def $memsd([]) = [] - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:287.1-287.44 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:287.1-287.44 def $memsd{mem : mem, `decl'*` : decl*}([(mem : mem <: decl)] ++ decl'*{decl' <- `decl'*`}) = [mem] ++ $memsd(decl'*{decl' <- `decl'*`}) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:288.1-288.55 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:288.1-288.55 def $memsd{decl : decl, `decl'*` : decl*}([decl] ++ decl'*{decl' <- `decl'*`}) = $memsd(decl'*{decl' <- `decl'*`}) -- otherwise } -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec rec { -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:263.1-263.77 +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:263.1-263.77 def $tablesd(decl*) : table* - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:290.1-290.24 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:290.1-290.24 def $tablesd([]) = [] - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:291.1-291.52 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:291.1-291.52 def $tablesd{table : table, `decl'*` : decl*}([(table : table <: decl)] ++ decl'*{decl' <- `decl'*`}) = [table] ++ $tablesd(decl'*{decl' <- `decl'*`}) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:292.1-292.59 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:292.1-292.59 def $tablesd{decl : decl, `decl'*` : decl*}([decl] ++ decl'*{decl' <- `decl'*`}) = $tablesd(decl'*{decl' <- `decl'*`}) -- otherwise } -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec rec { -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:264.1-264.76 +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:264.1-264.76 def $funcsd(decl*) : func* - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:294.1-294.23 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:294.1-294.23 def $funcsd([]) = [] - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:295.1-295.48 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:295.1-295.48 def $funcsd{func : func, `decl'*` : decl*}([(func : func <: decl)] ++ decl'*{decl' <- `decl'*`}) = [func] ++ $funcsd(decl'*{decl' <- `decl'*`}) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:296.1-296.57 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:296.1-296.57 def $funcsd{decl : decl, `decl'*` : decl*}([decl] ++ decl'*{decl' <- `decl'*`}) = $funcsd(decl'*{decl' <- `decl'*`}) -- otherwise } -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec rec { -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:265.1-265.76 +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:265.1-265.76 def $datasd(decl*) : data* - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:298.1-298.23 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:298.1-298.23 def $datasd([]) = [] - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:299.1-299.48 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:299.1-299.48 def $datasd{data : data, `decl'*` : decl*}([(data : data <: decl)] ++ decl'*{decl' <- `decl'*`}) = [data] ++ $datasd(decl'*{decl' <- `decl'*`}) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:300.1-300.57 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:300.1-300.57 def $datasd{decl : decl, `decl'*` : decl*}([decl] ++ decl'*{decl' <- `decl'*`}) = $datasd(decl'*{decl' <- `decl'*`}) -- otherwise } -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec rec { -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:266.1-266.76 +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:266.1-266.76 def $elemsd(decl*) : elem* - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:302.1-302.23 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:302.1-302.23 def $elemsd([]) = [] - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:303.1-303.48 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:303.1-303.48 def $elemsd{elem : elem, `decl'*` : decl*}([(elem : elem <: decl)] ++ decl'*{decl' <- `decl'*`}) = [elem] ++ $elemsd(decl'*{decl' <- `decl'*`}) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:304.1-304.57 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:304.1-304.57 def $elemsd{decl : decl, `decl'*` : decl*}([decl] ++ decl'*{decl' <- `decl'*`}) = $elemsd(decl'*{decl' <- `decl'*`}) -- otherwise } -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec rec { -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:267.1-267.77 +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:267.1-267.77 def $startsd(decl*) : start* - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:306.1-306.24 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:306.1-306.24 def $startsd([]) = [] - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:307.1-307.52 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:307.1-307.52 def $startsd{start : start, `decl'*` : decl*}([(start : start <: decl)] ++ decl'*{decl' <- `decl'*`}) = [start] ++ $startsd(decl'*{decl' <- `decl'*`}) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:308.1-308.59 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:308.1-308.59 def $startsd{decl : decl, `decl'*` : decl*}([decl] ++ decl'*{decl' <- `decl'*`}) = $startsd(decl'*{decl' <- `decl'*`}) -- otherwise } -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec rec { -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:268.1-268.78 +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:268.1-268.78 def $exportsd(decl*) : export* - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:310.1-310.25 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:310.1-310.25 def $exportsd([]) = [] - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:311.1-311.56 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:311.1-311.56 def $exportsd{export : export, `decl'*` : decl*}([(export : export <: decl)] ++ decl'*{decl' <- `decl'*`}) = [export] ++ $exportsd(decl'*{decl' <- `decl'*`}) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec:312.1-312.61 + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec:312.1-312.61 def $exportsd{decl : decl, `decl'*` : decl*}([decl] ++ decl'*{decl' <- `decl'*`}) = $exportsd(decl'*{decl' <- `decl'*`}) -- otherwise } -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec def $ordered(decl*) : bool - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec def $ordered{`decl'*` : decl*}(decl'*{decl' <- `decl'*`}) = true -- if ($importsd(decl'*{decl' <- `decl'*`}) = []) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec def $ordered{`decl_1*` : decl*, import : import, `decl_2*` : decl*}(decl_1*{decl_1 <- `decl_1*`} ++ [(import : import <: decl)] ++ decl_2*{decl_2 <- `decl_2*`}) = (((((($importsd(decl_1*{decl_1 <- `decl_1*`}) = []) /\ ($tagsd(decl_1*{decl_1 <- `decl_1*`}) = [])) /\ ($globalsd(decl_1*{decl_1 <- `decl_1*`}) = [])) /\ ($memsd(decl_1*{decl_1 <- `decl_1*`}) = [])) /\ ($tablesd(decl_1*{decl_1 <- `decl_1*`}) = [])) /\ ($funcsd(decl_1*{decl_1 <- `decl_1*`}) = [])) -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Tdecl_(I : I) : (decl, idctxt) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : (type, idctxt)} ``:Ttype_(I) => (`` : (type, idctxt) <: (decl, idctxt)) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : (import, idctxt)} ``:Timport_(I) => (`` : (import, idctxt) <: (decl, idctxt)) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : (tag, idctxt)} ``:Ttag_(I) => (`` : (tag, idctxt) <: (decl, idctxt)) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : (global, idctxt)} ``:Tglobal_(I) => (`` : (global, idctxt) <: (decl, idctxt)) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : (mem, idctxt)} ``:Tmem_(I) => (`` : (mem, idctxt) <: (decl, idctxt)) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : (table, idctxt)} ``:Ttable_(I) => (`` : (table, idctxt) <: (decl, idctxt)) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : (func, idctxt)} ``:Tfunc_(I) => (`` : (func, idctxt) <: (decl, idctxt)) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : (data, idctxt)} ``:Tdata_(I) => (`` : (data, idctxt) <: (decl, idctxt)) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : (elem, idctxt)} ``:Telem_(I) => (`` : (elem, idctxt) <: (decl, idctxt)) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : (start, idctxt)} ``:Tstart_(I) => (`` : (start, idctxt) <: (decl, idctxt)) - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : (export, idctxt)} ``:Texport_(I) => (`` : (export, idctxt) <: (decl, idctxt)) -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Tmodule : module - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec - prod{`decl*` : decl*, `I*` : I*, I' : I, `type*` : type*, `import*` : import*, `tag*` : tag*, `global*` : global*, `mem*` : mem*, `table*` : table*, `func*` : func*, `data*` : data*, `elem*` : elem*, `start?` : start?, `export*` : export*} {{"("} {"module"} {Tid?{}} {(decl, I)*{I <- `I*`, decl <- `decl*`}:Tdecl_(I')*{}} {")"}} => MODULE_module(type*{type <- `type*`}, import*{import <- `import*`}, tag*{tag <- `tag*`}, global*{global <- `global*`}, mem*{mem <- `mem*`}, table*{table <- `table*`}, func*{func <- `func*`}, data*{data <- `data*`}, elem*{elem <- `elem*`}, start?{start <- `start?`}, export*{export <- `export*`}) + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec + prod{`type*` : type*, `import*` : import*, `tag*` : tag*, `global*` : global*, `mem*` : mem*, `table*` : table*, `func*` : func*, `data*` : data*, `elem*` : elem*, `start?` : start?, `export*` : export*, `I*` : I*, `decl*` : decl*, I' : I} {{"("} {"module"} {Tid?{}} {(decl, I)*{I <- `I*`, decl <- `decl*`}:Tdecl_(I')*{}} {")"}} => MODULE_module(type*{type <- `type*`}, import*{import <- `import*`}, tag*{tag <- `tag*`}, global*{global <- `global*`}, mem*{mem <- `mem*`}, table*{table <- `table*`}, func*{func <- `func*`}, data*{data <- `data*`}, elem*{elem <- `elem*`}, start?{start <- `start?`}, export*{export <- `export*`}) -- if (I' = $concat_idctxt(I*{I <- `I*`})) -- Idctxt_ok: `|-%:OK`(I') -- if (type*{type <- `type*`} = $typesd(decl*{decl <- `decl*`})) @@ -11181,9 +11181,9 @@ grammar Tmodule : module -- if (export*{export <- `export*`} = $exportsd(decl*{decl <- `decl*`})) -- if $ordered(decl*{decl <- `decl*`}) -;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec +;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec grammar Tdecldots_(I : I) : (decl, idctxt)* - ;; ../../../../specification/wasm-3.0/6.3-text.modules.spectec + ;; ../../../../specification/wasm-3.0/6.4-text.modules.spectec prod{`` : (decl, idctxt)} [``]:Tdecl_(I)*{} => [``] ;; ../../../../specification/wasm-3.0/X.1-notation.syntax.spectec @@ -11194,14 +11194,14 @@ syntax B = nat ;; ../../../../specification/wasm-3.0/X.1-notation.syntax.spectec syntax sym = - | _FIRST{A_1 : A}(A_1 : A) + | _FIRST(A_1 : A) | _DOTS - | _LAST{A_n : A}(A_n : A) + | _LAST(A_n : A) ;; ../../../../specification/wasm-3.0/X.1-notation.syntax.spectec syntax symsplit = - | _FIRST{A_1 : A}(A_1 : A) - | _LAST{A_2 : A}(A_2 : A) + | _FIRST(A_1 : A) + | _LAST(A_2 : A) ;; ../../../../specification/wasm-3.0/X.1-notation.syntax.spectec syntax recorddots = () @@ -11209,9 +11209,9 @@ syntax recorddots = () ;; ../../../../specification/wasm-3.0/X.1-notation.syntax.spectec syntax record = { - FIELD_1{A_1 : A} A, - FIELD_2{A_2 : A} A, - `...`{recorddots : recorddots} recorddots + FIELD_1 A, + FIELD_2 A, + `...` recorddots } ;; ../../../../specification/wasm-3.0/X.1-notation.syntax.spectec @@ -11243,12 +11243,12 @@ rec { ;; ../../../../specification/wasm-3.0/X.2-notation.typing.spectec:20.1-20.83 relation NotationTypingInstrScheme: `%|-%:%`(context, instr*, instrtype) ;; ../../../../specification/wasm-3.0/X.2-notation.typing.spectec:22.1-23.38 - rule i32.add{C : context}: + rule `i32.add`{C : context}: `%|-%:%`(C, [BINOP_instr(I32_numtype, ADD_binop_)], `%->_%%`_instrtype(`%`_resulttype([I32_valtype I32_valtype]), [], `%`_resulttype([I32_valtype]))) ;; ../../../../specification/wasm-3.0/X.2-notation.typing.spectec:25.1-27.29 - rule global.get{C : context, x : idx, t : valtype, mut : mut}: - `%|-%:%`(C, [GLOBAL.GET_instr(x)], `%->_%%`_instrtype(`%`_resulttype([]), [], `%`_resulttype([t]))) + rule `global.get`{C : context, x : idx, t : valtype, mut : mut}: + `%|-%:%`(C, [`GLOBAL.GET`_instr(x)], `%->_%%`_instrtype(`%`_resulttype([]), [], `%`_resulttype([t]))) -- if (C.GLOBALS_context[x!`%`_idx.0] = `%%`_globaltype(?(mut), t)) ;; ../../../../specification/wasm-3.0/X.2-notation.typing.spectec:29.1-32.78 @@ -11277,11 +11277,11 @@ def $instrdots : instr* ;; ../../../../specification/wasm-3.0/X.3-notation.execution.spectec syntax label = - | `LABEL_%{%}`{n : n, `instr*` : instr*}(n : n, instr*{instr <- `instr*`} : instr*) + | `LABEL_%{%}`(n : n, `instr*` : instr*) ;; ../../../../specification/wasm-3.0/X.3-notation.execution.spectec syntax callframe = - | `FRAME_%{%}`{n : n, frame : frame}(n : n, frame : frame) + | `FRAME_%{%}`(n : n, frame : frame) ;; ../../../../specification/wasm-3.0/X.3-notation.execution.spectec def $allocX(syntax X, syntax Y, store : store, X : X, Y : Y) : (store, addr) @@ -11301,7 +11301,7 @@ def $allocXs(syntax X, syntax Y, store : store, X*, Y*) : (store, addr*) ;; ../../../../specification/wasm-3.0/X.4-notation.binary.spectec syntax symdots = - | `%`{i : nat}(i : nat) + | `%`(i : nat) -- if (i = 0) ;; ../../../../specification/wasm-3.0/X.4-notation.binary.spectec @@ -11312,7 +11312,7 @@ def $var(syntax X) : nat ;; ../../../../specification/wasm-3.0/X.4-notation.binary.spectec grammar Bvar(syntax X) : () ;; ../../../../specification/wasm-3.0/X.4-notation.binary.spectec - prod 0x00 => () + prod 0x00 => ((), ()).1 ;; ../../../../specification/wasm-3.0/X.4-notation.binary.spectec grammar Bsym : A @@ -11324,14 +11324,14 @@ grammar Bsym : A ;; ../../../../specification/wasm-3.0/X.4-notation.binary.spectec grammar Bsymsplit : () ;; ../../../../specification/wasm-3.0/X.4-notation.binary.spectec - prod{`` : ()} ``:Bvar(syntax B) => `` + prod{`` : ()} ``:Bvar(syntax B) => (``, ()).1 ;; ../../../../specification/wasm-3.0/X.4-notation.binary.spectec - prod{`` : ()} ``:Bvar(syntax B) => `` + prod{`` : ()} ``:Bvar(syntax B) => (``, ()).1 ;; ../../../../specification/wasm-3.0/X.5-notation.text.spectec grammar Tvar(syntax X) : () ;; ../../../../specification/wasm-3.0/X.5-notation.text.spectec - prod 0x00 => () + prod 0x00 => ((), ()).1 ;; ../../../../specification/wasm-3.0/X.5-notation.text.spectec grammar Tsym : A @@ -11343,9 +11343,9 @@ grammar Tsym : A ;; ../../../../specification/wasm-3.0/X.5-notation.text.spectec grammar Tsymsplit : () ;; ../../../../specification/wasm-3.0/X.5-notation.text.spectec - prod{`` : ()} ``:Tvar(syntax B) => `` + prod{`` : ()} ``:Tvar(syntax B) => (``, ()).1 ;; ../../../../specification/wasm-3.0/X.5-notation.text.spectec - prod{`` : ()} ``:Tvar(syntax B) => `` + prod{`` : ()} ``:Tvar(syntax B) => (``, ()).1 ;; ../../../../specification/wasm-3.0/X.5-notation.text.spectec syntax abbreviated = () diff --git a/spectec/test-frontend/test.spectec b/spectec/test-frontend/test.spectec index 14b46a4ec8..d170e52544 100644 --- a/spectec/test-frontend/test.spectec +++ b/spectec/test-frontend/test.spectec @@ -116,6 +116,9 @@ def $testemptyn6(eps 0) = 0 def $testemptyn6(0) = 0 def $testemptyn6("" 0) = 0 def $testemptyn6("" "" "" 0) = 0 +def $testemptyn6([] 0) = 0 +def $testemptyn6([""] 0) = 0 +def $testemptyn6(["" "" ""] 0) = 0 def $testemptyn6(([]) 0) = 0 def $testemptyn6(([""]) 0) = 0 def $testemptyn6((["" "" ""]) 0) = 0