2024-12-06 14:17:52 +01:00
|
|
|
export type VType =
|
|
|
|
| { type: "error" }
|
|
|
|
| { type: "unknown" }
|
|
|
|
| { type: "null" }
|
|
|
|
| { type: "int" }
|
|
|
|
| { type: "string" }
|
|
|
|
| { type: "bool" }
|
|
|
|
| { type: "array"; inner: VType }
|
2024-12-25 17:01:57 +01:00
|
|
|
| { type: "struct"; fields: VTypeParam[] }
|
2024-12-23 03:15:43 +01:00
|
|
|
| {
|
|
|
|
type: "fn";
|
|
|
|
genericParams?: VTypeGenericParam[];
|
|
|
|
params: VTypeParam[];
|
|
|
|
returnType: VType;
|
|
|
|
}
|
|
|
|
| { type: "generic" }
|
|
|
|
| {
|
2024-12-25 17:01:57 +01:00
|
|
|
type: "generic_spec";
|
2024-12-23 03:15:43 +01:00
|
|
|
subject: VType;
|
2024-12-25 17:01:57 +01:00
|
|
|
genericParams: VType[];
|
2024-12-23 03:15:43 +01:00
|
|
|
};
|
2024-12-06 14:17:52 +01:00
|
|
|
|
|
|
|
export type VTypeParam = {
|
|
|
|
ident: string;
|
|
|
|
vtype: VType;
|
|
|
|
};
|
|
|
|
|
2024-12-23 03:15:43 +01:00
|
|
|
export type VTypeGenericParam = {
|
|
|
|
ident: string;
|
|
|
|
};
|
|
|
|
|
2024-12-06 14:17:52 +01:00
|
|
|
export function vtypesEqual(a: VType, b: VType): boolean {
|
|
|
|
if (a.type !== b.type) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (
|
2024-12-09 10:52:05 +01:00
|
|
|
["error", "unknown", "null", "int", "string", "bool"]
|
2024-12-06 14:17:52 +01:00
|
|
|
.includes(a.type)
|
|
|
|
) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (a.type === "array" && b.type === "array") {
|
|
|
|
return vtypesEqual(a.inner, b.inner);
|
|
|
|
}
|
|
|
|
if (a.type === "fn" && b.type === "fn") {
|
|
|
|
if (a.params.length !== b.params.length) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
for (let i = 0; i < a.params.length; ++i) {
|
|
|
|
if (!vtypesEqual(a.params[i].vtype, b.params[i].vtype)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return vtypesEqual(a.returnType, b.returnType);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function vtypeToString(vtype: VType): string {
|
|
|
|
if (
|
2024-12-09 10:52:05 +01:00
|
|
|
["error", "unknown", "null", "int", "string", "bool"]
|
2024-12-06 14:17:52 +01:00
|
|
|
.includes(vtype.type)
|
|
|
|
) {
|
|
|
|
return vtype.type;
|
|
|
|
}
|
|
|
|
if (vtype.type === "array") {
|
|
|
|
return `[${vtypeToString(vtype.inner)}]`;
|
|
|
|
}
|
|
|
|
if (vtype.type === "fn") {
|
|
|
|
const paramString = vtype.params.map((param) =>
|
|
|
|
`${param.ident}: ${vtypeToString(param.vtype)}`
|
|
|
|
)
|
|
|
|
.join(", ");
|
|
|
|
return `fn (${paramString}) -> ${vtypeToString(vtype.returnType)}`;
|
|
|
|
}
|
2024-12-23 03:15:43 +01:00
|
|
|
if (vtype.type === "generic") {
|
|
|
|
return `generic`;
|
|
|
|
}
|
2024-12-06 14:17:52 +01:00
|
|
|
throw new Error(`unhandled vtype '${vtype.type}'`);
|
|
|
|
}
|