Compare commits

...

2 Commits

Author SHA1 Message Date
sfja
81d8e32a04 properly merge ids commit 2025-02-03 15:55:29 +01:00
sfja
7389692993 fix ids 2025-02-03 15:47:27 +01:00
10 changed files with 137 additions and 64 deletions

View File

@ -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"; import { Span } from "../diagnostics.ts";
export type File = { export type File = {
@ -7,7 +7,7 @@ export type File = {
}; };
export type Stmt = { export type Stmt = {
id: number; id: AstId;
kind: StmtKind; kind: StmtKind;
span: Span; span: Span;
}; };
@ -44,7 +44,7 @@ export type AssignType = "=" | "+=" | "-=";
export type ExprStmt = { expr: Expr }; export type ExprStmt = { expr: Expr };
export type Item = { export type Item = {
id: number; id: AstId;
kind: ItemKind; kind: ItemKind;
span: Span; span: Span;
ident: Ident; ident: Ident;
@ -122,7 +122,7 @@ export type GenericParam = {
}; };
export type Expr = { export type Expr = {
id: number; id: AstId;
kind: ExprKind; kind: ExprKind;
span: Span; span: Span;
}; };
@ -205,7 +205,7 @@ export type Block = {
}; };
export type Pat = { export type Pat = {
id: number; id: AstId;
kind: PatKind; kind: PatKind;
span: Span; span: Span;
}; };
@ -219,7 +219,7 @@ export type BindPat = { ident: Ident; mut: boolean };
export type PathPat = { qty?: Ty; path: Path }; export type PathPat = { qty?: Ty; path: Path };
export type Ty = { export type Ty = {
id: number; id: AstId;
kind: TyKind; kind: TyKind;
span: Span; span: Span;
}; };

View File

@ -1,4 +1,5 @@
import { Span } from "../diagnostics.ts"; import { Span } from "../diagnostics.ts";
import { AstId, Ids } from "../ids.ts";
import { import {
Expr, Expr,
ExprKind, ExprKind,
@ -14,10 +15,10 @@ import {
} from "./ast.ts"; } from "./ast.ts";
export class Cx { export class Cx {
private idCounter = 0; private astIdGen = new Ids<AstId>();
private id(): number { private id(): AstId {
return this.idCounter++; return this.astIdGen.nextThenStep();
} }
public stmt(kind: StmtKind, span: Span): Stmt { public stmt(kind: StmtKind, span: Span): Stmt {

View File

@ -1,15 +1,16 @@
import * as ast from "../ast/mod.ts"; import * as ast from "../ast/mod.ts";
import { Ctx, File } from "../ctx.ts"; import { Ctx, File } from "../ctx.ts";
import { Span } from "../diagnostics.ts"; import { Span } from "../diagnostics.ts";
import { AstId, IdMap } from "../ids.ts";
import { Resols } from "../resolve/resolver.ts"; import { Resols } from "../resolve/resolver.ts";
import { tyToString } from "../ty/to_string.ts"; import { tyToString } from "../ty/to_string.ts";
import { Ty } from "../ty/ty.ts"; import { Ty } from "../ty/ty.ts";
import { exhausted, Res, todo } from "../util.ts"; import { exhausted, Res, todo } from "../util.ts";
export class Checker { export class Checker {
private itemTys = new Map<number, Ty>(); private itemTys = new IdMap<AstId, Ty>();
private exprTys = new Map<number, Ty>(); private exprTys = new IdMap<AstId, Ty>();
private tyTys = new Map<number, Ty>(); private tyTys = new IdMap<AstId, Ty>();
private currentFile: File; private currentFile: File;

View File

@ -6,15 +6,18 @@ import {
Report, Report,
Span, Span,
} from "./diagnostics.ts"; } from "./diagnostics.ts";
import { DefId, File, IdentId, IdMap, Ids } from "./ids.ts";
export { type File } from "./ids.ts";
export class Ctx { export class Ctx {
private fileIds = new Ids<File>(); private fileIds = new Ids<File>();
private files = new Map<Key<File>, FileInfo>(); private files = new IdMap<File, FileInfo>();
private _entryFile?: File;
private reports: Report[] = []; private reports: Report[] = [];
public fileHasChildWithIdent(file: File, childIdent: string): boolean { public fileHasChildWithIdent(file: File, childIdent: string): boolean {
return this.files.get(idKey(file))! return this.files.get(file)!
.subFiles.has(childIdent); .subFiles.has(childIdent);
} }
@ -26,7 +29,7 @@ export class Ctx {
text: string, text: string,
): File { ): File {
const file = this.fileIds.nextThenStep(); const file = this.fileIds.nextThenStep();
this.files.set(idKey(file), { this.files.set(file, {
ident, ident,
absPath, absPath,
relPath, relPath,
@ -34,35 +37,38 @@ export class Ctx {
subFiles: new Map(), subFiles: new Map(),
text, text,
}); });
this._entryFile = this._entryFile ?? file;
if (superFile) { if (superFile) {
this.files.get(idKey(superFile))! this.files.get(superFile)!
.subFiles.set(ident, file); .subFiles.set(ident, file);
} }
return file; return file;
} }
public addFileAst(file: File, ast: ast.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 { public fileInfo(file: File): FileInfo {
return this.files.get(idKey(file))!; return this.files.get(file)!;
} }
public entryFile(): File { public entryFile(): File {
return keyId(0); if (!this._entryFile) {
throw new Error();
}
return this._entryFile;
} }
public iterFiles(): IteratorObject<File> { public iterFiles(): IteratorObject<File> {
return this.files.keys() return this.files.keys();
.map((key) => keyId(key));
} }
// //
private identIds = new Ids<IdentId>(); private identIds = new Ids<IdentId>();
private identStringToId = new Map<string, IdentId>(); private identStringToId = new Map<string, IdentId>();
private identIdToString = new Map<Key<IdentId>, string>(); private identIdToString = new IdMap<IdentId, string>();
public internIdent(ident: string): IdentId { public internIdent(ident: string): IdentId {
if (this.identStringToId.has(ident)) { if (this.identStringToId.has(ident)) {
@ -70,12 +76,12 @@ export class Ctx {
} }
const id = this.identIds.nextThenStep(); const id = this.identIds.nextThenStep();
this.identStringToId.set(ident, id); this.identStringToId.set(ident, id);
this.identIdToString.set(idKey(id), ident); this.identIdToString.set(id, ident);
return id; return id;
} }
public identText(ident: IdentId): string { public identText(ident: IdentId): string {
return this.identIdToString.get(idKey(ident))!; return this.identIdToString.get(ident)!;
} }
public filePosLineText(file: File, pos: Pos): string { public filePosLineText(file: File, pos: Pos): string {
@ -100,10 +106,6 @@ export class Ctx {
// //
private defIds = new Ids<DefId>();
//
public report(rep: Report) { public report(rep: Report) {
this.reports.push(rep); this.reports.push(rep);
this.reportImmediately(rep); this.reportImmediately(rep);
@ -128,8 +130,6 @@ export class Ctx {
} }
} }
export type File = IdBase & { readonly _: unique symbol };
export type FileInfo = { export type FileInfo = {
ident: string; ident: string;
absPath: string; absPath: string;
@ -139,23 +139,3 @@ export type FileInfo = {
text: string; text: string;
ast?: ast.File; 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 extends IdBase> = IdType["key"];
export const idKey = <IdType extends IdBase>(id: IdType): Key<IdType> => id.key;
export const keyId = <IdType extends IdBase>(
key: Key<IdType>,
): IdType => ({ key } as IdType);
export class Ids<IdType extends IdBase> {
private next = 0;
public nextThenStep(): IdType {
const key = this.next;
this.next += 1;
return { key } as IdType;
}
}

91
compiler/ids.ts Normal file
View File

@ -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 extends IdBase> = IdType["rawId"];
export const idRaw = <IdType extends IdBase>(id: IdType): IdRaw<IdType> =>
id.rawId;
export const idFromRaw = <IdType extends IdBase>(
rawId: IdRaw<IdType>,
): IdType => ({ rawId } as IdType);
export class Ids<IdType extends IdBase> {
private next = 0;
public nextThenStep(): IdType {
const rawId = this.next;
this.next += 1;
return idFromRaw(rawId);
}
}
export class IdMap<Id extends IdBase, V> implements Map<Id, V> {
private map = new Map<IdRaw<Id>, 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<Id> {
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<Id, V>) => 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<V> {
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];
}
}

View File

@ -1,8 +1,7 @@
import * as path from "jsr:@std/path"; import * as path from "jsr:@std/path";
import { Parser } from "./parse/parser.ts"; import { Parser } from "./parse/parser.ts";
import * as ast from "./ast/mod.ts"; import * as ast from "./ast/mod.ts";
import { Ctx } from "./ctx.ts"; import { Ctx, File } from "./ctx.ts";
import { File } from "./ctx.ts";
import { Resolver } from "./resolve/resolver.ts"; import { Resolver } from "./resolve/resolver.ts";
import { Checker } from "./check/checker.ts"; import { Checker } from "./check/checker.ts";

View File

@ -1,5 +1,6 @@
import { Ctx, File } from "../ctx.ts"; import { Ctx } from "../ctx.ts";
import { Pos, Span } from "../diagnostics.ts"; import { Pos, Span } from "../diagnostics.ts";
import { File } from "../ids.ts";
import { ControlFlow, range } from "../util.ts"; import { ControlFlow, range } from "../util.ts";
import { Token, TokenIter } from "./token.ts"; import { Token, TokenIter } from "./token.ts";

View File

@ -1,5 +1,5 @@
import { IdentId } from "../ctx.ts";
import { Span } from "../diagnostics.ts"; import { Span } from "../diagnostics.ts";
import { IdentId } from "../ids.ts";
export type Token = { export type Token = {
type: string; type: string;

View File

@ -1,5 +1,5 @@
import * as ast from "../ast/mod.ts"; import * as ast from "../ast/mod.ts";
import { IdentId, idKey, Key } from "../ctx.ts"; import { IdentId, IdMap } from "../ids.ts";
import { Res } from "../util.ts"; import { Res } from "../util.ts";
export interface Syms { export interface Syms {
@ -30,17 +30,17 @@ export type Redef = {
}; };
export class SymsOneNsTab { export class SymsOneNsTab {
private defs = new Map<Key<IdentId>, Resolve>(); private defs = new IdMap<IdentId, Resolve>();
public get(ident: ast.Ident): Resolve | undefined { public get(ident: ast.Ident): Resolve | undefined {
return this.defs.get(idKey(ident.id))!; return this.defs.get(ident.id)!;
} }
public def(ident: ast.Ident, kind: ResolveKind): Res<void, Redef> { public def(ident: ast.Ident, kind: ResolveKind): Res<void, Redef> {
if (this.defs.has(idKey(ident.id))) { if (this.defs.has(ident.id)) {
return Res.Err({ ident: this.defs.get(idKey(ident.id))!.ident }); return Res.Err({ ident: this.defs.get(ident.id)!.ident });
} }
this.defs.set(idKey(ident.id), { ident, kind }); this.defs.set(ident.id, { ident, kind });
return Res.Ok(undefined); return Res.Ok(undefined);
} }
} }
@ -127,4 +127,3 @@ export class LocalSyms implements Syms {
return this.syms.defTy(ident, kind); return this.syms.defTy(ident, kind);
} }
} }

View File

@ -1,5 +1,6 @@
import * as ast from "../ast/mod.ts"; import * as ast from "../ast/mod.ts";
import { Ctx, File } from "../ctx.ts"; import { Ctx, File } from "../ctx.ts";
import { AstId, IdMap } from "../ids.ts";
import { exhausted, todo } from "../util.ts"; import { exhausted, todo } from "../util.ts";
import { import {
FnSyms, FnSyms,
@ -12,10 +13,10 @@ import {
export class Resols { export class Resols {
public constructor( public constructor(
private exprResols: Map<number, Resolve>, private exprResols: IdMap<AstId, Resolve>,
) {} ) {}
public exprRes(id: number): Resolve { public exprRes(id: AstId): Resolve {
if (!this.exprResols.has(id)) { if (!this.exprResols.has(id)) {
throw new Error(); throw new Error();
} }
@ -28,7 +29,7 @@ export class Resolver implements ast.Visitor {
private rootSyms = new RootSyms(); private rootSyms = new RootSyms();
private syms: Syms = this.rootSyms; private syms: Syms = this.rootSyms;
private exprResols = new Map<number, Resolve>(); private exprResols = new IdMap<AstId, Resolve>();
public constructor( public constructor(
private ctx: Ctx, private ctx: Ctx,