aboutsummaryrefslogtreecommitdiffgithub
diff options
context:
space:
mode:
authorAustin Adams <git@austinjadams.com>2018-08-08 03:53:41 -0400
committerAustin Adams <git@austinjadams.com>2018-08-08 03:58:35 -0400
commit07a6ae595c1106ec2fa3683a4cb550bbacad5a75 (patch)
treea026617bf0acb9dd00f936dc3cc1f8ddfefdc3c4
parent6080e7cf91b16a6919cc159a54eb3959c5b7cd4a (diff)
downloadnovice-07a6ae595c1106ec2fa3683a4cb550bbacad5a75.tar.gz
novice-07a6ae595c1106ec2fa3683a4cb550bbacad5a75.tar.xz
Add assembler class
-rw-r--r--novice/assembler/assembler.ts62
-rw-r--r--novice/assembler/index.ts3
-rw-r--r--novice/cli.ts25
-rw-r--r--novice/main.ts3
-rw-r--r--tsconfig.json3
-rw-r--r--tslint.json5
6 files changed, 93 insertions, 8 deletions
diff --git a/novice/assembler/assembler.ts b/novice/assembler/assembler.ts
new file mode 100644
index 0000000..1e0da2d
--- /dev/null
+++ b/novice/assembler/assembler.ts
@@ -0,0 +1,62 @@
+import { Buffer } from 'buffer';
+import { Readable } from 'stream';
+
+interface Instruction {
+ op: string;
+ operands: (string|number)[];
+}
+
+interface Section {
+ startAddr: number;
+ instructions: Instruction[];
+}
+
+interface Assembly {
+ sections: Section[];
+ labels: {[s: string]: number};
+}
+
+class Assembler {
+ public parse(fp: Readable): Promise<Assembly> {
+ return new AssemblerParse().parse(fp);
+ }
+}
+
+class AssemblerParse {
+ private assembly: Assembly;
+
+ public constructor() {
+ this.assembly = {sections: [], labels: {}};
+ }
+
+ public async parse(fp: Readable): Promise<Assembly> {
+ const endPromise = new Promise((resolve) => fp.on('end', () => {
+ // send EOF to scanner
+ this.nextChar('');
+ resolve();
+ }));
+ fp.on('data', this.onData.bind(this));
+ await endPromise;
+ return this.assembly;
+ }
+
+ private onData(data: string | Buffer) {
+ let buf: string;
+ if (typeof data === 'string') {
+ buf = data;
+ } else {
+ buf = data.toString();
+ }
+
+ for (let i = 0; i < buf.length; i++) {
+ this.nextChar(buf.charAt(i));
+ }
+ }
+
+ // '' is EOF
+ private nextChar(c: string) {
+ // nothing for now
+ }
+}
+
+export { Assembler, Assembly, Section, Instruction };
diff --git a/novice/assembler/index.ts b/novice/assembler/index.ts
new file mode 100644
index 0000000..27c29dd
--- /dev/null
+++ b/novice/assembler/index.ts
@@ -0,0 +1,3 @@
+import { Assembler } from './assembler';
+
+export { Assembler };
diff --git a/novice/cli.ts b/novice/cli.ts
index cd843e6..adcdab4 100644
--- a/novice/cli.ts
+++ b/novice/cli.ts
@@ -1,13 +1,16 @@
+import * as fs from 'fs';
import { Writable } from 'stream';
+import { Assembler } from './assembler';
-function main(args: string[], stderr: Writable): number {
+async function main(args: string[], stdout: Writable, stderr: Writable):
+ Promise<number> {
const subcommand = args[0];
switch (subcommand) {
case 'asm':
if (args.length === 2) {
const path = args[1];
- return asm(path, stderr);
+ return await asm(path, stdout, stderr);
} else {
return usage(stderr);
}
@@ -21,9 +24,21 @@ function usage(stderr: Writable): number {
return 1;
}
-function asm(path: string, stderr: Writable): number {
- stderr.write('assembling ' + path + '\n');
- return 0;
+async function asm(path: string, stdout: Writable, stderr: Writable):
+ Promise<number> {
+ try {
+ const fp = fs.createReadStream(path);
+ await new Promise((resolve, reject) => {
+ fp.on('readable', resolve);
+ fp.on('error', reject);
+ });
+ const assembly = await new Assembler().parse(fp);
+ stdout.write(JSON.stringify(assembly));
+ return 0;
+ } catch (err) {
+ stderr.write('asm error: ' + err.message + '\n');
+ return 1;
+ }
}
export default main;
diff --git a/novice/main.ts b/novice/main.ts
index 1f5799c..34230cf 100644
--- a/novice/main.ts
+++ b/novice/main.ts
@@ -2,4 +2,5 @@
import main from './cli';
-process.exitCode = main(process.argv.slice(2), process.stderr);
+main(process.argv.slice(2), process.stdout, process.stderr)
+ .then((exitCode) => process.exitCode = exitCode);
diff --git a/tsconfig.json b/tsconfig.json
index 563ad8b..5db6261 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,6 +1,7 @@
{
"compilerOptions": {
- "strict": true
+ "strict": true,
+ "lib": ["ES6"]
},
"include": [
"novice/**/*.ts"
diff --git a/tslint.json b/tslint.json
index c02ae02..f502f05 100644
--- a/tslint.json
+++ b/tslint.json
@@ -5,7 +5,10 @@
],
"jsRules": {},
"rules": {
- "quotemark": [true, "single", "avoid-escape"]
+ "quotemark": [true, "single", "avoid-escape"],
+ "array-type": [true, "array"],
+ "interface-name": [true, "never-prefix"],
+ "max-classes-per-file": false
},
"rulesDirectory": []
}