548 lines
18 KiB
OCaml
548 lines
18 KiB
OCaml
[@@@warning "-30"]
|
|
|
|
module I = AST
|
|
|
|
open Region
|
|
|
|
module SMap = Map.Make(String)
|
|
|
|
module O = struct
|
|
type type_name = string
|
|
type ast = {
|
|
types : type_decl list;
|
|
parameter : typed_var;
|
|
storage : typed_var;
|
|
operations : typed_var;
|
|
declarations : decl list;
|
|
prev : I.ast;
|
|
}
|
|
and typed_var = { name:string; ty:type_expr }
|
|
and type_decl = { name:string; ty:type_expr }
|
|
and decl = { name:string; ty:type_expr; value: expr }
|
|
and type_expr =
|
|
Prod of type_expr list
|
|
| Sum of (type_name * type_expr) list
|
|
| Record of (type_name * type_expr) list
|
|
| TypeApp of type_name * type_expr list
|
|
| Function of { args: type_expr list; ret: type_expr }
|
|
| Ref of type_expr
|
|
| Unit
|
|
| Lambda of {
|
|
parameters: type_expr SMap.t;
|
|
declarations: decl list;
|
|
instructions: instr list;
|
|
body: expr;
|
|
}
|
|
| TODO
|
|
and expr =
|
|
Binary of { operator: string; left: expr; right: expr }
|
|
| Variable of string
|
|
| UnitExpr
|
|
and instr =
|
|
Fail
|
|
end
|
|
|
|
(* open Sanity: *)
|
|
let (|>) v f = f v (* pipe f to v *)
|
|
let (@@) f v = f v (* apply f on v *)
|
|
let (@.) f g x = f (g x) (* compose *)
|
|
let map f l = List.rev (List.rev_map f l)
|
|
let fold_map f a l =
|
|
let f (acc, l) elem =
|
|
let acc', elem' = f acc elem
|
|
in acc', (elem' :: l) in
|
|
let last_acc, last_l = List.fold_left f (a, []) l
|
|
in last_acc, List.rev last_l
|
|
|
|
(* Simplify the AST *)
|
|
|
|
let s_nsepseq : ('a,'sep) Utils.nsepseq -> 'a list =
|
|
fun (first, rest) -> first :: (map snd rest)
|
|
|
|
let s_sepseq : ('a,'sep) Utils.sepseq -> 'a list =
|
|
function
|
|
None -> []
|
|
| Some nsepseq -> s_nsepseq nsepseq
|
|
|
|
let s_name {value=name; region} : string =
|
|
let _ = region in
|
|
name
|
|
|
|
let s_sum_type {value=sequence; region} : O.type_expr =
|
|
let _ = region in
|
|
let _todo = sequence in
|
|
(* Sum (List.map s_type_expr (s_nsepseq sequence)) *)
|
|
TODO
|
|
|
|
and s_record_type {value=(kwd_record, field_decls, kwd_end); region} : O.type_expr =
|
|
let _ = kwd_record,region,kwd_end in
|
|
let _todo = (* s_field_decls *) field_decls in
|
|
TODO
|
|
|
|
and s_type_app {value=node; region} : O.type_expr =
|
|
let _ = region in
|
|
let _todo = node in
|
|
TODO
|
|
(* let type_name, type_tuple = node in *)
|
|
(* s_var type_name; *)
|
|
(* s_type_tuple type_tuple *)
|
|
|
|
and s_par_type {value=node; region} : O.type_expr =
|
|
let _ = region in
|
|
let _todo = node in
|
|
TODO
|
|
|
|
and s_var {region; value=lexeme} : O.type_expr =
|
|
let _ = region in
|
|
let _todo = lexeme in
|
|
TODO
|
|
|
|
(* let lpar, type_expr, rpar = node in
|
|
s_token lpar "(";
|
|
s_type_expr type_expr;
|
|
s_token rpar ")"*)
|
|
|
|
(* I.{value=sequence; region} *)
|
|
(* (\* let _ = region in *\) *)
|
|
(* (\* Prod (List.map s_type_expr (s_nsepseq sequence)) *\) *)
|
|
|
|
let s_cartesian _x = O.TODO
|
|
let s_sum_type _x = O.TODO
|
|
and s_record_type _x = O.TODO
|
|
and s_type_app _x = O.TODO
|
|
and s_par_type _x = O.TODO
|
|
and s_var _x = O.TODO
|
|
|
|
|
|
and s_type_expr : I.type_expr -> O.type_expr = function
|
|
Prod cartesian -> s_cartesian cartesian
|
|
| Sum sum_type -> s_sum_type sum_type
|
|
| Record record_type -> s_record_type record_type
|
|
| TypeApp type_app -> s_type_app type_app
|
|
| ParType par_type -> s_par_type par_type
|
|
| TAlias type_alias -> s_var type_alias
|
|
|
|
|
|
(* let s_ast (ast : I.ast) : O.ast = *)
|
|
(* let I.{types;constants;parameter;storage;operations;lambdas;block;eof} = ast in *)
|
|
(* let _ = eof in *)
|
|
(* O.{ *)
|
|
(* types = List.map s_type_decl types; *)
|
|
(* parameter = s_parameter parameter; *)
|
|
(* storage = s_storage storage; *)
|
|
(* operations = s_operations operations; *)
|
|
(* declarations = List.append (List.map s_const_decl constants) *)
|
|
(* (List.map s_lambda_decl lambdas) *)
|
|
(* [s_main_block block]; *)
|
|
(* prev = ast *)
|
|
(* } *)
|
|
|
|
(* and s_type_decl I.{value={kwd_type;name;kwd_is;type_expr;terminator}; region} : O.type_decl = *)
|
|
(* let _ = kwd_type,kwd_is,terminator,region in *)
|
|
(* O.{ name = s_name name; ty = s_type_expr type_expr } *)
|
|
|
|
(* and s_parameter_decl I.{value={kwd_parameter;name;colon;param_type;terminator};region} : O.typed_var = *)
|
|
(* let _ = region in *)
|
|
(* O.{ name = s_name name; ty = s_type_expr param_type } *)
|
|
|
|
(* and s_storage_decl I.{value={kwd_storage; store_type; terminator}; region} : O.typed_var = *)
|
|
(* let _ = kwd_storage,terminator,region in *)
|
|
(* O.{ name = "storage"; ty = s_type_expr store_type } *)
|
|
|
|
(* and s_operations_decl I.{value={kwd_operations;op_type;terminator}; region} : O.typed_var = *)
|
|
(* let _ = kwd_operations,terminator,region in *)
|
|
(* O.{ name = "operations"; ty = s_type_expr op_type } *)
|
|
|
|
(* and s_const_decl I.{value={kwd_const;name;colon;vtype;equal;init;terminator}; region} : O.decl = *)
|
|
(* let _ = kwd_const,colon,equal,terminator in *)
|
|
(* O.{ name = s_name name; ty = s_type_expr vtype; value = s_expr init } *)
|
|
|
|
(* and s_lambda_decl : I.lambda_decl -> O.decl = function *)
|
|
(* FunDecl fun_decl -> s_fun_decl fun_decl *)
|
|
(* | ProcDecl proc_decl -> s_proc_decl proc_decl *)
|
|
|
|
(* and s_fun_decl I.{value={kwd_function;name;param;colon;ret_type;kwd_is;local_decls;block;kwd_with;return;terminator}; region} : O.decl = *)
|
|
(* let _ = kwd_function,colon,kwd_is,kwd_with,terminator in *)
|
|
(* O.{ *)
|
|
(* name = s_name name; *)
|
|
(* ty = Function { args = s_type_expr param; ret = s_type_expr ret_type }; *)
|
|
(* value = Lambda { *)
|
|
(* parameters = s_type_expr param; *)
|
|
(* declarations = List.map s_local_decls local_decls; *)
|
|
(* instructions = s_block block; *)
|
|
(* body = s_expr return *)
|
|
(* } *)
|
|
(* } *)
|
|
|
|
(* and s_proc_decl I.{value={kwd_procedure;name;param;kwd_is;local_decls;block;terminator}; region} = *)
|
|
(* let _ = kwd_procedure,kwd_is,terminator in *)
|
|
(* O.{ *)
|
|
(* name = s_name name; *)
|
|
(* ty = Function { args = s_type_expr param; ret = Unit }; *)
|
|
(* value = Lambda { *)
|
|
(* parameters = s_type_expr param; *)
|
|
(* declarations = List.map s_local_decls local_decls; *)
|
|
(* instructions = s_block block; *)
|
|
(* body = O.UnitExpr *)
|
|
(* } *)
|
|
(* } *)
|
|
|
|
|
|
|
|
|
|
|
|
(* let s_token region lexeme = *)
|
|
(* printf "%s: %s\n"(compact region) lexeme *)
|
|
|
|
(* and s_var {region; value=lexeme} = *)
|
|
(* printf "%s: Ident \"%s\"\n" (compact region) lexeme *)
|
|
|
|
(* and s_constr {region; value=lexeme} = *)
|
|
(* printf "%s: Constr \"%s\"\n" *)
|
|
(* (compact region) lexeme *)
|
|
|
|
(* and s_string {region; value=lexeme} = *)
|
|
(* printf "%s: String \"%s\"\n" *)
|
|
(* (compact region) lexeme *)
|
|
|
|
(* and s_bytes {region; value = lexeme, abstract} = *)
|
|
(* printf "%s: Bytes (\"%s\", \"0x%s\")\n" *)
|
|
(* (compact region) lexeme *)
|
|
(* (MBytes.to_hex abstract |> Hex.to_string) *)
|
|
|
|
(* and s_int {region; value = lexeme, abstract} = *)
|
|
(* printf "%s: Int (\"%s\", %s)\n" *)
|
|
(* (compact region) lexeme *)
|
|
(* (Z.to_string abstract) *)
|
|
|
|
(* and s_cartesian {value=sequence; _} = *)
|
|
(* s_nsepseq "*" s_type_expr sequence *)
|
|
|
|
(* and s_variant {value=node; _} = *)
|
|
(* let constr, kwd_of, cartesian = node in *)
|
|
(* s_constr constr; *)
|
|
(* s_token kwd_of "of"; *)
|
|
(* s_cartesian cartesian *)
|
|
|
|
(* and s_field_decls sequence = *)
|
|
(* s_nsepseq ";" s_field_decl sequence *)
|
|
|
|
(* and s_field_decl {value=node; _} = *)
|
|
(* let var, colon, type_expr = node in *)
|
|
(* s_var var; *)
|
|
(* s_token colon ":"; *)
|
|
(* s_type_expr type_expr *)
|
|
|
|
(* and s_type_tuple {value=node; _} = *)
|
|
(* let lpar, sequence, rpar = node in *)
|
|
(* s_token lpar "("; *)
|
|
(* s_nsepseq "," s_var sequence; *)
|
|
(* s_token rpar ")" *)
|
|
|
|
|
|
(* and s_parameters {value=node; _} = *)
|
|
(* let lpar, sequence, rpar = node in *)
|
|
(* s_token lpar "("; *)
|
|
(* s_nsepseq ";" s_param_decl sequence; *)
|
|
(* s_token rpar ")" *)
|
|
|
|
(* and s_param_decl = function *)
|
|
(* ParamConst param_const -> s_param_const param_const *)
|
|
(* | ParamVar param_var -> s_param_var param_var *)
|
|
|
|
(* and s_param_const {value=node; _} = *)
|
|
(* let kwd_const, variable, colon, type_expr = node in *)
|
|
(* s_token kwd_const "const"; *)
|
|
(* s_var variable; *)
|
|
(* s_token colon ":"; *)
|
|
(* s_type_expr type_expr *)
|
|
|
|
(* and s_param_var {value=node; _} = *)
|
|
(* let kwd_var, variable, colon, type_expr = node in *)
|
|
(* s_token kwd_var "var"; *)
|
|
(* s_var variable; *)
|
|
(* s_token colon ":"; *)
|
|
(* s_type_expr type_expr *)
|
|
|
|
(* and s_block {value=node; _} = *)
|
|
(* s_token node.opening "begin"; *)
|
|
(* s_instructions node.instr; *)
|
|
(* s_terminator node.terminator; *)
|
|
(* s_token node.close "end" *)
|
|
|
|
(* and s_local_decls sequence = *)
|
|
(* List.iter s_local_decl sequence *)
|
|
|
|
(* and s_local_decl = function *)
|
|
(* LocalLam decl -> s_lambda_decl decl *)
|
|
(* | LocalConst decl -> s_const_decl decl *)
|
|
(* | LocalVar decl -> s_var_decl decl *)
|
|
|
|
(* and s_var_decl {value={kwd_var;name;colon;vtype;ass;init;terminator}; region} = *)
|
|
|
|
|
|
(* and s_instructions {value=sequence; _} = *)
|
|
(* s_nsepseq ";" s_instruction sequence *)
|
|
|
|
(* and s_instruction = function *)
|
|
(* Single instr -> s_single_instr instr *)
|
|
(* | Block block -> s_block block *)
|
|
|
|
(* and s_single_instr = function *)
|
|
(* Cond {value; _} -> s_conditional value *)
|
|
(* | Match {value; _} -> s_match_instr value *)
|
|
(* | Ass instr -> s_ass_instr instr *)
|
|
(* | Loop loop -> s_loop loop *)
|
|
(* | ProcCall fun_call -> s_fun_call fun_call *)
|
|
(* | Null kwd_null -> s_token kwd_null "null" *)
|
|
(* | Fail {value; _} -> s_fail value *)
|
|
|
|
(* and s_fail (kwd_fail, expr) = *)
|
|
(* s_token kwd_fail "fail"; *)
|
|
(* s_expr expr *)
|
|
|
|
(* and s_conditional node ={kwd_if;test;kwd_then;ifso;kwd_else;ifnot} *)
|
|
|
|
|
|
(* and s_regionmatch_instr node ={kwd_match;expr;kwd_with;cases;kwd_end} *)
|
|
|
|
|
|
(* and s_region_cases {value=sequence; _} = *)
|
|
(* s_nsepseq "|" s_case sequence *)
|
|
|
|
(* and s_case {value=node; _} = *)
|
|
(* let pattern, arrow, instruction = node in *)
|
|
(* s_pattern pattern; *)
|
|
(* s_token arrow "->"; *)
|
|
(* s_instruction instruction *)
|
|
|
|
(* and s_ass_instr {value=node; _} = *)
|
|
(* let variable, ass, expr = node in *)
|
|
(* s_var variable; *)
|
|
(* s_token ass ":="; *)
|
|
(* s_expr expr *)
|
|
|
|
(* and s_loop = function *)
|
|
(* While while_loop -> s_while_loop while_loop *)
|
|
(* | For for_loop -> s_for_loop for_loop *)
|
|
|
|
(* and s_while_loop {value=node; _} = *)
|
|
(* let kwd_while, expr, block = node in *)
|
|
(* s_token kwd_while "while"; *)
|
|
(* s_expr expr; *)
|
|
(* s_block block *)
|
|
|
|
(* and s_for_loop = function *)
|
|
(* ForInt for_int -> s_for_int for_int *)
|
|
(* | ForCollect for_collect -> s_for_collect for_collect *)
|
|
|
|
(* and s_for_int ({value={kwd_for;ass;down;kwd_to;bound;step;block}; region} : for_int reg) = *)
|
|
|
|
|
|
(* and s_down = function *)
|
|
(* Some kwd_down -> s_token kwd_down "down" *)
|
|
(* | None -> () *)
|
|
|
|
(* and s_step = function *)
|
|
(* Some (kwd_step, expr) -> *)
|
|
(* s_token kwd_step "step"; *)
|
|
(* s_expr expr *)
|
|
(* | None -> () *)
|
|
|
|
(* and s_for_collect ({value=node; _} : for_collect reg) = *)
|
|
(* s_token node.kwd_for "for"; *)
|
|
(* s_var node.var; *)
|
|
(* s_bind_to node.bind_to; *)
|
|
(* s_token node.kwd_in "in"; *)
|
|
(* s_expr node.expr; *)
|
|
(* s_block node.block *)
|
|
|
|
(* and s_bind_to = function *)
|
|
(* Some (arrow, variable) -> *)
|
|
(* s_token arrow "->"; *)
|
|
(* s_var variable *)
|
|
(* | None -> () *)
|
|
|
|
(* and s_expr = function *)
|
|
(* Or {value = expr1, bool_or, expr2; _} -> *)
|
|
(* s_expr expr1; s_token bool_or "||"; s_expr expr2 *)
|
|
(* | And {value = expr1, bool_and, expr2; _} -> *)
|
|
(* s_expr expr1; s_token bool_and "&&"; s_expr expr2 *)
|
|
(* | Lt {value = expr1, lt, expr2; _} -> *)
|
|
(* s_expr expr1; s_token lt "<"; s_expr expr2 *)
|
|
(* | Leq {value = expr1, leq, expr2; _} -> *)
|
|
(* s_expr expr1; s_token leq "<="; s_expr expr2 *)
|
|
(* | Gt {value = expr1, gt, expr2; _} -> *)
|
|
(* s_expr expr1; s_token gt ">"; s_expr expr2 *)
|
|
(* | Geq {value = expr1, geq, expr2; _} -> *)
|
|
(* s_expr expr1; s_token geq ">="; s_expr expr2 *)
|
|
(* | Equal {value = expr1, equal, expr2; _} -> *)
|
|
(* s_expr expr1; s_token equal "="; s_expr expr2 *)
|
|
(* | Neq {value = expr1, neq, expr2; _} -> *)
|
|
(* s_expr expr1; s_token neq "=/="; s_expr expr2 *)
|
|
(* | Cat {value = expr1, cat, expr2; _} -> *)
|
|
(* s_expr expr1; s_token cat "^"; s_expr expr2 *)
|
|
(* | Cons {value = expr1, cons, expr2; _} -> *)
|
|
(* s_expr expr1; s_token cons "<:"; s_expr expr2 *)
|
|
(* | Add {value = expr1, add, expr2; _} -> *)
|
|
(* s_expr expr1; s_token add "+"; s_expr expr2 *)
|
|
(* | Sub {value = expr1, sub, expr2; _} -> *)
|
|
(* s_expr expr1; s_token sub "-"; s_expr expr2 *)
|
|
(* | Mult {value = expr1, mult, expr2; _} -> *)
|
|
(* s_expr expr1; s_token mult "*"; s_expr expr2 *)
|
|
(* | Div {value = expr1, div, expr2; _} -> *)
|
|
(* s_expr expr1; s_token div "/"; s_expr expr2 *)
|
|
(* | Mod {value = expr1, kwd_mod, expr2; _} -> *)
|
|
(* s_expr expr1; s_token kwd_mod "mod"; s_expr expr2 *)
|
|
(* | Neg {value = minus, expr; _} -> *)
|
|
(* s_token minus "-"; s_expr expr *)
|
|
(* | Not {value = kwd_not, expr; _} -> *)
|
|
(* s_token kwd_not "not"; s_expr expr *)
|
|
(* | Int i -> s_int i *)
|
|
(* | Var var -> s_var var *)
|
|
(* | String s -> s_string s *)
|
|
(* | Bytes b -> s_bytes b *)
|
|
(* | False region -> s_token region "False" *)
|
|
(* | True region -> s_token region "True" *)
|
|
(* | Unit region -> s_token region "Unit" *)
|
|
(* | Tuple tuple -> s_tuple tuple *)
|
|
(* | List list -> s_list list *)
|
|
(* | EmptyList elist -> s_empty_list elist *)
|
|
(* | Set set -> s_set set *)
|
|
(* | EmptySet eset -> s_empty_set eset *)
|
|
(* | NoneExpr nexpr -> s_none_expr nexpr *)
|
|
(* | FunCall fun_call -> s_fun_call fun_call *)
|
|
(* | ConstrApp capp -> s_constr_app capp *)
|
|
(* | SomeApp sapp -> s_some_app sapp *)
|
|
(* | MapLookUp lookup -> s_map_lookup lookup *)
|
|
(* | ParExpr pexpr -> s_par_expr pexpr *)
|
|
|
|
(* and s_tuple {value=node; _} = *)
|
|
(* let lpar, sequence, rpar = node in *)
|
|
(* s_token lpar "("; *)
|
|
(* s_nsepseq "," s_expr sequence; *)
|
|
(* s_token rpar ")" *)
|
|
|
|
(* and s_list {value=node; _} = *)
|
|
(* let lbra, sequence, rbra = node in *)
|
|
(* s_token lbra "["; *)
|
|
(* s_nsepseq "," s_expr sequence; *)
|
|
(* s_token rbra "]" *)
|
|
|
|
(* and s_empty_list {value=node; _} = *)
|
|
(* let lpar, (lbracket, rbracket, colon, type_expr), rpar = node in *)
|
|
(* s_token lpar "("; *)
|
|
(* s_token lbracket "["; *)
|
|
(* s_token rbracket "]"; *)
|
|
(* s_token colon ":"; *)
|
|
(* s_type_expr type_expr; *)
|
|
(* s_token rpar ")" *)
|
|
|
|
(* and s_set {value=node; _} = *)
|
|
(* let lbrace, sequence, rbrace = node in *)
|
|
(* s_token lbrace "{"; *)
|
|
(* s_nsepseq "," s_expr sequence; *)
|
|
(* s_token rbrace "}" *)
|
|
|
|
(* and s_empty_set {value=node; _} = *)
|
|
(* let lpar, (lbrace, rbrace, colon, type_expr), rpar = node in *)
|
|
(* s_token lpar "("; *)
|
|
(* s_token lbrace "{"; *)
|
|
(* s_token rbrace "}"; *)
|
|
(* s_token colon ":"; *)
|
|
(* s_type_expr type_expr; *)
|
|
(* s_token rpar ")" *)
|
|
|
|
(* and s_none_expr {value=node; _} = *)
|
|
(* let lpar, (c_None, colon, type_expr), rpar = node in *)
|
|
(* s_token lpar "("; *)
|
|
(* s_token c_None "None"; *)
|
|
(* s_token colon ":"; *)
|
|
(* s_type_expr type_expr; *)
|
|
(* s_token rpar ")" *)
|
|
|
|
(* and s_fun_call {value=node; _} = *)
|
|
(* let fun_name, arguments = node in *)
|
|
(* s_var fun_name; *)
|
|
(* s_tuple arguments *)
|
|
|
|
(* and s_constr_app {value=node; _} = *)
|
|
(* let constr, arguments = node in *)
|
|
(* s_constr constr; *)
|
|
(* s_tuple arguments *)
|
|
|
|
(* and s_some_app {value=node; _} = *)
|
|
(* let c_Some, arguments = node in *)
|
|
(* s_token c_Some "Some"; *)
|
|
(* s_tuple arguments *)
|
|
|
|
(* and s_map_lookup {value=node; _} = *)
|
|
(* let {value = lbracket, expr, rbracket; _} = node.index in *)
|
|
(* s_var node.map_name; *)
|
|
(* s_token node.selector "."; *)
|
|
(* s_token lbracket "["; *)
|
|
(* s_expr expr; *)
|
|
(* s_token rbracket "]" *)
|
|
|
|
(* and s_par_expr {value=node; _} = *)
|
|
(* let lpar, expr, rpar = node in *)
|
|
(* s_token lpar "("; *)
|
|
(* s_expr expr; *)
|
|
(* s_token rpar ")" *)
|
|
|
|
(* and s_pattern {value=sequence; _} = *)
|
|
(* s_nsepseq "<:" s_core_pattern sequence *)
|
|
|
|
(* and s_core_pattern = function *)
|
|
(* PVar var -> s_var var *)
|
|
(* | PWild wild -> s_token wild "_" *)
|
|
(* | PInt i -> s_int i *)
|
|
(* | PBytes b -> s_bytes b *)
|
|
(* | PString s -> s_string s *)
|
|
(* | PUnit region -> s_token region "Unit" *)
|
|
(* | PFalse region -> s_token region "False" *)
|
|
(* | PTrue region -> s_token region "True" *)
|
|
(* | PNone region -> s_token region "None" *)
|
|
(* | PSome psome -> s_psome psome *)
|
|
(* | PList pattern -> s_list_pattern pattern *)
|
|
(* | PTuple ptuple -> s_ptuple ptuple *)
|
|
|
|
(* and s_psome {value=node; _} = *)
|
|
(* let c_Some, patterns = node in *)
|
|
(* s_token c_Some "Some"; *)
|
|
(* s_patterns patterns *)
|
|
|
|
(* and s_patterns {value=node; _} = *)
|
|
(* let lpar, core_pattern, rpar = node in *)
|
|
(* s_token lpar "("; *)
|
|
(* s_core_pattern core_pattern; *)
|
|
(* s_token rpar ")" *)
|
|
|
|
(* and s_list_pattern = function *)
|
|
(* Sugar sugar -> s_sugar sugar *)
|
|
(* | Raw raw -> s_raw raw *)
|
|
|
|
(* and s_sugar {value=node; _} = *)
|
|
(* let lbracket, sequence, rbracket = node in *)
|
|
(* s_token lbracket "["; *)
|
|
(* s_sepseq "," s_core_pattern sequence; *)
|
|
(* s_token rbracket "]" *)
|
|
|
|
(* and s_raw {value=node; _} = *)
|
|
(* let lpar, (core_pattern, cons, pattern), rpar = node in *)
|
|
(* s_token lpar "("; *)
|
|
(* s_core_pattern core_pattern; *)
|
|
(* s_token cons "<:"; *)
|
|
(* s_pattern pattern; *)
|
|
(* s_token rpar ")" *)
|
|
|
|
(* and s_ptuple {value=node; _} = *)
|
|
(* let lpar, sequence, rpar = node in *)
|
|
(* s_token lpar "("; *)
|
|
(* s_nsepseq "," s_core_pattern sequence; *)
|
|
(* s_token rpar ")" *)
|
|
|
|
(* and s_terminator = function *)
|
|
(* Some semi -> s_token semi ";" *)
|
|
(* | None -> () *)
|