Assemble kernel on the client #1
39
asm.js
39
asm.js
@@ -87,6 +87,8 @@ const State = Object.freeze({
|
||||
GLOBAL_NAME: 15,
|
||||
GLOBAL_TYPE: 16,
|
||||
GLOBAL_INIT: 17,
|
||||
AT_MEM: 18,
|
||||
AT_ADDR: 19,
|
||||
});
|
||||
|
||||
const Action = Object.freeze({
|
||||
@@ -100,6 +102,7 @@ const Action = Object.freeze({
|
||||
MEM: 7,
|
||||
IMPORT: 8,
|
||||
GLOBAL: 9,
|
||||
AT: 10,
|
||||
});
|
||||
|
||||
const types = {
|
||||
@@ -142,6 +145,7 @@ class Parser {
|
||||
".mem": State.MEM_NAME,
|
||||
".import": State.IMPORT_NAME,
|
||||
".global": State.GLOBAL_NAME,
|
||||
".at": State.AT_MEM,
|
||||
};
|
||||
this.handlers = {
|
||||
[State.TOP]: (token) => this.token_top(token),
|
||||
@@ -162,6 +166,8 @@ class Parser {
|
||||
[State.GLOBAL_NAME]: (token) => this.token_global_name(token),
|
||||
[State.GLOBAL_TYPE]: (token) => this.token_global_type(token),
|
||||
[State.GLOBAL_INIT]: (token) => this.token_global_init(token),
|
||||
[State.AT_MEM]: (token) => this.token_at_mem(token),
|
||||
[State.AT_ADDR]: (token) => this.token_at_addr(token),
|
||||
};
|
||||
|
||||
this.results = [];
|
||||
@@ -425,6 +431,27 @@ class Parser {
|
||||
}
|
||||
}
|
||||
|
||||
token_at_mem(token) {
|
||||
this.at = { mem: token };
|
||||
this.state = State.AT_ADDR;
|
||||
}
|
||||
|
||||
token_at_addr(token) {
|
||||
const value = this.integer(token);
|
||||
if (value == null) {
|
||||
console.error(
|
||||
`ERROR: Unexpected token {token} in .mem: expected address`);
|
||||
this.at = undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
this.at.addr = value;
|
||||
const action = { type: Action.AT, at: this.at };
|
||||
this.at = undefined;
|
||||
this.state = State.TOP;
|
||||
return action;
|
||||
}
|
||||
|
||||
mem_action() {
|
||||
const action = {
|
||||
type: Action.MEM,
|
||||
@@ -476,6 +503,7 @@ export class Assembler {
|
||||
[Action.MEM]: (action) => this.action_mem(action),
|
||||
[Action.IMPORT]: (action) => this.action_import(action),
|
||||
[Action.GLOBAL]: (action) => this.action_global(action),
|
||||
[Action.AT]: (action) => this.action_at(action),
|
||||
};
|
||||
|
||||
this.exports = [];
|
||||
@@ -483,6 +511,7 @@ export class Assembler {
|
||||
this.mems = {};
|
||||
this.imports = [];
|
||||
this.globals = {};
|
||||
this.pos = { mem: 0, addr: 0 };
|
||||
}
|
||||
|
||||
action_append(action) {
|
||||
@@ -549,6 +578,16 @@ export class Assembler {
|
||||
Object.assign(this.globals, action.global);
|
||||
}
|
||||
|
||||
action_at(action) {
|
||||
const mem = Object.keys(this.mems).indexOf(action.at.mem);
|
||||
if (mem == -1) {
|
||||
console.error(`ERROR: No memory named {action.at.mem}`);
|
||||
return;
|
||||
}
|
||||
this.pos.mem = mem;
|
||||
this.pos.addr = action.at.addr;
|
||||
}
|
||||
|
||||
push(chunk) {
|
||||
const text = this.decoder.decode(chunk, { stream: true });
|
||||
for (const action of this.parser.handle(text))
|
||||
|
||||
Reference in New Issue
Block a user