rename crate to pkg

This commit is contained in:
nora 2023-12-15 18:35:20 +01:00
parent 7ca78530a1
commit b273b20a75
11 changed files with 124 additions and 124 deletions

View file

@ -50,10 +50,10 @@ export type AnyPhase = {
typeckResults: No | HasTypeckResults;
};
export type CrateId = number;
export type PkgId = number;
export type Crate<P extends Phase> = {
id: CrateId;
export type Pkg<P extends Phase> = {
id: PkgId;
rootItems: Item<P>[];
itemsById: ComplexMap<ItemId, Item<P>>;
packageName: string;
@ -61,7 +61,7 @@ export type Crate<P extends Phase> = {
fatalError: ErrorEmitted | undefined;
} & P["typeckResults"];
export type DepCrate = Crate<Final>;
export type DepPkg = Pkg<Final>;
export type Ident = {
name: string;
@ -74,11 +74,11 @@ export type IdentWithRes<P extends Phase> = {
} & P["res"];
export class ItemId {
public crateId: number;
public pkgId: number;
public itemIdx: number;
constructor(crateId: number, itemIdx: number) {
this.crateId = crateId;
constructor(pkgId: number, itemIdx: number) {
this.pkgId = pkgId;
this.itemIdx = itemIdx;
}
@ -86,15 +86,15 @@ export class ItemId {
return new ItemId(999999, 999999);
}
static crateRoot(crate: CrateId): ItemId {
return new ItemId(crate, 0);
static pkgRoot(pkg: PkgId): ItemId {
return new ItemId(pkg, 0);
}
toString(): string {
if (this.crateId === 0) {
if (this.pkgId === 0) {
return `${this.itemIdx}`;
}
return `[${this.crateId}@${this.itemIdx}]`;
return `[${this.pkgId}@${this.itemIdx}]`;
}
}
@ -698,9 +698,9 @@ export function mkDefaultFolder<
}
export function foldAst<From extends Phase, To extends Phase>(
ast: Crate<From>,
ast: Pkg<From>,
folder: Folder<From, To>,
): Crate<To> {
): Pkg<To> {
if ((folder.item as any)[ITEM_DEFAULT] !== ITEM_DEFAULT) {
unreachable("must not override `item` on folders");
}

View file

@ -1,5 +1,5 @@
import {
Crate,
Pkg,
Expr,
ExprBlock,
Folder,
@ -119,7 +119,7 @@ function appendData(cx: Context, newData: Uint8Array): number {
const KNOWN_DEF_PATHS = [ALLOCATE_ITEM, DEALLOCATE_ITEM];
function getKnownDefPaths(
crates: Crate<Typecked>[],
pkgs: Pkg<Typecked>[],
): ComplexMap<string[], ItemId> {
const knows = new ComplexMap<string[], ItemId>();
@ -145,15 +145,15 @@ function getKnownDefPaths(
},
};
crates.forEach((crate) =>
crate.rootItems.forEach((item) => folder.item(item)),
pkgs.forEach((pkg) =>
pkg.rootItems.forEach((item) => folder.item(item)),
);
return knows;
}
export function lower(gcx: GlobalContext): wasm.Module {
const knownDefPaths = getKnownDefPaths(gcx.finalizedCrates);
const knownDefPaths = getKnownDefPaths(gcx.finalizedPkgs);
const mod: wasm.Module = {
types: [],
@ -220,7 +220,7 @@ export function lower(gcx: GlobalContext): wasm.Module {
}
});
}
gcx.finalizedCrates.forEach((ast) => lowerMod(ast.rootItems));
gcx.finalizedPkgs.forEach((ast) => lowerMod(ast.rootItems));
const HEAP_ALIGN = 0x08;
cx.reservedHeapMemoryStart =
@ -228,7 +228,7 @@ export function lower(gcx: GlobalContext): wasm.Module {
? (mod.datas[0].init.length + (HEAP_ALIGN - 1)) & ~(HEAP_ALIGN - 1)
: 0;
addRt(cx, gcx.finalizedCrates);
addRt(cx, gcx.finalizedPkgs);
// THE LINKER
const offset = cx.mod.imports.length;
@ -1576,16 +1576,16 @@ function todo(msg: string): never {
}
// Make the program runnable using wasi-preview-1
function addRt(cx: Context, crates: Crate<Typecked>[]) {
function addRt(cx: Context, pkgs: Pkg<Typecked>[]) {
const { mod } = cx;
const crate0 = unwrap(crates.find((crate) => crate.id === 0));
const pkg0 = unwrap(pkgs.find((pkg) => pkg.id === 0));
const mainCall: wasm.Instr = { kind: "call", func: DUMMY_IDX };
cx.relocations.push({
kind: "funccall",
instr: mainCall,
res: unwrap(crate0.typeckResults.main),
res: unwrap(pkg0.typeckResults.main),
});
const start: wasm.Func = {

View file

@ -1,76 +1,76 @@
import { Crate, DepCrate, Final, Item, ItemId, Phase } from "./ast";
import { Pkg, DepPkg, Final, Item, ItemId, Phase } from "./ast";
import { ErrorHandler, Span } from "./error";
import { Ids, unwrap } from "./utils";
import fs from "fs";
import path from "path";
export type CrateLoader = (
export type PkgLoader = (
gcx: GlobalContext,
name: string,
span: Span,
) => DepCrate;
) => DepPkg;
/**
* The global context containing information about the _global compilation session_,
* like loaded crates.
* Notably, the global context is _not_ supposed to have information specific to the "local crate",
* because with the current compilation model, there is no "local crate" in a session.
* like loaded pkgs.
* Notably, the global context is _not_ supposed to have information specific to the "local pkg",
* because with the current compilation model, there is no "local pkg" in a session.
*
* There is a "downstream"/"binary"/"final" crate with crateId=0, where `function main()` lives, but
* There is a "downstream"/"binary"/"final" pkg with pkgId=0, where `function main()` lives, but
* dependencies (which also use the same context) do not care about that.
*/
export class GlobalContext {
public error: ErrorHandler = new ErrorHandler();
public finalizedCrates: Crate<Final>[] = [];
public finalizedPkgs: Pkg<Final>[] = [];
// For cycle detection.
public cratesBeingLoaded: Set<string> = new Set<string>();
public crateId: Ids = new Ids();
public pkgsBeingLoaded: Set<string> = new Set<string>();
public pkgId: Ids = new Ids();
constructor(public opts: Options, public crateLoader: CrateLoader) {}
constructor(public opts: Options, public pkgLoader: PkgLoader) {}
public findItem<P extends Phase>(
id: ItemId,
localCrate?: Crate<P>,
localPkg?: Pkg<P>,
): Item<P> | Item<Final> {
const allCrates: (Crate<P> | Crate<Final>)[] = [
...(localCrate ? [localCrate] : []),
...this.finalizedCrates,
const allPkgs: (Pkg<P> | Pkg<Final>)[] = [
...(localPkg ? [localPkg] : []),
...this.finalizedPkgs,
];
const crate: Crate<P> | Crate<Final> = unwrap(
allCrates.find((crate) => crate.id === id.crateId),
const pkg: Pkg<P> | Pkg<Final> = unwrap(
allPkgs.find((pkg) => pkg.id === id.pkgId),
);
if (crate.fatalError) {
if (pkg.fatalError) {
return {
kind: "error",
defPath: [],
err: crate.fatalError,
id: new ItemId(crate.id, 0),
err: pkg.fatalError,
id: new ItemId(pkg.id, 0),
name: "",
span: Span.startOfFile(crate.rootFile),
span: Span.startOfFile(pkg.rootFile),
};
}
if (id.itemIdx === 0) {
const contents: Item<P>[] | Item<Final>[] = crate.rootItems;
const contents: Item<P>[] | Item<Final>[] = pkg.rootItems;
// Typescript does not seem to be able to understand this here.
// The type of this is supposed to be (Item<P> | Item<Final>)["contents"] which is
// "too complex to represent".
const erasedContents: any = contents;
// Return a synthetic module representing the crate root.
// Return a synthetic module representing the pkg root.
const mod: Item<P> | Item<Final> = {
kind: "mod",
name: crate.packageName,
name: pkg.packageName,
contents: erasedContents,
span: Span.startOfFile(crate.rootFile),
span: Span.startOfFile(pkg.rootFile),
id,
};
return mod;
}
const mod = unwrap(crate.itemsById.get(id));
const mod = unwrap(pkg.itemsById.get(id));
return mod;
}
}

View file

@ -8,9 +8,9 @@ import { typeck } from "./typeck";
import { writeModuleWatToString } from "./wasm/wat";
import fs from "fs";
import { exec } from "child_process";
import { Crate, Built, Typecked } from "./ast";
import { Pkg, Built, Typecked } from "./ast";
import { GlobalContext, parseArgs } from "./context";
import { loadCrate } from "./loader";
import { loadPkg } from "./loader";
const INPUT = `
type A = struct { a: Int };
@ -39,13 +39,13 @@ function main() {
const file: LoadedFile = { path: filename, content: input };
const gcx = new GlobalContext(opts, loadCrate);
const mainCrate = gcx.crateId.next();
const gcx = new GlobalContext(opts, loadPkg);
const mainPkg = gcx.pkgId.next();
const start = Date.now();
if (packageName !== "std") {
gcx.crateLoader(gcx, "std", Span.startOfFile(file));
gcx.pkgLoader(gcx, "std", Span.startOfFile(file));
}
const tokens = tokenize(gcx.error, file);
@ -60,7 +60,7 @@ function main() {
const parseState: ParseState = { tokens: tokens.tokens, gcx, file };
const ast: Crate<Built> = parse(packageName, parseState, mainCrate);
const ast: Pkg<Built> = parse(packageName, parseState, mainPkg);
if (debug.has("ast")) {
console.log("-----AST---------------");
@ -83,7 +83,7 @@ function main() {
if (debug.has("typecked")) {
console.log("-----AST typecked------");
}
const typecked: Crate<Typecked> = typeck(gcx, resolved);
const typecked: Pkg<Typecked> = typeck(gcx, resolved);
if (debug.has("typecked")) {
const typeckPrinted = printAst(typecked);
console.log(typeckPrinted);
@ -98,7 +98,7 @@ function main() {
process.exit(1);
}
gcx.finalizedCrates.push(typecked);
gcx.finalizedPkgs.push(typecked);
const wasmModule = lowerToWasm(gcx);
const moduleStringColor = writeModuleWatToString(wasmModule, true);
const moduleString = writeModuleWatToString(wasmModule);

View file

@ -1,5 +1,5 @@
import { CrateId, DepCrate } from "./ast";
import { CrateLoader, GlobalContext } from "./context";
import { PkgId, DepPkg } from "./ast";
import { PkgLoader, GlobalContext } from "./context";
import { CompilerError, ErrorEmitted, LoadedFile, Span } from "./error";
import fs from "fs";
import path from "path";
@ -67,11 +67,11 @@ export function loadModuleFile(
return { ok: true, value: { content, path: filePath } };
}
function dummyErrorCrate(
id: CrateId,
function dummyErrorPkg(
id: PkgId,
packageName: string,
emitted: ErrorEmitted,
): DepCrate {
): DepPkg {
return {
id,
packageName,
@ -85,26 +85,26 @@ function dummyErrorCrate(
};
}
export const loadCrate: CrateLoader = (
export const loadPkg: PkgLoader = (
gcx: GlobalContext,
name: string,
span: Span,
): DepCrate => {
// If we've loaded the crate already, great.
const existing = gcx.finalizedCrates.find(
(crate) => crate.packageName === name,
): DepPkg => {
// If we've loaded the pkg already, great.
const existing = gcx.finalizedPkgs.find(
(pkg) => pkg.packageName === name,
);
if (existing) {
return existing;
}
const crateId = gcx.crateId.next();
const pkgId = gcx.pkgId.next();
// If we have not loaded the crate yet, we may actually already be loading it.
// If we have not loaded the pkg yet, we may actually already be loading it.
// A cycle!!
if (gcx.cratesBeingLoaded.has(name)) {
return dummyErrorCrate(
crateId,
if (gcx.pkgsBeingLoaded.has(name)) {
return dummyErrorPkg(
pkgId,
name,
gcx.error.emit(
new CompilerError(`cycle detected loading extern module ${name}`, span),
@ -112,33 +112,33 @@ export const loadCrate: CrateLoader = (
);
}
// Let's start loading the crate!
gcx.cratesBeingLoaded.add(name);
// Let's start loading the pkg!
gcx.pkgsBeingLoaded.add(name);
// We really, really want a good algorithm for finding crates.
// We really, really want a good algorithm for finding pkgs.
// But right now we just look for files in the CWD.
const file = loadModuleFile(".", name, span);
if (!file.ok) {
return dummyErrorCrate(crateId, name, gcx.error.emit(file.err));
return dummyErrorPkg(pkgId, name, gcx.error.emit(file.err));
}
const tokens = tokenize(gcx.error, file.value);
if (!tokens.ok) {
return dummyErrorCrate(crateId, name, tokens.err);
return dummyErrorPkg(pkgId, name, tokens.err);
}
const parseState: ParseState = {
tokens: tokens.tokens,
file: file.value,
gcx,
};
const ast = parse(name, parseState, crateId);
const ast = parse(name, parseState, pkgId);
const resolved = resolve(gcx, ast);
const typecked = typeck(gcx, resolved);
gcx.finalizedCrates.push(typecked);
// Crate is loaded, no cycles.
gcx.cratesBeingLoaded.delete(name);
gcx.finalizedPkgs.push(typecked);
// Pkg is loaded, no cycles.
gcx.pkgsBeingLoaded.delete(name);
return typecked;
};

View file

@ -1,7 +1,7 @@
import {
ARITH_FACTOR_KINDS,
ARITH_TERM_KINDS,
Crate,
Pkg,
BinaryKind,
COMPARISON_KINDS,
mkDefaultFolder,
@ -58,8 +58,8 @@ class FatalParseError extends Error {
export function parse(
packageName: string,
t: State,
crateId: number,
): Crate<Built> {
pkgId: number,
): Pkg<Built> {
let items: Item<Parsed>[];
let fatalError: ErrorEmitted | undefined = undefined;
try {
@ -73,10 +73,10 @@ export function parse(
}
}
const ast: Crate<Built> = buildCrate(
const ast: Pkg<Built> = buildPkg(
packageName,
items,
crateId,
pkgId,
t.file,
fatalError,
);
@ -847,7 +847,7 @@ function unexpectedToken(t: ParseState, token: Token, expected: string): never {
);
}
function validateAst(ast: Crate<Built>, gcx: GlobalContext) {
function validateAst(ast: Pkg<Built>, gcx: GlobalContext) {
const seenItemIds = new ComplexSet();
const validator: Folder<Built, Built> = {
@ -915,19 +915,19 @@ function validateAst(ast: Crate<Built>, gcx: GlobalContext) {
foldAst(ast, validator);
}
function buildCrate(
function buildPkg(
packageName: string,
rootItems: Item<Parsed>[],
crateId: number,
pkgId: number,
rootFile: LoadedFile,
fatalError: ErrorEmitted | undefined,
): Crate<Built> {
): Pkg<Built> {
const itemId = new Ids();
itemId.next(); // crate root ID
itemId.next(); // pkg root ID
const loopId = new Ids();
const ast: Crate<Built> = {
id: crateId,
const ast: Pkg<Built> = {
id: pkgId,
rootItems,
itemsById: new ComplexMap(),
packageName,
@ -938,7 +938,7 @@ function buildCrate(
const assigner: Folder<Parsed, Built> = {
...mkDefaultFolder(),
itemInner(item: Item<Parsed>): Item<Built> {
const id = new ItemId(crateId, itemId.next());
const id = new ItemId(pkgId, itemId.next());
return { ...superFoldItem(item, this), id };
},
expr(expr: Expr<Parsed>): Expr<Built> {
@ -958,7 +958,7 @@ function buildCrate(
},
};
const crate = foldAst(ast, assigner);
const pkg = foldAst(ast, assigner);
return crate;
return pkg;
}

View file

@ -1,6 +1,6 @@
import {
AnyPhase,
Crate,
Pkg,
Expr,
ItemFunction,
IdentWithRes,
@ -16,7 +16,7 @@ import {
substituteTy,
} from "./ast";
export function printAst(ast: Crate<AnyPhase>): string {
export function printAst(ast: Pkg<AnyPhase>): string {
return ast.rootItems.map(printItem).join("\n");
}

View file

@ -1,5 +1,5 @@
import {
Crate,
Pkg,
BUILTINS,
Built,
BuiltinName,
@ -25,17 +25,17 @@ import { ComplexMap } from "./utils";
const BUILTIN_SET = new Set<string>(BUILTINS);
type Context = {
ast: Crate<Built>;
ast: Pkg<Built>;
gcx: GlobalContext;
modContentsCache: ComplexMap<ItemId, Map<string, ItemId>>;
newItemsById: ComplexMap<ItemId, Item<Resolved>>;
};
function loadCrate(cx: Context, name: string, span: Span): Map<string, ItemId> {
const loadedCrate = cx.gcx.crateLoader(cx.gcx, name, span);
function loadPkg(cx: Context, name: string, span: Span): Map<string, ItemId> {
const loadedPkg = cx.gcx.pkgLoader(cx.gcx, name, span);
const contents = new Map(
loadedCrate.rootItems.map((item) => [item.name, item.id]),
loadedPkg.rootItems.map((item) => [item.name, item.id]),
);
return contents;
@ -56,7 +56,7 @@ function resolveModItem(
if ("contents" in mod) {
contents = new Map(mod.contents.map((item) => [item.name, item.id]));
} else {
contents = loadCrate(cx, mod.name, mod.span);
contents = loadPkg(cx, mod.name, mod.span);
}
cx.modContentsCache.set(mod.id, contents);
@ -65,8 +65,8 @@ function resolveModItem(
export function resolve(
gcx: GlobalContext,
ast: Crate<Built>,
): Crate<Resolved> {
ast: Pkg<Built>,
): Pkg<Resolved> {
const cx: Context = {
ast,
gcx,
@ -151,12 +151,12 @@ function resolveModule(
};
}
// All loaded crates are in scope.
for (const crate of [cx.ast, ...cx.gcx.finalizedCrates]) {
if (ident.name === crate.packageName) {
// All loaded pkgs are in scope.
for (const pkg of [cx.ast, ...cx.gcx.finalizedPkgs]) {
if (ident.name === pkg.packageName) {
return {
kind: "item",
id: ItemId.crateRoot(crate.id),
id: ItemId.pkgRoot(pkg.id),
};
}
}
@ -217,10 +217,10 @@ function resolveModule(
};
}
case "extern": {
// Eagerly resolve the crate.
// Note that because you can reference extern crates before the item,
// we still need the loadCrate in the field access code above.
loadCrate(cx, item.name, item.span);
// Eagerly resolve the pkg.
// Note that because you can reference extern pkgs before the item,
// we still need the loadPkg in the field access code above.
loadPkg(cx, item.name, item.span);
return {
...item,

View file

@ -1,7 +1,7 @@
import {
BuiltinName,
COMPARISON_KINDS,
Crate,
Pkg,
EQUALITY_KINDS,
Expr,
ExprBinary,
@ -119,7 +119,7 @@ export function typeOfBuiltinValue(
export function checkBody(
cx: TypeckCtx,
ast: Crate<Resolved>,
ast: Pkg<Resolved>,
body: Expr<Resolved>,
fnTy: TyFn,
): Expr<Typecked> {

View file

@ -1,5 +1,5 @@
import {
Crate,
Pkg,
Expr,
Folder,
Item,
@ -23,8 +23,8 @@ import { emitError, typeOfItem } from "./item";
export function typeck(
gcx: GlobalContext,
ast: Crate<Resolved>,
): Crate<Typecked> {
ast: Pkg<Resolved>,
): Pkg<Typecked> {
const cx = {
gcx,
itemTys: new ComplexMap<ItemId, Ty | null>(),
@ -203,7 +203,7 @@ export function typeck(
});
if (ast.id === 0) {
// Only the final id=0 crate needs and cares about main.
// Only the final id=0 pkg needs and cares about main.
if (!main) {
emitError(
cx,

View file

@ -1,5 +1,5 @@
import {
Crate,
Pkg,
ItemId,
Resolved,
Ty,
@ -26,7 +26,7 @@ export type TypeckCtx = {
* afterwards, we get the ty.
*/
itemTys: ComplexMap<ItemId, Ty | null>;
ast: Crate<Resolved>;
ast: Pkg<Resolved>;
};
export function mkTyFn(params: Ty[], returnTy: Ty): Ty {
@ -160,8 +160,8 @@ export function typeOfItem(
genericArgs: Ty[],
cause: Span,
): Ty {
if (itemId.crateId !== cx.ast.id) {
// Look up foreign items in the foreign crates, we don't need to lower those
if (itemId.pkgId !== cx.ast.id) {
// Look up foreign items in the foreign pkgs, we don't need to lower those
// ourselves.
const item = cx.gcx.findItem(itemId);