diff --git a/asm.js b/asm.js index 068e8eb..47ac5d1 100644 --- a/asm.js +++ b/asm.js @@ -92,6 +92,7 @@ const State = Object.freeze({ BYTE: 20, WORD: 21, UTF8: 22, + ALIGN: 23, }); const Action = Object.freeze({ @@ -107,6 +108,7 @@ const Action = Object.freeze({ GLOBAL: 9, AT: 10, DATA: 11, + ALIGN: 12, }); const types = { @@ -154,6 +156,7 @@ class Parser { ".byte": State.BYTE, ".word": State.WORD, ".utf8": State.UTF8, + ".align": State.ALIGN, }; this.handlers = { [State.TOP]: (token) => this.token_top(token), @@ -179,6 +182,7 @@ class Parser { [State.BYTE]: (token) => this.token_byte(token), [State.WORD]: (token) => this.token_word(token), [State.UTF8]: (token) => this.token_utf8(token), + [State.ALIGN]: (token) => this.token_align(token), }; this.results = []; @@ -509,7 +513,7 @@ class Parser { return; } else if (token.string == undefined) { console.error( - `ERROR: unexpected token ${token}, expected string`); + `ERROR: Unexpected token ${token}, expected string`); return; } const value = this.encoder.encode(token.string); @@ -517,6 +521,23 @@ class Parser { return action; } + token_align(token) { + const action = { type: Action.ALIGN }; + if (token == LINE_END) { + action.alignment = 4; + } else { + action.alignment = this.integer(token); + if (action.alignment == null) { + console.error( + `ERROR: Unexpected token ${token}, expected alignment`); + this.state = State.TOP; + return action; + } + } + this.state = State.TOP + return action; + } + mem_action() { const action = { type: Action.MEM, @@ -571,6 +592,7 @@ export class Assembler { [Action.GLOBAL]: (action) => this.action_global(action), [Action.AT]: (action) => this.action_at(action), [Action.DATA]: (action) => this.action_data(action), + [Action.ALIGN]: (action) => this.action_align(action), }; this.exports = []; @@ -663,6 +685,15 @@ export class Assembler { this.pos.addr += action.size; } + action_align(action) { + const alignment = action.alignment; + const data = this.data.at(-1).data; + while (this.pos.addr % alignment != 0) { + data.push(0); + ++this.pos.addr; + } + } + push(chunk) { const text = this.decoder.decode(chunk, { stream: true }); for (const action of this.parser.handle(text))