package comby-kernel
A match engine for structural code search and replace that supports ~every language
Install
Dune Dependency
Authors
Maintainers
Sources
comby-kernel.1.7.0.tar.gz
md5=ee6556d8bd9b25ed0445ebe23862e48a
sha512=e6386c8ce5ef14bbcab2b0ead5b1edc39375438f56330d5f02e81e467afe6623a7e299f97f26008d77bbc62850c6dc63a7cbe5b81671b5183ff3adeee5946bb3
doc/src/comby-kernel.matchers/rule.ml.html
Source file rule.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
open Core_kernel open Vangstrom open Types.Ast module Make (Metasyntax : Types.Metasyntax.S) (External : Types.External.S) = struct module Template = Template.Make (Metasyntax) (External) let is_whitespace = function | ' ' | '\t' | '\r' | '\n' -> true | _ -> false let spaces = take_while is_whitespace let spaces1 = satisfy is_whitespace *> take_while is_whitespace let alphanum = satisfy (function | 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' -> true | _ -> false) let to_atom s = match Template.parse s with | [] -> String "" | [ Constant c ] -> String c | t -> Template t (** Interpret escape sequences inside quotes *) let char_token_s = (char '\\' *> any_char >>| function | 'r' -> Char.to_string '\r' | 'n' -> Char.to_string '\n' | 't' -> Char.to_string '\t' | '\\' -> Char.to_string '\\' | c -> Format.sprintf {|\%c|} c) <|> (lift String.of_char any_char) (** With escape sequences *) let quote s = lift2 (fun _ v -> String.concat v) (string s) (many_till char_token_s (string s)) let raw s = lift2 (fun _ v -> String.of_char_list v) (string s) (many_till any_char (string s)) let quoted_parser = choice ~failure_msg:"could not parse quoted value" [ quote {|"|}; quote {|'|}; raw {|`|} ] let map_special s = if String.is_prefix s ~prefix:"~" then Template (Template.parse (Format.sprintf ":[%s]" s)) else if String.equal s "_" then Template (Template.parse ":[_]") else to_atom s let up_to p = many1 (not_followed_by p *> any_char) let atom_up_to_spaces () = choice [ (lift to_atom quoted_parser) ; lift (fun v -> to_atom (String.of_char_list v)) (up_to spaces1) ] let atom_up_to_terminal () = choice [ (lift to_atom quoted_parser) ; (lift (fun v -> to_atom (String.of_char_list v)) (up_to (choice [ spaces1 *> return () ; char ',' *> return () ; char '}' *> return () ]))) ] let antecedent_parser () = choice ~failure_msg:"could not parse LHS of ->" [ (lift to_atom quoted_parser) ; (lift (fun v -> map_special (String.of_char_list v)) (up_to (spaces *> string Syntax.arrow))) ] let value_to_open_brace () = choice [ (lift to_atom quoted_parser) ; (lift (fun v -> to_atom (String.of_char_list v)) (up_to (spaces *> char '{'))) ] let value_to_comma () = choice [ (lift to_atom quoted_parser) ; (lift (fun v -> to_atom (String.of_char_list v)) (up_to (spaces *> char ','))) ] let rewrite_consequent_parser () = choice [ (lift to_atom quoted_parser) ; (lift (fun v -> to_atom (String.of_char_list v)) (up_to (spaces *> char '}'))) ] let operator_parser = choice [ string Syntax.equal ; string Syntax.not_equal ] let make_equality_expression left operator right = if String.equal operator Syntax.equal then Equal (left, right) else Not_equal (left, right) let optional_trailing c = option () (skip (Char.equal c)) let option_parser = lift (fun _ -> Option "nested") (spaces *> (string Syntax.option_nested) <* spaces) let true' = lift (fun _ -> True) (spaces *> string Syntax.true' <* spaces) let false' = lift (fun _ -> False) (spaces *> string Syntax.false' <* spaces) (** <atom> [==, !=] <atom> *) let compare_parser = lift3 make_equality_expression (spaces *> atom_up_to_spaces ()) (spaces *> operator_parser) (spaces *> atom_up_to_terminal ()) <* spaces let make_rewrite_expression atom match_template rewrite_template = Rewrite (atom, (match_template, rewrite_template)) (** rewrite <atom> { <atom> -> <atom> } *) let rewrite_pattern_parser = lift3 make_rewrite_expression (string Syntax.start_rewrite_pattern *> spaces*> value_to_open_brace () <* spaces <* char '{' <* spaces) (antecedent_parser () <* spaces <* string Syntax.arrow <* spaces) (rewrite_consequent_parser () <* spaces <* char '}') (** <atom> -> atom [, <expr>], [,] *) let match_arrow_parser expression_parser = both (antecedent_parser () <* spaces <* string Syntax.arrow <* spaces) (sep_by (char ',') expression_parser <* spaces <* optional_trailing ',' <* spaces) (** [|] <match_arrow> *) let first_case_parser expression_parser = spaces *> option () (Omega_parser_helper.ignore @@ string Syntax.pipe_operator *> spaces) *> match_arrow_parser expression_parser (** | <match_arrow> *) let case_parser expression_parser = spaces *> string Syntax.pipe_operator *> spaces *> match_arrow_parser expression_parser (** [|] <match_arrow> | <match_arrow> *) let case_block expression_parser = first_case_parser expression_parser >>= fun case -> many (case_parser expression_parser) >>= fun cases -> return (case :: cases) (** match <atom> { <case_parser> } *) let match_pattern_parser expression_parser = lift3 (fun _ atom cases -> Match (atom, cases)) (string Syntax.start_match_pattern *> spaces) (value_to_open_brace () <* spaces <* char '{' <* spaces) (case_block expression_parser <* char '}' <* spaces) let expression_parser = fix (fun expression_parser -> choice ~failure_msg:"could not parse expression" [ match_pattern_parser expression_parser ; rewrite_pattern_parser ; compare_parser ; true' ; false' ; option_parser ]) (** where <expression> [,] *) let parse = spaces *> string Syntax.rule_prefix *> spaces1 *> sep_by1 (spaces *> char ',' <* spaces) expression_parser <* optional_trailing ',' <* spaces let create rule = match parse_string ~consume:All (parse <* end_of_input) rule with | Ok rule -> Ok rule | Error error -> Or_error.error_string error end type t = Types.Rule.t [@@deriving sexp] let create ?(metasyntax = Metasyntax.default_metasyntax) ?(external_handler = External.default_external) rule = let (module Metasyntax) = Metasyntax.create metasyntax in let module External = struct let handler = external_handler end in let (module Rule : Types.Rule.S) = (module (Make (Metasyntax) (External))) in Rule.create rule type options = { nested : bool } let options rule = List.fold rule ~init:{ nested = false } ~f:(fun acc -> function | Types.Ast.Option name when String.(name = Syntax.option_nested) -> { nested = true } | _ -> acc)
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>