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:
|
Gir supports following optimizations:
|
||||||
|
|
||||||
* Turn runs of +- or <> into one command
|
* 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}]}
|
// [-] → {type: loop, contents: [{type: add, value: -1}]}
|
||||||
const loop = Symbol('loop');
|
const loop = Symbol('loop');
|
||||||
|
|
||||||
|
// [-] → {type: clear}
|
||||||
|
const clear = Symbol('clear');
|
||||||
|
|
||||||
// TODO: Add extensions from Eldis
|
// 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
|
// i is not incremented, since it already
|
||||||
// points to a location containig a char we
|
// points to a location containig a char we
|
||||||
// have not yet handled
|
// 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
|
// see +/- for why we don't increment i
|
||||||
|
|
||||||
} else if(program[i] == '.') {
|
} else if(program[i] == '.') {
|
||||||
|
@ -162,6 +171,9 @@ function prettyPrint(parsed) {
|
||||||
line += 'loop';
|
line += 'loop';
|
||||||
console.log(line);
|
console.log(line);
|
||||||
printIndented(command.contents, indent + ' ');
|
printIndented(command.contents, indent + ' ');
|
||||||
|
} else if(command.type == clear) {
|
||||||
|
line += 'clear';
|
||||||
|
console.log(line);
|
||||||
} else {
|
} else {
|
||||||
line += `unknown ${command.type}`;
|
line += `unknown ${command.type}`;
|
||||||
console.log(line);
|
console.log(line);
|
||||||
|
@ -219,6 +231,33 @@ function joinAdjacentOps(parsed) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ([commandObjects]) → [commandObjects]
|
// ([commandObjects]) → [commandObjects]
|
||||||
function optimize(parsed) {
|
function transformClearLoops(parsed) {
|
||||||
return joinAdjacentOps(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