famalam 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +4 -1
- data/lib/famalam.rb +5 -3
- data/lib/famalam/patches.rb +33 -0
- data/public/scripts/graphics.js +112 -0
- data/public/scripts/step.js +99 -0
- data/public/scripts/submitter.js +28 -0
- data/public/styles/cpu.css +68 -0
- data/public/styles/master.css +29 -0
- data/public/styles/ram.css +33 -0
- data/public/styles/submit.css +53 -0
- data/views/index.haml +8 -0
- data/views/program.haml +79 -0
- metadata +74 -6
- data/bin/famalam +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 15842d54b4123e74f02c913e6075cc9d74bcbd71fdb449883e74cf7c00e3236b
|
4
|
+
data.tar.gz: 89521d9e9c1894ae915b8cd6ac7c071efadd20357a4b62de3c877ab484111738
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0e4efdebbd3dd701108b0330a983077bdfac247e1a0946d9e66c91d9240c1064d13091b95856ae6b857cb6f16916a29e41cda954fb5a17ca148aea14512d4d0e
|
7
|
+
data.tar.gz: 932b9e080668bc7c146f2bfff9ed47992ed44ebdd39fa7a54e0a839952a6dee27f3f2683eeb432c46dc4766e3146e10990d260b3de908c7e4dbccf4b68a4f38f
|
data/README.md
CHANGED
data/lib/famalam.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
require 'fam'
|
2
|
+
require 'haml'
|
3
|
+
|
1
4
|
module FAMalam
|
2
|
-
VERSIONS = { :major => 0, :minor =>
|
5
|
+
VERSIONS = { :major => 0, :minor => 1, :tiny => 0 }
|
3
6
|
|
4
7
|
def self.version *args
|
5
8
|
VERSIONS.flatten.select.with_index { |val, i| i.odd? }.join '.'
|
6
9
|
end
|
7
10
|
end
|
8
11
|
|
9
|
-
Dir["#{File.dirname __FILE__}/
|
10
|
-
Dir["#{File.dirname __FILE__}/fam/**/*.rb"].each { |f| require f }
|
12
|
+
Dir["#{File.dirname __FILE__}/famalam/*.rb"].each { |f| require f }
|
@@ -0,0 +1,33 @@
|
|
1
|
+
FAM::Machine::CPU.class_eval do
|
2
|
+
def cpu_output out, ascii
|
3
|
+
ascii == :PLAIN ? out.to_s : out.chr
|
4
|
+
end
|
5
|
+
|
6
|
+
def inject_input i
|
7
|
+
@inject = i
|
8
|
+
end
|
9
|
+
|
10
|
+
def cpu_input
|
11
|
+
@inject || -1
|
12
|
+
end
|
13
|
+
|
14
|
+
def step parsed
|
15
|
+
@parsed = parsed
|
16
|
+
return {:state => 'done'} if @tree_index >= parsed.tree.size || @halted
|
17
|
+
@tree_index += 1
|
18
|
+
node = parsed[@tree_index]
|
19
|
+
if parsed[@tree_index].base_name == 'InNode' && !@rerun
|
20
|
+
@tree_index -= 1
|
21
|
+
@rerun = true
|
22
|
+
return {:state => 'running', :input => true, :output => @outputting}
|
23
|
+
end
|
24
|
+
|
25
|
+
@rerun = false
|
26
|
+
status = execute node
|
27
|
+
if status == :STOP
|
28
|
+
@halted = true
|
29
|
+
return {:state => 'done'}
|
30
|
+
end
|
31
|
+
{:state => 'running', :input => false, :output => @outputting}
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
const pad = (n, width, char) => {
|
2
|
+
char = char || '0';
|
3
|
+
n = n + '';
|
4
|
+
return n.length >= width ? n : new Array(width - n.length + 1).join(char) + n;
|
5
|
+
}
|
6
|
+
|
7
|
+
const draw_step = (step) => {
|
8
|
+
if (step['ERROR']) {
|
9
|
+
$('#alloc').removeAttr('disabled');
|
10
|
+
return;
|
11
|
+
}
|
12
|
+
$('#alloc').prop('disabled', true);
|
13
|
+
for (let i = 0; i < step['ram'].length; i++) {
|
14
|
+
let elem = $('.address:nth-child(' + (i + 1) + ') > .value')
|
15
|
+
if (elem.html() != '' + step['ram'][i]) {
|
16
|
+
elem.empty();
|
17
|
+
elem.html(step['ram'][i])
|
18
|
+
elem.stop().css({ backgroundColor: '#ffff9c' });
|
19
|
+
elem.animate({ backgroundColor: '#ffffff' }, 3200 / get_clock());
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
let reg_elem = $('.cpu .registers');
|
24
|
+
reg_elem.empty();
|
25
|
+
for (let i = 0; i < Object.keys(step['registers']).length; i++) {
|
26
|
+
reg_elem.append(
|
27
|
+
`<div class="register">
|
28
|
+
<div class="name">`
|
29
|
+
+ Object.keys(step['registers'])[i]
|
30
|
+
+ `</div>
|
31
|
+
<div class="value">`
|
32
|
+
+ Object.values(step['registers'])[i]
|
33
|
+
+ `</div>
|
34
|
+
</div>`);
|
35
|
+
}
|
36
|
+
|
37
|
+
let out_elem = $('.cpu .output');
|
38
|
+
if (step['output'] != '') {
|
39
|
+
out_elem.append(`<div>` + step['output'] + `</div>`);
|
40
|
+
out_elem.animate({ scrollTop: out_elem.prop("scrollHeight")}, 100);
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
let get_alloc = () => {
|
45
|
+
return $('#alloc').val() - 0;
|
46
|
+
}
|
47
|
+
|
48
|
+
draw_ram = () => {
|
49
|
+
let alloc = get_alloc();
|
50
|
+
$('.ram').empty();
|
51
|
+
for (let i = 0; i < get_alloc(); i++) {
|
52
|
+
$('.ram').append(`
|
53
|
+
<div class="address">
|
54
|
+
<div class="number">` + pad(i, 3) + `</div>
|
55
|
+
<div class="value">NULL</div>
|
56
|
+
</div>
|
57
|
+
`);
|
58
|
+
$('.address:nth-child(' + (i + 1) + ') .value').css({
|
59
|
+
width: (500 / alloc) + 'em'
|
60
|
+
});
|
61
|
+
$('.address:nth-child(' + (i + 1) + ') .number').css({
|
62
|
+
width: (200 / alloc) + 'em'
|
63
|
+
});
|
64
|
+
}
|
65
|
+
}
|
66
|
+
$('#alloc').change(draw_ram);
|
67
|
+
|
68
|
+
$(document).ready(() => {
|
69
|
+
// disable inputs
|
70
|
+
$('input[name=input]').prop('disabled', true);
|
71
|
+
// Initiate RAM
|
72
|
+
draw_ram();
|
73
|
+
});
|
74
|
+
|
75
|
+
// Textbox tab handling
|
76
|
+
let tab_level = 0;
|
77
|
+
$(document).delegate('#code', 'keydown', function(e) {
|
78
|
+
let tab = " ";
|
79
|
+
|
80
|
+
let key_code = e.keyCode || e.which;
|
81
|
+
if (key_code == 9 && tab) { // Tab key
|
82
|
+
let start = this.selectionStart;
|
83
|
+
let end = this.selectionEnd;
|
84
|
+
$(this).val($(this).val().substring(0, start)
|
85
|
+
+ tab
|
86
|
+
+ $(this).val().substring(end));
|
87
|
+
this.selectionStart = this.selectionEnd = start + tab.length;
|
88
|
+
tab_level++;
|
89
|
+
return false
|
90
|
+
}
|
91
|
+
if (key_code == 13) { // Autotab on enter
|
92
|
+
let start = this.selectionStart;
|
93
|
+
let end = this.selectionEnd;
|
94
|
+
$(this).val($(this).val().substring(0, start)
|
95
|
+
+ "\n"
|
96
|
+
+ (new Array(tab.length * tab_level + 1).join(tab))
|
97
|
+
+ $(this).val().substring(end));
|
98
|
+
this.selectionStart = this.selectionEnd = 1 + start + tab.length * tab_level;
|
99
|
+
return false;
|
100
|
+
}
|
101
|
+
if (key_code == 8) { // Backspace key
|
102
|
+
let start = this.selectionStart;
|
103
|
+
let end = this.selectionEnd;
|
104
|
+
if ($(this).val().substring(start, start - tab.length) == tab) {
|
105
|
+
$(this).val($(this).val().substring(0, start-tab.length)
|
106
|
+
+ $(this).val().substring(end));
|
107
|
+
this.selectionStart = this.selectionEnd = start - tab.length;
|
108
|
+
if (tab_level > 0) { tab_level--; }
|
109
|
+
return false;
|
110
|
+
}
|
111
|
+
}
|
112
|
+
});
|
@@ -0,0 +1,99 @@
|
|
1
|
+
const get_clock = () => {
|
2
|
+
let c = Math.abs($('input[name=clock]').val() - 0) + 0.001;
|
3
|
+
if (c > 21) {
|
4
|
+
$('input[name=clock]').val("20");
|
5
|
+
get_clock();
|
6
|
+
}
|
7
|
+
return c;
|
8
|
+
}
|
9
|
+
|
10
|
+
const handle_input = interval => {
|
11
|
+
interval.disable();
|
12
|
+
let input_box = $('input[name=input]')
|
13
|
+
input_box.prop('disabled', false);
|
14
|
+
input_box.focus();
|
15
|
+
|
16
|
+
let input;
|
17
|
+
const wait = () => {
|
18
|
+
console.log('waiting...');
|
19
|
+
if (!input_box.val()) window.setTimeout(wait, 5);
|
20
|
+
else {
|
21
|
+
input = input_box.val();
|
22
|
+
interval.enable();
|
23
|
+
input_box
|
24
|
+
.val('')
|
25
|
+
.attr('placeholder', input)
|
26
|
+
.blur()
|
27
|
+
.prop('disabled', true);
|
28
|
+
|
29
|
+
$.ajax({
|
30
|
+
type: 'POST',
|
31
|
+
url: '/program/input',
|
32
|
+
async: false,
|
33
|
+
data: { input: input + " ...in" },
|
34
|
+
error: (s, e) => {
|
35
|
+
console.log(
|
36
|
+
'An error occured in posting input!\nERROR: ',
|
37
|
+
s, '\n\n', e
|
38
|
+
);
|
39
|
+
}
|
40
|
+
});
|
41
|
+
return;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
wait();
|
45
|
+
input_box.attr('placeholder', '');
|
46
|
+
return input;
|
47
|
+
}
|
48
|
+
|
49
|
+
class ClockInterval {
|
50
|
+
constructor(f, speed) {
|
51
|
+
this.lambda = f;
|
52
|
+
this.speed = speed;
|
53
|
+
this.interval = null;
|
54
|
+
}
|
55
|
+
enable(speed=this.speed) {
|
56
|
+
this.speed = speed;
|
57
|
+
this.interval = window.setInterval(this.lambda, (1.0 / speed) * 1000);
|
58
|
+
}
|
59
|
+
disable() {
|
60
|
+
window.clearInterval(this.interval);
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
|
65
|
+
const stepper = () => {
|
66
|
+
let clock = get_clock();
|
67
|
+
let step_interval;
|
68
|
+
|
69
|
+
const response = () => {
|
70
|
+
let step = {};
|
71
|
+
$.ajax({
|
72
|
+
url: "/program/step.json",
|
73
|
+
async: false,
|
74
|
+
dataType: 'json',
|
75
|
+
success: (data) => {
|
76
|
+
step = data;
|
77
|
+
}
|
78
|
+
});
|
79
|
+
if (step['ERROR']) step_interval.disable();
|
80
|
+
if (step['inputting']) handle_input(step_interval);
|
81
|
+
return step;
|
82
|
+
}
|
83
|
+
|
84
|
+
const update = () => {
|
85
|
+
let step = response();
|
86
|
+
console.log("Errors: ", step['ERROR']);
|
87
|
+
console.log("Step: ", step);
|
88
|
+
draw_step(step);
|
89
|
+
}
|
90
|
+
|
91
|
+
|
92
|
+
step_interval = new ClockInterval(update, clock)
|
93
|
+
step_interval.enable();
|
94
|
+
$('input[name=clock]').on("change paste keyup", () => {
|
95
|
+
clock = get_clock();
|
96
|
+
step_interval.disable();
|
97
|
+
step_interval.enable(clock);
|
98
|
+
});
|
99
|
+
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
$(document).ready(() => {
|
2
|
+
let clock = get_clock();
|
3
|
+
|
4
|
+
$('form').submit(() => {
|
5
|
+
$.ajax({
|
6
|
+
type: 'POST',
|
7
|
+
url: '/program',
|
8
|
+
async: false,
|
9
|
+
data: {
|
10
|
+
title: $('input[name=title]').val(),
|
11
|
+
code: $('textarea[name=code]').val(),
|
12
|
+
alloc: get_alloc(),
|
13
|
+
clock: clock,
|
14
|
+
},
|
15
|
+
error: () => {
|
16
|
+
console.log('Code could not be sent!');
|
17
|
+
},
|
18
|
+
success: (m) => {
|
19
|
+
stepper();
|
20
|
+
}
|
21
|
+
});
|
22
|
+
return false;
|
23
|
+
});
|
24
|
+
$('#submit').click(() => {
|
25
|
+
$('form').submit();
|
26
|
+
return false;
|
27
|
+
});
|
28
|
+
})
|
@@ -0,0 +1,68 @@
|
|
1
|
+
.cpu {
|
2
|
+
float: left;
|
3
|
+
width: 10em;
|
4
|
+
border: 1px dotted #ccc;
|
5
|
+
border-radius: 4px;
|
6
|
+
padding: 1em;
|
7
|
+
}
|
8
|
+
|
9
|
+
.cpu .input, .cpu .input input {
|
10
|
+
width: 100%;
|
11
|
+
padding: 0;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
.cpu .CU {
|
15
|
+
width: calc(100% - 8px);
|
16
|
+
padding: 4px;
|
17
|
+
margin: 5px 0;
|
18
|
+
border: 1px solid #e1e1e1;
|
19
|
+
border-radius: 4px;
|
20
|
+
min-height: 1em;
|
21
|
+
}
|
22
|
+
|
23
|
+
.cpu .registers, .cpu .output {
|
24
|
+
margin: 5px 0;
|
25
|
+
padding: 0 3px;
|
26
|
+
border: 1px solid #e1e1e1;
|
27
|
+
border-radius: 4px;
|
28
|
+
min-height: 1em;
|
29
|
+
}
|
30
|
+
.cpu .register {
|
31
|
+
margin: 4px 0;
|
32
|
+
border: 1px solid #e1e1e1;
|
33
|
+
border-radius: 3px;
|
34
|
+
padding: 0;
|
35
|
+
font-family: 'FantasqueSansMonoRegular', monospace;
|
36
|
+
}
|
37
|
+
.cpu .register .name {
|
38
|
+
display: inline-block;
|
39
|
+
text-align: right;
|
40
|
+
padding: 2px 4px 2px 0;
|
41
|
+
border-right: 1px solid #e1e1e1;
|
42
|
+
width: 2.4em;
|
43
|
+
}
|
44
|
+
.cpu .register .value {
|
45
|
+
display: inline-block;
|
46
|
+
}
|
47
|
+
|
48
|
+
.cpu .output {
|
49
|
+
overflow-y: scroll;
|
50
|
+
padding: 0;
|
51
|
+
min-height: 2em;
|
52
|
+
max-height: 4em;
|
53
|
+
}
|
54
|
+
.cpu .output div {
|
55
|
+
padding: 0 0.5em;
|
56
|
+
font-family: 'FantasqueSansMonoRegular', monospace;
|
57
|
+
}
|
58
|
+
.cpu .output div:nth-child(2n) {
|
59
|
+
background: #f4f4f4;
|
60
|
+
}
|
61
|
+
|
62
|
+
.cpu .input input {
|
63
|
+
width: calc(100% - 4px);
|
64
|
+
margin: 5px 0 0 0;
|
65
|
+
padding: 3px 2px;
|
66
|
+
border: 1px solid #e1e1e1;
|
67
|
+
border-radius: 4px;
|
68
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
@import url('https://fontlibrary.org/face/fantasque-sans-mono');
|
2
|
+
@import url('https://fonts.googleapis.com/css?family=Rubik:400,400i,700');
|
3
|
+
|
4
|
+
* { outline: none; }
|
5
|
+
body, html {
|
6
|
+
padding: 0;
|
7
|
+
margin: 0;
|
8
|
+
overflow-y: hidden;
|
9
|
+
font-size: 16px;
|
10
|
+
font-weight: 400;
|
11
|
+
font-family: 'Rubik', sans-serif;
|
12
|
+
color: #222;
|
13
|
+
}
|
14
|
+
|
15
|
+
|
16
|
+
#post, .computer {
|
17
|
+
height: calc(100vh - 5rem);
|
18
|
+
margin: 1em;
|
19
|
+
}
|
20
|
+
|
21
|
+
#post {
|
22
|
+
width: 14em;
|
23
|
+
float: left;
|
24
|
+
padding: 1.5em;
|
25
|
+
}
|
26
|
+
.computer {
|
27
|
+
width: 44em;
|
28
|
+
float: right;
|
29
|
+
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
.ram {
|
2
|
+
width: 31em;
|
3
|
+
background: none;
|
4
|
+
padding: 5px;
|
5
|
+
float: right;
|
6
|
+
overflow: auto;
|
7
|
+
text-align: right;
|
8
|
+
}
|
9
|
+
.address {
|
10
|
+
display: inline-block;
|
11
|
+
background-color: rgba(255, 255, 255, 0.8);
|
12
|
+
border: 1px solid #ccc;
|
13
|
+
border-radius: 3px;
|
14
|
+
margin: 3px 1px;
|
15
|
+
font-size: 0.6em;
|
16
|
+
font-family: 'FantasqueSansMonoRegular', monospace;
|
17
|
+
text-align: center;
|
18
|
+
}
|
19
|
+
|
20
|
+
.address .value, .address .number {
|
21
|
+
padding: 4px;
|
22
|
+
display: inline-block;
|
23
|
+
}
|
24
|
+
|
25
|
+
.address .number {
|
26
|
+
float: left;
|
27
|
+
border-right: 1px solid #ccc;
|
28
|
+
}
|
29
|
+
|
30
|
+
.address .value {
|
31
|
+
border-top-right-radius: 4px;
|
32
|
+
border-bottom-right-radius: 4px;
|
33
|
+
}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#post {
|
2
|
+
display: inline-block;
|
3
|
+
border: 1px solid #ccc;
|
4
|
+
border-radius: 5px;
|
5
|
+
}
|
6
|
+
|
7
|
+
#post input, #post #code, #post select {
|
8
|
+
display: block;
|
9
|
+
margin: 0 0 1em 0;
|
10
|
+
width: 100%;
|
11
|
+
font-family: 'Rubik', sans-serif;
|
12
|
+
}
|
13
|
+
#post input:last-child {
|
14
|
+
margin: 0;
|
15
|
+
}
|
16
|
+
#post input[name=title] {
|
17
|
+
border: none;
|
18
|
+
border-bottom: 1px dotted #ccc;
|
19
|
+
font-size: 1.5em;
|
20
|
+
}
|
21
|
+
|
22
|
+
#post #code {
|
23
|
+
padding: 0.5em;
|
24
|
+
width: calc(100% - 1em);
|
25
|
+
margin: 0 0 1em 0;
|
26
|
+
resize: none;
|
27
|
+
height: calc(100% - 13em);
|
28
|
+
font-family: 'FantasqueSansMonoRegular', monospace;
|
29
|
+
border: 1px solid #e1e1e1;
|
30
|
+
border-radius: 4px;
|
31
|
+
}
|
32
|
+
|
33
|
+
#post select {
|
34
|
+
border: 1px solid #e1e1e1;
|
35
|
+
border-radius: 4px;
|
36
|
+
background: none;
|
37
|
+
}
|
38
|
+
|
39
|
+
#post input[type=submit] {
|
40
|
+
background: #fff;
|
41
|
+
color: #333;
|
42
|
+
border-radius: 4px;
|
43
|
+
border: 1px solid #e1e1e1;
|
44
|
+
cursor: pointer;
|
45
|
+
transition: all .1s ease-in-out;
|
46
|
+
}
|
47
|
+
#post input[type=submit]:active {
|
48
|
+
background: #f3f3f3;
|
49
|
+
border: 1px solid #ccc;
|
50
|
+
}
|
51
|
+
#post input[type=submit]:hover {
|
52
|
+
background: #f8f8f8;
|
53
|
+
}
|
data/views/index.haml
ADDED
data/views/program.haml
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
!!!
|
2
|
+
%html
|
3
|
+
%head
|
4
|
+
%title FAMalam
|
5
|
+
%link{:rel => "stylesheet", :type => "text/css", :href => "https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css"}
|
6
|
+
%link{:rel => "stylesheet", :type => "text/css", :href => "/styles/master.css"}
|
7
|
+
%link{:rel => "stylesheet", :type => "text/css", :href => "/styles/submit.css"}
|
8
|
+
%link{:rel => "stylesheet", :type => "text/css", :href => "/styles/cpu.css"}
|
9
|
+
%link{:rel => "stylesheet", :type => "text/css", :href => "/styles/ram.css"}
|
10
|
+
%script{:type=> "text/javascript", :src => "https://code.jquery.com/jquery-3.3.1.min.js"}
|
11
|
+
%script{:type=> "text/javascript", :src => "https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"}
|
12
|
+
%body
|
13
|
+
%form{:id => "post", :action => "/program", :method => "POST"}
|
14
|
+
%input{:type => "text", :autofocus => "", :autocomplete => "off", :name => "title", :placeholder => "Project Title"}
|
15
|
+
%datalist{:id => "tickmarks"}
|
16
|
+
%option{:value => "2", :label => "2"}
|
17
|
+
%option{:value => "4"}
|
18
|
+
%option{:value => "6"}
|
19
|
+
%option{:value => "8"}
|
20
|
+
%option{:value => "10", :label => "10"}
|
21
|
+
%option{:value => "12"}
|
22
|
+
%option{:value => "14"}
|
23
|
+
%option{:value => "16"}
|
24
|
+
%option{:value => "18"}
|
25
|
+
%option{:value => "20", :label => "20"}
|
26
|
+
%input{:type => "range", :name => "clock",
|
27
|
+
:value => "1", :list => "tickmarks",
|
28
|
+
:max => "20", :min => "2", :step => "1"}
|
29
|
+
|
30
|
+
|
31
|
+
%textarea{:name => "code", :id => "code",
|
32
|
+
:autocomplete => "off",
|
33
|
+
:autocorrect => "off",
|
34
|
+
:autocapitalize => "off",
|
35
|
+
:spellcheck => "false"}
|
36
|
+
= preserve do
|
37
|
+
:escaped
|
38
|
+
STORE 55 : @0
|
39
|
+
DATA dyn : 0b01101
|
40
|
+
LOAD -0xf : &DAT
|
41
|
+
LOAD &DAT : &ACC
|
42
|
+
|
43
|
+
LOOP:
|
44
|
+
ADD 1 : &ACC
|
45
|
+
OUT &ACC
|
46
|
+
STORE &ACC : dyn
|
47
|
+
|
48
|
+
MORE &ACC : 29
|
49
|
+
| GOTO END
|
50
|
+
| GOTO LOOP
|
51
|
+
|
52
|
+
END: HALT 0
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
%select{:id => "alloc"}
|
57
|
+
%option{:value => "120", :selected => ""}120B
|
58
|
+
%option{:value => "94"}94B
|
59
|
+
%option{:value => "64"}64B
|
60
|
+
%option{:value => "32"}32B
|
61
|
+
%input{:type => "submit", :id => "submit", :value => "Run"}
|
62
|
+
|
63
|
+
.computer
|
64
|
+
.cpu
|
65
|
+
%span Control Unit
|
66
|
+
.CU
|
67
|
+
%span Registers
|
68
|
+
.registers
|
69
|
+
%span Output
|
70
|
+
.output
|
71
|
+
%span Input
|
72
|
+
.input
|
73
|
+
%input{:type => "text",
|
74
|
+
:autofocus => "", :autocomplete => "off",
|
75
|
+
:name => "input", :placeholder => "Enter value"}
|
76
|
+
.ram
|
77
|
+
%script{:type=> "text/javascript", :src => "/scripts/graphics.js"}
|
78
|
+
%script{:type=> "text/javascript", :src => "/scripts/step.js"}
|
79
|
+
%script{:type=> "text/javascript", :src => "/scripts/submitter.js"}
|
metadata
CHANGED
@@ -1,26 +1,94 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: famalam
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Demonstrandum
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
12
|
-
dependencies:
|
11
|
+
date: 2018-04-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: fam
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.0'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.0.1
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.0'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.0.1
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: haml
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '5.0'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 5.0.4
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '5.0'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 5.0.4
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: sinatra
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '2.0'
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 2.0.1
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '2.0'
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 2.0.1
|
13
73
|
description: FAMalam is a front end web interface for FAM
|
14
74
|
email: knutsen@jetspace.co
|
15
|
-
executables:
|
16
|
-
- famalam
|
75
|
+
executables: []
|
17
76
|
extensions: []
|
18
77
|
extra_rdoc_files: []
|
19
78
|
files:
|
20
79
|
- LICENSE
|
21
80
|
- README.md
|
22
|
-
- bin/famalam
|
23
81
|
- lib/famalam.rb
|
82
|
+
- lib/famalam/patches.rb
|
83
|
+
- public/scripts/graphics.js
|
84
|
+
- public/scripts/step.js
|
85
|
+
- public/scripts/submitter.js
|
86
|
+
- public/styles/cpu.css
|
87
|
+
- public/styles/master.css
|
88
|
+
- public/styles/ram.css
|
89
|
+
- public/styles/submit.css
|
90
|
+
- views/index.haml
|
91
|
+
- views/program.haml
|
24
92
|
homepage: https://github.com/Demonstrandum/FAM
|
25
93
|
licenses:
|
26
94
|
- GPL-2.0
|
data/bin/famalam
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|