diff --git a/sbc/Makefile b/sbc/Makefile index c783d04..39e9a0c 100644 --- a/sbc/Makefile +++ b/sbc/Makefile @@ -11,7 +11,7 @@ out: entry.o out.o lib.o nasm -f elf64 $< -o $@ out.nasm: program.sbl - deno run --allow-read --allow-write --check main.ts $< + deno run --allow-read --allow-write --check main.ts $< $@ clean: rm -rf out.asm out.o lib.o entry.o out diff --git a/sbc/ast.ts b/sbc/ast.ts index 6550c55..b144a4e 100644 --- a/sbc/ast.ts +++ b/sbc/ast.ts @@ -83,6 +83,7 @@ export type Ty = { export type TyKind = | { tag: "error" } + | { tag: "void" } | { tag: "ident"; ident: string } | { tag: "ptr"; ty: Ty }; diff --git a/sbc/front.ts b/sbc/front.ts index 603827d..656a60f 100644 --- a/sbc/front.ts +++ b/sbc/front.ts @@ -188,6 +188,8 @@ export class Checker { switch (k.tag) { case "error": return { tag: "error" }; + case "void": + return { tag: "void" }; case "ident": { switch (k.ident) { case "int": @@ -232,6 +234,8 @@ export class Checker { if (a.tag === "error" || b.tag === "error") { return ok(a); + } else if (both("void")) { + return ok(a); } else if (both("int")) { return ok(a); } else if (both("str")) { @@ -912,7 +916,14 @@ export class Parser { } private parseTy(): AstTy { - if (this.eat("ident")) { + if (this.eat("(")) { + if (this.eat(")")) { + return this.ty({ tag: "void" }, this.eaten!.line); + } else { + this.report("expected ')'"); + return this.ty({ tag: "error" }, this.last!.line); + } + } else if (this.eat("ident")) { return this.ty( { tag: "ident", ident: this.eaten!.identVal! }, this.eaten!.line, diff --git a/sbc/main.ts b/sbc/main.ts index eb46dc6..7931c0c 100644 --- a/sbc/main.ts +++ b/sbc/main.ts @@ -8,7 +8,13 @@ import { AsmGen } from "./asm_gen.ts"; import { optimizeLir } from "./lir_optimize.ts"; async function main() { - const text = await Deno.readTextFile(Deno.args[0]); + const inputFile = Deno.args[0]; + const outputFile = Deno.args[1]; + if (!inputFile || !outputFile) { + throw new Error("incorrect arguments"); + } + + const text = await Deno.readTextFile(inputFile); const ast = new Parser(text).parse(); // console.log("=== AST ==="); @@ -44,7 +50,7 @@ async function main() { // console.log("=== ASM ==="); // console.log(asm); - await Deno.writeTextFile("out.nasm", asm); + await Deno.writeTextFile(outputFile, asm); } main(); diff --git a/sbc/program.sbl b/sbc/program.sbl index fa55611..d0c0c67 100644 --- a/sbc/program.sbl +++ b/sbc/program.sbl @@ -11,6 +11,10 @@ fn factorial(v: int) -> int { return v * factorial(v - 1); } +fn return_void_ptr(ptr: *()) -> *() { + return ptr; +} + #[c_export("sbc_main")] fn main() -> int { let i = 0; diff --git a/sbc/ty.ts b/sbc/ty.ts index 8d9054b..7ce56c2 100644 --- a/sbc/ty.ts +++ b/sbc/ty.ts @@ -3,6 +3,7 @@ import * as ast from "./ast.ts"; export type Ty = | { tag: "error" } | { tag: "unknown" } + | { tag: "void" } | { tag: "int" } | { tag: "str" } | { tag: "ptr"; ty: Ty } @@ -14,6 +15,8 @@ export function tyToString(ty: Ty): string { return ``; case "unknown": return ``; + case "void": + return `()`; case "int": return `int`; case "str":