mirror of
https://github.com/Noratrieb/riverdelta.git
synced 2026-01-14 16:35:03 +01:00
move ty defs
This commit is contained in:
parent
a22cc15b59
commit
d18ab34e9f
14 changed files with 173 additions and 192 deletions
156
src/ast.ts
156
src/ast.ts
|
|
@ -1,5 +1,6 @@
|
|||
import { ErrorEmitted, LoadedFile, Span, unreachable } from "./error";
|
||||
import { LitIntType } from "./lexer";
|
||||
import { Ty, TyFn, TypeckResults } from "./types";
|
||||
import { ComplexMap } from "./utils";
|
||||
import { Instr, ValType } from "./wasm/defs";
|
||||
|
||||
|
|
@ -507,161 +508,6 @@ export type LocalInfo = {
|
|||
|
||||
// types
|
||||
|
||||
export type TyString = {
|
||||
kind: "string";
|
||||
};
|
||||
|
||||
export type TyInt = {
|
||||
kind: "int";
|
||||
};
|
||||
|
||||
export type TyI32 = {
|
||||
kind: "i32";
|
||||
};
|
||||
|
||||
export type TyBool = {
|
||||
kind: "bool";
|
||||
};
|
||||
|
||||
export type TyTuple = {
|
||||
kind: "tuple";
|
||||
elems: Ty[];
|
||||
};
|
||||
|
||||
export type TyUnit = {
|
||||
kind: "tuple";
|
||||
elems: [];
|
||||
};
|
||||
|
||||
export type TyFn = {
|
||||
kind: "fn";
|
||||
params: Ty[];
|
||||
returnTy: Ty;
|
||||
};
|
||||
|
||||
export type TyVar = {
|
||||
kind: "var";
|
||||
index: number;
|
||||
};
|
||||
|
||||
export type TyStruct = {
|
||||
kind: "struct";
|
||||
itemId: ItemId;
|
||||
params: string[];
|
||||
genericArgs: Ty[];
|
||||
_name: string;
|
||||
fields_no_subst: [string, Ty][];
|
||||
};
|
||||
|
||||
export type TyRawPtr = {
|
||||
kind: "rawptr";
|
||||
inner: Ty;
|
||||
};
|
||||
|
||||
export type TyNever = {
|
||||
kind: "never";
|
||||
};
|
||||
|
||||
export type TyParam = {
|
||||
kind: "param";
|
||||
/**
|
||||
* The index of the type parameter of the parent.
|
||||
* If the parent is `type A[T, U] = U;`
|
||||
* then `U` will have index 1.
|
||||
*/
|
||||
idx: number;
|
||||
name: string;
|
||||
};
|
||||
|
||||
export type TyAlias = {
|
||||
kind: "alias";
|
||||
actual: Ty;
|
||||
genericArgs: Ty[];
|
||||
params: string[];
|
||||
};
|
||||
|
||||
export type TyError = {
|
||||
kind: "error";
|
||||
err: ErrorEmitted;
|
||||
};
|
||||
|
||||
export type Ty =
|
||||
| TyString
|
||||
| TyInt
|
||||
| TyI32
|
||||
| TyBool
|
||||
| TyTuple
|
||||
| TyFn
|
||||
| TyVar
|
||||
| TyStruct
|
||||
| TyRawPtr
|
||||
| TyNever
|
||||
| TyParam
|
||||
| TyAlias
|
||||
| TyError;
|
||||
|
||||
export function tyIsUnit(ty: Ty): ty is TyUnit {
|
||||
return ty.kind === "tuple" && ty.elems.length === 0;
|
||||
}
|
||||
|
||||
export const TY_UNIT: Ty = { kind: "tuple", elems: [] };
|
||||
export const TY_STRING: Ty = { kind: "string" };
|
||||
export const TY_BOOL: Ty = { kind: "bool" };
|
||||
export const TY_INT: Ty = { kind: "int" };
|
||||
export const TY_I32: Ty = { kind: "i32" };
|
||||
export const TY_NEVER: Ty = { kind: "never" };
|
||||
|
||||
export type TypeckResults = {
|
||||
main: Resolution | undefined;
|
||||
};
|
||||
|
||||
export function structFieldsSubstituted(ty: TyStruct): [string, Ty][] {
|
||||
const args = ty.genericArgs;
|
||||
return ty.fields_no_subst.map(([name, type]) => [
|
||||
name,
|
||||
substituteTy(args, type),
|
||||
]);
|
||||
}
|
||||
|
||||
// Substitute the parameter of a type. We are only able to handle one
|
||||
// level of generic definitions, for example for fields the struct def or for exprs the function generics.
|
||||
export function substituteTy(genericArgs: Ty[], ty: Ty): Ty {
|
||||
const subst = (ty: Ty) => substituteTy(genericArgs, ty);
|
||||
switch (ty.kind) {
|
||||
case "param":
|
||||
if (ty.idx >= genericArgs.length) {
|
||||
throw new Error(
|
||||
`substitution out of range, param index ${ty.idx} of param ${ty.name} out of range for length ${genericArgs.length}`,
|
||||
);
|
||||
}
|
||||
return genericArgs[ty.idx];
|
||||
case "tuple":
|
||||
return { ...ty, elems: ty.elems.map(subst) };
|
||||
case "fn":
|
||||
return {
|
||||
...ty,
|
||||
returnTy: subst(ty.returnTy),
|
||||
params: ty.params.map(subst),
|
||||
};
|
||||
case "struct":
|
||||
case "alias":
|
||||
return {
|
||||
...ty,
|
||||
genericArgs: ty.genericArgs.map(subst),
|
||||
};
|
||||
case "rawptr":
|
||||
return { ...ty, inner: subst(ty.inner) };
|
||||
// Primitives
|
||||
case "var":
|
||||
case "string":
|
||||
case "int":
|
||||
case "i32":
|
||||
case "bool":
|
||||
case "never":
|
||||
case "error":
|
||||
return ty;
|
||||
}
|
||||
}
|
||||
|
||||
// folders
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { ItemId, TY_I32, TY_INT, TyStruct } from "./ast";
|
||||
import { ItemId } from "./ast";
|
||||
import { layoutOfStruct } from "./codegen";
|
||||
import { TY_I32, TY_INT, TyStruct } from "./types";
|
||||
|
||||
it("should compute struct layout correctly", () => {
|
||||
const ty: TyStruct = {
|
||||
|
|
|
|||
|
|
@ -10,22 +10,17 @@ import {
|
|||
ItemId,
|
||||
LoopId,
|
||||
Resolution,
|
||||
Ty,
|
||||
TyFn,
|
||||
TyStruct,
|
||||
TyTuple,
|
||||
Typecked,
|
||||
mkDefaultFolder,
|
||||
superFoldExpr,
|
||||
superFoldItem,
|
||||
varUnreachable,
|
||||
TyRawPtr,
|
||||
paramUnreachable as codegenUnreachableTy,
|
||||
structFieldsSubstituted,
|
||||
} from "./ast";
|
||||
import { GlobalContext } from "./context";
|
||||
import { unreachable } from "./error";
|
||||
import { printTy } from "./printer";
|
||||
import { Ty, TyFn, TyRawPtr, TyStruct, TyTuple, structFieldsSubstituted } from "./types";
|
||||
import { ComplexMap, encodeUtf8, unwrap } from "./utils";
|
||||
import * as wasm from "./wasm/defs";
|
||||
|
||||
|
|
|
|||
|
|
@ -9,12 +9,10 @@ import {
|
|||
ItemMod,
|
||||
Resolution,
|
||||
StringLiteral,
|
||||
Ty,
|
||||
Type,
|
||||
ItemType,
|
||||
tyIsUnit,
|
||||
substituteTy,
|
||||
} from "./ast";
|
||||
import { Ty, substituteTy, tyIsUnit } from "./types";
|
||||
|
||||
export function printAst(ast: Pkg<AnyPhase>): string {
|
||||
return ast.rootItems.map(printItem).join("\n");
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { ItemId, Pkg, Resolved, Ty } from "../ast";
|
||||
import { ItemId, Pkg, Resolved } from "../ast";
|
||||
import { GlobalContext } from "../context";
|
||||
import { CompilerError, ErrorEmitted } from "../error";
|
||||
import { Ty } from "../types";
|
||||
import { ComplexMap } from "../utils";
|
||||
|
||||
export type TypeckCtx = {
|
||||
|
|
|
|||
|
|
@ -13,14 +13,6 @@ import {
|
|||
Resolution,
|
||||
Resolved,
|
||||
StructLiteralField,
|
||||
TY_BOOL,
|
||||
TY_I32,
|
||||
TY_INT,
|
||||
TY_NEVER,
|
||||
TY_STRING,
|
||||
TY_UNIT,
|
||||
Ty,
|
||||
TyFn,
|
||||
Type,
|
||||
Typecked,
|
||||
mkDefaultFolder,
|
||||
|
|
@ -28,6 +20,7 @@ import {
|
|||
} from "../ast";
|
||||
import { CompilerError, ErrorEmitted, Span, unreachable } from "../error";
|
||||
import { printTy } from "../printer";
|
||||
import { TY_BOOL, TY_I32, TY_INT, TY_NEVER, TY_STRING, TY_UNIT, Ty, TyFn } from "../types";
|
||||
import { INSTRS, Instr, VALTYPES, ValType } from "../wasm/defs";
|
||||
import { TypeckCtx, emitError, mkTyFn, tyError, tyErrorFrom } from "./base";
|
||||
import { InferContext } from "./infer";
|
||||
|
|
|
|||
|
|
@ -5,17 +5,13 @@ import {
|
|||
Item,
|
||||
ItemId,
|
||||
Resolved,
|
||||
TY_I32,
|
||||
TY_INT,
|
||||
Ty,
|
||||
TyFn,
|
||||
Typecked,
|
||||
foldAst,
|
||||
mkDefaultFolder,
|
||||
tyIsUnit,
|
||||
} from "../ast";
|
||||
import { GlobalContext } from "../context";
|
||||
import { CompilerError, ErrorEmitted, Span } from "../error";
|
||||
import { TY_I32, TY_INT, Ty, TyFn, tyIsUnit } from "../types";
|
||||
import { ComplexMap } from "../utils";
|
||||
import { emitError } from "./base";
|
||||
import { checkBody, exprError } from "./expr";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { TY_INT, TY_STRING, TY_UNIT } from "../ast";
|
||||
import { Emitter, ErrorHandler, Span } from "../error";
|
||||
import { TY_INT, TY_STRING, TY_UNIT } from "../types";
|
||||
import { InferContext } from "./infer";
|
||||
|
||||
const SPAN: Span = Span.startOfFile({ content: "" });
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Ty } from "../ast";
|
||||
import { CompilerError, ErrorHandler, Span } from "../error";
|
||||
import { printTy } from "../printer";
|
||||
import { Ty } from "../types";
|
||||
|
||||
type TyVarRes =
|
||||
| {
|
||||
|
|
|
|||
|
|
@ -1,18 +1,11 @@
|
|||
import {
|
||||
ItemId,
|
||||
Resolved,
|
||||
Ty,
|
||||
TY_BOOL,
|
||||
TY_I32,
|
||||
TY_INT,
|
||||
TY_NEVER,
|
||||
TY_STRING,
|
||||
TY_UNIT,
|
||||
Type,
|
||||
substituteTy,
|
||||
} from "../ast";
|
||||
import { CompilerError, Span } from "../error";
|
||||
import { printTy } from "../printer";
|
||||
import { TY_BOOL, TY_I32, TY_INT, TY_NEVER, TY_STRING, TY_UNIT, Ty, substituteTy } from "../types";
|
||||
import { TypeckCtx, tyError, tyErrorFrom } from "./base";
|
||||
|
||||
function builtinAsTy(cx: TypeckCtx, name: string, span: Span): Ty {
|
||||
|
|
|
|||
158
src/types.ts
Normal file
158
src/types.ts
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
import { ItemId, Resolution } from "./ast";
|
||||
import { ErrorEmitted } from "./error";
|
||||
|
||||
export type TyString = {
|
||||
kind: "string";
|
||||
};
|
||||
|
||||
export type TyInt = {
|
||||
kind: "int";
|
||||
};
|
||||
|
||||
export type TyI32 = {
|
||||
kind: "i32";
|
||||
};
|
||||
|
||||
export type TyBool = {
|
||||
kind: "bool";
|
||||
};
|
||||
|
||||
export type TyTuple = {
|
||||
kind: "tuple";
|
||||
elems: Ty[];
|
||||
};
|
||||
|
||||
export type TyUnit = {
|
||||
kind: "tuple";
|
||||
elems: [];
|
||||
};
|
||||
|
||||
export type TyFn = {
|
||||
kind: "fn";
|
||||
params: Ty[];
|
||||
returnTy: Ty;
|
||||
};
|
||||
|
||||
export type TyVar = {
|
||||
kind: "var";
|
||||
index: number;
|
||||
};
|
||||
|
||||
export type TyStruct = {
|
||||
kind: "struct";
|
||||
itemId: ItemId;
|
||||
params: string[];
|
||||
genericArgs: Ty[];
|
||||
_name: string;
|
||||
fields_no_subst: [string, Ty][];
|
||||
};
|
||||
|
||||
export type TyRawPtr = {
|
||||
kind: "rawptr";
|
||||
inner: Ty;
|
||||
};
|
||||
|
||||
export type TyNever = {
|
||||
kind: "never";
|
||||
};
|
||||
|
||||
export type TyParam = {
|
||||
kind: "param";
|
||||
/**
|
||||
* The index of the type parameter of the parent.
|
||||
* If the parent is `type A[T, U] = U;`
|
||||
* then `U` will have index 1.
|
||||
*/
|
||||
idx: number;
|
||||
name: string;
|
||||
};
|
||||
|
||||
export type TyAlias = {
|
||||
kind: "alias";
|
||||
actual: Ty;
|
||||
genericArgs: Ty[];
|
||||
params: string[];
|
||||
};
|
||||
|
||||
export type TyError = {
|
||||
kind: "error";
|
||||
err: ErrorEmitted;
|
||||
};
|
||||
|
||||
export type Ty =
|
||||
| TyString
|
||||
| TyInt
|
||||
| TyI32
|
||||
| TyBool
|
||||
| TyTuple
|
||||
| TyFn
|
||||
| TyVar
|
||||
| TyStruct
|
||||
| TyRawPtr
|
||||
| TyNever
|
||||
| TyParam
|
||||
| TyAlias
|
||||
| TyError;
|
||||
|
||||
export function tyIsUnit(ty: Ty): ty is TyUnit {
|
||||
return ty.kind === "tuple" && ty.elems.length === 0;
|
||||
}
|
||||
|
||||
export const TY_UNIT: Ty = { kind: "tuple", elems: [] };
|
||||
export const TY_STRING: Ty = { kind: "string" };
|
||||
export const TY_BOOL: Ty = { kind: "bool" };
|
||||
export const TY_INT: Ty = { kind: "int" };
|
||||
export const TY_I32: Ty = { kind: "i32" };
|
||||
export const TY_NEVER: Ty = { kind: "never" };
|
||||
|
||||
export type TypeckResults = {
|
||||
main: Resolution | undefined;
|
||||
};
|
||||
|
||||
export function structFieldsSubstituted(ty: TyStruct): [string, Ty][] {
|
||||
const args = ty.genericArgs;
|
||||
return ty.fields_no_subst.map(([name, type]) => [
|
||||
name,
|
||||
substituteTy(args, type),
|
||||
]);
|
||||
}
|
||||
|
||||
// Substitute the parameter of a type. We are only able to handle one
|
||||
// level of generic definitions, for example for fields the struct def or for exprs the function generics.
|
||||
export function substituteTy(genericArgs: Ty[], ty: Ty): Ty {
|
||||
const subst = (ty: Ty) => substituteTy(genericArgs, ty);
|
||||
switch (ty.kind) {
|
||||
case "param":
|
||||
if (ty.idx >= genericArgs.length) {
|
||||
throw new Error(
|
||||
`substitution out of range, param index ${ty.idx} of param ${ty.name} out of range for length ${genericArgs.length}`,
|
||||
);
|
||||
}
|
||||
return genericArgs[ty.idx];
|
||||
case "tuple":
|
||||
return { ...ty, elems: ty.elems.map(subst) };
|
||||
case "fn":
|
||||
return {
|
||||
...ty,
|
||||
returnTy: subst(ty.returnTy),
|
||||
params: ty.params.map(subst),
|
||||
};
|
||||
case "struct":
|
||||
case "alias":
|
||||
return {
|
||||
...ty,
|
||||
genericArgs: ty.genericArgs.map(subst),
|
||||
};
|
||||
case "rawptr":
|
||||
return { ...ty, inner: subst(ty.inner) };
|
||||
// Primitives
|
||||
case "var":
|
||||
case "string":
|
||||
case "int":
|
||||
case "i32":
|
||||
case "bool":
|
||||
case "never":
|
||||
case "error":
|
||||
return ty;
|
||||
}
|
||||
}
|
||||
|
|
@ -14,4 +14,4 @@ Error: substitution out of range, param index 0 of param T out of range for leng
|
|||
at Array.map (<anonymous>)
|
||||
at foldAst (/home/nils/projects/riverdelta/target/ast.js:164:34)
|
||||
|
||||
Node.js v18.18.2
|
||||
Node.js v20.10.0
|
||||
|
|
|
|||
|
|
@ -14,4 +14,4 @@ Error: substitution out of range, param index 0 of param T out of range for leng
|
|||
at Array.map (<anonymous>)
|
||||
at foldAst (/home/nils/projects/riverdelta/target/ast.js:164:34)
|
||||
|
||||
Node.js v18.18.2
|
||||
Node.js v20.10.0
|
||||
|
|
|
|||
|
|
@ -14,4 +14,4 @@ Error: substitution out of range, param index 0 of param T out of range for leng
|
|||
at Array.map (<anonymous>)
|
||||
at foldAst (/home/nils/projects/riverdelta/target/ast.js:164:34)
|
||||
|
||||
Node.js v18.18.2
|
||||
Node.js v20.10.0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue