mirror of
https://github.com/Noratrieb/riverdelta.git
synced 2026-01-14 16:35:03 +01:00
"implement" use
This commit is contained in:
parent
d6123836e8
commit
8b33910aec
9 changed files with 66 additions and 6 deletions
12
src/ast.ts
12
src/ast.ts
|
|
@ -107,6 +107,7 @@ export type ItemKind<P extends Phase> =
|
||||||
| ItemKindMod<P>
|
| ItemKindMod<P>
|
||||||
| ItemKindExtern
|
| ItemKindExtern
|
||||||
| ItemKindGlobal<P>
|
| ItemKindGlobal<P>
|
||||||
|
| ItemKindUse<P>
|
||||||
| ItemKindError;
|
| ItemKindError;
|
||||||
|
|
||||||
type ItemVariant<Variant, P extends Phase> = Variant & Item<P>;
|
type ItemVariant<Variant, P extends Phase> = Variant & Item<P>;
|
||||||
|
|
@ -117,6 +118,7 @@ export type ItemImport<P extends Phase> = ItemVariant<ItemKindImport<P>, P>;
|
||||||
export type ItemMod<P extends Phase> = ItemVariant<ItemKindMod<P>, P>;
|
export type ItemMod<P extends Phase> = ItemVariant<ItemKindMod<P>, P>;
|
||||||
export type ItemExtern<P extends Phase> = ItemVariant<ItemKindExtern, P>;
|
export type ItemExtern<P extends Phase> = ItemVariant<ItemKindExtern, P>;
|
||||||
export type ItemGlobal<P extends Phase> = ItemVariant<ItemKindGlobal<P>, P>;
|
export type ItemGlobal<P extends Phase> = ItemVariant<ItemKindGlobal<P>, P>;
|
||||||
|
export type ItemUse<P extends Phase> = ItemVariant<ItemKindUse<P>, P>;
|
||||||
export type ItemError<P extends Phase> = ItemVariant<ItemKindError, P>;
|
export type ItemError<P extends Phase> = ItemVariant<ItemKindError, P>;
|
||||||
|
|
||||||
export type Item<P extends Phase> = ItemKind<P> & {
|
export type Item<P extends Phase> = ItemKind<P> & {
|
||||||
|
|
@ -183,6 +185,11 @@ export type ItemKindGlobal<P extends Phase> = {
|
||||||
ty?: Ty;
|
ty?: Ty;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ItemKindUse<P extends Phase> = {
|
||||||
|
kind: "use";
|
||||||
|
segments: Ident[];
|
||||||
|
} & P["res"];
|
||||||
|
|
||||||
export type ItemKindError = {
|
export type ItemKindError = {
|
||||||
kind: "error";
|
kind: "error";
|
||||||
err: ErrorEmitted;
|
err: ErrorEmitted;
|
||||||
|
|
@ -448,7 +455,7 @@ export type Resolution =
|
||||||
* ```
|
* ```
|
||||||
* When traversing resolutions, a stack of locals has to be kept.
|
* When traversing resolutions, a stack of locals has to be kept.
|
||||||
* It's similar to a De Bruijn index.
|
* It's similar to a De Bruijn index.
|
||||||
*
|
*
|
||||||
* You generally want to index the stack as stack[stack.len - 1 - res.idx].
|
* You generally want to index the stack as stack[stack.len - 1 - res.idx].
|
||||||
*/
|
*/
|
||||||
index: number;
|
index: number;
|
||||||
|
|
@ -652,6 +659,9 @@ export function superFoldItem<From extends Phase, To extends Phase>(
|
||||||
init: folder.expr(item.init),
|
init: folder.expr(item.init),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
case "use": {
|
||||||
|
return { ...item };
|
||||||
|
}
|
||||||
case "error": {
|
case "error": {
|
||||||
return { ...item };
|
return { ...item };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -209,6 +209,7 @@ export function lower(gcx: GlobalContext): wasm.Module {
|
||||||
}
|
}
|
||||||
case "extern":
|
case "extern":
|
||||||
case "type":
|
case "type":
|
||||||
|
case "use":
|
||||||
break;
|
break;
|
||||||
case "error":
|
case "error":
|
||||||
unreachable("codegen should never see errors");
|
unreachable("codegen should never see errors");
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ export type DatalessToken =
|
||||||
| "mod"
|
| "mod"
|
||||||
| "global"
|
| "global"
|
||||||
| "struct"
|
| "struct"
|
||||||
|
| "use"
|
||||||
| "("
|
| "("
|
||||||
| ")"
|
| ")"
|
||||||
| "{"
|
| "{"
|
||||||
|
|
@ -364,6 +365,7 @@ const KEYOWRDS: DatalessToken[] = [
|
||||||
"mod",
|
"mod",
|
||||||
"global",
|
"global",
|
||||||
"struct",
|
"struct",
|
||||||
|
"use",
|
||||||
];
|
];
|
||||||
|
|
||||||
const KEYWORD_SET = new Set<string>(KEYOWRDS);
|
const KEYWORD_SET = new Set<string>(KEYOWRDS);
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import {
|
||||||
ItemGlobal,
|
ItemGlobal,
|
||||||
StructLiteralField,
|
StructLiteralField,
|
||||||
TypeDefKind,
|
TypeDefKind,
|
||||||
|
ItemUse,
|
||||||
} from "./ast";
|
} from "./ast";
|
||||||
import { GlobalContext } from "./context";
|
import { GlobalContext } from "./context";
|
||||||
import { CompilerError, ErrorEmitted, LoadedFile, Span } from "./error";
|
import { CompilerError, ErrorEmitted, LoadedFile, Span } from "./error";
|
||||||
|
|
@ -293,6 +294,33 @@ function parseItem(t: State): [State, Item<Parsed>] {
|
||||||
id: ItemId.dummy(),
|
id: ItemId.dummy(),
|
||||||
};
|
};
|
||||||
return [t, global];
|
return [t, global];
|
||||||
|
} else if (tok.kind === "use") {
|
||||||
|
let ident;
|
||||||
|
[t, ident] = expectNext<TokenIdent>(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<TokenIdent>(t, "identifier");
|
||||||
|
segments.push({ name: ident.ident, span: ident.span });
|
||||||
|
}
|
||||||
|
|
||||||
|
[t] = expectNext(t, ";");
|
||||||
|
|
||||||
|
const use: ItemUse<Parsed> = {
|
||||||
|
kind: "use",
|
||||||
|
name: segments[segments.length - 1].name,
|
||||||
|
segments,
|
||||||
|
span: tok.span,
|
||||||
|
id: ItemId.dummy(),
|
||||||
|
};
|
||||||
|
|
||||||
|
return [t, use];
|
||||||
} else {
|
} else {
|
||||||
unexpectedToken(t, tok, "item");
|
unexpectedToken(t, tok, "item");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import {
|
||||||
Type,
|
Type,
|
||||||
ItemType,
|
ItemType,
|
||||||
} from "./ast";
|
} from "./ast";
|
||||||
import { Ty, substituteTy, tyIsUnit } from "./types";
|
import { Ty, tyIsUnit } from "./types";
|
||||||
|
|
||||||
export function printAst(ast: Pkg<AnyPhase>): string {
|
export function printAst(ast: Pkg<AnyPhase>): string {
|
||||||
return ast.rootItems.map(printItem).join("\n");
|
return ast.rootItems.map(printItem).join("\n");
|
||||||
|
|
@ -50,6 +50,9 @@ function printItem(item: Item<AnyPhase>): string {
|
||||||
)};`
|
)};`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
case "use": {
|
||||||
|
return id + `use ${item.segments.map((ident) => ident.name).join(".")};`;
|
||||||
|
}
|
||||||
case "error":
|
case "error":
|
||||||
return "<ERROR>";
|
return "<ERROR>";
|
||||||
}
|
}
|
||||||
|
|
@ -57,7 +60,7 @@ function printItem(item: Item<AnyPhase>): string {
|
||||||
|
|
||||||
function printFunction(func: ItemFunction<AnyPhase>): string {
|
function printFunction(func: ItemFunction<AnyPhase>): string {
|
||||||
const args = func.params
|
const args = func.params
|
||||||
.map(({ ident: name, type }) => `${name}: ${printType(type)}`)
|
.map(({ ident: name, type }) => `${name.name}: ${printType(type)}`)
|
||||||
.join(", ");
|
.join(", ");
|
||||||
const ret = func.returnType ? `: ${printType(func.returnType)}` : "";
|
const ret = func.returnType ? `: ${printType(func.returnType)}` : "";
|
||||||
return `function ${func.name}(${args})${ret} = ${printExpr(func.body, 0)};`;
|
return `function ${func.name}(${args})${ret} = ${printExpr(func.body, 0)};`;
|
||||||
|
|
@ -89,7 +92,7 @@ function printTypeDef(type: ItemType<AnyPhase>): string {
|
||||||
|
|
||||||
function printImportDef(def: ItemImport<AnyPhase>): string {
|
function printImportDef(def: ItemImport<AnyPhase>): string {
|
||||||
const args = def.params
|
const args = def.params
|
||||||
.map(({ ident: name, type }) => `${name}: ${printType(type)}`)
|
.map(({ ident: name, type }) => `${name.name}: ${printType(type)}`)
|
||||||
.join(", ");
|
.join(", ");
|
||||||
const ret = def.returnType ? `: ${printType(def.returnType)}` : "";
|
const ret = def.returnType ? `: ${printType(def.returnType)}` : "";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,14 @@ function resolveModule(
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -162,6 +162,9 @@ export function typeck(gcx: GlobalContext, ast: Pkg<Resolved>): Pkg<Typecked> {
|
||||||
init: initChecked,
|
init: initChecked,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
case "use": {
|
||||||
|
return { ...item };
|
||||||
|
}
|
||||||
case "error": {
|
case "error": {
|
||||||
return { ...item };
|
return { ...item };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,7 @@ function itemGenerics(item: Item<Typecked> | Item<Resolved>): Generics {
|
||||||
case "global":
|
case "global":
|
||||||
case "mod":
|
case "mod":
|
||||||
case "import":
|
case "import":
|
||||||
|
case "use":
|
||||||
return none;
|
return none;
|
||||||
case "type":
|
case "type":
|
||||||
return { kind: "some", params: item.genericParams };
|
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);
|
ty = lowerAstTy(cx, item.type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "use": {
|
||||||
|
// TODO: use the power of typescript to eliminate `use` from this.
|
||||||
|
ty = TYS.UNIT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "error": {
|
case "error": {
|
||||||
ty = tyErrorFrom(item);
|
ty = tyErrorFrom(item);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
function main() = (
|
function main() = (
|
||||||
let _l = list.new();
|
let _false, l = list.new();
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue