diff --git a/src/desugar/desugar.ts b/src/desugar/desugar.ts new file mode 100644 index 0000000000..eaeb8e4999 --- /dev/null +++ b/src/desugar/desugar.ts @@ -0,0 +1,121 @@ +import type {CompilerContext} from "@/context/context"; +import {getAllStaticFunctions, getAllTypes} from "@/types/resolveDescriptors"; +import type * as Ast from "@/ast/ast"; +import {registerExpType} from "@/types/resolveExpression"; +import {binaryOperationFromAugmentedAssignOperation} from "@/ast/util"; + +export function desugar(ctx: CompilerContext): CompilerContext { + const funcs = getAllStaticFunctions(ctx) + + for (const func of funcs) { + if (func.ast.kind === "function_def") { + func.ast = { + ...func.ast, + statements: func.ast.statements.flatMap(stmt => { + if (stmt.kind === "statement_augmentedassign") { + const binaryExpression: Ast.OpBinary = { + kind: "op_binary", + loc: stmt.loc, + id: stmt.id, + left: stmt.path, + right: stmt.expression, + op: binaryOperationFromAugmentedAssignOperation(stmt.op) + } + ctx = registerExpType(ctx, binaryExpression, { + kind: "ref", + name: "Int", + optional: false, + }) + + return { + kind: "statement_assign", + path: stmt.path, + expression: binaryExpression, + loc: stmt.loc, + id: stmt.id, + } + } + + // if (stmt.kind === "statement_assign") { + // const expr: Ast.Number = { + // kind: "number", + // base: 10, + // value: 10000n, + // id: stmt.id, + // loc: stmt.loc, + // }; + // ctx = registerExpType(ctx, expr, { + // kind: "ref", + // name: "Int", + // optional: false, + // }) + // return [ + // stmt, + // { + // kind: "statement_return", + // expression: expr, + // loc: stmt.loc, + // id: stmt.id, + // } satisfies Ast.StatementReturn as Ast.Statement + // ] + // } + return [stmt] + }) + } + + } + } + + const types = getAllTypes(ctx) + for (const type of types) { + type.functions.forEach((func, key) => { + if (type.name === "BaseTrait") { + return + } + + if (func.ast.kind === "function_def" && func.self) { + const paramName: Ast.Id = { + kind: "id", + text: "self", + loc: func.ast.loc, + id: func.ast.id, + }; + + func.params.splice(0, 0, { + name: paramName, + type: { + kind: "ref", + name: func.self.kind === "ref" ? func.self.name : "", + optional: false, + }, + loc: func.ast.loc, + }) + + func.ast = { + ...func.ast, + params: [ + { + kind: "typed_parameter", + name: paramName, + type: { + kind: "type_id", + text: func.self.kind === "ref" ? func.self.name : "", + loc: func.ast.loc, + id: func.ast.id, + }, + loc: func.ast.loc, + id: func.ast.id, + }, + ...func.ast.params, + ] + } + + type.functions.set(key, func) + } + + console.log(func.name) + }) + } + + return ctx; +} diff --git a/src/generator/writers/writeFunction.ts b/src/generator/writers/writeFunction.ts index a880be2c2d..073d76c17c 100644 --- a/src/generator/writers/writeFunction.ts +++ b/src/generator/writers/writeFunction.ts @@ -171,6 +171,7 @@ export function writeStatement( return; } case "statement_augmentedassign": { + // throw new Error("unexpected statement"); const lvaluePath = tryExtractPath(f.path); if (lvaluePath === null) { // typechecker is supposed to catch this diff --git a/src/pipeline/precompile.ts b/src/pipeline/precompile.ts index 3c1d455155..9e90d72a86 100644 --- a/src/pipeline/precompile.ts +++ b/src/pipeline/precompile.ts @@ -12,6 +12,7 @@ import type { FactoryAst } from "@/ast/ast-helpers"; import type { Parser } from "@/grammar"; import { evalComptimeExpressions } from "@/types/evalComptimeExpressions"; import { computeReceiversEffects } from "@/types/effects"; +import {desugar} from "@/desugar/desugar"; export function precompile( ctx: CompilerContext, @@ -60,6 +61,8 @@ export function precompile( */ evalComptimeExpressions(ctx, ast); + ctx = desugar(ctx) + // This creates TLB-style type definitions ctx = resolveSignatures(ctx, ast); diff --git a/src/types/resolveExpression.ts b/src/types/resolveExpression.ts index 4367b7e60b..2a46524666 100644 --- a/src/types/resolveExpression.ts +++ b/src/types/resolveExpression.ts @@ -37,7 +37,7 @@ export function getExpType(ctx: CompilerContext, exp: Ast.Expression) { return t.description; } -function registerExpType( +export function registerExpType( ctx: CompilerContext, exp: Ast.Expression, description: TypeRef,