Turn [-] or [+] into a clear command
This commit is contained in:
parent
b945657163
commit
39890cdc5a
|
@ -14,3 +14,4 @@ Gir can parse and prettyprint to Javascript console programs in brainfuck.
|
|||
Gir supports following optimizations:
|
||||
|
||||
* Turn runs of +- or <> into one command
|
||||
* Turn [-] or [+] into one command
|
||||
|
|
47
gir.js
47
gir.js
|
@ -18,6 +18,9 @@ const readByte = Symbol('readByte');
|
|||
// [-] → {type: loop, contents: [{type: add, value: -1}]}
|
||||
const loop = Symbol('loop');
|
||||
|
||||
// [-] → {type: clear}
|
||||
const clear = Symbol('clear');
|
||||
|
||||
// TODO: Add extensions from Eldis
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
@ -78,7 +81,10 @@ function parse(program) {
|
|||
}
|
||||
}
|
||||
|
||||
commands.push({type: add, value: value});
|
||||
// Only add the command is value is not 0
|
||||
if(value != 0) {
|
||||
commands.push({type: add, value: value});
|
||||
}
|
||||
// i is not incremented, since it already
|
||||
// points to a location containig a char we
|
||||
// have not yet handled
|
||||
|
@ -97,7 +103,10 @@ function parse(program) {
|
|||
}
|
||||
}
|
||||
|
||||
commands.push({type: moveHead, value: value});
|
||||
// Only add the command is value is not 0
|
||||
if(value != 0) {
|
||||
commands.push({type: moveHead, value: value});
|
||||
}
|
||||
// see +/- for why we don't increment i
|
||||
|
||||
} else if(program[i] == '.') {
|
||||
|
@ -162,6 +171,9 @@ function prettyPrint(parsed) {
|
|||
line += 'loop';
|
||||
console.log(line);
|
||||
printIndented(command.contents, indent + ' ');
|
||||
} else if(command.type == clear) {
|
||||
line += 'clear';
|
||||
console.log(line);
|
||||
} else {
|
||||
line += `unknown ${command.type}`;
|
||||
console.log(line);
|
||||
|
@ -219,6 +231,33 @@ function joinAdjacentOps(parsed) {
|
|||
}
|
||||
|
||||
// ([commandObjects]) → [commandObjects]
|
||||
function optimize(parsed) {
|
||||
return joinAdjacentOps(parsed);
|
||||
function transformClearLoops(parsed) {
|
||||
let optimized = [];
|
||||
|
||||
for(let command of parsed) {
|
||||
// Only match loops like [-] or [+]
|
||||
let isClearLoop = command.type == loop &&
|
||||
command.contents.length == 1 &&
|
||||
command.contents[0].type == add &&
|
||||
(command.contents[0].value == 1 ||
|
||||
command.contents[0].value == -1);
|
||||
if(isClearLoop) {
|
||||
optimized.push({type: clear});
|
||||
} else if(command.type == loop) {
|
||||
// Run for inner loops
|
||||
optimized.push({type: loop,
|
||||
contents: transformClearLoops(command.contents)});
|
||||
} else {
|
||||
optimized.push(command);
|
||||
}
|
||||
}
|
||||
|
||||
return optimized;
|
||||
}
|
||||
|
||||
// ([commandObjects]) → [commandObjects]
|
||||
function optimize(parsed) {
|
||||
const optimizations = [joinAdjacentOps, transformClearLoops];
|
||||
return optimizations.reduce((IR, optimization) =>
|
||||
optimization(IR), parsed);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue