diff --git a/source/compiler/codegen/expression/operand.ts b/source/compiler/codegen/expression/operand.ts index be8aff1..63e7a1b 100644 --- a/source/compiler/codegen/expression/operand.ts +++ b/source/compiler/codegen/expression/operand.ts @@ -3,6 +3,7 @@ import * as colors from "https://deno.land/std@0.201.0/fmt/colors.ts"; import type * as Syntax from "../../../bnf/syntax.d.ts"; import { CompileConstFloat, CompileConstInt } from "./constant.ts"; import { AssertUnreachable, Yeet } from "../../../helper.ts"; +import { CompilePostfixes } from "./postfix.ts"; import { CompilePrefix } from "./prefix.ts"; import { Instruction } from "../../../wasm/index.ts"; import { CompileExpr } from "./index.ts"; @@ -26,8 +27,8 @@ export function CompileArg(ctx: Context, syntax: Syntax.Term_Expr_arg, expect?: default: AssertUnreachable(val); } - if (postfix.length > 0) throw new Error("Unimplemented postfix operations"); - if (prefix) return CompilePrefix(ctx, prefix, res, expect); + if (prefix) res = CompilePrefix(ctx, prefix, res, expect); + if (postfix.length > 0) CompilePostfixes(ctx, postfix, res, expect); return res; } diff --git a/source/compiler/codegen/expression/postfix.ts b/source/compiler/codegen/expression/postfix.ts new file mode 100644 index 0000000..15170cb --- /dev/null +++ b/source/compiler/codegen/expression/postfix.ts @@ -0,0 +1,81 @@ +import * as colors from "https://deno.land/std@0.201.0/fmt/colors.ts"; + +import type * as Syntax from "../../../bnf/syntax.d.ts"; +import Function from "../../function.ts"; +import { AssertUnreachable, Yeet } from "../../../helper.ts"; +import { CompileArg } from "./operand.ts"; +import { Intrinsic } from "../../intrinsic.ts"; +import { Namespace } from "../../file.ts"; +import { Context } from "./../context.ts"; +import { Instruction } from "../../../wasm/index.ts"; + + +export type OperandType = Intrinsic | Namespace; + + +export function CompilePostfixes(ctx: Context, syntax: Syntax.Term_Expr_postfix[], type: OperandType, expect?: Intrinsic): OperandType { + let res = type; + for (const postfix of syntax) { + const act = postfix.value[0]; + + switch (act.type) { + case "expr_call": res = CompileCall(ctx, act, res); break; + case "expr_get": Yeet( + `${colors.red("Error")}: Unimplemented postfix operation ${act.type}\n`, + { path: ctx.file.path, name: ctx.file.name, ref: act.ref } + ); break; + case "expr_param": Yeet( + `${colors.red("Error")}: Unimplemented postfix operation ${act.type}\n`, + { path: ctx.file.path, name: ctx.file.name, ref: act.ref } + ); break; + default: AssertUnreachable(act); + } + } + + return res; +} + + +function CompileCall(ctx: Context, syntax: Syntax.Term_Expr_call, operand: OperandType, expect?: Intrinsic) { + if (!(operand instanceof Function)) Yeet( + `${colors.red("Error")}: Cannot call on a non function value\n`, + { path: ctx.file.path, name: ctx.file.name, ref: syntax.ref } + ); + + operand.compile(); // check the function is compiled + + if (operand.returns.length != 1) Yeet( + `${colors.red("Error")}: Cannot currently handle functions which don't return a single value\n`, + { path: ctx.file.path, name: ctx.file.name, ref: syntax.ref } + ); + + if (!operand.ref) throw new Error("A function somehow compiled with a reference generated"); + + const args = LineariseArgList(syntax.value[0]); + if (args.length != operand.arguments.length) Yeet( + `${colors.red("Error")}: Miss matched argument count\n`, + { path: ctx.file.path, name: ctx.file.name, ref: syntax.ref } + ); + + for (let i=0; i x.value[0]); +} \ No newline at end of file