slige/compiler/desugar/array_literal.ts

95 lines
2.8 KiB
TypeScript
Raw Normal View History

2024-12-31 03:38:38 +01:00
import {
AstCreator,
ETypeKind,
Expr,
ExprKind,
Stmt,
StmtKind,
} from "../ast.ts";
import { AstVisitor, visitExpr, VisitRes, visitStmts } from "../ast_visitor.ts";
import { Pos } from "../token.ts";
export class ArrayLiteralDesugarer implements AstVisitor {
public constructor(
private astCreator: AstCreator,
) {}
public desugar(stmts: Stmt[]) {
visitStmts(stmts, this);
}
visitArrayExpr(expr: Expr): VisitRes {
if (expr.kind.type !== "array") {
throw new Error();
}
const npos: Pos = { index: 0, line: 1, col: 1 };
const Expr = (kind: ExprKind, pos = npos) =>
this.astCreator.expr(kind, pos);
const Stmt = (kind: StmtKind, pos = npos) =>
this.astCreator.stmt(kind, pos);
const EType = (kind: ETypeKind, pos = npos) =>
this.astCreator.etype(kind, pos);
const std = (ident: string): Expr =>
Expr({
type: "path",
subject: Expr({
type: "ident",
ident: "std",
}),
ident,
});
if (expr.kind.exprs.length < 1) {
throw new Error("");
}
expr.kind = {
type: "block",
stmts: [
Stmt({
type: "let",
2025-01-02 06:46:51 +01:00
param: this.astCreator.param({
2024-12-31 03:38:38 +01:00
ident: "::value",
2025-01-17 07:44:53 +01:00
mut: true,
2024-12-31 03:38:38 +01:00
pos: npos,
2025-01-02 06:46:51 +01:00
}),
2024-12-31 03:38:38 +01:00
value: Expr({
type: "call",
subject: Expr({
type: "etype_args",
subject: std("array_new"),
etypeArgs: [
EType({
type: "type_of",
expr: expr.kind.exprs[0],
}),
],
}),
args: [],
}),
}),
...expr.kind.exprs
.map((expr) =>
Stmt({
type: "expr",
expr: Expr({
type: "call",
subject: std("array_push"),
args: [
Expr({ type: "ident", ident: "::value" }),
expr,
],
}),
})
),
],
expr: Expr({ type: "ident", ident: "::value" }),
};
visitExpr(expr, this);
return "stop";
}
}