Skip to content

Instantly share code, notes, and snippets.

@L8D
Last active January 3, 2016 03:18
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 L8D/8400966 to your computer and use it in GitHub Desktop.
Save L8D/8400966 to your computer and use it in GitHub Desktop.
Brainf*ck compiler using C as a midpoint.
#!/usr/bin/env node
var fs = require('fs'),
spawn = require('child_process').spawn,
argv = require('optimist').argv;
var gcc = spawn('gcc', [
'--std=c99',
'-o', argv.o || argv._[0] ? argv._[0].split('.')[0] : 'a.out',
'-x', 'c',
'-'
]);
gcc.stdout.pipe(process.stdout);
gcc.stderr.pipe(process.stderr);
gcc.stdin.write([
'#include <stdio.h>',
'int main() {',
'char m[30000];',
'char *p=m;',
'FILE *f = NULL;',
'char mode = 0;'
].join('\n'));
var writeCode = function(err, code) {
if (err) {
gcc.kill();
throw err;
}
var brackets = 0;
var codes = code.split('').filter(function(char) {
return '+-><.,[]'.indexOf(char) !== -1;
}).map(function(ins) {
switch (ins) {
case '+': return '(*p)++;';
case '-': return '(*p)--;';
case '>': return 'p++;';
case '<': return 'p--;';
case '.': return 'fputc(*p, mode ? f : stdout);' + '\n' +
'fflush(mode ? f : stdout);';
case ',': return '*p = fgetc(mode ? f : stdout);';
case '[': brackets++;
return 'while (*p) {';
case ']': brackets--;
return '}';
case '!': return 'mode = !mode;'
case '#': return [
'if (mode) {',
'if (f) fclose(f);',
'f = fopen(p, "rw");',
'}'
].join('\n');
}
});
if (brackets > 0) {
throw Error("uneven amount of '['s");
} else if (brackets < 0) {
throw Error("uneven amount of ']'s");
}
gcc.stdin.write(codes.join('\n'));
gcc.stdin.write('return 0;\n}');
gcc.stdin.end();
};
if (argv._.length) {
fs.readFile(argv._[0], {encoding: 'utf8'}, writeCode);
} else {
var code = '';
process.stdin.on('data', function(chunk) {
code += chunk;
});
process.stdin.on('end', function() {
writeCode(null, code);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment