UNPKG

braintsck

Version:

Brainfuck to JavaScript compiler in TypeScript

134 lines (99 loc) 3.52 kB
// -- START HEADER -- // Copyright (c) benja2998. You may redistribute under the terms of the GPL-3.0-or-later. // brainTSck is a Brainfuck to JavaScript compiler written in TypeScript. // -- END HEADER -- // -- START IMPORTS -- import * as fs from 'fs'; import * as path from 'path'; // -- END IMPORTS -- // Check if the provided file exists // If it does, return the contents of the file // If it doesn't, exit with an error if (process.argv[2] == undefined) { console.log("Usage: braintsck <file>"); process.exit(1); } const file = process.argv[2]; if (!fs.existsSync(file)) { console.log(`File ${file} does not exist`); process.exit(1); } const contents = fs.readFileSync(file, 'utf8'); let compiledContents = ""; compiledContents = `#!/usr/bin/env node // DO NOT MODIFY. // This is an automatically generated file by brainTSck. // If you want to modify it, modify ${file} and recompile by running: braintsck ${file} const TAPE_SIZE = 30000; const tape = new Uint8Array(TAPE_SIZE); let pointer = 0; ` // Display a banner console.log(` _ _ _____ ___ _ | |__ _ _ __ _(_)_ |_ _/ __| __| |__ | '_ \\ '_/ _\` | | ' \\| | \\__ \\/ _| / / |_.__/\\_| \\__,_|_|_||_|_| |___/\\__|_\\_\\ `); console.log(`Compiling ${file}...`); console.time("Compilation time"); // In a loop, store each character of <contents> in a variable for (let i = 0; i < contents.length; i++) { const char = contents.charAt(i); switch (char) { case '+': console.log("Compiling '+'"); compiledContents += `tape[pointer]++; `; break; case '-': console.log("Compiling '-'"); compiledContents += `tape[pointer]--; `; break; case '>': console.log("Compiling '>'"); compiledContents += `pointer = (pointer + 1) % TAPE_SIZE; `; break; case '<': console.log("Compiling '<'"); compiledContents += `pointer = (pointer - 1 + TAPE_SIZE) % TAPE_SIZE; `; break; case '.': console.log("Compiling '.'"); compiledContents += `process.stdout.write(String.fromCharCode(tape[pointer])); `; break; case ',': console.log("Compiling ','"); compiledContents += `{ const buffer = Buffer.alloc(1); require('fs').readSync(0, buffer, 0, 1, null); tape[pointer] = buffer[0]; } `; break; case '[': console.log("Compiling '['"); compiledContents += `while (tape[pointer] != 0) { `; break; case ']': console.log("Compiling ']'"); compiledContents += `} `; break; default: console.log(`Skipping ${char}`); break; } } console.timeEnd("Compilation time"); // Get the file name without the extension const fileName = path.parse(file).name; // Write the compiled contents to a file named <fileName>.js fs.writeFileSync(`${fileName}.js`, compiledContents); console.log(`Compiled ${file} to ${fileName}.js`); console.log(`Run it by running: node ${fileName}.js`);