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} |