mirror of
https://github.com/Mercantec-GHC/h4-projekt-gruppe-0-sm.git
synced 2025-04-27 16:24:07 +02:00
compiler: add builtins
This commit is contained in:
parent
6e5ac26c84
commit
0bdfd78ca2
@ -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 };
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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,
|
||||
")",
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user