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"); }); });