implement some more stuff around raw pointers

This commit is contained in:
nora 2023-11-05 11:29:41 +01:00
parent ef04f21100
commit 3af8f4fc40
8 changed files with 67 additions and 17 deletions

1
.envrc Normal file
View file

@ -0,0 +1 @@
use flake

1
.gitignore vendored
View file

@ -3,3 +3,4 @@
*.tsbuildinfo
/*-example.wat
/out.wat
.direnv

6
flake.lock generated
View file

@ -2,11 +2,11 @@
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1690100086,
"narHash": "sha256-ajup699tAa2zw3WdnMAjLnk9SQm0Q8sJHzqeg5td9TQ=",
"lastModified": 1699091535,
"narHash": "sha256-cAwCoYXMO1FSiEhla/Bp98dMfPTNyLFk3MjT/UBWv+I=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "ffce3e381807c51a98cc62bd1afa251a0456248c",
"rev": "47ab3596a7163c69d642235da3d88f9fbe95df03",
"type": "github"
},
"original": {

View file

@ -25,6 +25,7 @@
];
packages = with pkgs; [
nodejs-18_x # Node.js 18, plus npm, npx, and corepack
yarn
wasmtime
wasm-tools
binaryen

View file

@ -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 = {

View file

@ -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.

View file

@ -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 };

View file

@ -43,7 +43,7 @@ function deallocateItem(ptr: I32, objSize: I32) = (
std.println("uwu deawwocate :3");
);
// Port of https://github.com/CCareaga/heap_allocator
// Port of https://github.com/CCareaga/heap_allocator fc423c6113df598ac8d10bc1f2954d51248e6443
//
// MIT License
//
@ -120,12 +120,10 @@ function getWilderness() =;
// llist.c
function addNode(bin: *BinS, node: *NodeS) = (
node.next = ___transmute(0_I32);
node.prev = ___transmute(0_I32);
node.next = __NULL;
node.prev = __NULL;
let bin_head_addr: I32 = ___transmute(bin.head); // bin.head
if (bin_head_addr == 0_I32) then (
if (bin.head == __NULL) then (
bin.head = node;
) else (
let current: *NodeS = bin.head;
@ -160,8 +158,21 @@ function addNode(bin: *BinS, node: *NodeS) = (
)
);
function removeNode(bin: BinPtr, node: NodePtr) = (
function removeNode(bin: *BinS, node: *NodeS) = (
if (bin.head != __NULL) then (
if (bin.head == node) then (
bin.head = bin.head.next;
) else (
let temp: *NodeS = bin.head.next;
loop (
if (temp == __NULL) then break;
if (temp == node) then (
)
)
)
)
);
function test() =;