diff --git a/driver.html b/driver.html index 9640d1014b57206579b5410b25184b6d9f4cbeac..1b209cc188208a050ae124e4df59222c4ac261bd 100644 --- a/driver.html +++ b/driver.html @@ -106,6 +106,7 @@ Load file: <input type='file' accept='.js' id='select_file' /> <table id='main_table'><tr> <td> + <div id='source_tabs'></div> <textarea id='source_code' class='source' rows='6' cols='60'>source code here</textarea> </td> <td width='600'> diff --git a/esprima-to-ast.js b/esprima-to-ast.js index 4bece2b66eaeb330eaf6e13c9a41a80f5f761522..1550fbd1f2dfaf5910a46c2878caa088369715f1 100644 --- a/esprima-to-ast.js +++ b/esprima-to-ast.js @@ -2,7 +2,10 @@ //https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API$revision/707671 -function esprimaToAST(prog, sourceText) { +function esprimaToAST(prog, sourceText, filename) { + + filename = filename || "_toplevel_"; + var returnSourceText = filename.startsWith("_eval_"); var contextStrictMode = false; @@ -16,10 +19,13 @@ function esprimaToAST(prog, sourceText) { var toLoc = function (pos) { if (pos === null) {throw "null position in esprima AST";}; - return {file: "input.js", - start: {line: pos.start.line, column: pos.start.column}, - end: {line: pos.end.line, column: pos.end.column}}; // TODO : could reuse the start and end object + var loc = {file: filename, + start: {line: pos.start.line, column: pos.start.column}, + end: {line: pos.end.line, column: pos.end.column}, + sourceText: ""}; + if (returnSourceText) loc.sourceText = sourceText; + return loc; }; var toOption = function (funcTr, node) { diff --git a/generator/tests/jsref/Translate_syntax.js b/generator/tests/jsref/Translate_syntax.js index 32f88b0d365bc9c8bfca162c6e42a53605e31441..550d195883eeb2d7c5787a8e4db8896da752f5f4 100644 --- a/generator/tests/jsref/Translate_syntax.js +++ b/generator/tests/jsref/Translate_syntax.js @@ -1,8 +1,9 @@ var Translate_syntax = { + eval_counter: 0, parse_esprima: function (strictness, src) { try { // TODO Fixup line numbers for eval context - return Some(esprimaToAST(esprima.parse(src, {loc: true, range: true}), src)); + return Some(parseSource(src, "_eval_" + Translate_syntax.eval_counter++, true)); } catch (e) { return None(); } diff --git a/navig-driver.js b/navig-driver.js index db5bec662890a98a6f38bbd8ef1b0e4a93b4ae50..25ce3befbf7251825f0b64650762efebe22897a5 100644 --- a/navig-driver.js +++ b/navig-driver.js @@ -51,9 +51,6 @@ function ctx_to_jsobject(env) { // view var handlers = []; -var parsedTree; - - // --------------- Variables ---------------- // file currently displayed @@ -72,6 +69,8 @@ var tracer_pos = 0; var source = null; var interpreter = null; +var source_docs = {}; + // Initial source code var source_files = [ @@ -90,7 +89,9 @@ var source_files = [ 'var x = { a : { c: 1 } };\n x.a.b = 2;\nx', '(function (x) {return 1;})()', '(function (x) {\nreturn 1;\n})({a:{b:2}})', -// 'eval("var x = { a : 1 }; x.b = 2; x");', + 'eval("var x = { a : 1 };\\nx.b = 2;\\nx");', + 'var f = function() {return "f"}; eval("var g = function() {return \\"g\\"}; eval(\\"var h = function() {return \\\\\\"h\\\\\\"}; f(); g(); h()\\"); h();"); g(); h(); f();', + 'var t = {};\nfor (var i = 0; i < 3; i++) {\n t[i] = eval("i + " + i); \n};\nt; ', ]; source_files.reduce((select, file_content) => { @@ -101,19 +102,53 @@ source_files.reduce((select, file_content) => { return select; }, $('#select_source_code')); -function setSourceCode(text) { +function initSourceDocs() { + source_docs = {}; + Translate_syntax.eval_counter = 0; + $('#source_tabs').empty(); +} + +// Registers a new source doc +function newSourceDoc(name, text, readOnly) { + if (!source_docs.hasOwnProperty(name)) { + source_docs[name] = CodeMirror.Doc(text, 'js'); + var tab = $('<span>').addClass('file_item') + .text(name) + .click(e => selectSourceDoc(e.target.textContent)) + .appendTo('#source_tabs'); + source_docs[name].tab = tab; + source_docs[name].readOnly = Boolean(readOnly); + } + return source_docs[name]; +} + +// Switches current source doc +function selectSourceDoc(name) { + var old_doc = source.swapDoc(source_docs[name]); + if (old_doc.tab) old_doc.tab.removeClass('file_item_current'); + source_docs[name].tab.addClass('file_item_current'); + source.setOption('readOnly', source_docs[name].readOnly); +} + +// Sets the initial source doc +function setInitialSourceCode(name, text) { + initSourceDocs(); + var doc = newSourceDoc(name, text); + $("#source_code").val(text); + if (source !== null) { - source.setValue(text); + selectSourceDoc(name); buttonRunHandler(); } } -$('#select_source_code').change(e => { setSourceCode(e.target.value)}); +$('#select_source_code').change(e => { setInitialSourceCode("_toplevel_", e.target.value)}); $('#select_file').change(e => { + var f = e.target.files[0]; var fr = new FileReader(); - fr.onload = function (e) { setSourceCode(e.target.result) }; - fr.readAsText(e.target.files[0]); + fr.onload = function (e) { setInitialSourceCode(f.name, e.target.result) }; + fr.readAsText(f); }); // --------------- Initialization ---------------- @@ -121,8 +156,7 @@ $('#select_file').change(e => { // WARNING: do not move this initialization further down in the file // source code displayed initially -//source_files.length - 1 -setSourceCode(source_files[0]); +setInitialSourceCode("_toplevel_", source_files[0]); // --------------- Predicate search ---------------- @@ -351,6 +385,7 @@ $("#navigation_step").change(function(e) { }); function buttonRunHandler() { + initSourceDocs(); var message = readSourceParseAndRun(); $("#action_output").html(message); var timeoutID = window.setTimeout(function() { $("#action_output").html(""); }, 1000); @@ -1102,6 +1137,10 @@ function updateSelection() { // source panel source_loc_selected = item.source_loc; + + newSourceDoc(item.source_loc.file, item.source_loc.sourceText); + selectSourceDoc(item.source_loc.file); + updateSelectionInCodeMirror(source, source_loc_selected); // console.log(source_loc_selected); @@ -1218,7 +1257,7 @@ interpreter.focus(); // the corresponding location from the piece of AST that corresponds. // These locations are used for source highlighting. function assignExtraInfosInTrace() { - var last_loc = parsedTree.loc; + var last_loc = program.loc; var last_state = undefined; var last_execution_ctx = undefined; // { start: { line: 1, column: 0}, end: { line: 1, column: 1 } }; @@ -1281,21 +1320,24 @@ function run() { return (success) ? "Run successful!" : "Error during the run!"; } +function parseSource(source, name, readOnly) { + var tree = esprimaToAST(esprima.parse(source, {loc: true, range: true}), source, name); + newSourceDoc(name, source, readOnly); + return tree; +} + function readSourceParseAndRun() { var message = ""; var code = source.getValue(); //console.log(code); // TODO handle parsing error + // TODO handle out of scope errors try { - parsedTree = esprima.parse(code, {loc: true, range: true}); + program = parseSource(code, "_toplevel_"); } catch (e) { return "Parse error"; } - // console.log(parsedTree); - - // TODO handle out of scope errors - program = esprimaToAST(parsedTree, code); - // console.log(program); + return run(); }