src/Pure/ML/ml_antiquotations.ML
changeset 74562 8403bd51f8b1
parent 74559 9189d949abb9
child 74563 042041c0ebeb
equal deleted inserted replaced
74561:8e6c973003c8 74562:8403bd51f8b1
   219    (Scan.succeed "ML_Antiquotations.dest_judgment ML_context"));
   219    (Scan.succeed "ML_Antiquotations.dest_judgment ML_context"));
   220 
   220 
   221 
   221 
   222 (* type/term constructors *)
   222 (* type/term constructors *)
   223 
   223 
   224 fun read_embedded ctxt keywords src parse =
   224 fun read_embedded ctxt keywords parse src =
   225   let
   225   Token.syntax (Scan.lift Args.embedded_input) src ctxt
   226     val input = #1 (Token.syntax (Scan.lift Args.embedded_input) src ctxt);
   226   |> #1 |> Token.read_embedded ctxt keywords parse;
   227     val toks = input
       
   228       |> Input.source_explode
       
   229       |> Token.tokenize keywords {strict = true}
       
   230       |> filter Token.is_proper;
       
   231     val _ = Context_Position.reports_text ctxt (maps (Token.reports keywords) toks);
       
   232   in
       
   233     (case Scan.read Token.stopper parse toks of
       
   234       SOME res => res
       
   235     | NONE => error ("Bad input" ^ Position.here (Input.pos_of input)))
       
   236   end;
       
   237 
       
   238 val parse_embedded_ml =
       
   239   Parse.embedded_input >> ML_Lex.read_source ||
       
   240   Parse.control >> (ML_Lex.read_symbols o Antiquote.control_symbols);
       
   241 
       
   242 val parse_embedded_ml_underscore =
       
   243   Parse.input Parse.underscore >> ML_Lex.read_source || parse_embedded_ml;
       
   244 
       
   245 fun ml_args ctxt args =
       
   246   let
       
   247     val (decls, ctxt') = fold_map (ML_Context.expand_antiquotes) args ctxt;
       
   248     fun decl' ctxt'' = map (fn decl => decl ctxt'') decls;
       
   249   in (decl', ctxt') end
       
   250 
   227 
   251 local
   228 local
   252 
   229 
   253 val keywords = Keyword.add_minor_keywords ["for", "=>"] Keyword.empty_keywords;
   230 val keywords = Keyword.add_minor_keywords ["for", "=>"] Keyword.empty_keywords;
   254 
   231 
   255 val parse_name = Parse.input Parse.name;
   232 val parse_name = Parse.input Parse.name;
   256 
   233 
   257 val parse_args = Scan.repeat parse_embedded_ml_underscore;
   234 val parse_args = Scan.repeat Parse.embedded_ml_underscore;
   258 val parse_for_args = Scan.optional (Parse.$$$ "for" |-- Parse.!!! parse_args) [];
   235 val parse_for_args = Scan.optional (Parse.$$$ "for" |-- Parse.!!! parse_args) [];
   259 
   236 
   260 fun parse_body b =
   237 fun parse_body b =
   261   if b then Parse.$$$ "=>" |-- Parse.!!! Parse.embedded_input >> (ML_Lex.read_source #> single)
   238   if b then Parse.$$$ "=>" |-- Parse.!!! Parse.embedded_input >> (ML_Lex.read_source #> single)
   262   else Scan.succeed [];
   239   else Scan.succeed [];
   277 
   254 
   278 fun type_antiquotation binding {function} =
   255 fun type_antiquotation binding {function} =
   279   ML_Context.add_antiquotation binding true
   256   ML_Context.add_antiquotation binding true
   280     (fn range => fn src => fn ctxt =>
   257     (fn range => fn src => fn ctxt =>
   281       let
   258       let
   282         val ((s, type_args), fn_body) =
   259         val ((s, type_args), fn_body) = src
   283           read_embedded ctxt keywords src (parse_name -- parse_args -- parse_body function);
   260           |> read_embedded ctxt keywords (parse_name -- parse_args -- parse_body function);
   284         val pos = Input.pos_of s;
   261         val pos = Input.pos_of s;
   285 
   262 
   286         val Type (c, Ts) =
   263         val Type (c, Ts) =
   287           Proof_Context.read_type_name {proper = true, strict = true} ctxt
   264           Proof_Context.read_type_name {proper = true, strict = true} ctxt
   288             (Syntax.implode_input s);
   265             (Syntax.implode_input s);
   290         val _ =
   267         val _ =
   291           length type_args = n orelse
   268           length type_args = n orelse
   292             error ("Type constructor " ^ quote (Proof_Context.markup_type ctxt c) ^
   269             error ("Type constructor " ^ quote (Proof_Context.markup_type ctxt c) ^
   293               " takes " ^ string_of_int n ^ " argument(s)" ^ Position.here pos);
   270               " takes " ^ string_of_int n ^ " argument(s)" ^ Position.here pos);
   294 
   271 
   295         val (decls1, ctxt1) = ml_args ctxt type_args;
   272         val (decls1, ctxt1) = ML_Context.expand_antiquotes_list type_args ctxt;
   296         val (decls2, ctxt2) = ml_args ctxt1 fn_body;
   273         val (decls2, ctxt2) = ML_Context.expand_antiquotes_list fn_body ctxt1;
   297         fun decl' ctxt' =
   274         fun decl' ctxt' =
   298           let
   275           let
   299             val (ml_args_env, ml_args_body) = split_list (decls1 ctxt');
   276             val (ml_args_env, ml_args_body) = split_list (decls1 ctxt');
   300             val (ml_fn_env, ml_fn_body) = split_list (decls2 ctxt');
   277             val (ml_fn_env, ml_fn_body) = split_list (decls2 ctxt');
   301             val ml1 =
   278             val ml1 =
   312 
   289 
   313 fun const_antiquotation binding {pattern, function} =
   290 fun const_antiquotation binding {pattern, function} =
   314   ML_Context.add_antiquotation binding true
   291   ML_Context.add_antiquotation binding true
   315     (fn range => fn src => fn ctxt =>
   292     (fn range => fn src => fn ctxt =>
   316       let
   293       let
   317         val (((s, type_args), term_args), fn_body) =
   294         val (((s, type_args), term_args), fn_body) = src
   318           read_embedded ctxt keywords src
   295           |> read_embedded ctxt keywords
   319             (parse_name -- parse_args -- parse_for_args -- parse_body function);
   296               (parse_name -- parse_args -- parse_for_args -- parse_body function);
   320 
   297 
   321         val Const (c, T) =
   298         val Const (c, T) =
   322           Proof_Context.read_const {proper = true, strict = true} ctxt
   299           Proof_Context.read_const {proper = true, strict = true} ctxt
   323             (Syntax.implode_input s);
   300             (Syntax.implode_input s);
   324 
   301 
   336           length type_args <> n andalso err (" takes " ^ string_of_int n ^ " type argument(s)");
   313           length type_args <> n andalso err (" takes " ^ string_of_int n ^ " type argument(s)");
   337         val _ =
   314         val _ =
   338           length term_args > m andalso Term.is_Type (Term.body_type T) andalso
   315           length term_args > m andalso Term.is_Type (Term.body_type T) andalso
   339             err (" cannot have more than " ^ string_of_int m ^ " argument(s)");
   316             err (" cannot have more than " ^ string_of_int m ^ " argument(s)");
   340 
   317 
   341         val (decls1, ctxt1) = ml_args ctxt type_args;
   318         val (decls1, ctxt1) = ML_Context.expand_antiquotes_list type_args ctxt;
   342         val (decls2, ctxt2) = ml_args ctxt1 term_args;
   319         val (decls2, ctxt2) = ML_Context.expand_antiquotes_list term_args ctxt1;
   343         val (decls3, ctxt3) = ml_args ctxt2 fn_body;
   320         val (decls3, ctxt3) = ML_Context.expand_antiquotes_list fn_body ctxt2;
   344         fun decl' ctxt' =
   321         fun decl' ctxt' =
   345           let
   322           let
   346             val (ml_args_env1, ml_args_body1) = split_list (decls1 ctxt');
   323             val (ml_args_env1, ml_args_body1) = split_list (decls1 ctxt');
   347             val (ml_args_env2, ml_args_body2) = split_list (decls2 ctxt');
   324             val (ml_args_env2, ml_args_body2) = split_list (decls2 ctxt');
   348             val (ml_fn_env, ml_fn_body) = split_list (decls3 ctxt');
   325             val (ml_fn_env, ml_fn_body) = split_list (decls3 ctxt');