Преглед на файлове

optimized line calculus from ast position

Nicolas Cannasse преди 17 години
родител
ревизия
33e24aae81
променени са 8 файла, в които са добавени 43 реда и са изтрити 10 реда
  1. 2 0
      common.ml
  2. 1 0
      doc/CHANGES.txt
  3. 1 1
      genjs.ml
  4. 3 5
      genneko.ml
  5. 1 1
      genswf8.ml
  6. 1 1
      genswf9.ml
  7. 33 2
      lexer.mll
  8. 1 0
      main.ml

+ 2 - 0
common.ml

@@ -68,6 +68,7 @@ type context = {
 	mutable php_front : string option;
 	(* typing *)
 	mutable type_api : context_type_api;
+	mutable lines : Lexer.line_index;
 }
 
 exception Abort of string * Ast.pos
@@ -102,6 +103,7 @@ let create() =
 			on_generate = (fun _ -> ());
 			get_type_module = (fun _ -> assert false);
 		};
+		lines = Lexer.build_line_index();
 	}
 
 let defined ctx v = PMap.mem v ctx.defines

+ 1 - 0
doc/CHANGES.txt

@@ -13,6 +13,7 @@
 	fixed Type.typeof and Std.is in case of too much large integers for Flash6-8/JS
 	haxe.xml.Check : treat comments the same as PCDATA spaces
 	haxe.io.BytesData now uses strings instead of arrays for PHP
+	optimized line calculus from ast position
 
 2008-10-04: 2.01
 	fixed php.Sys

+ 1 - 1
genjs.ml

@@ -273,7 +273,7 @@ and gen_expr ctx e =
 		ctx.in_value <- false;
 		ctx.in_loop <- false;
 		if snd ctx.curmethod then
-			ctx.curmethod <- (fst ctx.curmethod ^ "@" ^ string_of_int (Lexer.get_error_line e.epos), true)
+			ctx.curmethod <- (fst ctx.curmethod ^ "@" ^ string_of_int (Lexer.find_line_index ctx.com.lines e.epos), true)
 		else
 			ctx.curmethod <- (fst ctx.curmethod, true);
 		print ctx "function(%s) " (String.concat "," (List.map ident (List.map arg_name f.tf_args)));

+ 3 - 5
genneko.ml

@@ -56,7 +56,7 @@ let pos ctx p =
 	) in
 	{
 		psource = file;
-		pline = Lexer.get_error_line p;
+		pline = Lexer.find_line_index ctx.com.lines p;
 	}
 
 let add_local ctx v p =
@@ -731,7 +731,7 @@ let generate com libs =
 		curblock = [];
 		locals = PMap.empty;
 	} in
-	let t = Common.timer "neko ast" in
+	let t = Common.timer "neko compilation" in
 	let h = Hashtbl.create 0 in
 	let header = ENeko (
 		"@classes = $new(null);" ^
@@ -755,9 +755,7 @@ let generate com libs =
 	let inits = List.map (gen_expr ctx) (List.rev ctx.inits) in
 	let vars = List.concat (List.map (gen_static_vars ctx) com.types) in
 	let e = (EBlock (header :: packs @ methods @ boot :: names @ inits @ vars), null_pos) in
-	t();
 	let neko_file = (try Filename.chop_extension com.file with _ -> com.file) ^ ".neko" in
-	let w = Common.timer "neko ast write" in
 	let ch = IO.output_channel (open_out_bin neko_file) in
 	let source = Common.defined com "neko_source" in
 	if source then Nxml.write ch (Nxml.to_xml e) else Binast.write ch e;
@@ -768,7 +766,7 @@ let generate com libs =
 		Sys.remove neko_file;
 		Sys.rename ((try Filename.chop_extension com.file with _ -> com.file) ^ "2.neko") neko_file;
 	end;
-	w();
+	t();
 	let c = Common.timer "neko compilation" in
 	if command ("nekoc \"" ^ neko_file ^ "\"") <> 0 then failwith "Neko compilation failure";
 	c();

+ 1 - 1
genswf8.ml

@@ -1005,7 +1005,7 @@ and gen_expr_2 ctx retval e =
 		let old_meth = ctx.curmethod in
 		let reg_super = Codegen.local_find true "super" f.tf_expr in
 		if snd ctx.curmethod then
-			ctx.curmethod <- (fst ctx.curmethod ^ "@" ^ string_of_int (Lexer.get_error_line e.epos), true)
+			ctx.curmethod <- (fst ctx.curmethod ^ "@" ^ string_of_int (Lexer.find_line_index ctx.com.lines e.epos), true)
 		else
 			ctx.curmethod <- (fst ctx.curmethod, true);
 		(* only keep None bindings, for protect *)

+ 1 - 1
genswf9.ml

@@ -486,7 +486,7 @@ let begin_switch ctx =
 
 let debug_infos ?(is_min=true) ctx p =
 	if ctx.com.debug then begin
-		let line = Lexer.get_error_line (if is_min then p else { p with pmin = p.pmax }) in
+		let line = Lexer.find_line_index ctx.com.lines (if is_min then p else { p with pmin = p.pmax }) in
 		if ctx.last_file <> p.pfile then begin
 			write ctx (HDebugFile (if ctx.debugger then Common.get_full_path p.pfile else p.pfile));
 			ctx.last_file <- p.pfile;

+ 33 - 2
lexer.mll

@@ -87,12 +87,12 @@ let find_line p lines =
 		| (lp,line) :: l when lp > p -> line, p - delta
 		| (lp,line) :: l -> loop line lp l
 	in
-	loop 1 0 lines
+	loop 0 0 lines
 
 let get_error_line p =
 	let lines = List.rev (try Hashtbl.find all_lines p.pfile with Not_found -> []) in
 	let l, _ = find_line p.pmin lines in
-	l
+	l	
 
 let get_error_pos printer p =
 	if p.pmin = -1 then
@@ -126,6 +126,37 @@ let mk_ident lexbuf =
 let invalid_char lexbuf =
 	error (Invalid_character (lexeme_char lexbuf 0)) (lexeme_start lexbuf)
 
+type file_index = {
+	f_file : string;
+	f_lines : (int * int) list;
+	f_max_line : int;
+}
+
+type line_index = (string, file_index) PMap.t
+
+let make_index f l =
+	let lines = List.rev l in
+	{
+		f_file = f;
+		f_lines = lines;
+		f_max_line = (match l with (_,line) :: _ -> line + 1 | [] -> 1);
+	}
+
+let build_line_index() =
+	Hashtbl.fold (fun f l acc -> 
+		let l = List.rev l in
+		PMap.add f (make_index f l) acc
+	) all_lines PMap.empty
+
+let find_line_index idx p =
+	let idx = (try PMap.find p.pfile idx with Not_found -> make_index p.pfile []) in
+	let ppos = p.pmin in
+	let rec loop = function
+		| [] -> idx.f_max_line
+		| (lp,line) :: l -> if lp > ppos then line else loop l
+	in
+	loop idx.f_lines
+
 }
 
 let ident = ('_'* ['a'-'z'] ['_' 'a'-'z' 'A'-'Z' '0'-'9']* | '_')

+ 1 - 0
main.ml

@@ -430,6 +430,7 @@ try
 		if !display then xml_out := None;
 		if !no_output then com.platform <- Cross;
 		com.types <- Typer.types ctx com.main_class (!excludes);
+		com.lines <- Lexer.build_line_index();
 		Codegen.post_process com;
 		(match com.platform with
 		| Cross ->