compiler: add builtins

This commit is contained in:
sfja 2025-03-03 02:19:27 +01:00 committed by SimonFJ20
parent 6e5ac26c84
commit 0bdfd78ca2
6 changed files with 56 additions and 18 deletions

View File

@ -122,8 +122,16 @@ export class FnLowerer {
return this.lowerAssignStmt(stmt, k);
case "expr": {
const rval = this.lowerExpr(k.expr);
// ignore the fuck out of the value
void rval;
const ty = this.ch.exprTy(k.expr);
const local = this.local(ty);
this.addStmt({
tag: "assign",
place: { local, proj: [] },
rval,
});
return;
}
}
@ -374,6 +382,29 @@ export class FnLowerer {
return this.lowerCallExprTupleVariantCtor(expr, kind);
}
const args = kind.args.map((arg) => this.lowerExprToOperand(arg));
const calleeTy = this.ch.exprTy(kind.expr);
if (calleeTy.kind.tag !== "fn") {
throw new Error();
}
const builtinAttr = calleeTy.kind.item.attrs
.find((attr) => attr.ident.text === "builtin");
if (builtinAttr) {
if (
builtinAttr.args?.length !== 1 ||
builtinAttr.args[0].kind.tag !== "path" ||
builtinAttr.args[0].kind.path.segments.length !== 1 ||
!["Hello"].includes(
builtinAttr.args[0].kind.path.segments[0].ident.text,
)
) {
return { tag: "error" };
}
const builtinId =
builtinAttr.args[0].kind.path.segments[0].ident.text;
return { tag: "builtin", builtinId, args };
}
const func = this.lowerExprToOperand(kind.expr);
return { tag: "call", func, args };
}

View File

@ -86,7 +86,8 @@ export type RVal =
| { tag: "binary"; binaryType: BinaryType; left: Operand; right: Operand }
| { tag: "unary"; unaryType: UnaryType; operand: Operand }
| { tag: "adt"; ty: Ty; fields: Operand[]; variant?: ast.Variant }
| { tag: "call"; func: Operand; args: Operand[] };
| { tag: "call"; func: Operand; args: Operand[] }
| { tag: "builtin"; builtinId: string; args: Operand[] };
export type BinaryType =
| "add"

View File

@ -113,7 +113,6 @@ export class Parser {
const ident = this.parseIdent();
let args: Expr[] | undefined = undefined;
if (this.test("(")) {
this.step();
args = this.parseDelimitedList(
this.parseAttrArg,
")",

View File

@ -1,15 +1,9 @@
enum S {
A(int),
B { v: int },
}
#[builtin(Hello)]
fn c_hello() -> int {}
fn main() {
let s = S::A(123);
let r = match s {
S::A(v) => { 3 + 2 },
S::B { v: v } => { 4 },
};
c_hello();
}

View File

@ -44,22 +44,25 @@ export class HirStringifyer {
}
public item(item: ast.Item, d = 0): string {
const attrs = item.attrs.map((attr) => `${this.attr(attr)}\n`);
const ident = item.ident.text;
const pub = item.pub ? "pub " : "";
const k = item.kind;
switch (k.tag) {
case "error":
return "<error>;";
return `${attrs}<error>;`;
case "mod_block":
return `${pub}mod ${ident} ${this.block(k.block, d)}`;
return `${attrs}${pub}mod ${ident} ${this.block(k.block, d)}`;
case "mod_file":
return `${pub}mod ${ident} {\n${this.file(k.ast!, d + 1)}\n}`;
return `${attrs}${pub}mod ${ident} {\n${
this.file(k.ast!, d + 1)
}\n}`;
case "enum":
return `enum ${ident}: ${
return `${attrs}enum ${ident}: ${
this.ty(this.ch.enumItemTy(item, k))
};`;
case "struct":
return `struct ${ident}: ${
return `${attrs}struct ${ident}: ${
this.ty(this.ch.structItemTy(item, k))
};`;
case "fn": {
@ -70,7 +73,7 @@ export class HirStringifyer {
const params = k.params
.map((param) => this.pat(param.pat, d))
.join(", ");
return `${pub}fn ${ident}(${params}) -> ${
return `${attrs}${pub}fn ${ident}(${params}) -> ${
this.ty(ty.kind.returnTy)
} ${this.block(k.body!, d)}`;
}
@ -218,6 +221,12 @@ export class HirStringifyer {
.join("::");
}
public attr(attr: ast.Attr): string {
return `#[${attr.ident.text}${
attr.args && `(${attr.args.map((arg) => this.expr(arg, 1))})` || ""
}]`;
}
public ty(ty: Ty): string {
return tyToString(this.ctx, ty);
}

View File

@ -233,6 +233,10 @@ export class MirFnStringifyer {
return `call ${this.operand(rval.func)}(${
rval.args.map((arg) => this.operand(arg)).join(", ")
})`;
case "builtin":
return `builtin ${rval.builtinId}(${
rval.args.map((arg) => this.operand(arg)).join(", ")
})`;
}
exhausted(rval);
}