1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- type BFError = string;
- type Token = string;
- type Node = string | NodeArray;
- interface NodeArray extends Array<Node> {}
-
- const error = (message: BFError) => {
- console.error(message);
- process.exit(1);
- };
-
- const scan = (source: string): Token[] => {
- return source.split('').filter((c) => "+-<>[].,".includes(c));
- };
-
- const parse = (tokens: Token[]): Node[] | undefined => {
- let position = 0;
- let tree: Node[] = [];
- const parseNode = (token: string): Node | undefined => {
- if ("+-<>.,".includes(token)) {
- position++;
- return token;
- } else if (token === '[') {
- position++;
- const body: Node[] = [];
- while (position < tokens.length && tokens[position] !== ']') {
- const subnode = parseNode(tokens[position]);
- if (subnode) body.push(subnode);
- }
- if (tokens[position] === ']') { position++; }
- else if (position === tokens.length) { error('Expected ], got EOF'); }
- return body;
- } else {
- error(`Unrecognized token ${token}`);
- }
- };
- while (position < tokens.length) {
- const node = parseNode(tokens[position]);
- if (node) tree.push(node);
- }
- return tree;
- };
-
- const interpret = (tree: Node[]) => {
- let position = 0;
- let pointer = 0;
- let stack = Array.from({ length: 30_000 }, () => 0);
-
- const interpretNode = (node: Node) => {
- switch (node) {
- case '+': stack[pointer]++; break;
- case '-': stack[pointer]--; break;
- case '>': pointer++; break;
- case '<': pointer--; break;
- case '.': process.stdout.write(stack[pointer].toString()); break;
- case ',': throw('Unimplemented');
- default:
- while (stack[pointer] > 0) {
- let subposition = 0;
- while (subposition < node.length) {
- console.log(subposition);
- interpretNode(node[subposition]);
- subposition++;
- }
- }
- }
- position++;
- };
-
-
- while (position < tree.length) interpretNode(tree[position]);
- };
-
- const tree = parse(scan(process.argv[2]));
- if (tree) interpret(tree);
|