aboutsummaryrefslogtreecommitdiffgithub
path: root/novice/assembler/assembler.ts
blob: ed1803ec5681010543a4a989e59af585cd1424a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import { Readable, Writable } from 'stream';
import { Assembly, Isa, MachineCodeSection, SymbTable } from '../isa';
import { MachineCodeGenerator } from './codegen';
import { PseudoOpSpec } from './opspec';
import { Parser } from './parsers';
import { Serializer } from './serializers';

interface AssemblerConfig {
    parser: Parser;
    generator: MachineCodeGenerator;
    isa: Isa;
    opSpec: PseudoOpSpec;
    serializer: Serializer;
}

class Assembler {
    private cfg: AssemblerConfig;

    public constructor(cfg: AssemblerConfig) {
        this.cfg = cfg;
    }

    public async parse(fp: Readable): Promise<Assembly> {
        return await this.cfg.parser.parse(fp);
    }

    public codegen(asm: Assembly): [SymbTable, MachineCodeSection[]] {
        return this.cfg.generator.gen(this.cfg.isa, this.cfg.opSpec, asm);
    }

    public async assemble(fp: Readable):
            Promise<[SymbTable, MachineCodeSection[]]> {
        return this.codegen(await this.parse(fp));
    }

    public async assembleTo(inFp: Readable, outFp: Writable,
                            symbFp: Writable): Promise<void> {
        const [symbtable, code] = await this.assemble(inFp);
        this.cfg.serializer.serialize(this.cfg.isa, code, outFp);
        this.cfg.serializer.serializeSymb(symbtable, symbFp);
    }
}

export { Assembler, AssemblerConfig };