Files
KDL_WORK/kdl-wasm/web/tests/grl/parser.test.ts
2026-06-27 08:45:38 -04:00

104 lines
2.6 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { GrlParseError, parseGrl } from "../../src/grl/parser/index.js";
describe("GRL parser", () => {
it("parses the minimal language/module/proc skeleton with source ranges", () => {
const ast = parseGrl(`language grl 0.1
module Main
proc main()
// body comment should not affect parser
end
end
`);
expect(ast).toMatchObject({
kind: "Program",
language: {
kind: "LanguageDeclaration",
language: "grl",
version: "0.1",
range: {
start: { line: 1, column: 1 },
end: { line: 1, column: 17 }
}
},
module: {
kind: "ModuleDeclaration",
name: "Main",
declarations: [
{
kind: "ProcedureDeclaration",
name: "main",
params: []
}
]
}
});
expect(ast.module.range.start).toMatchObject({ line: 3, column: 1 });
expect(ast.module.range.end).toMatchObject({ line: 7, column: 4 });
});
it("parses imports, data declarations, targets, and procedure body tokens", () => {
const ast = parseGrl(`language grl 0.1
module Main
import CommonTools
const speed v_pick = linear(300 mm/s)
target home = joint_target {
joints: [0 deg, 0 deg]
}
proc main()
movej home
end
end
`);
expect(ast.module.declarations.map((decl) => decl.kind)).toEqual([
"ImportDeclaration",
"DataDeclaration",
"TargetDeclaration",
"ProcedureDeclaration"
]);
expect(ast.module.declarations[0]).toMatchObject({
kind: "ImportDeclaration",
moduleName: "CommonTools"
});
expect(ast.module.declarations[1]).toMatchObject({
kind: "DataDeclaration",
storage: "const",
typeName: "speed",
name: "v_pick",
initializer: {
kind: "CallExpression",
callee: "linear"
}
});
expect(ast.module.declarations[2]).toMatchObject({
kind: "TargetDeclaration",
name: "home",
target: {
kind: "ObjectExpression",
typeName: "joint_target"
}
});
expect(ast.module.declarations[3]).toMatchObject({
kind: "ProcedureDeclaration",
bodyTokens: [
{
kind: "keyword",
raw: "movej"
},
{
kind: "identifier",
raw: "home"
}
]
});
});
it("reports stable line and column on invalid syntax", () => {
expect(() => parseGrl("language grl\nmodule Main\nend\n")).toThrow(GrlParseError);
expect(() => parseGrl("language grl\nmodule Main\nend\n")).toThrow("Expected GRL language version at 2:1");
});
});