Skip to content

Commit

Permalink
Lex via Moo
Browse files Browse the repository at this point in the history
  • Loading branch information
samestep committed Jan 2, 2024
1 parent 37e756e commit e3662b5
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 5 deletions.
13 changes: 13 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"packages/*"
],
"devDependencies": {
"@types/moo": "^0.5",
"@types/node": "^20",
"@types/yargs": "^17",
"@vscode/vsce": "^2",
Expand Down
1 change: 1 addition & 0 deletions packages/rose/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"src"
],
"dependencies": {
"moo": "^0.5",
"yargs": "^17"
},
"scripts": {
Expand Down
46 changes: 46 additions & 0 deletions packages/rose/src/lex.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { expect, test } from "vitest";
import { lexer } from "./lex.js";

const tokens = (
source: string,
): { type: string | undefined; text: string }[] => {
const lex = lexer();
lex.reset(source);
return [...lex].map(({ type, text }) => ({ type, text }));
};

test("comment", () => {
expect(
tokens(`# one comment
# another comment`),
).toEqual([
{ type: "comment", text: "# one comment" },
{ type: "space", text: "\n\n" },
{ type: "comment", text: "# another comment" },
]);
});

test("string", () => {
expect(tokens('"one string" "another string"')).toEqual([
{ type: "str", text: '"one string"' },
{ type: "space", text: " " },
{ type: "str", text: '"another string"' },
]);
});

test("integer", () => {
expect(tokens("42")).toEqual([{ type: "num", text: "42" }]);
});

test("float", () => {
expect(tokens("42.0")).toEqual([{ type: "num", text: "42.0" }]);
});

test("number followed by letter", () => {
expect(() => tokens("1a")).toThrow("invalid syntax");
});

test("letter followed by number", () => {
expect(tokens("a1")).toEqual([{ type: "id", text: "a1" }]);
});
19 changes: 19 additions & 0 deletions packages/rose/src/lex.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import moo from "moo";

export const lexer = () =>
moo.compile({
op: /[^\s#\w"\(\)\[\]\{\},\.]+/,
space: { match: /\s+/, lineBreaks: true },
comment: /#.*?$/,
str: { match: /".*?"/, lineBreaks: true },
num: /\d+(?:\.\d+)?\b/,
id: /(?!\d)\w+/,
lparen: "(",
rparen: ")",
lbracket: "[",
rbracket: "]",
lbrace: "{",
rbrace: "}",
comma: ",",
dot: ".",
});
11 changes: 6 additions & 5 deletions packages/vscode/syntaxes/rose.tmLanguage.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,13 @@
"literals": {
"patterns": [
{
"name": "constant.numeric.rose",
"match": "\\b[0-9]+(\\.[0-9]+)?\\b"
"name": "string.quoted.double.rose",
"begin": "\"",
"end": "\""
},
{
"name": "string.quoted.double.rose",
"match": "\"([^\"\\\\]|\\\\.)*\""
"name": "constant.numeric.rose",
"match": "\\b\\d+(\\.\\d+)?\\b"
},
{
"name": "constant.language.rose",
Expand Down Expand Up @@ -91,7 +92,7 @@
"patterns": [
{
"name": "keyword.operator.rose",
"match": "[^\\s#\\w\\d\"\\(\\)\\[\\]\\{\\},\\.]+"
"match": "[^\\s#\\w\"\\(\\)\\[\\]\\{\\},\\.]+"
}
]
}
Expand Down

0 comments on commit e3662b5

Please sign in to comment.