#line 1094 "/home/travis/build/felix-lang/felix/src/packages/strings.fdoc"
  
  class Regdef {
    union regex =
    | Alts of list[regex]
    | Seqs of list[regex]
    | Rpt of regex * int * int
    | Charset of string
    | String of string
    | Group of regex
    | Perl of string
    ;
  
    private fun prec: regex -> int =
    | Perl _ => 3
    | Alts _ => 3
    | Seqs _ => 2
    | String _ => 2
    | Rpt _ => 1
    | Charset _ => 0
    | Group _ => 0
    ;
  
    private fun hex_digit (i:int)=>
      if i<10 then string (char (ord (char "0") + i))
      else string (char (ord (char "A") + i - 10))
      endif
    ;
    private fun hex2(c:char)=>
      let i = ord c in
      "\\x" + hex_digit ( i / 16 ) + hex_digit ( i % 16 )
    ;
    private fun charset_quote(c:char)=>
      if c in "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstvuwxyz" then string c
      else hex2 c
      endif
    ;
  
    private fun hex(s:string when len s > 0uz)= {
      var r = "";
      for var i in 0uz upto len s - 1uz do
        r += charset_quote s.[i];
      done
      return r;
    }
  
    fun ngrp (s:string)=> "(?:"+s+")";
    private fun cngrp (s:string, op: int, ip: int) => if ip > op then ngrp (s) else s endif;
  
    fun render: regex -> string =
    | Alts rs => fold_left
     (fun (acc:string) (elt:regex)=>
       (if acc == "" then "" else acc + "|" endif) + (render elt))
      "" rs
    | Seqs rs => fold_left
      (fun (acc:string) (elt:regex)=> acc + cngrp(render elt,2,prec elt))
      "" rs
    | Rpt (r,i,x) =>
      if i == 0 and x == -1 then ngrp (render r) + "*"
      elif i == 1 and x == -1 then ngrp (render r) + "+"
      elif i == 0 and x == 1 then ngrp (render r) + "?"
      else
        cngrp(render r,1,prec r) + "{" + str i + "," + if x < 0 then "" else str x endif + "}"
      endif
  
    | String s => hex(s)
    | Charset s => "[" + hex s + "]"
    | Group r => "(" + render r + ")"
    | Perl s => s
    ;
  }