Implement .align directive

This commit is contained in:
2026-03-14 13:19:59 +00:00
parent 93f3dd1f41
commit 2c3e5f46da

33
asm.js
View File

@@ -92,6 +92,7 @@ const State = Object.freeze({
BYTE: 20, BYTE: 20,
WORD: 21, WORD: 21,
UTF8: 22, UTF8: 22,
ALIGN: 23,
}); });
const Action = Object.freeze({ const Action = Object.freeze({
@@ -107,6 +108,7 @@ const Action = Object.freeze({
GLOBAL: 9, GLOBAL: 9,
AT: 10, AT: 10,
DATA: 11, DATA: 11,
ALIGN: 12,
}); });
const types = { const types = {
@@ -154,6 +156,7 @@ class Parser {
".byte": State.BYTE, ".byte": State.BYTE,
".word": State.WORD, ".word": State.WORD,
".utf8": State.UTF8, ".utf8": State.UTF8,
".align": State.ALIGN,
}; };
this.handlers = { this.handlers = {
[State.TOP]: (token) => this.token_top(token), [State.TOP]: (token) => this.token_top(token),
@@ -179,6 +182,7 @@ class Parser {
[State.BYTE]: (token) => this.token_byte(token), [State.BYTE]: (token) => this.token_byte(token),
[State.WORD]: (token) => this.token_word(token), [State.WORD]: (token) => this.token_word(token),
[State.UTF8]: (token) => this.token_utf8(token), [State.UTF8]: (token) => this.token_utf8(token),
[State.ALIGN]: (token) => this.token_align(token),
}; };
this.results = []; this.results = [];
@@ -509,7 +513,7 @@ class Parser {
return; return;
} else if (token.string == undefined) { } else if (token.string == undefined) {
console.error( console.error(
`ERROR: unexpected token ${token}, expected string`); `ERROR: Unexpected token ${token}, expected string`);
return; return;
} }
const value = this.encoder.encode(token.string); const value = this.encoder.encode(token.string);
@@ -517,6 +521,23 @@ class Parser {
return action; 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() { mem_action() {
const action = { const action = {
type: Action.MEM, type: Action.MEM,
@@ -571,6 +592,7 @@ export class Assembler {
[Action.GLOBAL]: (action) => this.action_global(action), [Action.GLOBAL]: (action) => this.action_global(action),
[Action.AT]: (action) => this.action_at(action), [Action.AT]: (action) => this.action_at(action),
[Action.DATA]: (action) => this.action_data(action), [Action.DATA]: (action) => this.action_data(action),
[Action.ALIGN]: (action) => this.action_align(action),
}; };
this.exports = []; this.exports = [];
@@ -663,6 +685,15 @@ export class Assembler {
this.pos.addr += action.size; 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) { push(chunk) {
const text = this.decoder.decode(chunk, { stream: true }); const text = this.decoder.decode(chunk, { stream: true });
for (const action of this.parser.handle(text)) for (const action of this.parser.handle(text))