You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
178 lines
6.2 KiB
178 lines
6.2 KiB
<!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>
|