Skip to content

Commit

Permalink
wip: creating discover module for importer feature
Browse files Browse the repository at this point in the history
  • Loading branch information
guiferpa committed Dec 28, 2023
1 parent ec2f6e2 commit ca41bbe
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 0 deletions.
Empty file added examples/from.ar
Empty file.
3 changes: 3 additions & 0 deletions src/importer/dependency.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default class Dependency {
constructor(public readonly id: string, public readonly alias: string) {}
}
57 changes: 57 additions & 0 deletions src/importer/discover.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Lexer } from "@/lexer";
import Discover from "./discover";
import Dependency from "./dependency";

describe("Discover test suite", () => {
test("Program that imports only one dependency", () => {
const program = `
from "github.com/guiferpa/testing" as testing
`;

const expected = [new Dependency("github.com/guiferpa/testing", "testing")];

const lexer = new Lexer(Buffer.from(program, "utf-8"));
const discover = new Discover(lexer);
const got = discover.run();
expect(got).toStrictEqual(expected);
});

test("Program that imports some dependencies", () => {
const program = `
from "github.com/guiferpa/testing" as testing
from "github.com/guiferpa/tester" as tester
from "github.com/guiferpa/test" as test
`;

const expected = [
new Dependency("github.com/guiferpa/testing", "testing"),
new Dependency("github.com/guiferpa/tester", "tester"),
new Dependency("github.com/guiferpa/test", "test"),
];

const lexer = new Lexer(Buffer.from(program, "utf-8"));
const discover = new Discover(lexer);
const got = discover.run();
expect(got).toStrictEqual(expected);
});

test("Program that imports some duplicated dependencies", () => {
const program = `
from "github.com/guiferpa/testing" as testing
from "github.com/guiferpa/testing" as testing
from "github.com/guiferpa/tester" as tester
from "github.com/guiferpa/test" as test
`;

const expected = [
new Dependency("github.com/guiferpa/testing", "testing"),
new Dependency("github.com/guiferpa/tester", "tester"),
new Dependency("github.com/guiferpa/test", "test"),
];

const lexer = new Lexer(Buffer.from(program, "utf-8"));
const discover = new Discover(lexer);
const got = discover.run();
expect(got).toStrictEqual(expected);
});
});
54 changes: 54 additions & 0 deletions src/importer/discover.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Lexer } from "@/lexer";
import { TokenTag } from "@/lexer/tokens/tag";
import { Token } from "@/lexer/tokens/token";

import Dependency from "./dependency";

export default class Discover {
private _lookahead: Token | null = null;

constructor(private readonly _lexer: Lexer) {}

private _discovery(): Dependency[] {
const deps = new Map<string, Dependency>();

this._lookahead = this._lexer.getNextToken();

while (this._lookahead?.tag === TokenTag.FROM) {
this._lookahead = this._lexer.getNextToken();
if (this._lookahead.tag !== TokenTag.STR) {
throw new Error(
`Missing dependency identifier at line ${this._lookahead.line}`
);
}

const id = this._lookahead.value;

this._lookahead = this._lexer.getNextToken();

if (this._lookahead.tag !== TokenTag.AS) {
throw new SyntaxError(
`Unexpected token ${this._lookahead.tag} at line ${this._lookahead.line}`
);
}

this._lookahead = this._lexer.getNextToken();

if (this._lookahead.tag !== TokenTag.IDENT) {
throw new Error(`Invalid alias at line ${this._lookahead.line}`);
}

const alias = this._lookahead.value;

deps.set(id, new Dependency(id, alias));

this._lookahead = this._lexer.getNextToken();
}

return Array.from(deps.values());
}

public run(): Dependency[] {
return this._discovery();
}
}
2 changes: 2 additions & 0 deletions src/lexer/tokens/tag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,7 @@ export enum TokenTag {
DESC_FUNC = "__DESC_FUNC__",
STR = "__STR__",
COMMENT = "__COMMENT__",
FROM = "__FROM__",
AS = "__AS__",
EOF = "__EOF__",
}
2 changes: 2 additions & 0 deletions src/lexer/tokens/terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export const Terminals: [RegExp, TokenTag][] = [
[new RegExp(/^desc/), TokenTag.DESC_FUNC],
[new RegExp(/^return void/), TokenTag.RETURN_VOID],
[new RegExp(/^return/), TokenTag.RETURN],
[new RegExp(/^from/), TokenTag.FROM],
[new RegExp(/^as/), TokenTag.AS],
[new RegExp(/^var [a-zA-Z_]+(\s?)=/), TokenTag.ASSIGN],
[new RegExp(/^func [a-zA-Z_><\-!?]+/), TokenTag.DECL_FN],
[new RegExp(/^\+/), TokenTag.OP_ADD],
Expand Down

0 comments on commit ca41bbe

Please sign in to comment.