From 8b33910aec6411cf66588ffc40e37a81f19807da Mon Sep 17 00:00:00 2001
From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com>
Date: Sat, 1 Jun 2024 14:55:19 +0200
Subject: [PATCH] "implement" use
---
src/ast.ts | 12 +++++++++++-
src/codegen.ts | 1 +
src/lexer.ts | 2 ++
src/parser.ts | 28 +++++++++++++++++++++++++++
src/printer.ts | 9 ++++++---
src/resolve.ts | 9 ++++++++-
src/typeck/index.ts | 3 +++
src/typeck/item.ts | 6 ++++++
ui-tests/resolve/module_not_found.nil | 2 +-
9 files changed, 66 insertions(+), 6 deletions(-)
diff --git a/src/ast.ts b/src/ast.ts
index 3d245d3..27e55e2 100644
--- a/src/ast.ts
+++ b/src/ast.ts
@@ -107,6 +107,7 @@ export type ItemKind
=
| ItemKindMod
| ItemKindExtern
| ItemKindGlobal
+ | ItemKindUse
| ItemKindError;
type ItemVariant = Variant & Item;
@@ -117,6 +118,7 @@ export type ItemImport
= ItemVariant, P>;
export type ItemMod = ItemVariant, P>;
export type ItemExtern = ItemVariant;
export type ItemGlobal = ItemVariant, P>;
+export type ItemUse = ItemVariant, P>;
export type ItemError = ItemVariant;
export type Item = ItemKind
& {
@@ -183,6 +185,11 @@ export type ItemKindGlobal
= {
ty?: Ty;
};
+export type ItemKindUse
= {
+ kind: "use";
+ segments: Ident[];
+} & P["res"];
+
export type ItemKindError = {
kind: "error";
err: ErrorEmitted;
@@ -448,7 +455,7 @@ export type Resolution =
* ```
* When traversing resolutions, a stack of locals has to be kept.
* It's similar to a De Bruijn index.
- *
+ *
* You generally want to index the stack as stack[stack.len - 1 - res.idx].
*/
index: number;
@@ -652,6 +659,9 @@ export function superFoldItem(
init: folder.expr(item.init),
};
}
+ case "use": {
+ return { ...item };
+ }
case "error": {
return { ...item };
}
diff --git a/src/codegen.ts b/src/codegen.ts
index fb9a829..519735a 100644
--- a/src/codegen.ts
+++ b/src/codegen.ts
@@ -209,6 +209,7 @@ export function lower(gcx: GlobalContext): wasm.Module {
}
case "extern":
case "type":
+ case "use":
break;
case "error":
unreachable("codegen should never see errors");
diff --git a/src/lexer.ts b/src/lexer.ts
index 537fa0e..e438e0e 100644
--- a/src/lexer.ts
+++ b/src/lexer.ts
@@ -20,6 +20,7 @@ export type DatalessToken =
| "mod"
| "global"
| "struct"
+ | "use"
| "("
| ")"
| "{"
@@ -364,6 +365,7 @@ const KEYOWRDS: DatalessToken[] = [
"mod",
"global",
"struct",
+ "use",
];
const KEYWORD_SET = new Set(KEYOWRDS);
diff --git a/src/parser.ts b/src/parser.ts
index c3ac6cb..34b2e29 100644
--- a/src/parser.ts
+++ b/src/parser.ts
@@ -27,6 +27,7 @@ import {
ItemGlobal,
StructLiteralField,
TypeDefKind,
+ ItemUse,
} from "./ast";
import { GlobalContext } from "./context";
import { CompilerError, ErrorEmitted, LoadedFile, Span } from "./error";
@@ -293,6 +294,33 @@ function parseItem(t: State): [State, Item] {
id: ItemId.dummy(),
};
return [t, global];
+ } else if (tok.kind === "use") {
+ let ident;
+ [t, ident] = expectNext(t, "identifier");
+
+ const segments: Ident[] = [{ name: ident.ident, span: ident.span }];
+
+ while (true) {
+ let semi;
+ [t, semi] = eat(t, ".");
+ if (!semi) {
+ break;
+ }
+ [t, ident] = expectNext(t, "identifier");
+ segments.push({ name: ident.ident, span: ident.span });
+ }
+
+ [t] = expectNext(t, ";");
+
+ const use: ItemUse = {
+ kind: "use",
+ name: segments[segments.length - 1].name,
+ segments,
+ span: tok.span,
+ id: ItemId.dummy(),
+ };
+
+ return [t, use];
} else {
unexpectedToken(t, tok, "item");
}
diff --git a/src/printer.ts b/src/printer.ts
index 6e980ad..c530593 100644
--- a/src/printer.ts
+++ b/src/printer.ts
@@ -12,7 +12,7 @@ import {
Type,
ItemType,
} from "./ast";
-import { Ty, substituteTy, tyIsUnit } from "./types";
+import { Ty, tyIsUnit } from "./types";
export function printAst(ast: Pkg): string {
return ast.rootItems.map(printItem).join("\n");
@@ -50,6 +50,9 @@ function printItem(item: Item): string {
)};`
);
}
+ case "use": {
+ return id + `use ${item.segments.map((ident) => ident.name).join(".")};`;
+ }
case "error":
return "";
}
@@ -57,7 +60,7 @@ function printItem(item: Item): string {
function printFunction(func: ItemFunction): string {
const args = func.params
- .map(({ ident: name, type }) => `${name}: ${printType(type)}`)
+ .map(({ ident: name, type }) => `${name.name}: ${printType(type)}`)
.join(", ");
const ret = func.returnType ? `: ${printType(func.returnType)}` : "";
return `function ${func.name}(${args})${ret} = ${printExpr(func.body, 0)};`;
@@ -89,7 +92,7 @@ function printTypeDef(type: ItemType): string {
function printImportDef(def: ItemImport): string {
const args = def.params
- .map(({ ident: name, type }) => `${name}: ${printType(type)}`)
+ .map(({ ident: name, type }) => `${name.name}: ${printType(type)}`)
.join(", ");
const ret = def.returnType ? `: ${printType(def.returnType)}` : "";
diff --git a/src/resolve.ts b/src/resolve.ts
index c3c0867..6f8aa8b 100644
--- a/src/resolve.ts
+++ b/src/resolve.ts
@@ -99,7 +99,14 @@ function resolveModule(
),
);
} else {
- items.set(item.name, item.id);
+ // TODO: This is awful
+ if (item.kind === "use") {
+ cx.gcx.error.emitError(
+ new CompilerError("TODO: use is not properly implemented", item.span),
+ );
+ } else {
+ items.set(item.name, item.id);
+ }
}
});
diff --git a/src/typeck/index.ts b/src/typeck/index.ts
index d7ea1a6..eef5edc 100644
--- a/src/typeck/index.ts
+++ b/src/typeck/index.ts
@@ -162,6 +162,9 @@ export function typeck(gcx: GlobalContext, ast: Pkg): Pkg {
init: initChecked,
};
}
+ case "use": {
+ return { ...item };
+ }
case "error": {
return { ...item };
}
diff --git a/src/typeck/item.ts b/src/typeck/item.ts
index 576afbc..08a1b77 100644
--- a/src/typeck/item.ts
+++ b/src/typeck/item.ts
@@ -152,6 +152,7 @@ function itemGenerics(item: Item | Item): Generics {
case "global":
case "mod":
case "import":
+ case "use":
return none;
case "type":
return { kind: "some", params: item.genericParams };
@@ -275,6 +276,11 @@ export function typeOfItem(cx: TypeckCtx, itemId: ItemId, cause: Span): Ty {
ty = lowerAstTy(cx, item.type);
break;
}
+ case "use": {
+ // TODO: use the power of typescript to eliminate `use` from this.
+ ty = TYS.UNIT;
+ break;
+ }
case "error": {
ty = tyErrorFrom(item);
}
diff --git a/ui-tests/resolve/module_not_found.nil b/ui-tests/resolve/module_not_found.nil
index 063c496..64deb9f 100644
--- a/ui-tests/resolve/module_not_found.nil
+++ b/ui-tests/resolve/module_not_found.nil
@@ -1,3 +1,3 @@
function main() = (
- let _l = list.new();
+ let _false, l = list.new();
);