Compare commits
2 Commits
60efd931f5
...
81d8e32a04
Author | SHA1 | Date | |
---|---|---|---|
|
81d8e32a04 | ||
|
7389692993 |
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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
91
compiler/ids.ts
Normal 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];
|
||||||
|
}
|
||||||
|
}
|
@ -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";
|
||||||
|
|
||||||
|
@ -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";
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user