Skip to content
This repository was archived by the owner on Sep 13, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ Then install minits:

```
$ git clone https://github.com/cryptape/minits
$ npm install
$ npm run build
$ cd minits
$ yarn
$ yarn run build
```

# Writing and Compiling a TypeScript Program
Expand Down
153 changes: 153 additions & 0 deletions examples/brainfuck_class/brainfuck.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
// $ node build/main/index.js build examples/brainfuck_class/brainfuck.ts -o brainfuck.ll
// $ clang brainfuck.ll -o brainfuck
//
// $ ./brainfuck "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>."

const enum Opcode {
SHR = '>',
SHL = '<',
ADD = '+',
SUB = '-',
PUTCHAR = '.',
GETCHAR = ',',
LB = '[',
RB = ']',
}

export class BrainfuckInterpreter {
code: string;
pc: number;
ps: number;

constructor(code: string) {
this.code = code;
this.pc = 0;
this.ps = 0;
}

reset() {
this.pc = 0;
this.ps = 0;
}

uint8(n: number): number {
if (n > 0xff) {
return this.uint8(n - 256);
}
if (n < 0x00) {
return this.uint8(n + 256);
}
return n
}

run(): number {
this.reset();
let stack = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];
// run
for (; this.pc < this.code.length;) {
let op = this.code[this.pc];
if (op === Opcode.SHR) {
this.ps += 1;
this.pc += 1;
continue
}
if (op === Opcode.SHL) {
this.ps -= 1;
this.pc += 1;
continue
}
if (op === Opcode.ADD) {
stack[this.ps] = this.uint8(stack[this.ps] + 1);
this.pc += 1;
continue
}
if (op === Opcode.SUB) {
stack[this.ps] = this.uint8(stack[this.ps] - 1);
this.pc += 1;
continue
}
if (op === Opcode.PUTCHAR) {
this.putchar(stack[this.ps]);
this.pc += 1;
continue
}
if (op === Opcode.GETCHAR) {
console.log('GETCHAR is disabled');
return 1;
}


if (op === Opcode.LB) {
if (stack[this.ps] != 0x00) {
this.pc += 1;
continue
}
let n = 1;
for (; n !== 0;) {
this.pc += 1;
if (this.code[this.pc] === Opcode.LB) {
n += 1;
continue
}
if (this.code[this.pc] === Opcode.RB) {
n -= 1;
continue
}
}
this.pc += 1;
continue
}
if (op === Opcode.RB) {
if (stack[this.ps] === 0x00) {
this.pc += 1;
continue
}
let n = 1;
for (; n !== 0;) {
this.pc -= 1;
if (this.code[this.pc] === Opcode.RB) {
n += 1;
continue
}
if (this.code[this.pc] === Opcode.LB) {
n -= 1;
continue
}
}
this.pc += 1;
continue
}
}
return 0;
}

putchar(n: number) {
console.log('%c', n);
}
}

export function main(argc: number, argv: string[]): number {
if (argc !== 2) {
return 1;
}
let bfi = new BrainfuckInterpreter(argv[1]);
let status_code = bfi.run();
return status_code;
}
14 changes: 14 additions & 0 deletions examples/brainfuck_class/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// use ts-node to run the file directly for devlopment and test.
// ts-node examples/brainfuck_class/test.ts
import { BrainfuckInterpreter } from './brainfuck';

BrainfuckInterpreter.prototype.putchar = (n: number) => {
process.stdout.write(String.fromCharCode(n));
}
let code = '++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.';
console.log(`code: ${code}`);
console.log('\n---------- start ----------');
let bfi = new BrainfuckInterpreter(code);
let status_code = bfi.run();
console.log('---------- end ----------\n');
console.log(`status_code: ${status_code}`);