Add the first optimization pass
This commit is contained in:
parent
90853793a8
commit
61e836afcf
|
@ -11,3 +11,6 @@ Everything in the repo is under Unlicense / CC0.
|
|||
Status
|
||||
------
|
||||
Gir can parse and prettyprint to Javascript console programs in brainfuck.
|
||||
Gir supports following optimizations:
|
||||
|
||||
* Turn runs or +- or <> into one command
|
||||
|
|
60
gir.js
60
gir.js
|
@ -1,5 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Definitions
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
// Use symbols for the names of the instructions
|
||||
// Unsure if this helps in any way over strings, but I feel it neater
|
||||
|
||||
|
@ -16,6 +20,10 @@ const loop = Symbol('loop');
|
|||
|
||||
// TODO: Add extensions from Eldis
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Parsing
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
class ParsingError extends Error {}
|
||||
|
||||
// (string) → [commandObjects]
|
||||
|
@ -162,3 +170,55 @@ function prettyPrint(parsed) {
|
|||
}
|
||||
printIndented(parsed);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Optimization passes
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
// ([commandObjects]) → [commandObjects]
|
||||
function joinAdjacentOps(parsed) {
|
||||
// ([commandObjects], commandType) → [commandObjects]
|
||||
function worker(parsed, type) {
|
||||
let optimized = [];
|
||||
|
||||
let prevOfType = false, value = 0;
|
||||
for(let command of parsed) {
|
||||
if(prevOfType && command.type == type) {
|
||||
// Update value, don't add to optimized yet
|
||||
value += command.value;
|
||||
} else if(!prevOfType && command.type == type) {
|
||||
// Start of a possible run of commands
|
||||
prevOfType = true;
|
||||
value = command.value;
|
||||
} else if(prevOfType && command.type != type) {
|
||||
// A run has ended, add it to optimized
|
||||
// However, skip it if value is 0
|
||||
if(value != 0) {
|
||||
optimized.push({type: type, value: value});
|
||||
}
|
||||
// Also add the command for this round
|
||||
optimized.push(command);
|
||||
prevOfType = false;
|
||||
} else {
|
||||
optimized.push(command);
|
||||
prevOfType = false;
|
||||
}
|
||||
}
|
||||
// Did we end with a command of given type
|
||||
if(prevOfType) {
|
||||
// Yes, add it to optimized (unless value is 0)
|
||||
if(value != 0) {
|
||||
optimized.push({type: type, value: value});
|
||||
}
|
||||
}
|
||||
|
||||
return optimized;
|
||||
}
|
||||
|
||||
return worker(worker(parsed, moveHead), add);
|
||||
}
|
||||
|
||||
// ([commandObjects]) → [commandObjects]
|
||||
function optimize(parsed) {
|
||||
return joinAdjacentOps(parsed);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue