Code now highlighted while executing.
[CS-101.git] / turing_tarpit.html
blob1fb696d593075397c2dec375af3279feab134863
1 <html>
2 <title>Turing Tarpit Simulator</title>
3 <script>
5 /* internal values for simulated computer */
6 var ins_pointer = 0; /* instruction pointer */
7 var dat_pointer = 0; /* data pointer */
8 var dat_pointer_changed = 0; /* bool set to 1 if data pointer has changed in the last step */
9 var dat_pointer_last_address = 0; /* address of data pointer in last step */
10 var ram_last_address = 0; /* address of RAM updated in last step */
11 var breakpoints = 1; /* bool set to 0 to ignore breakpoints */
12 var ram = new Array();
14 /* objects that display data to the user */
15 var disp_code;
16 var disp_ram;
17 var disp_ins_pointer;
18 var disp_pointer = "<div id=disp_pointer>&#8658;</div>"; /* data pointer displayed in memory block */
20 /* highlight current instruction running on machine */
21 function code_highlight(inputEl, selStart, selEnd) {
22 if (inputEl.setSelectionRange) {
23 inputEl.focus();
24 inputEl.setSelectionRange(selStart, selEnd);
25 } else if (inputEl.createTextRange) {
26 var range = inputEl.createTextRange();
27 range.collapse(true);
28 range.moveEnd('character', selEnd);
29 range.moveStart('character', selStart);
30 range.select();
34 /* turns breakpoints on and off */
35 function debug_toggle_breakpoints()
37 var button = document.getElementById("dbg_status");
38 if(breakpoints) {
39 breakpoints=0;
40 button.innerHTML='<img src="http://opentextbook.info/icons/32x32/bug_delete.png">';
41 }else {
42 breakpoints=1;
43 button.innerHTML='<img src="http://opentextbook.info/icons/32x32/bug_add.png">';
47 /* removes all breakpoints in source code */
48 function debug_remove_breakpoints()
50 /* ask user for permission first */
51 var ans = confirm("Permanently remove all breakpoints from code?");
52 var code = document.getElementById("code");
53 if(ans) { code.value = code.value.replace( /\*/g , '' ); }
56 /* execute next instruction from input */
57 function exe_nxt_inst()
59 var code = document.getElementById("code");
60 var ins = null; /* current instruction from code */
61 if(ins_pointer > code.value.length) {
62 alert("HALT: Program is Complete");
65 ins = code.value.substring(ins_pointer-1,ins_pointer); /* get data at ins_pointer location */
67 /* highlight code currently executing on screen */
68 code_highlight(code, ins_pointer-1, ins_pointer);
70 switch(ins)
72 case '+':
73 ram_modify(dat_pointer, 1);
74 break;
75 case '-':
76 ram_modify(dat_pointer, -1);
77 break;
78 case '>':
79 dat_point_modify(1);
80 break;
81 case '<':
82 dat_point_modify(-1);
83 break;
84 case '*': /* these are comments - a break from the standard language */
85 if(breakpoints) { stop(); }
86 break;
87 case '.':
88 print_mem();
89 break;
90 default:
91 /* must be a comment :) */
96 rewind code to beginning reset all memory locations
97 this simulates rebooting the computer
99 function reset()
101 update_ins_pointer(0);
102 dat_point_modify(0);
103 ram_reset();
104 ram_highlight_clear();
105 dat_point_highlight();
106 document.getElementById("output_disp").innerHTML = '';
107 document.getElementById("addr_0").innerHTML = "0" + disp_pointer;
110 /* stop stepping through code on timer if breakpoints enabled */
111 function stop()
113 alert("stop");
116 /* run through program on timer, stopping at breakpoints if enabled */
117 function run()
119 var total_steps = document.getElementById("code").value.length;
120 while(ins_pointer <= total_steps) { step_next(); }
123 /* step forward one instruction */
124 function step_next()
126 update_ins_pointer(1);
127 exe_nxt_inst();
128 dat_point_highlight();
131 /* more back one instruction - undoes work of previous instruction */
132 function step_back()
134 update_ins_pointer(-1);
135 dat_point_highlight();
138 /* update instruction pointer
139 direction:
141 1 increment pointer by one
142 0 set pointer to 0
143 -1 decrement pointer by one
145 function update_ins_pointer(direction)
147 if(direction < 0 && ins_pointer != 0 ) { ins_pointer--; }
148 else if (direction == 0 ) { ins_pointer = 0; }
149 else { ins_pointer++; }
150 disp_ins_pointer.value = ins_pointer;
153 /* setup virtual machine - must be called on page load */
154 function init_form()
156 disp_code = document.getElementById("code");
157 disp_ins_pointer = document.getElementById("ins_pointer_disp");
158 disp_ram = document.getElementById("ram_disp");
159 ram_reset();
160 ram_init();
161 document.getElementById("addr_0").innerHTML = "0" + disp_pointer;
162 /* reset_output(); */
165 /* reset all RAM to 0 */
166 function ram_reset()
168 var i;
169 for(i=0; i < 64; i++) { ram[i] = 0; }
172 /* update background color of one memory address */
173 function ram_highlight(address)
175 var disp_last_address = document.getElementById("ram_"+ram_last_address);
176 if(address%2==0) { /* will reset to original color of _stiped_ table */
177 document.getElementById("ram_"+address).style.backgroundColor = "#ff0";
178 } else {
179 document.getElementById("ram_"+address).style.backgroundColor = "#de0";
182 if(disp_last_address) {
183 if(ram_last_address%2==0) {
184 disp_last_address.style.backgroundColor = "#fff";
185 } else {
186 disp_last_address.style.backgroundColor = "#def";
191 /* remove highlight from all memory cells regardless of current status */
192 function ram_highlight_clear()
194 var i;
195 for(i=0; i < 64; i++)
197 if(i%2==0) {
198 document.getElementById("ram_"+i).style.backgroundColor = "#fff";
199 } else {
200 document.getElementById("ram_"+i).style.backgroundColor = "#def";
202 document.getElementById("ram_"+i).innerHTML = ram[i];
206 /* define RAM on screen */
207 function ram_init()
209 var i;
210 var table = "<table id=memory_table>\n";
211 for(i=0; i < 16; i++){
212 if(i%2==0) {
213 table += "\t<tr>";
214 } else {
215 table += "\t<tr class=odd>";
217 table += "<td width='35' class=addr id=addr_"+i+">"+i+"</td><td width='35' class=ram id=ram_"+i+">";
218 table += ram[i]+"</td><td width='35' class=addr id=addr_"+(i+16)+">";
219 table += (i+16)+"</td><td class=ram id=ram_"+(i+16)+">"+ram[i+16]+"</td>\n";
220 table += "<td class=addr id=addr_"+(i+32)+">"+(i+32)+"</td><td width='35' class=ram id=ram_";
221 table += (i+32)+">"+ram[i+32]+"</td><td class=addr id=addr_";
222 table += (i+48)+">"+(i+48)+"</td><td width='35' class=ram id=ram_"+(i+48)+">"+ram[i+48]+"</td></tr>\n";
224 table += "</table>\n";
225 disp_ram.innerHTML = table;
228 /* modify the value at this address - reset RAM highlights for all addresses
229 1 increment RAM by one
230 0 set RAM to 0
231 -1 decrement RAM by one
233 function ram_modify(address, change)
235 if(address < 0 || address > 63) {
236 alert("SEGFAULT: Cannot Modify Data Outside of Memory Range");
237 return;
240 if (change > 0 ) {
241 ram[address]++;
242 } else if(change < 0 ) {
243 ram[address]--;
244 } else {
245 ram[address] = 0;
247 ram_highlight(address);
248 document.getElementById("ram_"+address).innerHTML = ram[address];
249 ram_last_address = address;
252 /* modify state of data pointer */
253 function dat_point_modify(change)
255 dat_pointer_last_address = dat_pointer;
256 if (change > 0 ) {
257 dat_pointer++;
258 } else if(change < 0 ) {
259 /* could put SEGFAULT here, but C does not have a check for this, so neither will I ;) */
260 dat_pointer--;
261 } else {
262 dat_pointer = 0;
265 /* place '>' char next to memory address in table */
266 if(dat_pointer >= 0 && dat_pointer < 64) {
267 document.getElementById("addr_"+dat_pointer).innerHTML = dat_pointer + disp_pointer;
270 /* remove '>' char next to memory address in table */
271 if(dat_pointer_last_address >= 0 && dat_pointer_last_address < 64) {
272 document.getElementById("addr_"+dat_pointer_last_address).innerHTML = dat_pointer_last_address;
275 document.getElementById("dat_pointer_disp").value = dat_pointer;
276 dat_pointer_changed = 1;
279 /* turns on and off data pointer highlight if it has changed this step */
280 function dat_point_highlight()
282 var dat = document.getElementById("dat_pointer_disp");
283 //alert(dat_pointer_last_address+"\t"+dat_pointer);
284 if(dat_pointer_changed) {
285 //alert("diff");
286 dat.style.backgroundColor = "#ff0";
287 dat_pointer_changed = 0;
288 } else {
289 //alert("same");
290 dat.style.backgroundColor = "#fff";
293 /* as a convenience to the user, set to red if pointer is out of memory range */
294 if(dat_pointer < 0 || dat_pointer > 63) {
295 dat.style.backgroundColor = "#f00";
299 /* print ASCII representation of memory at data pointer */
300 function print_mem()
302 var x = String.fromCharCode(ram[dat_pointer]);
303 document.getElementById("output_disp").innerHTML += x;
306 </script>
308 <style type="text/css">
310 body {
311 font-family: Tahoma, Arial, Helvetica, sans-serif;
314 #disp_pointer {
315 float:right;
316 color: #f00;
319 #code_buttons {
320 position: absolute;
321 top: 570px;
322 left: 10px;
325 #input_banner {
326 position: absolute;
327 top: 120px;
328 left: 10px;
331 #da_banner {
332 position: absolute;
333 top: 450px;
334 left: 625px;
337 #ip_banner {
338 position: absolute;
339 top: 400px;
340 left: 625px;
343 #output_banner {
344 position: absolute;
345 top: 120px;
346 left: 625px;
349 #memory_banner {
350 position: absolute;
351 top: 120px;
352 left: 315px;
355 #input {
356 position: absolute;
357 top: 140px;
358 left: 10px;
361 #ram_disp {
362 position: absolute;
363 top: 140px;
364 left: 315px;
367 #memory_table {
368 border:1px solid #000;
369 border-collapse: collapse;
372 td {
373 padding: 5px;
374 border-bottom:1px solid #000;
377 .odd {
378 background-color: #def;
380 .odd td {
381 border-bottom: 1px solid #cef;
384 .addr {
385 color: #00f;
388 .ram {
389 border-right:1px solid #000;
392 #output {
393 position: absolute;
394 top: 140px;
395 left: 625px;
398 #instruction {
399 position: absolute;
400 top: 425px;
401 left: 625px;
404 #data {
405 position: absolute;
406 top: 475px;
407 left: 625px;
411 </style>
412 <body onLoad="init_form();">
414 <center><h2>Turing Tarpit Simulator</h2></center>
416 <center>
417 <button onClick='reset();'><img src="http://opentextbook.info/icons/32x32/resultset_first.png"></button>
418 &nbsp;&nbsp;
419 <button onClick='step_back();'><img src="http://opentextbook.info/icons/32x32/resultset_previous.png"></button>
420 &nbsp;&nbsp;
421 <button onClick='step_next();'><img src="http://opentextbook.info/icons/32x32/resultset_next.png"></button>
422 &nbsp;&nbsp;
423 <button onClick='run();'><img src="http://opentextbook.info/icons/32x32/resultset_last.png"></button>
424 &nbsp;&nbsp;
425 <button onClick='reset();'><img src="http://opentextbook.info/icons/32x32/cancel.png"></button>
426 &nbsp;&nbsp;
427 <button disabled><img src="http://opentextbook.info/icons/32x32/disk.png"></button>
428 </center>
430 <div id="code_buttons">
431 <button id="dbg_status" onClick='debug_toggle_breakpoints();'>
432 <img src="http://opentextbook.info/icons/32x32/bug_add.png">
433 </button>
434 &nbsp;&nbsp;
435 <button id="dbg_status" onClick='debug_remove_breakpoints();'>
436 <img src="http://opentextbook.info/icons/32x32/bin.png">
437 </button>
438 </div>
440 <div id="input_banner">INPUT</div>
441 <div id="input"><textarea id="code" rows="27" cols="38"></textarea></div>
443 <div id="ip_banner">INSTRUCTION POINTER</div>
444 <div id="instruction"><input id="ins_pointer_disp" type="text" diabled value=0></div>
446 <div id="da_banner">DATA POINTER</div>
447 <div id="data"><input id="dat_pointer_disp" type="text" diabled value=0></div>
449 <div id="memory_banner">MEMORY</div>
450 <div id="ram_disp"></div>
451 <div id="output_banner">OUTPUT</div>
452 <div id="output">
453 <textarea name=code id=output_disp rows="15" cols="38" disabled ></textarea>
454 </div>
456 </body>
457 </html>