diff --git a/asm.js b/asm.js index 9882baa..8fad25c 100644 --- a/asm.js +++ b/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,7 +166,9 @@ 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 = []; this.params = {}; @@ -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))