Skip to content

Instantly share code, notes, and snippets.

@buzzert
Created July 25, 2018 05:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save buzzert/6cb63bb6a74729034e5fa61a05a0010c to your computer and use it in GitHub Desktop.
Save buzzert/6cb63bb6a74729034e5fa61a05a0010c to your computer and use it in GitHub Desktop.
A fizzbuzz instructions compiler written in JavaScript
(fizzbuzz = () => {
/*
Instructions:
Loop a counter from 1 to 100.
If the counter is a multiple of 3 and the counter is a multiple of 5, then print "fizzbuzz".
If the counter is a multiple of 3, then print "fizz".
If the counter is a multiple of 5, then print "buzz".
Otherwise print counter.
Done.
*/
let programStr = fizzbuzz.toString().match(/\/\*(\*(?!\/)|[^*])*\*\//)[0];
let __LOOP = (matchesArr) => {
let varb = matchesArr[1];
let from = matchesArr[2];
let to = matchesArr[3];
return [ "for (" + varb + " = " + from + ";" + varb + "<" + to + ";" + varb + "++) {" ];
}
let __PRNT_STR = (matchesArr) => { return [ "console.log(\"" + matchesArr[1] + "\");" ]; }
let __PRNT_VAR = (matchesArr) => { return [ "console.log(" + matchesArr[1] + ");" ]; }
let __DONE = (matchesArr) => { return [ "}" ]; }
let __EQUL = (matchesArr) => { return [ matchesArr[1] + " == " + matchesArr[2] ]; }
let __MODU = (matchesArr) => { return [ matchesArr[1] + " % " + matchesArr[2] + " == 0" ]; }
let __ANDD = (matchesArr) => { return [ evaluateExpression(matchesArr[1]) + " && " + evaluateExpression(matchesArr[2]) ]; }
let __COND = (matchesArr, elseif=false) => {
let conditionalExpression = evaluateExpression(matchesArr[1]);
let branchExpression = evaluateExpression(matchesArr[2]);
return [ (elseif ? "else " : "") + "if (" + conditionalExpression + ") {" + branchExpression + "}" ];
}
let __ELSE = (matchesArr) => {
let branchExpression = evaluateExpression(matchesArr[1]);
return [ " else { " + branchExpression + "}" ];
}
let grammar = [
[/IF (.*) then (.*)/i, __COND],
[/ELSE|OTHERWISE (.*)/i, __ELSE],
[/LOOP (?:the|a|an)? ([A-Za-z0-9_]+) from (\d+) to (\d+)/i , __LOOP],
[/PRINT ([A-Za-z0-9_]+)/i , __PRNT_VAR],
[/PRINT \"(.*)\"/i , __PRNT_STR],
[/(.*) AND (.*)/i, __ANDD],
[/(?:the|a|an)?(.*) IS A MULTIPLE OF (\d+)/i, __MODU],
[/(?:the|a|an)?(.*) IS (.*)/i, __EQUL],
[/DONE.*/i, __DONE],
];
var tokens = [];
let evaluateExpression = (expression) => {
let assembledExpression = [];
grammar.some(gram => {
let matches = gram[0].exec(expression);
if (matches != null) {
if (gram[1] == __COND && tokens[tokens.length - 1] == __COND) {
// Special rule for conditionals, per this language:
// If the last expression was also __COND, then make this a __COND(elseif=true).
assembledExpression += __COND(matches, true);
} else {
assembledExpression += gram[1](matches);
}
tokens.push(gram[1]);
return true;
}
return false;
});
return assembledExpression;
}
var assembledProgram = [];
programStr.split('\n').forEach(line => {
assembledProgram += evaluateExpression(line);
});
eval(assembledProgram);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment