-
Notifications
You must be signed in to change notification settings - Fork 3
/
bfCompiler.js
75 lines (69 loc) · 2.02 KB
/
bfCompiler.js
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
'use strict';
function genInst(inst, depth) {
return ' '.repeat(depth * 2) + inst + '\n';
}
function genCode(code, depth) {
let result = '';
for (const i of code) {
if (Array.isArray(i)) {
result += genInst(` (block ;; [`, depth);
result += genInst(` (loop`, depth);
result += genInst(
` (br_if 1 (i32.eqz (i32.load8_s (get_local $ptr))))`,
depth
);
result += genCode(i, depth + 1);
result += genInst(` (br 0)`, depth);
result += genInst(' )', depth);
result += genInst(' ) ;; ]', depth);
} else if (i === '>') {
result += genInst(
' (set_local $ptr (i32.add (get_local $ptr) (i32.const 1))) ;; >',
depth
);
} else if (i === '<') {
result += genInst(
' (set_local $ptr (i32.sub (get_local $ptr) (i32.const 1))) ;; <',
depth
);
} else if (i === '+') {
result += genInst(
' (i32.store8 (get_local $ptr) (i32.add (i32.load8_s (get_local $ptr)) (i32.const 1))) ;; +',
depth
);
} else if (i === '-') {
result += genInst(
' (i32.store8 (get_local $ptr) (i32.sub (i32.load8_s (get_local $ptr)) (i32.const 1))) ;; -',
depth
);
} else if (i === '.') {
result += genInst(
' (i32.load8_s (get_local $ptr)) (call $putchar) ;; .',
depth
);
} else if (i === ',') {
result += genInst(
' (i32.store8 (get_local $ptr) (call $getchar)) ;; ,',
depth
);
}
}
return result;
}
function compile(bfCode, opts) {
const prologue = `(module
(func $getchar (import "imports" "getchar") (result i32))
(func $putchar (import "imports" "putchar") (param i32))
(memory $0 (export "memory") 1 1)
(func (export "main") (local $ptr i32)
`;
const epilogue = ` )
)
`;
const wast = `${prologue}${genCode(bfCode, 0)}${epilogue}`;
if (opts.verbose || process.env.NODE_ENV === 'debug') {
console.log(wast);
}
return wast;
}
exports.compile = compile;