-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
162 lines (161 loc) · 8.62 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
<!DOCTYPE html>
<html>
<head>
<title>JLearner</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/lib/codemirror.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/codemirror.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/addon/edit/matchbrackets.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/addon/hint/show-hint.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/addon/hint/show-hint.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/mode/clike/clike.js"></script>
<script src="https://cdn.jsdelivr.net/npm/cm-resize@1"></script>
<style>
body {font-family: Arial, Helvetica, sans-serif}
.result { font-style: italic; color: blue }
#callstack { background-color: lightgreen; border: 2px solid black; border-collapse: collapse }
.stackframe-title { text-align: center; border-top: 2px solid black; font-family: monospace; padding: 2px }
.stack-variable-name { text-align: right; font-family: monospace; padding: 2px 2px 2px 2px }
.keyword { font-family: monospace; font-weight: bold }
.stack-value-td { padding: 2px 2px 1.5px 2px }
.stack-value-div { padding: 1px 1px 1px 1px; background-color: white }
.object-table { background-color: #ffcccb; border: 2px solid black; border-radius: 5px; position: absolute }
.object-title-td { text-align: center; font-size: small }
.code { font-family: monospace; font-size: medium }
.field-name { text-align: right; font-family: monospace }
.field-value { background-color: white }
.CodeMirror {border: 1px solid black;}
.lint-error {font-family: arial; font-size: 70%; background: #ffa; color: #a00; padding: 2px 5px 3px; }
.lint-error-icon {color: white; background-color: red; font-weight: bold; border-radius: 50%; padding: 0 3px; margin-right: 7px;}
.syntax-error {background-color: #ff8080}
.current-instruction {background-color: lightgreen}
.cm-tab {
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);
background-position: right;
background-repeat: no-repeat;
}
</style>
</head>
<body style="background: lightgray">
<table width="100%"><tr><td width="*1"><h1>JLearner</h1></td><td style="text-align: center">Examples: <select id="examples"></select></td><td style="text-align: right"><a href="https://btj.github.io/jlearner/exercises.html">Exercises</a> <a href="https://btj.github.io/jlearner/java_vs_python.html">Java vs Python</a> <a href="https://btj.github.io/jlearner/language.html">Language Specification</a></td></tr></table>
<table width="100%" style="table-layout: fixed"><tr>
<td width="50%" style="vertical-align: top">
<p><b>Declarations:</b> <span id="abstractViewSpan" style="display: none"><input id="abstractViewCheckbox" type="checkbox" onchange="setViewMode(this.checked)">Abstract view</input></span></p>
<p><textarea id="declarations"></textarea></p>
<p><b>Statements:</b>
<button id="executeButton" onClick="executeStatements(false)">Execute (Ctrl+Enter)</button>
<button id="resetAndExecuteButton" onClick="resetAndExecute()">Reset machine and execute (Shift+Ctrl+Enter)</button>
<button id="stepThroughStatementsButton" onclick="executeStatements(true)">Step through</button></p>
<p><textarea id="statements"></textarea></p>
<p><b>Expression:</b> <button id="evaluateButton" onClick="evaluateExpression()">Evaluate (Ctrl+Enter)</button> <button id="stepThroughExpressionButton" onclick="evaluateExpression(true)">Step through</button></p>
<p><textarea id="expression"></textarea></p>
<p><b>Results:</b> <button onClick="resultsEditor.setValue('')">Clear</button></p>
<p><textarea id="results"></textarea></p>
</td>
<td id="machine" height="100%" style="vertical-align: top; padding-left: 20px">
<p>
<button id="stepButton" onclick="step()" disabled>Step</button>
<button id="smallStepButton" onclick="smallStep()" disabled>Small step</button>
<button id="stepOverButton" onclick="stepOver()" disabled>Step over</button>
<button id="stepOutButton" onClick="stepOut()" disabled>Step out</button>
<button id="continueButton" onclick="continue_()" disabled>Continue</button>
<button onclick="reset()">Reset (Ctrl+Esc)</button></p>
<div style="position: relative; display: flex; flex-direction: row; align-items: stretch">
<table id="callstack" style="background-color: lightgreen; border: 2px solid black; border-collapse: collapse">
</table>
<div id="heap" style="position: relative; flex-grow: 1; margin-left: 40px">
<!--
<table id="to" class="object-table">
<tr><td colspan="2" class="object-title-td"><span class="code" ><span class="keyword">int</span>[]</span> (id=1) (length=4)</td></tr>
<tr><td class="field-name"><span class="keyword">int</span> [0]</td><td class="field-value">50</td></tr>
<tr><td class="field-name">int [1]</td><td class="field-value">50</td></tr>
</table>
-->
</div>
<svg id="arrows-svg" style="position: absolute; left: 0; top: 0; pointer-events: none">
<defs>
<!-- arrowhead marker definition -->
<marker id="arrowhead" viewBox="0 0 10 10" refX="10" refY="5"
markerWidth="8" markerHeight="12"
orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" />
</marker>
</defs>
<line id="arrow" x1="0" y1="0" x2="100" y2="100" style="stroke:rgb(0,0,0);stroke-width:1;visibility:hidden"
marker-end="url(#arrowhead)" />
</svg>
</div>
</td>
</tr>
</table>
<script>
var declarationsEditor = CodeMirror.fromTextArea(document.getElementById('declarations'), {
lineNumbers: false,
matchBrackets: true,
mode: 'text/x-java'
});
declarationsEditor.setSize("100%", "15em");
cmResize(declarationsEditor);
declarationsEditor.on('changes', () => clearErrorWidgets());
var statementsEditor = CodeMirror.fromTextArea(document.getElementById('statements'), {
lineNumbers: false,
matchBrackets: true,
mode: 'text/x-java'
});
statementsEditor.on('changes', () => clearErrorWidgets());
statementsEditor.setSize("100%", "10em");
cmResize(statementsEditor);
statementsEditor.on('keydown', (editor, event) => {
if (event.keyCode == 13 && event.ctrlKey) {
event.preventDefault();
if (event.shiftKey)
resetAndExecute();
else
executeStatements(false);
}
});
document.addEventListener('keydown', event => {
if (event.keyCode == 27 && event.ctrlKey) {
event.preventDefault();
reset();
}
});
var expressionEditor = CodeMirror.fromTextArea(document.getElementById('expression'), {
lineNumbers: false,
matchBrackets: true,
mode: 'text/x-java'
});
expressionEditor.on('changes', () => clearErrorWidgets());
expressionEditor.setSize("100%", "3em");
cmResize(expressionEditor);
var resultsEditor = CodeMirror.fromTextArea(document.getElementById('results'), {
matchBrackets: true,
mode: 'text/plain'
});
resultsEditor.setSize("100%", "10em");
cmResize(resultsEditor);
expressionEditor.on('keydown', (editor, event) => {
if (event.keyCode == 13 && event.ctrlKey) {
event.preventDefault();
evaluateExpression(false);
}
});
</script>
<!-- script>
let machine = document.getElementById('arrows-svg');
let arrow = document.getElementById('arrow');
let from = document.getElementById('from');
let to = document.getElementById('to');
let fromRects = from.getClientRects();
console.log(fromRects);
let toRects = to.getClientRects();
console.log(toRects);
let machineRects = machine.getClientRects();
console.log(machineRects);
arrow.x1.baseVal.value = (fromRects[0].left + fromRects[0].right) / 2 - machineRects[0].left;
arrow.y1.baseVal.value = (fromRects[0].top + fromRects[0].bottom) / 2 - machineRects[0].top;
arrow.x2.baseVal.value = toRects[0].left - machineRects[0].left;
arrow.y2.baseVal.value = toRects[0].top - machineRects[0].top;
</script -->
<script src="jlearner.js"></script>
</body>
</html>