-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathbefunge.js
87 lines (81 loc) · 2.4 KB
/
befunge.js
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
var Immutable = require('immutable');
var _ = require('lodash');
var parse = require('./parser');
var interpret = require('./interpreter');
function initState(program) {
program = program || [[]];
return Immutable.fromJS({
x: -1,
y: 0,
height: program.length,
width: program.reduce(function(longest, line) { return Math.max(longest, line.length); }, 0),
direction: '>',
tick: 0,
stringmode: false,
skipmode: false,
noTick: false,
running: false,
terminated: false,
returncode: 0,
program: program,
_stack: [[]],
outputString: '',
currentStringLength: 0
});
}
var Befunge = function(programString, options) {
var settings = _.extend({
input: function() {
throw new Error('Please provide an input function if your program needs input');
},
output: function(output) {
console.log(output);
},
delay: 0
}, options);
var b = {
state: initState(parse(programString)),
setDelay: function(newDelay) {
settings.delay = newDelay;
},
parse: function(programString) {
return Immutable.fromJS(parse(programString));
},
reset: function(newProgramString) {
if (_.isString(newProgramString)) {
programString = newProgramString;
}
b.state = initState(b.parse(programString));
return b;
},
step: function() {
if (!b.state.get('terminated')) {
b.state = interpret(b.state, settings);
if (settings.callback) {
settings.callback(b.state);
}
}
return b.state;
},
run: function() {
if (programString != '') {
if (b.state.get('terminated')) {
b.reset();
}
b.state = b.state.set('running', true);
b._runStep();
}
},
_runStep: function() {
if (b.state.get('running') && !b.state.get('terminated')) {
b.step();
setTimeout(b._runStep.bind(b), settings.delay);
}
},
pause: function() {
b.state = b.state.set('running', false);
}
};
return b;
};
module.exports = Befunge;