mirror of
https://github.com/Noratrieb/riverdelta.git
synced 2026-01-14 16:35:03 +01:00
implement some more stuff around raw pointers
This commit is contained in:
parent
ef04f21100
commit
3af8f4fc40
8 changed files with 67 additions and 17 deletions
|
|
@ -465,6 +465,7 @@ export const BUILTINS = [
|
|||
"false",
|
||||
"trap",
|
||||
// Intrinsics:
|
||||
"__NULL", // null raw pointer
|
||||
"__i32_store",
|
||||
"__i64_store",
|
||||
"__i32_load",
|
||||
|
|
@ -536,7 +537,7 @@ export type TyStruct = {
|
|||
|
||||
export type TyRawPtr = {
|
||||
kind: "rawptr";
|
||||
inner: TyStruct;
|
||||
inner: Ty;
|
||||
};
|
||||
|
||||
export type TyNever = {
|
||||
|
|
|
|||
|
|
@ -669,6 +669,9 @@ function lowerExpr(
|
|||
break;
|
||||
case "print":
|
||||
todo("print function");
|
||||
case "__NULL":
|
||||
instrs.push({ kind: "i32.const", imm: 0n });
|
||||
break;
|
||||
default: {
|
||||
unreachable(`${res.name}#B is not a value`);
|
||||
}
|
||||
|
|
@ -688,7 +691,8 @@ function lowerExpr(
|
|||
const rhsTy = expr.rhs.ty;
|
||||
if (
|
||||
(lhsTy.kind === "int" && rhsTy.kind === "int") ||
|
||||
(lhsTy.kind === "i32" && rhsTy.kind === "i32")
|
||||
(lhsTy.kind === "i32" && rhsTy.kind === "i32") ||
|
||||
(lhsTy.kind === "rawptr" && rhsTy.kind === "rawptr")
|
||||
) {
|
||||
let kind: wasm.Instr["kind"];
|
||||
const valty = lhsTy.kind === "int" ? "i64" : "i32";
|
||||
|
|
@ -1332,6 +1336,9 @@ function sizeOfValtype(type: wasm.ValType): number {
|
|||
|
||||
export function layoutOfStruct(ty_: TyStruct | TyRawPtr): StructLayout {
|
||||
const ty = ty_.kind === "struct" ? ty_ : ty_.inner;
|
||||
if (ty.kind !== "struct") {
|
||||
unreachable("must be struct");
|
||||
}
|
||||
const fieldWasmTys = ty.fields.map(([, field]) => wasmTypeForBody(field));
|
||||
|
||||
// TODO: Use the max alignment instead.
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ function builtinAsTy(cx: TypeckCtx, name: string, span: Span): Ty {
|
|||
}
|
||||
}
|
||||
|
||||
function typeOfBuiltinValue(cx: TypeckCtx, name: BuiltinName, span: Span): Ty {
|
||||
function typeOfBuiltinValue(fcx: FuncCtx, name: BuiltinName, span: Span): Ty {
|
||||
switch (name) {
|
||||
case "false":
|
||||
case "true":
|
||||
|
|
@ -102,6 +102,8 @@ function typeOfBuiltinValue(cx: TypeckCtx, name: BuiltinName, span: Span): Ty {
|
|||
return mkTyFn([TY_STRING], TY_UNIT);
|
||||
case "trap":
|
||||
return mkTyFn([], TY_NEVER);
|
||||
case "__NULL":
|
||||
return { kind: "rawptr", inner: fcx.infcx.newVar() };
|
||||
case "__i32_store":
|
||||
return mkTyFn([TY_I32, TY_I32], TY_UNIT);
|
||||
case "__i64_store":
|
||||
|
|
@ -118,7 +120,7 @@ function typeOfBuiltinValue(cx: TypeckCtx, name: BuiltinName, span: Span): Ty {
|
|||
return mkTyFn([TY_I32], TY_INT);
|
||||
default: {
|
||||
return tyError(
|
||||
cx,
|
||||
fcx.cx,
|
||||
new CompilerError(`\`${name}\` cannot be used as a value`, span),
|
||||
);
|
||||
}
|
||||
|
|
@ -696,7 +698,7 @@ function typeOfValue(fcx: FuncCtx, res: Resolution, span: Span): Ty {
|
|||
return typeOfItem(fcx.cx, res.id, span);
|
||||
}
|
||||
case "builtin":
|
||||
return typeOfBuiltinValue(fcx.cx, res.name, span);
|
||||
return typeOfBuiltinValue(fcx, res.name, span);
|
||||
case "error":
|
||||
return tyErrorFrom(res);
|
||||
}
|
||||
|
|
@ -906,8 +908,29 @@ export function checkBody(
|
|||
}
|
||||
case "struct":
|
||||
case "rawptr": {
|
||||
const fields =
|
||||
lhs.ty.kind === "struct" ? lhs.ty.fields : lhs.ty.inner.fields;
|
||||
let fields: [string, Ty][];
|
||||
if (lhs.ty.kind === "struct") {
|
||||
fields = lhs.ty.fields;
|
||||
} else if (lhs.ty.kind === "rawptr") {
|
||||
let inner = fcx.infcx.resolveIfPossible(lhs.ty.inner);
|
||||
if (inner.kind !== "struct") {
|
||||
inner = tyError(
|
||||
fcx.cx,
|
||||
new CompilerError(
|
||||
"fields can only be accessed on pointers pointing to a struct",
|
||||
expr.lhs.span,
|
||||
),
|
||||
);
|
||||
ty = inner;
|
||||
break;
|
||||
} else {
|
||||
fields = inner.fields;
|
||||
}
|
||||
} else {
|
||||
fields = [];
|
||||
unreachable("must be struct or rawptr here");
|
||||
}
|
||||
|
||||
if (typeof field.value === "string") {
|
||||
const idx = fields.findIndex(([name]) => name === field.value);
|
||||
if (idx === -1) {
|
||||
|
|
@ -1149,6 +1172,11 @@ function checkBinary(
|
|||
return { ...expr, lhs, rhs, ty: TY_BOOL };
|
||||
}
|
||||
|
||||
if (lhsTy.kind === "rawptr" && rhsTy.kind === "rawptr") {
|
||||
fcx.infcx.assign(lhsTy.inner, rhsTy.inner, expr.span);
|
||||
return { ...expr, lhs, rhs, ty: TY_BOOL };
|
||||
}
|
||||
|
||||
if (EQUALITY_KINDS.includes(expr.binaryKind)) {
|
||||
if (lhsTy.kind === "bool" && rhsTy.kind === "bool") {
|
||||
return { ...expr, lhs, rhs, ty: TY_BOOL };
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue