-
Notifications
You must be signed in to change notification settings - Fork 35
/
repl.ts
78 lines (76 loc) · 2.88 KB
/
repl.ts
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
76
77
78
import { run, Config, augmentEnv } from "./runner";
// import { GlobalEnv } from "./compiler";
import { GlobalEnv } from "./compiler";
import { tc, defaultTypeEnv, GlobalTypeEnv } from "./type-check";
import { Program } from "./ir";
import { optimizeProgram } from "./optimization";
import { Value, Type, Annotation } from "./ast";
import { parse } from "./parser";
import { lowerProgram, resetNameCounters } from "./lower";
interface REPL {
run(source : string) : Promise<any>;
}
export class BasicREPL {
currentEnv: GlobalEnv
currentTypeEnv: GlobalTypeEnv
functions: string
importObject: any
memory: any
constructor(importObject : any) {
this.importObject = importObject;
resetNameCounters();
if(!importObject.js) {
const memory = new WebAssembly.Memory({initial:2000, maximum:2000});
const view = new Int32Array(memory.buffer);
view[0] = 4;
this.importObject.js = { memory: memory };
}
this.currentEnv = {
globals: new Map(),
classes: new Map(),
classIndices: new Map(),
functionNames: new Map(),
locals: new Set(),
labels: [],
offset: 1,
vtableMethods: []
};
this.currentTypeEnv = defaultTypeEnv;
this.functions = "";
}
async run(source : string) : Promise<Value<Annotation>> {
const config : Config = {importObject: this.importObject, env: this.currentEnv, typeEnv: this.currentTypeEnv, functions: this.functions};
const [result, newEnv, newTypeEnv, newFunctions, instance] = await run(source, config);
this.currentEnv = newEnv;
this.currentTypeEnv = newTypeEnv;
this.functions += newFunctions;
const currentGlobals = this.importObject.env || {};
Object.keys(instance.instance.exports).forEach(k => {
const maybeGlobal = instance.instance.exports[k];
if(maybeGlobal instanceof WebAssembly.Global) {
currentGlobals[k] = maybeGlobal;
}
});
this.importObject.env = currentGlobals;
return result;
}
optimize(source: string): [ Program<Annotation>, Program<Annotation> ] {
// console.log(stmt);
const config : Config = {importObject: this.importObject, env: this.currentEnv, typeEnv: this.currentTypeEnv, functions: this.functions};
const parsed = parse(source);
const [tprogram, tenv] = tc(config.typeEnv, parsed);
const globalEnv = augmentEnv(config.env, tprogram);
const irprogram = lowerProgram(tprogram, globalEnv);
if(!this.importObject.js) {
const memory = new WebAssembly.Memory({initial:2000, maximum:2000});
this.importObject.js = { memory: memory };
}
return [ irprogram, optimizeProgram(irprogram) ];
}
tc(source: string): Type {
const config: Config = { importObject: this.importObject, env: this.currentEnv, typeEnv: this.currentTypeEnv, functions: this.functions };
const parsed = parse(source);
const [result, _] = tc(this.currentTypeEnv, parsed);
return result.a.type;
}
}