From 7389692993de3600071f0f4505b84960b0075439 Mon Sep 17 00:00:00 2001 From: sfja Date: Mon, 3 Feb 2025 15:44:31 +0100 Subject: [PATCH] fix ids --- compiler/ast/ast.ts | 12 +++--- compiler/ast/cx.ts | 7 ++-- compiler/ctx.ts | 51 +++++++++---------------- compiler/ids.ts | 91 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+), 43 deletions(-) create mode 100644 compiler/ids.ts diff --git a/compiler/ast/ast.ts b/compiler/ast/ast.ts index f6ffc1c..219ccf0 100644 --- a/compiler/ast/ast.ts +++ b/compiler/ast/ast.ts @@ -1,4 +1,4 @@ -import { File as CtxFile, IdentId } from "../ctx.ts"; +import { AstId, File as CtxFile, IdentId } from "../ids.ts"; import { Span } from "../diagnostics.ts"; export type File = { @@ -7,7 +7,7 @@ export type File = { }; export type Stmt = { - id: number; + id: AstId; kind: StmtKind; span: Span; }; @@ -44,7 +44,7 @@ export type AssignType = "=" | "+=" | "-="; export type ExprStmt = { expr: Expr }; export type Item = { - id: number; + id: AstId; kind: ItemKind; span: Span; ident: Ident; @@ -122,7 +122,7 @@ export type GenericParam = { }; export type Expr = { - id: number; + id: AstId; kind: ExprKind; span: Span; }; @@ -205,7 +205,7 @@ export type Block = { }; export type Pat = { - id: number; + id: AstId; kind: PatKind; span: Span; }; @@ -219,7 +219,7 @@ export type BindPat = { ident: Ident; mut: boolean }; export type PathPat = { qty?: Ty; path: Path }; export type Ty = { - id: number; + id: AstId; kind: TyKind; span: Span; }; diff --git a/compiler/ast/cx.ts b/compiler/ast/cx.ts index cd6a24b..903aea6 100644 --- a/compiler/ast/cx.ts +++ b/compiler/ast/cx.ts @@ -1,4 +1,5 @@ import { Span } from "../diagnostics.ts"; +import { AstId, Ids } from "../ids.ts"; import { Expr, ExprKind, @@ -14,10 +15,10 @@ import { } from "./ast.ts"; export class Cx { - private idCounter = 0; + private astIdGen = new Ids(); - private id(): number { - return this.idCounter++; + private id(): AstId { + return this.astIdGen.nextThenStep(); } public stmt(kind: StmtKind, span: Span): Stmt { diff --git a/compiler/ctx.ts b/compiler/ctx.ts index 3c1ac01..6072567 100644 --- a/compiler/ctx.ts +++ b/compiler/ctx.ts @@ -6,15 +6,17 @@ import { Report, Span, } from "./diagnostics.ts"; +import { File, IdentId, IdMap, Ids } from "./ids.ts"; export class Ctx { private fileIds = new Ids(); - private files = new Map, FileInfo>(); + private files = new IdMap(); + private _entryFile?: File; private reports: Report[] = []; public fileHasChildWithIdent(file: File, childIdent: string): boolean { - return this.files.get(idKey(file))! + return this.files.get(file)! .subFiles.has(childIdent); } @@ -26,7 +28,7 @@ export class Ctx { text: string, ): File { const file = this.fileIds.nextThenStep(); - this.files.set(idKey(file), { + this.files.set(file, { ident, absPath, relPath, @@ -34,35 +36,38 @@ export class Ctx { subFiles: new Map(), text, }); + this._entryFile = this._entryFile ?? file; if (superFile) { - this.files.get(idKey(superFile))! + this.files.get(superFile)! .subFiles.set(ident, file); } return file; } public addFileAst(file: File, ast: ast.File) { - this.files.get(idKey(file))!.ast = ast; + this.files.get(file)!.ast = ast; } public fileInfo(file: File): FileInfo { - return this.files.get(idKey(file))!; + return this.files.get(file)!; } public entryFile(): File { - return keyId(0); + if (!this._entryFile) { + throw new Error(); + } + return this._entryFile; } public iterFiles(): IteratorObject { - return this.files.keys() - .map((key) => keyId(key)); + return this.files.keys(); } // private identIds = new Ids(); private identStringToId = new Map(); - private identIdToString = new Map, string>(); + private identIdToString = new IdMap(); public internIdent(ident: string): IdentId { if (this.identStringToId.has(ident)) { @@ -70,12 +75,12 @@ export class Ctx { } const id = this.identIds.nextThenStep(); this.identStringToId.set(ident, id); - this.identIdToString.set(idKey(id), ident); + this.identIdToString.set(id, ident); return id; } public identText(ident: IdentId): string { - return this.identIdToString.get(idKey(ident))!; + return this.identIdToString.get(ident)!; } public filePosLineText(file: File, pos: Pos): string { @@ -128,8 +133,6 @@ export class Ctx { } } -export type File = IdBase & { readonly _: unique symbol }; - export type FileInfo = { ident: string; absPath: string; @@ -139,23 +142,3 @@ export type FileInfo = { text: string; ast?: ast.File; }; - -export type IdentId = IdBase & { readonly _: unique symbol }; -export type DefId = IdBase & { readonly _: unique symbol }; - -export type IdBase = { key: number }; - -export type Key = IdType["key"]; -export const idKey = (id: IdType): Key => id.key; -export const keyId = ( - key: Key, -): IdType => ({ key } as IdType); - -export class Ids { - private next = 0; - public nextThenStep(): IdType { - const key = this.next; - this.next += 1; - return { key } as IdType; - } -} diff --git a/compiler/ids.ts b/compiler/ids.ts new file mode 100644 index 0000000..ec4af8c --- /dev/null +++ b/compiler/ids.ts @@ -0,0 +1,91 @@ +// + +export type File = IdBase & { readonly _: unique symbol }; +export type IdentId = IdBase & { readonly _: unique symbol }; +export type AstId = IdBase & { readonly _: unique symbol }; + +export type DefId = IdBase & { readonly _: unique symbol }; + +// + +export type IdBase = { rawId: number }; + +export type IdRaw = IdType["rawId"]; + +export const idRaw = (id: IdType): IdRaw => + id.rawId; + +export const idFromRaw = ( + rawId: IdRaw, +): IdType => ({ rawId } as IdType); + +export class Ids { + private next = 0; + public nextThenStep(): IdType { + const rawId = this.next; + this.next += 1; + return idFromRaw(rawId); + } +} + +export class IdMap implements Map { + private map = new Map, V>(); + + set(id: Id, val: V) { + this.map.set(idRaw(id), val); + return this; + } + + get(id: Id): V | undefined { + return this.map.get(idRaw(id)); + } + + has(id: Id): boolean { + return this.map.has(idRaw(id)); + } + + keys(): MapIterator { + return this.map.keys() + .map((rawId) => idFromRaw(rawId)); + } + + clear(): void { + this.map.clear(); + } + + delete(id: Id): boolean { + return this.map.delete(idRaw(id)); + } + + forEach( + callbackfn: (value: V, key: Id, map: Map) => void, + thisArg?: unknown, + ): void { + this.map.forEach( + (value, key, _map) => callbackfn(value, idFromRaw(key), this), + thisArg, + ); + } + + get size(): number { + return this.map.size; + } + + entries(): MapIterator<[Id, V]> { + return this.map.entries() + .map(([rawId, v]) => [idFromRaw(rawId), v]); + } + + values(): MapIterator { + return this.map.values(); + } + + [Symbol.iterator](): MapIterator<[Id, V]> { + return this.map[Symbol.iterator]() + .map(([rawId, v]) => [idFromRaw(rawId), v]); + } + + get [Symbol.toStringTag](): string { + return this.map[Symbol.toStringTag]; + } +}