mirror of
https://github.com/Ed94/pikuma_ps1.git
synced 2026-08-16 14:11:33 +00:00
78 lines
2.8 KiB
JavaScript
78 lines
2.8 KiB
JavaScript
"use strict";
|
|
|
|
const assert = require("node:assert/strict");
|
|
const test = require("node:test");
|
|
|
|
const { buildCallContexts, lex, nearestCall } = require("../lexer");
|
|
|
|
test("lex skips comments, strings, and character literals", () => {
|
|
const source = [
|
|
"MipsAtom_(visible)",
|
|
"// MipsAtom_(line_comment)",
|
|
"const char *s = \"atom_reads(R_Hidden)\";",
|
|
"char c = '\\''; /* gte_cmdw_hidden */",
|
|
"atom_reads(R_Visible)",
|
|
].join("\n");
|
|
|
|
const result = lex(source);
|
|
const identifiers = result.tokens
|
|
.filter((token) => token.kind === "identifier")
|
|
.map((token) => token.text);
|
|
|
|
assert.deepEqual(result.errors, []);
|
|
assert.equal(identifiers.includes("visible"), true);
|
|
assert.equal(identifiers.includes("R_Visible"), true);
|
|
assert.equal(identifiers.includes("line_comment"), false);
|
|
assert.equal(identifiers.includes("R_Hidden"), false);
|
|
assert.equal(identifiers.includes("gte_cmdw_hidden"), false);
|
|
});
|
|
|
|
test("lex reports unterminated block comments without returning comment tokens", () => {
|
|
const result = lex("R_Visible /* atom_reads(R_Hidden)");
|
|
|
|
assert.equal(result.tokens.some((token) => token.text === "R_Visible"), true);
|
|
assert.equal(result.tokens.some((token) => token.text === "R_Hidden"), false);
|
|
assert.deepEqual(result.errors.map((error) => error.kind), ["unterminated-block-comment"]);
|
|
});
|
|
|
|
test("line comments stop at CRLF boundaries", () => {
|
|
const result = lex("// atom_reads(R_Hidden)\r\natom_reads(R_Visible)\r\n");
|
|
const identifiers = result.tokens
|
|
.filter((token) => token.kind === "identifier")
|
|
.map((token) => token.text);
|
|
|
|
assert.equal(identifiers.includes("R_Hidden"), false);
|
|
assert.equal(identifiers.includes("R_Visible"), true);
|
|
});
|
|
|
|
test("balanced contexts retain multiline nesting and argument indexes", () => {
|
|
const source = [
|
|
"atom_info(",
|
|
"\tatom_phase(cube_g4),",
|
|
"\tatom_reads(R_A, nested(R_B, R_C)),",
|
|
"\tatom_writes(R_D)",
|
|
")",
|
|
].join("\n");
|
|
const lexical = lex(source);
|
|
const balanced = buildCallContexts(lexical.tokens);
|
|
|
|
const byText = new Map();
|
|
lexical.tokens.forEach((token, index) => {
|
|
if (token.kind === "identifier") byText.set(token.text, index);
|
|
});
|
|
|
|
assert.equal(nearestCall(balanced.contexts, byText.get("cube_g4")).callee, "atom_phase");
|
|
assert.equal(nearestCall(balanced.contexts, byText.get("R_A")).callee, "atom_reads");
|
|
assert.equal(nearestCall(balanced.contexts, byText.get("R_A")).argIndex, 0);
|
|
assert.equal(nearestCall(balanced.contexts, byText.get("R_C")).callee, "nested");
|
|
assert.equal(nearestCall(balanced.contexts, byText.get("R_D")).callee, "atom_writes");
|
|
assert.deepEqual(balanced.errors, []);
|
|
});
|
|
|
|
test("balanced contexts report unmatched parentheses", () => {
|
|
const lexical = lex("atom_reads(R_A");
|
|
const balanced = buildCallContexts(lexical.tokens);
|
|
|
|
assert.deepEqual(balanced.errors.map((error) => error.kind), ["unmatched-open-paren"]);
|
|
});
|