<!DOCTYPE html> <html> <head> <title>ChocoPy Web IDE</title> <link rel="stylesheet" href="css/normalize.css" /> <link rel="stylesheet" href="css/sakura.css" /> <script src="js/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script> <script src="js/ace.js" type="text/javascript" charset="utf-8"></script> <style> .example { border: 1px solid black; width: 50em; height: 20em; } .compile-error-marker { position: absolute; background-color: rgba(255, 200, 200, 0.3); } .compile-button { float: right; } </style> </head> <body> <h1>Compile Me!</h1> <select id="p1"> <option value="s">My Parser</option> <option value="r" selected>Reference Parser</option> </select> <button id='parseButton' class='compile-button'>Parse Syntax</button> <br /> <select id="p2"> <option value="s">My Semantic Analysis</option> <option value="r" selected>Reference Semantic Analysis</option> </select> <button id='staticCheckButton' class='compile-button'>Run Static Checks</button> <br /> <select id="p3"> <option value="s">My Code Generator</option> <option value="r" selected>Reference Code Generator</option> </select> <button id='compileButton' class='compile-button'>Compile to RISC-V</button> <pre class="example"></pre> <script> var compileService = "/compile"; var Range = require('ace/range').Range; function makeEditor(example) { var parseButton = $("#parseButton"); var staticCheckButton = $("#staticCheckButton"); var compileButton = $("#compileButton"); var editor = ace.edit(example, { theme: "ace/theme/github", mode: "ace/mode/python", fontSize: "1em" }); var errorMarkers = [] function clearMarkers() { editor.session.clearAnnotations(); for (var marker of errorMarkers) { editor.session.removeMarker(marker); } errorMarkers.length = 0; } editor.on('change', () => { clearMarkers(); }); $(".compile-button").click((e) => { var button = e.target.id; console.assert(button == 'parseButton' || button == 'staticCheckButton' || button == 'compileButton'); var parse = true; // always run stage 1 var check = button != 'parseButton'; // run unless only stage 1 requested var codegen = button == 'compileButton'; // run only when stage 3 requested clearMarkers(); var code = editor.getValue(); var p1 = parse ? $("#p1").val() : ""; var p2 = check ? $("#p2").val() : ""; var p3 = codegen ? $("#p3").val() : ""; if (codegen) { var resultWindow = window.open('venus.html?v=0.2.4' , '_blank'); if (resultWindow == null) { console.error("Could not open new window..."); return; // Cannot show result } resultWindow.onload = () => resultWindow.codeMirror.setValue("# Compiling... Please be patient. This can take a few seconds.\n" + "# (The first compilation takes the longest)"); } $.ajax({ url: compileService, type: "POST", contentType: "application/json; charset=utf-8", dataType: "json", data: JSON.stringify({input: code, passes:p1+p2+p3}), success: function(result) { if (result.asm) { var asm = result.asm; console.log(resultWindow.codeMirror); resultWindow.codeMirror.setValue("# Compiled ChocoPy Program to RISC-V assembly\n" + "# Execute (run or step-through) using the 'Simulator' tab above \n" + "# Output will appear on the bottom-left of the simulator\n" + asm); } else if (result.errors && result.errors.errors && result.errors.errors.length > 0) { if (codegen) { resultWindow.close(); } var annotations = [] for (var error of result.errors.errors) { var loc = error.location; var msg = error.message; var startLine = loc[0] - 1; var startCol = loc[1] - 1; var endLine = loc[2] - 1; var endCol = loc[3] - 1; var range = new Range(startLine, startCol, endLine, endCol+1); errorMarkers.push(editor.session.addMarker(range, "compile-error-marker", "text", true)); annotations.push({ row: Math.min(Math.max(0, startLine), editor.session.getLength()-1), text: msg, type: "error" }); } editor.session.setAnnotations(annotations); } else if (!codegen && result.kind && result.kind == "Program") { if (check) { alert("This program is semantically valid!"); } else { alert("This program parses!"); } } else { alert("Unknown error: Should not reach here :-\\"); } }, error: (xhr) => { var w = window; if (resultWindow) { w = resultWindow; } w.alert("Request to compile service failed :-(\n\n" + (xhr.responseText || "Unknown error")); if (resultWindow) { resultWindow.close(); } } }); }); } $(".example").each((i, e) => makeEditor(e)) </script> </body> </html>