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(); );