Skip to content

Commit

Permalink
feat(cli): add direct binary output support
Browse files Browse the repository at this point in the history
  • Loading branch information
Mati365 committed Nov 11, 2023
1 parent 0ac7968 commit e6547be
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 23 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@ Arguments:
source Relative or absolute path to source file

Options:
-b, --binary Emits binary stdout
-o, --output <string> Relative path to your output binary
-ps, --print-assembly Print assembly output
-d, --debug Print AST tree and assembly output
-ps, --print-assembly Print assembly output
-b, --bootsector Generate 512B bootsector output. Remember to have main entrypoint.
-h, --help display help for command
```
Expand Down
77 changes: 55 additions & 22 deletions apps/cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import 'source-map-support/register';
import fs from 'node:fs';
import * as E from 'fp-ts/Either';
import { pipe } from 'fp-ts/function';
import { program } from '@commander-js/extra-typings';
import { Option, program } from '@commander-js/extra-typings';

import { TableBinaryView, asm } from '@ts-c-compiler/x86-assembler';
import {
Expand All @@ -14,20 +14,35 @@ import {
} from '@ts-c-compiler/compiler';

import { NodeFsIncludeResolver } from './NodeFsIncludeResolver';
import { tapEither } from '@ts-c-compiler/core';

program
.argument('<source>', 'Relative or absolute path to source file')
.option('-o, --output <string>', 'Relative path to your output binary')
.option('-ps, --print-assembly', 'Print assembly output')
.option('-d, --debug', 'Print AST tree and assembly output')
.option('-b, --binary', 'Emits binary stdout')
.addOption(
new Option(
'-o, --output <string>',
'Relative path to your output binary',
).conflicts('binary'),
)
.addOption(
new Option('-d, --debug', 'Print AST tree and assembly output').conflicts(
'binary',
),
)
.addOption(
new Option('-ps, --print-assembly', 'Print assembly output').conflicts([
'binary',
'debug',
]),
)
.option(
'-b, --bootsector',
'Generate 512B bootsector output. Remember to have main entrypoint.',
)
.action((source, options) => {
const srcFile = fs.readFileSync(source, { encoding: 'utf8', flag: 'r' });

pipe(
const cCompile = pipe(
srcFile,
ccompiler({
arch: CCompilerArch.X86_16,
Expand All @@ -39,41 +54,59 @@ program
fsIncludeResolver: new NodeFsIncludeResolver(),
},
}),
E.match(
tapEither(
result => {
if (options.debug) {
result.dump();
}
},
(error: any) => {
if (options.debug && error?.[0]?.tree) {
console.info(serializeTypedTreeToString(error[0].tree));
}

console.error(error);
process.exit(1);
},
result => {
if (options.debug) {
result.dump();
}
),
);

let asmRaw = result.codegen.asm;
pipe(
E.Do,
E.bind('cResult', () => cCompile),
E.bind('asmResult', ({ cResult }) => {
let asmRaw = cResult.codegen.asm;

if (options.bootsector) {
asmRaw = wrapWithX86BootsectorAsm(asmRaw);
}
if (options.bootsector) {
asmRaw = wrapWithX86BootsectorAsm(asmRaw);
}

const asmResult = asm({
return pipe(
asmRaw,
asm({
preprocessor: true,
})(asmRaw);

}),
);
}),
tapEither(
({ asmResult }) => {
if (options.printAssembly) {
console.info(TableBinaryView.serializeToString(asmResult));
console.info(TableBinaryView.serializeToString(E.right(asmResult)));
}

if (options.binary) {
process.stdout.write(new Uint8Array(asmResult.output.getBinary()));
}

if (options.output && E.isRight(asmResult)) {
if (options.output) {
fs.writeFileSync(
options.output,
Buffer.from(asmResult.right.output.getBinary()),
Buffer.from(asmResult.output.getBinary()),
);
}
},
() => {
process.exit(1);
},
),
);
})
Expand Down
2 changes: 2 additions & 0 deletions packages/compiler-core/src/utils/fp-ts/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export * from './tap-either-error';
export * from './tap-either';
export * from './try-reduce-eithers';
export * from './unwrap-either-or-throw';
13 changes: 13 additions & 0 deletions packages/compiler-core/src/utils/fp-ts/tap-either-error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { pipe } from 'fp-ts/function';
import * as E from 'fp-ts/Either';

export const tapEitherError =
<E, A>(onLeft?: (error: E) => void) =>
(task: E.Either<E, A>): E.Either<E, A> =>
pipe(
task,
E.fold(error => {
onLeft?.(error);
return E.left(error);
}, E.right),
);
19 changes: 19 additions & 0 deletions packages/compiler-core/src/utils/fp-ts/tap-either.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { pipe } from 'fp-ts/function';
import * as E from 'fp-ts/Either';

export const tapEither =
<E, A>(onRight: (data: A) => void, onLeft?: (error: E) => void) =>
(task: E.Either<E, A>): E.Either<E, A> =>
pipe(
task,
E.fold(
error => {
onLeft?.(error);
return E.left(error);
},
data => {
onRight(data);
return E.right(data);
},
),
);

0 comments on commit e6547be

Please sign in to comment.