From 464800fd9f98992dc205656d22f2a1d64dca27a9 Mon Sep 17 00:00:00 2001 From: charguer <arthur@chargueraud.org> Date: Fri, 25 Mar 2016 14:58:44 +0100 Subject: [PATCH] ml_logging --- generator/Makefile | 31 +++++++------ generator/TODO | 8 ++++ generator/displayed_sources.ml | 26 +++++++++-- generator/js_of_ast.ml | 84 ++++++++++++++++++++++------------ generator/lineof.ml | 42 ++++++++++------- generator/main.ml | 34 ++++++++++++-- navig-driver.js | 58 ++++++++++++++++++----- tools.js | 35 ++++++++++++-- 8 files changed, 236 insertions(+), 82 deletions(-) diff --git a/generator/Makefile b/generator/Makefile index f8f3135..7404d6c 100644 --- a/generator/Makefile +++ b/generator/Makefile @@ -1,4 +1,4 @@ -# + # # Usage: # make all # not implemented yet, will build everything # make full # build *.log.js, *.unlog.js, *.token.js @@ -54,15 +54,17 @@ ASSEMBLY_JS_FILES := \ JsInit.unlog.js \ JsInterpreterMonads.unlog.js \ JsInterpreter.log.js -ASSEMBLY_JS := $(STDLIB_DIR)/stdlib.js $(addprefix tests/jsref/,$(ASSEMBLY_JS_FILES)); +ASSEMBLY_JS := $(STDLIB_DIR)/stdlib.js $(addprefix tests/jsref/,$(ASSEMBLY_JS_FILES)) ############################################################### -DISPLAYED_JS_FILES := \ - JsInterpreter.unlog.js +DISPLAYED_FILES := \ + JsInterpreter.ml + +DISPLAYED := $(addprefix tests/jsref/,$(DISPLAYED_FILES)) + -DISPLAYED_JS := $(addprefix tests/jsref/,$(DISPLAYED_JS_FILES)); ############################################################### @@ -70,7 +72,7 @@ DISPLAYED_JS := $(addprefix tests/jsref/,$(DISPLAYED_JS_FILES)); all: everything -.PHONY: all clean .log.js .unlog.js .token.js +.PHONY: all clean .log.js .unlog.js .token.js .mlloc.js # all gen log unlog # Do not delete intermediate files. @@ -132,13 +134,13 @@ tests/%.log.js: tests/%.ml main.byte stdlib tests/%.cmi tests/%.unlog.js: tests/%.ml main.byte stdlib tests/%.cmi ./main.byte -mode unlog -I $(<D) $< -tests/%.token.js: tests/%.ml main.byte stdlib tests/%.cmi +tests/%.token.js tests/%.mlloc.js: tests/%.ml main.byte stdlib tests/%.cmi ./main.byte -mode token -I $(<D) $< ##### Rule for lineof.js -$(JSREF_PATH)/lineof.js: lineof.byte $(JSREF_ML:.ml=.token.js) - ./lineof.byte -o $@ $(JSREF_ML:.ml=.token.js) +$(JSREF_PATH)/lineof.js: lineof.byte $(DISPLAYED:.ml=.token.js) $(DISPLAYED:.ml=.mlloc.js) + ./lineof.byte -o $@ $(DISPLAYED:.ml=.token.js) $(DISPLAYED:.ml=.mlloc.js) ##### Rule for assembly.js @@ -149,8 +151,8 @@ $(JSREF_PATH)/assembly.js: assembly.byte $(ASSEMBLY_JS) ##### Rule for displayed_sources.js -$(JSREF_PATH)/displayed_sources.js: displayed_sources.byte $(DISPLAYED_JS) - ./displayed_sources.byte -o $@ $(DISPLAYED_JS) +$(JSREF_PATH)/displayed_sources.js: displayed_sources.byte $(DISPLAYED:.ml=.unlog.js) $(DISPLAYED) + ./displayed_sources.byte -o $@ $(DISPLAYED:.ml=.unlog.js) $(DISPLAYED) #### maybe useful ?? @@ -186,17 +188,18 @@ stdlib: $(STDLIB_DIR)/stdlib.cmi ##################################################################### # Clean -DIRTY_EXTS := cmi,token.js,log.js,unlog.js,d,ml.d,mli.d,js.pre +DIRTY_EXTS := cmi,.mlloc.js,token.js,log.js,unlog.js,d,ml.d,mli.d,js.pre clean_genjs: rm -f $(JSREF_PATH)/lineof.js rm -f $(JSREF_PATH)/assembly.js clean_tests: - bash -c "rm -f $(TESTS_DIR)/*.{$(DIRTY_EXTS)}" - bash -c "rm -f $(TESTS_DIR)/$(JSREF_DIR)/*.{$(DIRTY_EXTS)}" + bash -c "rm -f $(JSREF_PATH)/*.{$(DIRTY_EXTS)}" bash -c "rm -f $(JSREF_PATH)/.depends" +# bash -c "rm -f $(TESTS_DIR)/*.{$(DIRTY_EXTS)}" + clean_stdlib: rm -f $(STDLIB_DIR)/*.cmi diff --git a/generator/TODO b/generator/TODO index 4c9c0e5..c218a52 100644 --- a/generator/TODO +++ b/generator/TODO @@ -1,6 +1,14 @@ +NEW NEW TODO +- remove _runs0 from arguments +- rename the p' variables +- restore button step into / next + +- tokens for if statement + +- switch,return,call,var generate events, NEW TODO diff --git a/generator/displayed_sources.ml b/generator/displayed_sources.ml index ba5f512..f317155 100644 --- a/generator/displayed_sources.ml +++ b/generator/displayed_sources.ml @@ -80,8 +80,8 @@ let hashtbl_keys t = takes as argument a list of javascript filenames, and create a javascript file with a definition of an array called "tracer_files", storing objects with - two fields: a filename, and a contents, with newline - and quotes properly escaped. + two fields: a filename, and a contents, with newline, + quotes and backslashes properly escaped. var tracer_files = [ @@ -141,18 +141,36 @@ let _ = output_string outchannel "\n" in + (*---------------------------------------------------*) + (* test *) + + (* DEBUG: to test how many backslashes are needed + let line = "foo \\n" in + let line = Str.global_replace (Str.regexp "\\") "\\\\\\\\" line in + print_string line; + print_newline(); + exit 0; + *) + (*---------------------------------------------------*) (* include of logged js files *) + put "var tracer_files = ["; ~~ List.iter !files (fun filename -> - let basename = Filename.chop_suffix (Filename.basename filename) ".unlog.js" in - let showed_filename = basename ^ ".js" in + let showed_filename = + let short = Filename.basename filename in + if (Filename.check_suffix short ".unlog.js") then begin + let basename = Filename.chop_suffix short ".unlog.js" in + basename ^ ".js" + end else short (* should be .ml file *) + in put (Printf.sprintf "\n/* --------------------- %s --------------------- */" showed_filename); put_no_endline (Printf.sprintf " { file: '%s', contents: '" showed_filename); let lines = XFile.get_lines filename in ~~ List.iter lines (fun line -> + let line = Str.global_replace (Str.regexp "\\") "\\\\\\\\" line in let line = Str.global_replace (Str.regexp "'") "\\'" line in put_no_endline line; put_no_endline "\\n"; diff --git a/generator/js_of_ast.ml b/generator/js_of_ast.ml index ad594fe..2abaa56 100644 --- a/generator/js_of_ast.ml +++ b/generator/js_of_ast.ml @@ -281,6 +281,24 @@ let id_fresh = fun prefix -> (incr r; prefix ^ string_of_int !r) +(****************************************************************) +(* TOKEN TO LOC BINDINGS FOR THE ML SOURCE FILES *) + +(* Keeps track of the location associated with each token, + maps int to (pos*pos). *) + +type pos = { pos_line: int; pos_col: int } +let token_locs = Hashtbl.create 50 + +let pos_of_lexing_pos lexing_pos = + let (file, line, char) = Location.get_pos_info lexing_pos in + { pos_line = line; pos_col = char } + +let pos_pair_of_loc loc = + (pos_of_lexing_pos loc.Location.loc_start, + pos_of_lexing_pos loc.Location.loc_end) + + (****************************************************************) (* FRESH TOKEN NAMES *) @@ -289,13 +307,19 @@ let token_basename_ref = ref "no_token_basename_registered" let token_register_basename basename = token_basename_ref := basename +(* returns a string of the form: ["filename.js", 3425], + where 3425 describes the token. *) + let token_fresh = let r = ref 0 in - fun () -> (incr r; + fun loc -> ( + incr r; + Hashtbl.add token_locs (!r) (pos_pair_of_loc loc); let token_start = Printf.sprintf "@{<%d>" !r in let token_stop = "@}" in - let token_lineof = Printf.sprintf "lineof(\"%s.js\", %d)" !token_basename_ref !r in - (token_start, token_stop, token_lineof)) + let token_loc = Printf.sprintf "\"%s.js\", %d" !token_basename_ref !r in + (token_start, token_stop, token_loc)) + (****************************************************************) @@ -314,10 +338,10 @@ let ctx_initial = (****************************************************************) (* LOGGED CONSTRUCTORS *) -let generate_logged_case spat binders ctx newctx sbody need_break = +let generate_logged_case loc spat binders ctx newctx sbody need_break = (* Note: binders is a list of pairs of id *) (* Note: if binders = [], then newctx = ctx *) - let (token_start, token_stop, token_lineof) = token_fresh() in + let (token_start, token_stop, token_loc) = token_fresh loc in let (shead, sintro) = match !current_mode with | Mode_cmi -> assert false @@ -336,7 +360,7 @@ let generate_logged_case spat binders ctx newctx sbody need_break = else Printf.sprintf "var %s = ctx_push(%s, %s);@," newctx ctx bindings in let sintro = Printf.sprintf "%slog_event(%s, %s, \"case\");@," - spreintro token_lineof newctx in + spreintro token_loc newctx in ("", sintro) | Mode_unlogged -> ("", "") in @@ -364,16 +388,16 @@ with help of (* LATER: optimize return when it's a value *) -let generate_logged_return ctx sbody = - let (token_start, token_stop, token_lineof) = token_fresh() in +let generate_logged_return loc ctx sbody = + let (token_start, token_stop, token_loc) = token_fresh loc in match !current_mode with | Mode_cmi -> assert false | Mode_unlogged | Mode_line_token -> Printf.sprintf "%sreturn %s;%s" token_start sbody token_stop | Mode_logged -> let id = id_fresh "_return_" in - Printf.sprintf "var %s = %s;@,log_event(%s, ctx_push(%s, [{key: \"return_value\", value: %s}]), \"return\");@,return %s; " - id sbody token_lineof ctx id id + Printf.sprintf "var %s = %s;@,log_event(%s, ctx_push(%s, [{key: \"return_value\", val: %s}]), \"return\");@,return %s; " + id sbody token_loc ctx id id (* ---- [insertReturnCode(e,ctx)] @@ -386,8 +410,8 @@ var t=e; logEvent(LINEOF(432423), ctx_push(ctx, {"return",t}), "return"); return -let generate_logged_let ids ctx newctx sdecl sbody = - let (token_start, token_stop, token_lineof) = token_fresh() in +let generate_logged_let loc ids ctx newctx sdecl sbody = + let (token_start, token_stop, token_loc) = token_fresh loc in match !current_mode with | Mode_cmi -> assert false | Mode_line_token -> @@ -400,7 +424,7 @@ let generate_logged_let ids ctx newctx sdecl sbody = Printf.sprintf "[%s]" (show_list ", " (List.map mk_binding ids)) in Printf.sprintf "%s@,var %s = ctx_push(%s, %s);@,log_event(%s, %s, \"let\");@,%s@," - sdecl newctx ctx bindings token_lineof newctx sbody + sdecl newctx ctx bindings token_loc newctx sbody | Mode_unlogged -> Printf.sprintf "%s@,%s" sdecl sbody @@ -417,8 +441,8 @@ var x=e; var newctx=ctx_push(ctx,x,e); logEvent(LINEOF(432423), "let", ctx);sbod (* LATER: factoriser les bindings *) -let generate_logged_enter arg_ids ctx newctx sbody = - let (token_start, token_stop, token_lineof) = token_fresh() in +let generate_logged_enter loc arg_ids ctx newctx sbody = + let (token_start, token_stop, token_loc) = token_fresh loc in let (shead1, shead2, sintro) = match !current_mode with | Mode_cmi -> assert false @@ -431,7 +455,7 @@ let generate_logged_enter arg_ids ctx newctx sbody = Printf.sprintf "[%s]" (show_list ", " (List.map mk_binding arg_ids)) in let sintro = Printf.sprintf "var %s = ctx_push(%s, %s);@,log_event(%s, %s, \"enter\");@," - newctx ctx bindings token_lineof newctx in + newctx ctx bindings token_loc newctx in ("", "", sintro) | Mode_unlogged -> ("", "", "") in @@ -469,10 +493,10 @@ type dest = | Dest_assign of string | Dest_inline -let apply_dest ctx dest sbody = +let apply_dest loc ctx dest sbody = match dest with | Dest_ignore -> sbody - | Dest_return -> generate_logged_return ctx sbody + | Dest_return -> generate_logged_return loc ctx sbody | Dest_assign id -> Printf.sprintf "var %s = %s;" id sbody | Dest_inline -> sbody @@ -572,7 +596,7 @@ and js_of_branch ctx dest b eobj = let newctx = if binders = [] then ctx else ctx_fresh() in let sbody = js_of_expression newctx dest b.c_rhs in let need_break = (dest <> Dest_return) in - generate_logged_case spat binders ctx newctx sbody need_break + generate_logged_case b.c_lhs.pat_loc spat binders ctx newctx sbody need_break and js_of_expression_inline_or_wrap ctx e = try @@ -595,15 +619,16 @@ and js_of_expression_naming_argument_if_non_variable ctx obj name_prefix = and js_of_expression ctx dest e = let inline_of_wrap = js_of_expression_inline_or_wrap ctx in (* shorthand *) let loc = e.exp_loc in + let apply_dest' = apply_dest loc in match e.exp_desc with | Texp_ident (path, ident, _) -> let sexp = js_of_path_longident path ident in - apply_dest ctx dest sexp + apply_dest' ctx dest sexp | Texp_constant c -> let sexp = js_of_constant c in - apply_dest ctx dest sexp + apply_dest' ctx dest sexp | Texp_let (_, vb_l, e) -> reject_inline dest; @@ -645,7 +670,7 @@ and js_of_expression ctx dest e = end in let newctx = ctx_fresh() in let sbody = js_of_expression newctx dest e in - let sexp = generate_logged_let ids ctx newctx sdecl sbody in + let sexp = generate_logged_let loc ids ctx newctx sdecl sbody in sexp | Texp_function (_, c :: [], Total) -> @@ -659,8 +684,8 @@ and js_of_expression ctx dest e = let arg_ids, body = explore [c.c_lhs] c.c_rhs in let newctx = ctx_fresh() in let sbody = js_of_expression newctx Dest_return body in - let sexp = generate_logged_enter arg_ids ctx newctx sbody in - apply_dest ctx dest sexp + let sexp = generate_logged_enter loc arg_ids ctx newctx sbody in + apply_dest' ctx dest sexp | Texp_apply (f, exp_l) -> (* first check not partial application *) @@ -696,7 +721,7 @@ and js_of_expression ctx dest e = end else begin ppf_apply se (String.concat ",@ " sl) end in - apply_dest ctx dest sexp + apply_dest' ctx dest sexp | Texp_match (obj, l, [], Total) -> reject_inline dest; @@ -708,7 +733,7 @@ and js_of_expression ctx dest e = | Texp_tuple (tl) -> let sexp = ppf_tuple @@ show_list_f (fun exp -> inline_of_wrap exp) ", " tl in - apply_dest ctx dest sexp + apply_dest' ctx dest sexp | Texp_construct (p, cd, el) -> let cstr_fullname = string_of_longident p.txt in @@ -725,7 +750,7 @@ and js_of_expression ctx dest e = let expr_strs = List.map (fun exp -> inline_of_wrap exp) el in ppf_cstrs_fct cstr_fullname expr_strs end in - apply_dest ctx dest sexp + apply_dest' ctx dest sexp | Texp_array (exp_l) -> ppf_array @@ show_list_f (fun exp -> inline_of_wrap exp) ", " exp_l | Texp_ifthenelse (e1, e2, None) -> out_of_scope loc "if without else" @@ -741,14 +766,15 @@ and js_of_expression ctx dest e = (* ppf_for (ppf_ident id) (js_of_expression st) (js_of_expression ed) fl (js_of_expression body) *) | Texp_record (llde,_) -> let sexp = ppf_record (List.map (fun (_, lbl, exp) -> (lbl.lbl_name, inline_of_wrap exp)) llde) in - apply_dest ctx dest sexp + apply_dest' ctx dest sexp | Texp_field (exp, _, lbl) -> let sexp = ppf_field_access (inline_of_wrap exp) lbl.lbl_name in - apply_dest ctx dest sexp + apply_dest' ctx dest sexp | Texp_assert e -> let sexp = inline_of_wrap e in Printf.sprintf "throw %s;" sexp + (* TODO: what about apply_dest? *) | Texp_function (label, cases, Total) when label = "" -> let mk_pat pat_des = diff --git a/generator/lineof.ml b/generator/lineof.ml index f0aca86..61cc2b4 100644 --- a/generator/lineof.ml +++ b/generator/lineof.ml @@ -208,9 +208,7 @@ let _ = *) -let generate_lineof_function put = - put "var lineof_data = {};"; - put "var lineof_temp;"; +let generate_lineof_entries put = ~~ List.iter !tokens (fun (basename, tokens_start, tokens_stop) -> put " lineof_temp = [];"; let filename = basename ^ ".js" in @@ -252,7 +250,7 @@ let generate_lineof_function put = } } - let generate_lineof_function output_file = + let generate_lineof_entries output_file = let aux_pos pos = Printf.sprintf "{ line: %d, col: %d }" pos.pos_line pos.pos_col in @@ -285,12 +283,15 @@ let generate_lineof_function put = let output = Format.flush_str_formatter () in XFile.put_contents output_file output - ==> generate_lineof_function output_filename + ==> generate_lineof_entries output_filename *) (*#########################################################################*) +(** The files called *.mlloc.js are appended directly; + they come first in the output file. *) + let files = ref ([]:string list) let outputfile = ref None @@ -313,6 +314,7 @@ let _ = ("usage: [..other options..] -o lineof.js file1.token.js file2.token.js .."); if !files = [] then failwith "No input file provided"; + files := List.rev !files; let input_filename1 = List.hd !files in let dirname = Filename.dirname input_filename1 in let output_filename = @@ -321,16 +323,6 @@ let _ = | Some f -> f in - (*---------------------------------------------------*) - (* processing source files *) - - ~~ List.iter !files (fun filename -> - if not (Filename.check_suffix filename ".token.js") then - failwith "Input file must be of the form *.token.js"; - let basename = Filename.chop_suffix (Filename.basename filename) ".token.js" in - let input_lines = XFile.get_lines filename in - gather_tokens basename input_lines - ); (*---------------------------------------------------*) (* open output file for writing *) @@ -340,11 +332,29 @@ let _ = output_string outchannel str; output_string outchannel "\n" in + put "var lineof_data = {};"; + put "var lineof_temp;"; + + + (*---------------------------------------------------*) + (* processing source files *) + + ~~ List.iter !files (fun filename -> + if (Filename.check_suffix filename ".mlloc.js") then begin + let input_lines = XFile.get_lines filename in + List.iter put input_lines; + end else if (Filename.check_suffix filename ".token.js") then begin + let basename = Filename.chop_suffix (Filename.basename filename) ".token.js" in + let input_lines = XFile.get_lines filename in + gather_tokens basename input_lines + end else + failwith "Input file must be of the form *.token.js" + ); (*---------------------------------------------------*) (* generating output file *) - generate_lineof_function put; + generate_lineof_entries put; close_out outchannel; Printf.printf "Wrote file: %s\n" output_filename; diff --git a/generator/main.ml b/generator/main.ml index fa077ea..2c2b312 100644 --- a/generator/main.ml +++ b/generator/main.ml @@ -34,6 +34,7 @@ let _ = ] (fun f -> files := f :: !files) ("usage: [-I dir] [..other options..] file.ml"); + files := List.rev !files; if List.length !files <> 1 then failwith "Expects one argument: the filename of the ML source file"; let sourcefile = List.hd !files in @@ -42,12 +43,13 @@ let _ = let basename = Filename.chop_suffix (Filename.basename sourcefile) ".ml" in let dirname = Filename.dirname sourcefile in let pathname = if dirname = "" then basename else (dirname ^ "/" ^ basename) in - let log_output, unlog_output, token_output = + let log_output, unlog_output, token_output, mlloc_output = match !outputfile with | None -> Filename.concat dirname (basename ^ ".log.js"), Filename.concat dirname (basename ^ ".unlog.js"), - Filename.concat dirname (basename ^ ".token.js") - | Some f -> f ^ ".log.js", f ^ ".unlog.js", f ^ ".token.js" + Filename.concat dirname (basename ^ ".token.js"), + Filename.concat dirname (basename ^ ".mlloc.js") + | Some f -> f ^ ".log.js", f ^ ".unlog.js", f ^ ".token.js", f ^ ".mlloc.js" in (*---------------------------------------------------*) @@ -61,6 +63,26 @@ let _ = then generate_qualified_names := true; *) + + (*---------------------------------------------------*) + (* generation of the mlloc file that binds tokens to positions *) + + let generate_mlloc_file () = + let outchannel = open_out mlloc_output in + let put str = + output_string outchannel str; + output_string outchannel "\n" in + put " lineof_temp = [];"; + let filename = basename ^ ".ml" in + ~~ Hashtbl.iter Js_of_ast.token_locs (fun key (pos_start,pos_stop) -> + put (Printf.sprintf " lineof_temp[%d] = [%d,%d,%d,%d];" + key pos_start.pos_line pos_start.pos_col + pos_stop.pos_line pos_stop.pos_col); + ); + put (Printf.sprintf "lineof_data[\"%s\"] = lineof_temp;" filename); + close_out outchannel; + in + (*---------------------------------------------------*) (* "reading and typing source file" *) @@ -82,4 +104,8 @@ let _ = | _ -> assert false in file_put_contents output_filename out; - Printf.printf "Wrote %s\n" output_filename + Printf.printf "Wrote %s\n" output_filename; + if !current_mode = Mode_line_token + then generate_mlloc_file() + + diff --git a/navig-driver.js b/navig-driver.js index 1ef6ae9..122aee3 100644 --- a/navig-driver.js +++ b/navig-driver.js @@ -72,7 +72,10 @@ var source = ""; var interpreter = null; // Initial source code -var source_file = 'var x = 2;\n'; +var source_file = 'var x = 2;\nx'; + +var source_file = ' var t = {}; for (var i = 0; i < 3; i++) { t[i] = function() { return i; } }; t[0](); '; +var source_file = '{}'; // --------------- Initialization ---------------- @@ -250,14 +253,23 @@ function previous() { shared_next(-1, 0); } function finish() { shared_next(+1, -1); } +// --------------- Auxiliary ---------------- + +function get_file_extension(filename) { + var re = /(?:\.([^.]+))?$/; + return re.exec(filename)[1]; +} + + // --------------- Methods ---------------- // load files in CodeMirror view var docs = {}; for (var i = 0; i < tracer_files.length; i++) { var file = tracer_files[i].file; + var ext = get_file_extension(file); var txt = tracer_files[i].contents; - docs[file] = CodeMirror.Doc(txt, 'js'); + docs[file] = CodeMirror.Doc(txt, ext); } function viewFile(file) { @@ -381,7 +393,7 @@ function ctxToHtml(ctx) { function itemToHtml(item) { var s = ''; - s += htmlDiv("token: " + item.loc.token + JSON.stringify(item.loc.start) + JSON.stringify(item.loc.end)); + s += htmlDiv("token: " + item.token + JSON.stringify(item.locByExt)); s += htmlDiv("type: " + item.type); s += ctxToHtml(item.ctx); return s; @@ -390,12 +402,26 @@ function itemToHtml(item) { // --------------- Selection view ---------------- function updateSelectionInCodeMirror(codeMirrorObj, loc) { - if (loc === undefined) { + if (loc === undefined) { + return; + } + var anchor = {line: loc.start.line-1 , ch: loc.start.column }; + var head = {line: loc.end.line-1, ch: loc.end.column }; + codeMirrorObj.setSelection(anchor, head); +} + +function updateSelectionInCodeMirrorAccordingToExt(codeMirrorObj, locByExt) { + if (locByExt === undefined) { return; - } - var anchor = {line: loc.start.line-1 , ch: loc.start.column }; - var head = {line: loc.end.line-1, ch: loc.end.column }; - codeMirrorObj.setSelection(anchor, head); + } + var ext = get_file_extension(curfile); + var loc = locByExt[ext]; + if (loc === undefined) { + console.log("Error: missing loc for " + curfile + " in:"); + console.log(locByExt); + return; + } + updateSelectionInCodeMirror(codeMirrorObj, loc); } function updateSelection() { @@ -423,15 +449,15 @@ function updateSelection() { updateContext("#disp_ctx", item.heap, item.ctx); // interpreter code panel - viewFile(item.loc.file); - //console.log("pos: " + tracer_pos); + // TEMPORARILY DISABLED BECAUSE ONLY SINGLE FILE TO TRACE + // viewFile(item.loc.file); var color = '#F3F781'; // possible to use different colors depending on event type // var color = (item.type === 'enter') ? '#F3F781' : '#CCCCCC'; $('.CodeMirror-selected').css({ background: color }); $('.CodeMirror-focused .CodeMirror-selected').css({ background: color }); - updateSelectionInCodeMirror(interpreter, item.loc); + updateSelectionInCodeMirrorAccordingToExt(interpreter, item.locByExt); } // navig panel @@ -572,4 +598,14 @@ readSourceParseAndRun(); function showCurrent() { console.log(tracer_items[tracer_pos]); +}; + + +function findToken(token) { + for (var i = 0; i < tracer_items.length; i++) { + if (tracer_items[i].token == token) { + return i; + } + } + return -1; }; \ No newline at end of file diff --git a/tools.js b/tools.js index 9b86145..b23b7e5 100644 --- a/tools.js +++ b/tools.js @@ -3,14 +3,28 @@ // see "generator/lineof.ml" and "lineof.js" function lineof(filename, token) { - var d = lineof_data[filename][token]; + var f = lineof_data[filename]; + if (f == undefined) { + console.log("could not find lineof for " + filename); + return; + } + var d = f[token]; + if (d == undefined) { + console.log("could not find token " + token + " for " + filename); + return; + } return { file: filename, - token: token, start: {line: d[0], column: d[1]}, end: {line: d[2], column: d[3]} }; }; +// ----------- Auxiliary -------------- + +String.prototype.replaceAt=function(index, character) { + return this.substr(0, index) + character + this.substr(index+character.length); +} + // ----------- Datalog ---------------- var datalog = []; @@ -19,12 +33,25 @@ function reset_datalog() { datalog = []; } -function log_event(loc, ctx, type) { +// filename assumed to be of js extension +function log_event(filename, token, ctx, type) { // TODO populate state with object_heap, env_record_heap, fresh_locations, and populate env - var event = {loc : loc, ctx : ctx, type : type, state: {}, env: {}}; + + // compute "foo.ml" from "foo.js" + var len = filename.length; + var mlfilename = filename.replaceAt(len-2, "m"); + mlfilename = mlfilename.replaceAt(len-1, "l"); + + var jsloc = lineof(filename, token); + var mlloc = lineof(mlfilename, token); + + var event = { token: token, locByExt: { "ml": mlloc, "js": jsloc }, + ctx : ctx, type : type, state: {}, env: {}}; datalog.push(event); } + + // ----------- Context ---------------- -- GitLab