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();
 }