1 (* Title: Pure/ML/ml_compiler_polyml-5.3.ML
4 Advanced runtime compilation for Poly/ML 5.3 (SVN 762).
7 signature ML_COMPILER =
9 val exception_position: exn -> Position.T
10 val eval: bool -> Position.T -> ML_Lex.token list -> unit
13 structure ML_Compiler: ML_COMPILER =
16 (* source locations *)
18 fun position_of (loc: PolyML.location) =
20 val {file = text, startLine = line, startPosition = offset,
21 endLine = end_line, endPosition = end_offset} = loc;
23 (case YXML.parse text of
24 XML.Elem (e, atts, _) => if e = Markup.positionN then atts else []
25 | XML.Text s => Position.file_name s);
27 Position.value Markup.lineN line @
28 Position.value Markup.offsetN offset @
29 Position.value Markup.end_lineN end_line @
30 Position.value Markup.end_offsetN end_offset @
32 end |> Position.of_properties;
34 fun exception_position exn =
35 (case PolyML.exceptionLocation exn of
37 | SOME loc => position_of loc);
42 fun report_parse_tree depth space =
44 fun report loc (PolyML.PTtype types) =
45 PolyML.NameSpace.displayTypeExpression (types, depth, space)
46 |> pretty_ml |> Pretty.from_ML |> Pretty.string_of
47 |> Position.report_text Markup.ML_typing (position_of loc)
48 | report loc (PolyML.PTdeclaredAt decl) =
50 (Markup.properties (Position.properties_of (position_of decl)) Markup.ML_def) ""
51 |> Position.report_text Markup.ML_ref (position_of loc)
52 | report _ (PolyML.PTnextSibling tree) = report_tree (tree ())
53 | report _ (PolyML.PTfirstChild tree) = report_tree (tree ())
55 and report_tree (loc, props) = List.app (report loc) props;
59 (* eval ML source tokens *)
61 fun eval verbose pos toks =
63 val _ = Secure.secure_mltext ();
64 val {name_space = space, print, error = err, ...} = ML_Env.local_context;
70 Markup.markup (Markup.position |> Markup.properties
71 (filter (member (op =) [Markup.idN, Markup.fileN] o #1) (Position.properties_of pos))) "";
73 val input = toks |> maps (fn tok =>
75 val syms = Symbol.explode (ML_Lex.check_content_of tok);
76 val (ps, _) = fold_map (fn s => fn p => (p, Position.advance s p)) syms
77 (Position.reset_range (ML_Lex.pos_of tok));
78 in ps ~~ map (String.explode o Symbol.esc) syms end);
80 val input_buffer = ref input;
81 val line = ref (the_default 1 (Position.line_of pos));
85 (get_first (fn (_, []) => NONE | (p, _) => Position.offset_of p) (! input_buffer));
88 (case ! input_buffer of
90 | (_, []) :: rest => (input_buffer := rest; get ())
91 | (p, c :: cs) :: rest =>
92 (input_buffer := (p, cs) :: rest;
93 if c = #"\n" then line := ! line + 1 else ();
99 val output_buffer = ref Buffer.empty;
100 fun output () = Buffer.content (! output_buffer);
101 fun put s = change output_buffer (Buffer.add s);
103 fun put_message {message, hard, location, context = _} =
104 (put (if hard then "Error: " else "Warning: ");
105 put (Pretty.string_of (Pretty.from_ML (pretty_ml message)));
106 put (Position.str_of (position_of location) ^ "\n"));
111 val depth = get_print_depth ();
113 fun apply_result {fixes, types, signatures, structures, functors, values} =
117 (disp x |> pretty_ml |> Pretty.from_ML |> Pretty.string_of |> put; put "\n")
120 fun apply_fix (a, b) =
121 (display PolyML.NameSpace.displayFix (a, b); #enterFix space (a, b));
122 fun apply_type (a, b) =
123 (display PolyML.NameSpace.displayType (b, depth, space); #enterType space (a, b));
124 fun apply_sig (a, b) =
125 (display PolyML.NameSpace.displaySig (b, depth, space); #enterSig space (a, b));
126 fun apply_struct (a, b) =
127 (display PolyML.NameSpace.displayStruct (b, depth, space); #enterStruct space (a, b));
128 fun apply_funct (a, b) =
129 (display PolyML.NameSpace.displayFunct (b, depth, space); #enterFunct space (a, b));
130 fun apply_val (a, b) =
131 (display PolyML.NameSpace.displayVal (b, depth, space); #enterVal space (a, b));
133 List.app apply_fix fixes;
134 List.app apply_type types;
135 List.app apply_sig signatures;
136 List.app apply_struct structures;
137 List.app apply_funct functors;
138 List.app apply_val values
141 fun result_fun (phase1, phase2) () =
142 (case phase1 of NONE => ()
143 | SOME parse_tree => report_parse_tree depth space parse_tree;
144 case phase2 of NONE => err "Static Errors"
145 | SOME code => apply_result (code ())); (* FIXME cf. Toplevel.program *)
148 (* compiler invocation *)
151 [PolyML.Compiler.CPOutStream put,
152 PolyML.Compiler.CPNameSpace space,
153 PolyML.Compiler.CPErrorMessageProc put_message,
154 PolyML.Compiler.CPLineNo (fn () => ! line),
155 PolyML.Compiler.CPFileName location_props,
156 PolyML.Compiler.CPLineOffset get_offset,
157 PolyML.Compiler.CPCompilerResultFun result_fun];
159 (while not (List.null (! input_buffer)) do
160 PolyML.compiler (get, parameters) ())
162 (put ("Exception- " ^ General.exnMessage exn ^ " raised");
163 err (output ()); raise exn);
164 in if verbose then print (output ()) else () end;