Skip to content

Commit

Permalink
Add compile jack comand to cli (#459)
Browse files Browse the repository at this point in the history
* Add compile jack comand to cli
  • Loading branch information
happytomatoe authored Sep 17, 2024
1 parent d7688f8 commit b55db92
Showing 1 changed file with 95 additions and 1 deletion.
96 changes: 95 additions & 1 deletion cli/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
#!/usr/bin/env node
import { dirname, parse, resolve } from "path";
import path, { dirname, parse, resolve } from "path";
import yargs from "yargs";
import { hideBin } from "yargs/helpers";
import { main } from "./grading.js";
import { testRunner } from "./testrunner.js";
import { NodeFileSystemAdapter } from "@davidsouther/jiffies/lib/esm/fs_node.js";
import { FileSystem } from "@davidsouther/jiffies/lib/esm/fs.js";
import * as fsCore from "fs";
import { compile } from "@nand2tetris/simulator/jack/compiler.js";

yargs(hideBin(process.argv))
.usage("$0 <cmd>")
Expand Down Expand Up @@ -74,6 +78,96 @@ yargs(hideBin(process.argv))
}
},
)
.command(
"compile <src> [dst]",
"Compile .jack files inside a folder",
(yargs) =>
yargs
.positional("src", {
type: "string",
describe: "Path to input folder with jack files",
})
.option("dst", {
type: "string",
describe: "Path to destination folder",
default: "",
})
.coerce(["src", "dst"], function (arg) {
return path.resolve(arg) + "/";
})
.check((argv, options) => {
const src = argv.src;
const dst = argv.dst;
if (src === undefined) {
throw Error("Please provide input folder path");
}

if (dst && !fsCore.lstatSync(dst).isDirectory()) {
throw Error(src + " is not a folder");
}
if (!fsCore.lstatSync(src).isDirectory()) {
throw Error(src + " is not a folder");
}

return true;
})
.showHelpOnFail(false, "Specify --help for available options"),
async (argv) => {
enum Colors {
Red = "\x1b[31m",
Green = "\x1b[32m",
Reset = "\u001b[0m",
}
const JACK_EXT = ".jack";
const src = argv.src;
const dst = argv.dst ?? src;
if (src === undefined) {
throw Error("Please provde input folder path");
}

if (dst === undefined) {
throw Error("Please provde input folder path");
}
const fs = new FileSystem(new NodeFileSystemAdapter());

const files = await fs.readdir(src);
const jackFiles = files.filter((file) => file.endsWith(JACK_EXT));
if (jackFiles.length === 0) {
throw Error("No jack files inside a folder");
}
const nameToContent = {} as Record<string, string>;
for (const file of jackFiles) {
const filepath = path.join(src, file);
const content = await fs.readFile(filepath);
nameToContent[file.replace(JACK_EXT, "")] = content;
}
let error = false;
for (const [name, compiled] of Object.entries(compile(nameToContent))) {
if (typeof compiled === "string") {
const outputFilename = name + ".vm";
const outpath = path.join(dst, outputFilename);
await fs.writeFile(outpath, compiled);
} else {
if (!error) {
console.error("Compilation failed\n");
}
console.error(
Colors.Red +
compiled.message.replace(
/Line\s([\d]+):/g,
name + ".jack:$1" + Colors.Reset,
),
);
error = true;
}
}
if (error) {
process.exit(1);
} else {
console.log(Colors.Green + "Compiled files" + Colors.Reset);
}
},
)
.help()
.demandCommand(1)
.parse();

0 comments on commit b55db92

Please sign in to comment.