mirror of
https://github.com/Mercantec-GHC/h4-projekt-gruppe-0-sm.git
synced 2025-04-28 00:34:06 +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);
|
return this.lowerAssignStmt(stmt, k);
|
||||||
case "expr": {
|
case "expr": {
|
||||||
const rval = this.lowerExpr(k.expr);
|
const rval = this.lowerExpr(k.expr);
|
||||||
|
|
||||||
// ignore the fuck out of the value
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -374,6 +382,29 @@ export class FnLowerer {
|
|||||||
return this.lowerCallExprTupleVariantCtor(expr, kind);
|
return this.lowerCallExprTupleVariantCtor(expr, kind);
|
||||||
}
|
}
|
||||||
const args = kind.args.map((arg) => this.lowerExprToOperand(arg));
|
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);
|
const func = this.lowerExprToOperand(kind.expr);
|
||||||
return { tag: "call", func, args };
|
return { tag: "call", func, args };
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,8 @@ export type RVal =
|
|||||||
| { tag: "binary"; binaryType: BinaryType; left: Operand; right: Operand }
|
| { tag: "binary"; binaryType: BinaryType; left: Operand; right: Operand }
|
||||||
| { tag: "unary"; unaryType: UnaryType; operand: Operand }
|
| { tag: "unary"; unaryType: UnaryType; operand: Operand }
|
||||||
| { tag: "adt"; ty: Ty; fields: Operand[]; variant?: ast.Variant }
|
| { 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 =
|
export type BinaryType =
|
||||||
| "add"
|
| "add"
|
||||||
|
@ -113,7 +113,6 @@ export class Parser {
|
|||||||
const ident = this.parseIdent();
|
const ident = this.parseIdent();
|
||||||
let args: Expr[] | undefined = undefined;
|
let args: Expr[] | undefined = undefined;
|
||||||
if (this.test("(")) {
|
if (this.test("(")) {
|
||||||
this.step();
|
|
||||||
args = this.parseDelimitedList(
|
args = this.parseDelimitedList(
|
||||||
this.parseAttrArg,
|
this.parseAttrArg,
|
||||||
")",
|
")",
|
||||||
|
@ -1,15 +1,9 @@
|
|||||||
|
|
||||||
enum S {
|
#[builtin(Hello)]
|
||||||
A(int),
|
fn c_hello() -> int {}
|
||||||
B { v: int },
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let s = S::A(123);
|
c_hello();
|
||||||
let r = match s {
|
|
||||||
S::A(v) => { 3 + 2 },
|
|
||||||
S::B { v: v } => { 4 },
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,22 +44,25 @@ export class HirStringifyer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public item(item: ast.Item, d = 0): string {
|
public item(item: ast.Item, d = 0): string {
|
||||||
|
const attrs = item.attrs.map((attr) => `${this.attr(attr)}\n`);
|
||||||
const ident = item.ident.text;
|
const ident = item.ident.text;
|
||||||
const pub = item.pub ? "pub " : "";
|
const pub = item.pub ? "pub " : "";
|
||||||
const k = item.kind;
|
const k = item.kind;
|
||||||
switch (k.tag) {
|
switch (k.tag) {
|
||||||
case "error":
|
case "error":
|
||||||
return "<error>;";
|
return `${attrs}<error>;`;
|
||||||
case "mod_block":
|
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":
|
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":
|
case "enum":
|
||||||
return `enum ${ident}: ${
|
return `${attrs}enum ${ident}: ${
|
||||||
this.ty(this.ch.enumItemTy(item, k))
|
this.ty(this.ch.enumItemTy(item, k))
|
||||||
};`;
|
};`;
|
||||||
case "struct":
|
case "struct":
|
||||||
return `struct ${ident}: ${
|
return `${attrs}struct ${ident}: ${
|
||||||
this.ty(this.ch.structItemTy(item, k))
|
this.ty(this.ch.structItemTy(item, k))
|
||||||
};`;
|
};`;
|
||||||
case "fn": {
|
case "fn": {
|
||||||
@ -70,7 +73,7 @@ export class HirStringifyer {
|
|||||||
const params = k.params
|
const params = k.params
|
||||||
.map((param) => this.pat(param.pat, d))
|
.map((param) => this.pat(param.pat, d))
|
||||||
.join(", ");
|
.join(", ");
|
||||||
return `${pub}fn ${ident}(${params}) -> ${
|
return `${attrs}${pub}fn ${ident}(${params}) -> ${
|
||||||
this.ty(ty.kind.returnTy)
|
this.ty(ty.kind.returnTy)
|
||||||
} ${this.block(k.body!, d)}`;
|
} ${this.block(k.body!, d)}`;
|
||||||
}
|
}
|
||||||
@ -218,6 +221,12 @@ export class HirStringifyer {
|
|||||||
.join("::");
|
.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 {
|
public ty(ty: Ty): string {
|
||||||
return tyToString(this.ctx, ty);
|
return tyToString(this.ctx, ty);
|
||||||
}
|
}
|
||||||
|
@ -233,6 +233,10 @@ export class MirFnStringifyer {
|
|||||||
return `call ${this.operand(rval.func)}(${
|
return `call ${this.operand(rval.func)}(${
|
||||||
rval.args.map((arg) => this.operand(arg)).join(", ")
|
rval.args.map((arg) => this.operand(arg)).join(", ")
|
||||||
})`;
|
})`;
|
||||||
|
case "builtin":
|
||||||
|
return `builtin ${rval.builtinId}(${
|
||||||
|
rval.args.map((arg) => this.operand(arg)).join(", ")
|
||||||
|
})`;
|
||||||
}
|
}
|
||||||
exhausted(rval);
|
exhausted(rval);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user