src/Pure/Syntax/printer.ML
changeset 69079 fedacfd60fdb
parent 69078 a5e904112ea9
child 69575 f77cc54f6d47
equal deleted inserted replaced
69078:a5e904112ea9 69079:fedacfd60fdb
   109 fun is_arg (Arg _) = true
   109 fun is_arg (Arg _) = true
   110   | is_arg (TypArg _) = true
   110   | is_arg (TypArg _) = true
   111   | is_arg _ = false;
   111   | is_arg _ = false;
   112 
   112 
   113 fun is_space str = forall_string (fn s => s = " ") str;
   113 fun is_space str = forall_string (fn s => s = " ") str;
   114 val is_delim = not o is_space;
   114 
   115 
   115 fun clean symbs = symbs |> maps
   116 fun is_delimiter (String (_, d)) = is_delim d
   116   (fn Block (_, body) => clean body
   117   | is_delimiter _ = false;
   117     | symb as String (_, s) => if is_space s then [] else [symb]
   118 
   118     | symb => if is_arg symb then [symb] else []);
   119 fun flatten (Block (_, symbs)) = maps flatten symbs
       
   120   | flatten symb = [symb];
       
   121 
   119 
   122 in
   120 in
   123 
   121 
   124 fun get_prefix prtabs c =
   122 fun get_prefix prtabs c =
   125   lookup_default prtabs c
   123   lookup_default prtabs c
   126   |> get_first (fn (symbs, _, _) =>
   124   |> get_first (fn (symbs, _, _) =>
   127       (case filter (is_arg orf is_delimiter) (maps flatten symbs) of
   125       (case clean symbs of
   128         String (_, d) :: rest => if forall is_arg rest then SOME d else NONE
   126         String (_, d) :: rest => if forall is_arg rest then SOME d else NONE
   129       | _ => NONE));
   127       | _ => NONE));
   130 
   128 
   131 fun get_binder prtabs c =
   129 fun get_binder prtabs c =
   132   lookup_default prtabs (Mixfix.binder_name c)
   130   lookup_default prtabs (Mixfix.binder_name c)
   133   |> get_first (fn (symbs, _, _) =>
   131   |> get_first (fn (symbs, _, _) =>
   134       (case maps flatten symbs of
   132       (case clean symbs of
   135         String (_, d) :: _ => if is_delim d then SOME d else NONE
   133         String (_, d) :: _ => SOME d
   136       | _ => NONE));
   134       | _ => NONE));
   137 
   135 
   138 fun get_infix prtabs c =
   136 fun get_infix prtabs c =
   139   lookup_default prtabs c
   137   lookup_default prtabs c
   140   |> map_filter (fn (symbs, _, p) =>
   138   |> map_filter (fn (symbs, _, p) =>
   141       (case symbs of
   139       (case clean symbs of
   142         [Block (_, [Arg p1, String (_, s), String (_, d), Break _, Arg p2])] =>
   140         [Arg p1, String (_, d), Arg p2] => SOME (p1, p2, d, p)
   143           if is_space s andalso is_delim d then SOME (p1, p2, d, p) else NONE
   141       | [TypArg p1, String (_, d), TypArg p2] => SOME (p1, p2, d, p)
   144       | [Block (_, [TypArg p1, String (_, s), String (_, d), Break _, TypArg p2])] =>
       
   145           if is_space s andalso is_delim d then SOME (p1, p2, d, p) else NONE
       
   146       | _ => NONE))
   142       | _ => NONE))
   147   |> get_first (fn (p1, p2, d, p) =>
   143   |> get_first (fn (p1, p2, d, p) =>
   148       if p1 = p + 1 andalso p2 = p + 1 then SOME {assoc = No_Assoc, delim = d, pri = p}
   144       if p1 = p + 1 andalso p2 = p + 1 then SOME {assoc = No_Assoc, delim = d, pri = p}
   149       else if p1 = p andalso p2 = p + 1 then SOME {assoc = Left_Assoc, delim = d, pri = p}
   145       else if p1 = p andalso p2 = p + 1 then SOME {assoc = Left_Assoc, delim = d, pri = p}
   150       else if p1 = p + 1 andalso p2 = p then SOME {assoc = Right_Assoc, delim = d, pri = p}
   146       else if p1 = p + 1 andalso p2 = p then SOME {assoc = Right_Assoc, delim = d, pri = p}