fix ids
This commit is contained in:
		
							parent
							
								
									60efd931f5
								
							
						
					
					
						commit
						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 { | ||||||
|  | |||||||
| @ -6,15 +6,17 @@ import { | |||||||
|     Report, |     Report, | ||||||
|     Span, |     Span, | ||||||
| } from "./diagnostics.ts"; | } from "./diagnostics.ts"; | ||||||
|  | import { File, IdentId, IdMap, Ids } 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 +28,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 +36,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 +75,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 { | ||||||
| @ -128,8 +133,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 +142,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]; | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user