From 2f1f4a97989cc362e6887288b2ad3a2e2d6d0652 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Wed, 2 Aug 2023 19:18:52 +0200 Subject: [PATCH] refactorings --- src/ast.ts | 33 +++++++------------------------ src/context.ts | 12 +++++++----- src/error.ts | 49 +++++++++++++++++++++++++--------------------- src/index.ts | 10 ++++++---- src/lexer.test.ts | 4 ++-- src/lexer.ts | 4 ++-- src/loader.ts | 4 ++-- src/lower.ts | 26 +++++++++--------------- src/parser.ts | 10 +++++----- src/resolve.ts | 17 +++++++++------- src/typeck.test.ts | 4 +++- src/typeck.ts | 12 +++++------- 12 files changed, 85 insertions(+), 100 deletions(-) diff --git a/src/ast.ts b/src/ast.ts index 502fb55..3ed4330 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -1,6 +1,6 @@ -import { DUMMY_SPAN, LoadedFile, Span } from "./error"; +import { LoadedFile, Span } from "./error"; import { LitIntType } from "./lexer"; -import { ComplexMap, unwrap } from "./utils"; +import { ComplexMap } from "./utils"; export type Phase = { res: unknown; @@ -57,7 +57,7 @@ export type Crate
= { rootItems: Item
[];
itemsById: ComplexMap (
- crate: Crate ,
- id: ItemId
-): Item {
- if (id.crateId !== crate.id) {
- throw new Error("trying to get item from the wrong crate");
- }
- if (id.itemIdx === 0) {
- // Return a synthetic module representing the crate root.
- return {
- kind: "mod",
- node: {
- contents: crate.rootItems,
- name: crate.packageName,
- },
- span: DUMMY_SPAN,
- id,
- };
- }
-
- return unwrap(crate.itemsById.get(id));
-}
-
// folders
export type FoldFn (
id: ItemId,
- localCrate: Crate
+ localCrate?: Crate
): Item {
const crate = unwrap(
- [localCrate, ...this.depCrates].find((crate) => crate.id === id.crateId)
+ [...(localCrate ? [localCrate] : []), ...this.finalizedCrates].find(
+ (crate) => crate.id === id.crateId
+ )
);
if (id.itemIdx === 0) {
@@ -41,7 +43,7 @@ export class GlobalContext {
contents: crate.rootItems,
name: crate.packageName,
},
- span: DUMMY_SPAN,
+ span: Span.startOfFile(crate.rootFile),
id,
};
}
diff --git a/src/error.ts b/src/error.ts
index d9797b6..1bb4a1a 100644
--- a/src/error.ts
+++ b/src/error.ts
@@ -3,30 +3,35 @@ export type LoadedFile = {
content: string;
};
-export type Span = {
- start: number;
- end: number;
- file: LoadedFile;
-};
+export class Span {
+ constructor(
+ public start: number,
+ public end: number,
+ public file: LoadedFile
+ ) {}
-export function spanMerge(a: Span, b: Span): Span {
- if (a.file !== b.file) {
- throw new Error("cannot merge spans from different files");
+ public merge(b: Span): Span {
+ if (this.file !== b.file) {
+ throw new Error("cannot merge spans from different files");
+ }
+
+ return new Span(
+ Math.min(this.start, b.start),
+ Math.max(this.end, b.end),
+ this.file
+ );
}
- return {
- start: Math.min(a.start, b.start),
- end: Math.max(a.end, b.end),
- file: a.file,
- };
-}
+ public static eof(file: LoadedFile): Span {
+ return new Span(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER, file);
+ }
-export const DUMMY_SPAN: Span = { start: 0, end: 0, file: { content: "" } };
-export const eofSpan = (file: LoadedFile): Span => ({
- start: Number.MAX_SAFE_INTEGER,
- end: Number.MAX_SAFE_INTEGER,
- file,
-});
+ public static startOfFile(file: LoadedFile): Span {
+ return new Span(0, 1, file);
+ }
+
+ public static DUMMY: Span = new Span(0, 0, { content: "" });
+}
export class CompilerError extends Error {
msg: string;
@@ -98,11 +103,11 @@ function spanToSnippet(input: string, span: Span): string {
}
export function lines(file: LoadedFile): Span[] {
- const lines: Span[] = [{ start: 0, end: 0, file }];
+ const lines: Span[] = [new Span(0, 0, file)];
for (let i = 0; i < file.content.length; i++) {
if (file.content[i] === "\n") {
- lines.push({ start: i + 1, end: i + 1, file });
+ lines.push(new Span(i + 1, i + 1, file));
} else {
lines[lines.length - 1].end++;
}
diff --git a/src/index.ts b/src/index.ts
index 605897b..26d6247 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,4 +1,4 @@
-import { LoadedFile, withErrorPrinter } from "./error";
+import { LoadedFile, Span, withErrorPrinter } from "./error";
import { isValidIdent, tokenize } from "./lexer";
import { lower as lowerToWasm } from "./lower";
import { ParseState, parse } from "./parser";
@@ -13,8 +13,6 @@ import { GlobalContext, parseArgs } from "./context";
import { loadCrate } from "./loader";
const INPUT = `
-extern mod std;
-
type A = { a: Int };
function main() = (
@@ -49,6 +47,8 @@ function main() {
const gcx = new GlobalContext(opts, loadCrate);
const mainCrate = gcx.crateId.next();
+ gcx.crateLoader(gcx, "std", Span.startOfFile(file));
+
withErrorPrinter(
() => {
const start = Date.now();
@@ -93,7 +93,9 @@ function main() {
if (debug.has("wat")) {
console.log("-----wasm--------------");
}
- const wasmModule = lowerToWasm([typecked, ...gcx.depCrates]);
+
+ gcx.finalizedCrates.push(typecked);
+ const wasmModule = lowerToWasm(gcx);
const moduleStringColor = writeModuleWatToString(wasmModule, true);
const moduleString = writeModuleWatToString(wasmModule);
diff --git a/src/lexer.test.ts b/src/lexer.test.ts
index 69c62e4..390d164 100644
--- a/src/lexer.test.ts
+++ b/src/lexer.test.ts
@@ -3,7 +3,7 @@ import { tokenize } from "./lexer";
it("should tokenize an emtpy function", () => {
const input = `function hello() = ;`;
- const tokens = tokenize(input);
+ const tokens = tokenize({ content: input });
expect(tokens).toMatchSnapshot();
});
@@ -11,7 +11,7 @@ it("should tokenize an emtpy function", () => {
it("should tokenize hello world", () => {
const input = `print("hello world")`;
- const tokens = tokenize(input);
+ const tokens = tokenize({ content: input });
expect(tokens).toMatchSnapshot();
});
diff --git a/src/lexer.ts b/src/lexer.ts
index 5586092..b850b9b 100644
--- a/src/lexer.ts
+++ b/src/lexer.ts
@@ -92,7 +92,7 @@ export function tokenize(file: LoadedFile): Token[] {
finish: while (i < input.length) {
const next = input[i];
- const span: Span = { start: i, end: i + 1, file };
+ const span: Span = new Span(i, i + 1, file);
if (next === "/" && input[i + 1] === "/") {
while (input[i] !== "\n") {
@@ -206,7 +206,7 @@ export function tokenize(file: LoadedFile): Token[] {
default:
throw new CompilerError(
`invalid escape character: ${input[i]}`,
- { start: span.end - 1, end: span.end, file }
+ new Span(span.end - 1, span.end, file)
);
}
continue;
diff --git a/src/loader.ts b/src/loader.ts
index 526382c..362da1b 100644
--- a/src/loader.ts
+++ b/src/loader.ts
@@ -45,7 +45,7 @@ export const loadCrate: CrateLoader = (
// We really, really want a good algorithm for finding crates.
// But right now we just look for files in the CWD.
- const existing = gcx.depCrates.find((crate) => crate.packageName === name);
+ const existing = gcx.finalizedCrates.find((crate) => crate.packageName === name);
if (existing) {
return existing;
}
@@ -64,7 +64,7 @@ export const loadCrate: CrateLoader = (
const typecked = typeck(gcx, resolved);
- gcx.depCrates.push(typecked);
+ gcx.finalizedCrates.push(typecked);
return typecked;
},
() => {
diff --git a/src/lower.ts b/src/lower.ts
index 0c3a952..4f6d0a8 100644
--- a/src/lower.ts
+++ b/src/lower.ts
@@ -2,7 +2,6 @@ import {
Crate,
Expr,
ExprBlock,
- Final,
Folder,
FunctionDef,
GlobalItem,
@@ -16,12 +15,12 @@ import {
TyStruct,
TyTuple,
Typecked,
- findCrateItem,
mkDefaultFolder,
superFoldExpr,
superFoldItem,
varUnreachable,
} from "./ast";
+import { GlobalContext } from "./context";
import { printTy } from "./printer";
import { ComplexMap, encodeUtf8, unwrap } from "./utils";
import * as wasm from "./wasm/defs";
@@ -61,7 +60,7 @@ export type Context = {
reservedHeapMemoryStart: number;
funcIndices: ComplexMap