diff --git a/slige/compiler/middle/ast_lower.ts b/slige/compiler/middle/ast_lower.ts index 5a51d6d..a540f07 100644 --- a/slige/compiler/middle/ast_lower.ts +++ b/slige/compiler/middle/ast_lower.ts @@ -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 }; } diff --git a/slige/compiler/middle/mir.ts b/slige/compiler/middle/mir.ts index 7ef125f..ec5763e 100644 --- a/slige/compiler/middle/mir.ts +++ b/slige/compiler/middle/mir.ts @@ -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" diff --git a/slige/compiler/parse/parser.ts b/slige/compiler/parse/parser.ts index 13b5b46..e30fc10 100644 --- a/slige/compiler/parse/parser.ts +++ b/slige/compiler/parse/parser.ts @@ -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, ")", diff --git a/slige/compiler/program.slg b/slige/compiler/program.slg index 8c677c6..ce8a38b 100644 --- a/slige/compiler/program.slg +++ b/slige/compiler/program.slg @@ -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(); } diff --git a/slige/compiler/stringify/hir.ts b/slige/compiler/stringify/hir.ts index 0fa1e04..836267c 100644 --- a/slige/compiler/stringify/hir.ts +++ b/slige/compiler/stringify/hir.ts @@ -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 ";"; + return `${attrs};`; 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); } diff --git a/slige/compiler/stringify/mir.ts b/slige/compiler/stringify/mir.ts index 0c181ae..7d92d73 100644 --- a/slige/compiler/stringify/mir.ts +++ b/slige/compiler/stringify/mir.ts @@ -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); }