src/Pure/Syntax/syntax_phases.ML
changeset 52190 c87b7f26e2c7
parent 52188 2da0033370a0
child 52210 0226035df99d
equal deleted inserted replaced
52184:d6627b50b131 52190:c87b7f26e2c7
   134   in typ [] NONE tm end;
   134   in typ [] NONE tm end;
   135 
   135 
   136 
   136 
   137 (* parsetree_to_ast *)
   137 (* parsetree_to_ast *)
   138 
   138 
   139 fun parsetree_to_ast ctxt raw trf parsetree =
   139 fun parsetree_to_ast ctxt trf parsetree =
   140   let
   140   let
   141     val reports = Unsynchronized.ref ([]: Position.report list);
   141     val reports = Unsynchronized.ref ([]: Position.report list);
   142     fun report pos = Position.store_reports reports [pos];
   142     fun report pos = Position.store_reports reports [pos];
   143 
   143 
   144     fun trans a args =
   144     fun trans a args =
   153 
   153 
   154     fun ast_of_position tok =
   154     fun ast_of_position tok =
   155       Ast.Variable (Term_Position.encode (Lexicon.pos_of_token tok));
   155       Ast.Variable (Term_Position.encode (Lexicon.pos_of_token tok));
   156 
   156 
   157     fun ast_of_dummy a tok =
   157     fun ast_of_dummy a tok =
   158       if raw then Ast.Constant a
   158       Ast.Appl [Ast.Constant "_constrain", Ast.Constant a, ast_of_position tok];
   159       else Ast.Appl [Ast.Constant "_constrain", Ast.Constant a, ast_of_position tok];
       
   160 
   159 
   161     fun asts_of_position c tok =
   160     fun asts_of_position c tok =
   162       if raw then asts_of_token tok
   161       [Ast.Appl [Ast.Constant c, ast_of (Parser.Tip tok), ast_of_position tok]]
   163       else [Ast.Appl [Ast.Constant c, ast_of (Parser.Tip tok), ast_of_position tok]]
       
   164 
   162 
   165     and asts_of (Parser.Node ("_class_name", [Parser.Tip tok])) =
   163     and asts_of (Parser.Node ("_class_name", [Parser.Tip tok])) =
   166           let
   164           let
   167             val pos = Lexicon.pos_of_token tok;
   165             val pos = Lexicon.pos_of_token tok;
   168             val c = Proof_Context.read_class ctxt (Lexicon.str_of_token tok)
   166             val c = Proof_Context.read_class ctxt (Lexicon.str_of_token tok)
   320           (("Ambiguous input" ^ Position.here (Position.reset_range pos) ^
   318           (("Ambiguous input" ^ Position.here (Position.reset_range pos) ^
   321             "\nproduces " ^ string_of_int len ^ " parse trees" ^
   319             "\nproduces " ^ string_of_int len ^ " parse trees" ^
   322             (if len <= limit then "" else " (" ^ string_of_int limit ^ " displayed)") ^ ":") ::
   320             (if len <= limit then "" else " (" ^ string_of_int limit ^ " displayed)") ^ ":") ::
   323             map (Pretty.string_of o Parser.pretty_parsetree) (take limit pts))];
   321             map (Pretty.string_of o Parser.pretty_parsetree) (take limit pts))];
   324 
   322 
   325   in (ambig_msgs, map (parsetree_to_ast ctxt raw ast_tr) pts) end;
   323   in (ambig_msgs, map (parsetree_to_ast ctxt ast_tr) pts) end;
   326 
   324 
   327 fun parse_tree ctxt root input =
   325 fun parse_tree ctxt root input =
   328   let
   326   let
   329     val syn = Proof_Context.syn_of ctxt;
   327     val syn = Proof_Context.syn_of ctxt;
   330     val tr = Syntax.parse_translation syn;
   328     val tr = Syntax.parse_translation syn;
   419 
   417 
   420 fun parse_ast_pattern ctxt (root, str) =
   418 fun parse_ast_pattern ctxt (root, str) =
   421   let
   419   let
   422     val syn = Proof_Context.syn_of ctxt;
   420     val syn = Proof_Context.syn_of ctxt;
   423 
   421 
   424     fun constify (ast as Ast.Constant _) = ast
   422     val reports = Unsynchronized.ref ([]: Position.report list);
   425       | constify (ast as Ast.Variable x) =
   423     fun report ps = Position.store_reports reports ps;
       
   424 
       
   425     fun decode_const ps c = (report ps (markup_entity ctxt) c; Ast.Constant c);
       
   426     fun decode_var ps x = (report ps (fn () => [Markup.name x Markup.free]) (); Ast.Variable x);
       
   427     fun decode_appl ps asts = Ast.Appl (map (decode ps) asts)
       
   428     and decode ps (Ast.Constant c) = decode_const ps c
       
   429       | decode ps (Ast.Variable x) =
   426           if is_some (Syntax.lookup_const syn x) orelse Long_Name.is_qualified x
   430           if is_some (Syntax.lookup_const syn x) orelse Long_Name.is_qualified x
   427           then Ast.Constant x
   431           then decode_const ps x
   428           else ast
   432           else decode_var ps x
   429       | constify (Ast.Appl asts) = Ast.Appl (map constify asts);
   433       | decode ps (Ast.Appl (asts as (Ast.Constant c :: ast :: Ast.Variable x :: args))) =
       
   434           if member (op =) Term_Position.markers c then
       
   435             (case Term_Position.decode x of
       
   436               SOME p => Ast.mk_appl (decode (p :: ps) ast) (map (decode ps) args)
       
   437             | NONE => decode_appl ps asts)
       
   438           else decode_appl ps asts
       
   439       | decode ps (Ast.Appl asts) = decode_appl ps asts;
   430 
   440 
   431     val (syms, pos) = Syntax.read_token str;
   441     val (syms, pos) = Syntax.read_token str;
   432   in
   442     val ast =
   433     parse_asts ctxt true root (syms, pos)
   443       parse_asts ctxt true root (syms, pos)
   434     |> uncurry (report_result ctxt pos)
   444       |> uncurry (report_result ctxt pos)
   435     |> constify
   445       |> decode [];
   436   end;
   446     val _ = Context_Position.reports ctxt (! reports);
       
   447   in ast end;
   437 
   448 
   438 
   449 
   439 
   450 
   440 (** encode parse trees **)
   451 (** encode parse trees **)
   441 
   452 
   539       | mark Ts (t as t1 $ t2) =
   550       | mark Ts (t as t1 $ t2) =
   540           (if is_Const (Term.head_of t) orelse not (is_prop Ts t) then I else aprop)
   551           (if is_Const (Term.head_of t) orelse not (is_prop Ts t) then I else aprop)
   541             (mark Ts t1 $ mark Ts t2);
   552             (mark Ts t1 $ mark Ts t2);
   542   in mark [] tm end;
   553   in mark [] tm end;
   543 
   554 
   544 in
   555 fun prune_types ctxt tm =
   545 
   556   let
   546 fun term_to_ast idents is_syntax_const ctxt trf tm =
       
   547   let
       
   548     val show_types =
       
   549       Config.get ctxt show_types orelse Config.get ctxt show_sorts orelse
       
   550       Config.get ctxt show_all_types;
       
   551     val show_structs = Config.get ctxt show_structs;
       
   552     val show_free_types = Config.get ctxt show_free_types;
   557     val show_free_types = Config.get ctxt show_free_types;
   553     val show_all_types = Config.get ctxt show_all_types;
   558 
   554     val show_markup = Config.get ctxt show_markup;
   559     fun prune (t_seen as (Const _, _)) = t_seen
   555 
   560       | prune (t as Free (x, ty), seen) =
   556     val {structs, fixes} = idents;
       
   557 
       
   558     fun prune_typs (t_seen as (Const _, _)) = t_seen
       
   559       | prune_typs (t as Free (x, ty), seen) =
       
   560           if ty = dummyT then (t, seen)
   561           if ty = dummyT then (t, seen)
   561           else if not show_free_types orelse member (op aconv) seen t then (Syntax.free x, seen)
   562           else if not show_free_types orelse member (op aconv) seen t then (Syntax.free x, seen)
   562           else (t, t :: seen)
   563           else (t, t :: seen)
   563       | prune_typs (t as Var (xi, ty), seen) =
   564       | prune (t as Var (xi, ty), seen) =
   564           if ty = dummyT then (t, seen)
   565           if ty = dummyT then (t, seen)
   565           else if not show_free_types orelse member (op aconv) seen t then (Syntax.var xi, seen)
   566           else if not show_free_types orelse member (op aconv) seen t then (Syntax.var xi, seen)
   566           else (t, t :: seen)
   567           else (t, t :: seen)
   567       | prune_typs (t_seen as (Bound _, _)) = t_seen
   568       | prune (t_seen as (Bound _, _)) = t_seen
   568       | prune_typs (Abs (x, ty, t), seen) =
   569       | prune (Abs (x, ty, t), seen) =
   569           let val (t', seen') = prune_typs (t, seen);
   570           let val (t', seen') = prune (t, seen);
   570           in (Abs (x, ty, t'), seen') end
   571           in (Abs (x, ty, t'), seen') end
   571       | prune_typs (t1 $ t2, seen) =
   572       | prune (t1 $ t2, seen) =
   572           let
   573           let
   573             val (t1', seen') = prune_typs (t1, seen);
   574             val (t1', seen') = prune (t1, seen);
   574             val (t2', seen'') = prune_typs (t2, seen');
   575             val (t2', seen'') = prune (t2, seen');
   575           in (t1' $ t2', seen'') end;
   576           in (t1' $ t2', seen'') end;
   576 
   577   in #1 (prune (tm, [])) end;
   577     fun mark_atoms ((t as Const (c, _)) $ u) =
   578 
       
   579 fun mark_atoms {structs, fixes} is_syntax_const ctxt tm =
       
   580   let
       
   581     val show_structs = Config.get ctxt show_structs;
       
   582 
       
   583     fun mark ((t as Const (c, _)) $ u) =
   578           if member (op =) Pure_Thy.token_markers c
   584           if member (op =) Pure_Thy.token_markers c
   579           then t $ u else mark_atoms t $ mark_atoms u
   585           then t $ u else mark t $ mark u
   580       | mark_atoms (t $ u) = mark_atoms t $ mark_atoms u
   586       | mark (t $ u) = mark t $ mark u
   581       | mark_atoms (Abs (x, T, t)) = Abs (x, T, mark_atoms t)
   587       | mark (Abs (x, T, t)) = Abs (x, T, mark t)
   582       | mark_atoms (t as Const (c, T)) =
   588       | mark (t as Const (c, T)) =
   583           if is_syntax_const c then t
   589           if is_syntax_const c then t
   584           else Const (Lexicon.mark_const c, T)
   590           else Const (Lexicon.mark_const c, T)
   585       | mark_atoms (t as Free (x, T)) =
   591       | mark (t as Free (x, T)) =
   586           let val i = find_index (fn s => s = x) structs + 1 in
   592           let val i = find_index (fn s => s = x) structs + 1 in
   587             if i = 0 andalso member (op =) fixes x then
   593             if i = 0 andalso member (op =) fixes x then
   588               Const (Lexicon.mark_fixed x, T)
   594               Const (Lexicon.mark_fixed x, T)
   589             else if i = 1 andalso not show_structs then
   595             else if i = 1 andalso not show_structs then
   590               Syntax.const "_struct" $ Syntax.const "_indexdefault"
   596               Syntax.const "_struct" $ Syntax.const "_indexdefault"
   591             else Syntax.const "_free" $ t
   597             else Syntax.const "_free" $ t
   592           end
   598           end
   593       | mark_atoms (t as Var (xi, T)) =
   599       | mark (t as Var (xi, T)) =
   594           if xi = Syntax_Ext.dddot_indexname then Const ("_DDDOT", T)
   600           if xi = Syntax_Ext.dddot_indexname then Const ("_DDDOT", T)
   595           else Syntax.const "_var" $ t
   601           else Syntax.const "_var" $ t
   596       | mark_atoms a = a;
   602       | mark a = a;
       
   603   in mark tm end;
       
   604 
       
   605 in
       
   606 
       
   607 fun term_to_ast idents is_syntax_const ctxt trf tm =
       
   608   let
       
   609     val show_types = Config.get ctxt show_types orelse Config.get ctxt show_sorts;
       
   610     val show_markup = Config.get ctxt show_markup;
   597 
   611 
   598     fun ast_of tm =
   612     fun ast_of tm =
   599       (case strip_comb tm of
   613       (case strip_comb tm of
   600         (t as Abs _, ts) => Ast.mk_appl (ast_of (Syntax_Trans.abs_tr' ctxt t)) (map ast_of ts)
   614         (t as Abs _, ts) => Ast.mk_appl (ast_of (Syntax_Trans.abs_tr' ctxt t)) (map ast_of ts)
   601       | ((c as Const ("_free", _)), Free (x, T) :: ts) =>
   615       | ((c as Const ("_free", _)), Free (x, T) :: ts) =>
   608               if show_markup andalso not show_types orelse B <> dummyT then T
   622               if show_markup andalso not show_types orelse B <> dummyT then T
   609               else dummyT;
   623               else dummyT;
   610           in Ast.mk_appl (constrain (c $ Syntax.free x) X) (map ast_of ts) end
   624           in Ast.mk_appl (constrain (c $ Syntax.free x) X) (map ast_of ts) end
   611       | (Const ("_idtdummy", T), ts) =>
   625       | (Const ("_idtdummy", T), ts) =>
   612           Ast.mk_appl (constrain (Syntax.const "_idtdummy") T) (map ast_of ts)
   626           Ast.mk_appl (constrain (Syntax.const "_idtdummy") T) (map ast_of ts)
   613       | (const as Const (c, T), ts) =>
   627       | (const as Const (c, T), ts) => trans c T ts
   614           if show_all_types
       
   615           then Ast.mk_appl (constrain const T) (map ast_of ts)
       
   616           else trans c T ts
       
   617       | (t, ts) => Ast.mk_appl (simple_ast_of ctxt t) (map ast_of ts))
   628       | (t, ts) => Ast.mk_appl (simple_ast_of ctxt t) (map ast_of ts))
   618 
   629 
   619     and trans a T args = ast_of (trf a ctxt T args)
   630     and trans a T args = ast_of (trf a ctxt T args)
   620       handle Match => Ast.mk_appl (Ast.Constant a) (map ast_of args)
   631       handle Match => Ast.mk_appl (Ast.Constant a) (map ast_of args)
   621 
   632 
   625           ast_of_termT ctxt trf (term_of_typ ctxt T)]
   636           ast_of_termT ctxt trf (term_of_typ ctxt T)]
   626       else simple_ast_of ctxt t;
   637       else simple_ast_of ctxt t;
   627   in
   638   in
   628     tm
   639     tm
   629     |> mark_aprop
   640     |> mark_aprop
   630     |> show_types ? (#1 o prune_typs o rpair [])
   641     |> show_types ? prune_types ctxt
   631     |> mark_atoms
   642     |> mark_atoms idents is_syntax_const ctxt
   632     |> ast_of
   643     |> ast_of
   633   end;
   644   end;
   634 
   645 
   635 end;
   646 end;
   636 
   647 
   664 
   675 
   665 fun unparse_t t_to_ast prt_t markup ctxt t =
   676 fun unparse_t t_to_ast prt_t markup ctxt t =
   666   let
   677   let
   667     val show_markup = Config.get ctxt show_markup;
   678     val show_markup = Config.get ctxt show_markup;
   668     val show_sorts = Config.get ctxt show_sorts;
   679     val show_sorts = Config.get ctxt show_sorts;
   669     val show_types =
   680     val show_types = Config.get ctxt show_types orelse show_sorts;
   670       Config.get ctxt show_types orelse show_sorts orelse
       
   671       Config.get ctxt show_all_types;
       
   672 
   681 
   673     val syn = Proof_Context.syn_of ctxt;
   682     val syn = Proof_Context.syn_of ctxt;
   674     val prtabs = Syntax.prtabs syn;
   683     val prtabs = Syntax.prtabs syn;
   675     val trf = Syntax.print_ast_translation syn;
   684     val trf = Syntax.print_ast_translation syn;
   676 
   685