Implement .param directive

This commit is contained in:
2026-03-09 23:46:55 +00:00
parent 554d918640
commit 6a4877d52c

54
asm.js
View File

@@ -47,10 +47,12 @@ class Tokenizer {
} }
const State = Object.freeze({ const State = Object.freeze({
TOP: 0, TOP: 0,
EXPORT: 1, EXPORT: 1,
FUNC: 2, FUNC: 2,
RESULT: 3, RESULT: 3,
PARAM_NAME: 4,
PARAM_TYPE: 5,
}); });
const Action = Object.freeze({ const Action = Object.freeze({
@@ -58,6 +60,7 @@ const Action = Object.freeze({
EXPORT: 1, EXPORT: 1,
FUNC: 2, FUNC: 2,
RESULT: 3, RESULT: 3,
PARAM: 4,
}); });
const types = { const types = {
@@ -67,6 +70,7 @@ const types = {
const opcodes = { const opcodes = {
"end": 0x0b, "end": 0x0b,
"local.get": 0x20,
"i32.const": 0x41, "i32.const": 0x41,
"i32.mul": 0x6c, "i32.mul": 0x6c,
}; };
@@ -80,15 +84,19 @@ class Parser {
".export": State.EXPORT, ".export": State.EXPORT,
".func": State.FUNC, ".func": State.FUNC,
".result": State.RESULT, ".result": State.RESULT,
".param": State.PARAM_NAME,
}; };
this.handlers = { this.handlers = {
[State.TOP]: (token) => this.token_top(token), [State.TOP]: (token) => this.token_top(token),
[State.EXPORT]: (token) => this.token_export(token), [State.EXPORT]: (token) => this.token_export(token),
[State.FUNC]: (token) => this.token_func(token), [State.FUNC]: (token) => this.token_func(token),
[State.RESULT]: (token) => this.token_result(token), [State.RESULT]: (token) => this.token_result(token),
[State.PARAM_NAME]: (token) => this.token_param_name(token),
[State.PARAM_TYPE]: (token) => this.token_param_type(token),
}; };
this.results = []; this.results = [];
this.params = {};
} }
translate_code(token) { translate_code(token) {
@@ -132,6 +140,31 @@ class Parser {
} }
} }
token_param_name(token) {
if (token == LINE_END) {
const action = { type: Action.PARAM, params: this.params };
this.state = State.TOP;
this.params = {};
return action;
} else {
this.current_param = token;
this.state = State.PARAM_TYPE;
}
}
token_param_type(token) {
if (token == LINE_END) {
console.error(
"ERROR: Unexpected newline in .params: expected type");
this.state = State.TOP;
this.params = {};
} else {
this.params[this.current_param] = types[token];
this.current_param = undefined;
this.state = State.PARAM_NAME;
}
}
*handle(src) { *handle(src) {
let action; let action;
for (const token of this.tokenizer.handle(src)) { for (const token of this.tokenizer.handle(src)) {
@@ -158,6 +191,7 @@ export class Assembler {
[Action.EXPORT]: (action) => this.action_export(action), [Action.EXPORT]: (action) => this.action_export(action),
[Action.FUNC]: (action) => this.action_func(action), [Action.FUNC]: (action) => this.action_func(action),
[Action.RESULT]: (action) => this.action_result(action), [Action.RESULT]: (action) => this.action_result(action),
[Action.PARAM]: (action) => this.action_param(action),
}; };
this.exports = []; this.exports = [];
@@ -187,6 +221,10 @@ export class Assembler {
this.funcs[this.current_func].results.push(...action.results); this.funcs[this.current_func].results.push(...action.results);
} }
action_param(action) {
Object.assign(this.funcs[this.current_func].params, action.params);
}
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))