Skip to content

Commit 6f4edd4

Browse files
committed
refactor: simplify code for clarity and maintainability
- Simplify getExprId function by removing redundant null check - Convert arrow functions to regular function declarations - Remove unused compiledNodeIndices variable - Replace if-else chain with switch statement for short-circuit operators - Remove duplicate code path in parseUnary for +/- operators
1 parent 9a07340 commit 6f4edd4

2 files changed

Lines changed: 30 additions & 45 deletions

File tree

src/compile.ts

Lines changed: 30 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -72,16 +72,14 @@ export function compile<TResult>(
7272

7373
// 第一步:为每个表达式分配唯一 ID
7474
const exprIdMap = new WeakMap<Expression<Record<string, unknown>, unknown>, symbol>();
75-
const getExprId = (expr: Expression<Record<string, unknown>, unknown>): symbol => {
76-
if (!exprIdMap.has(expr)) {
77-
exprIdMap.set(expr, Symbol("expr"));
78-
}
79-
const id = exprIdMap.get(expr);
75+
function getExprId(expr: Expression<Record<string, unknown>, unknown>): symbol {
76+
let id = exprIdMap.get(expr);
8077
if (id === undefined) {
81-
throw new Error("Expression ID not found");
78+
id = Symbol("expr");
79+
exprIdMap.set(expr, id);
8280
}
8381
return id;
84-
};
82+
}
8583

8684
// 为所有变量创建 node
8785
const nodeMap = new Map<symbol, ExprNode>();
@@ -102,7 +100,7 @@ export function compile<TResult>(
102100

103101
// 第二步:递归收集所有依赖的节点,并检测循环依赖
104102
const exprNodes = new Map<symbol, ExprNode>();
105-
const collectNodes = (expr: Expression<Record<string, unknown>, unknown>): ExprNode => {
103+
function collectNodes(expr: Expression<Record<string, unknown>, unknown>): ExprNode {
106104
const exprId = getExprId(expr);
107105

108106
if (visited.has(exprId)) {
@@ -144,7 +142,7 @@ export function compile<TResult>(
144142
visiting.delete(exprId);
145143

146144
return node;
147-
};
145+
}
148146

149147
// 收集根表达式的所有节点
150148
const rootNode = collectNodes(expression);
@@ -153,7 +151,7 @@ export function compile<TResult>(
153151
const sortedExprNodes: ExprNode[] = [];
154152
const exprVisited = new Set<symbol>();
155153

156-
const topologicalSort = (node: ExprNode) => {
154+
function topologicalSort(node: ExprNode): void {
157155
if (exprVisited.has(node.id)) {
158156
return;
159157
}
@@ -169,7 +167,7 @@ export function compile<TResult>(
169167
if (node.tag === "expression") {
170168
sortedExprNodes.push(node);
171169
}
172-
};
170+
}
173171

174172
topologicalSort(rootNode);
175173

@@ -198,11 +196,11 @@ export function compile<TResult>(
198196
}
199197

200198
// 判断哪些表达式可以内联(只被引用一次且不是根节点)
201-
const canInline = (node: ExprNode): boolean => {
199+
function canInline(node: ExprNode): boolean {
202200
if (!inline) return false;
203201
if (node.id === rootNode.id) return false; // 根节点不能内联
204202
return (refCount.get(node.id) ?? 0) === 1;
205-
};
203+
}
206204

207205
// 第六步:为所有不能内联的表达式分配索引
208206
let exprIndex = 0;
@@ -270,11 +268,8 @@ export function compile<TResult>(
270268
const expressions: CompiledExpression[] = [];
271269
let nextIndex = context.variableOrder.length;
272270

273-
// 用于追踪已经编译过的节点
274-
const compiledNodeIndices = new Map<symbol, number>();
275-
276271
// 编译单个 AST 节点到指令序列,返回结果所在的索引
277-
const compileAst = (ast: ASTNode): number => {
272+
function compileAst(ast: ASTNode): number {
278273
// 检查是否需要短路处理
279274
if (ast.type === "BinaryExpr" && (ast.operator === "||" || ast.operator === "&&" || ast.operator === "??")) {
280275
return compileShortCircuit(ast);
@@ -289,24 +284,27 @@ export function compile<TResult>(
289284
const idx = nextIndex++;
290285
expressions.push(exprStr);
291286
return idx;
292-
};
287+
}
293288

294289
// 编译短路运算符 (&&, ||, ??)
295-
const compileShortCircuit = (node: ASTNode & { type: "BinaryExpr" }): number => {
290+
function compileShortCircuit(node: ASTNode & { type: "BinaryExpr" }): number {
296291
// 递归编译左操作数
297292
const leftIdx = compileAst(node.left);
298293

299294
// 生成跳转条件
300295
let branchCondition: string;
301-
if (node.operator === "||") {
302-
// || : 如果左边为 true,跳过右边
303-
branchCondition = `$${leftIdx}`;
304-
} else if (node.operator === "&&") {
305-
// && : 如果左边为 false,跳过右边
306-
branchCondition = `!$${leftIdx}`;
307-
} else {
308-
// ?? : 如果左边非 null/undefined,跳过右边
309-
branchCondition = `$${leftIdx}!=null`;
296+
switch (node.operator) {
297+
case "||":
298+
// || : 如果左边为 true,跳过右边
299+
branchCondition = `$${leftIdx}`;
300+
break;
301+
case "&&":
302+
// && : 如果左边为 false,跳过右边
303+
branchCondition = `!$${leftIdx}`;
304+
break;
305+
default:
306+
// ?? : 如果左边非 null/undefined,跳过右边
307+
branchCondition = `$${leftIdx}!=null`;
310308
}
311309

312310
// 记录 br 指令的位置,稍后填入正确的 offset
@@ -326,10 +324,10 @@ export function compile<TResult>(
326324
expressions.push(["phi"] as PhiNode);
327325

328326
return phiIdx;
329-
};
327+
}
330328

331329
// 编译三元表达式
332-
const compileConditional = (node: ASTNode & { type: "ConditionalExpr" }): number => {
330+
function compileConditional(node: ASTNode & { type: "ConditionalExpr" }): number {
333331
// 编译条件
334332
const testIdx = compileAst(node.test);
335333

@@ -363,14 +361,13 @@ export function compile<TResult>(
363361
expressions.push(["phi"] as PhiNode);
364362

365363
return phiIdx;
366-
};
364+
}
367365

368366
// 为每个不能内联的表达式生成指令
369367
for (const exprNode of sortedExprNodes) {
370368
if (!canInline(exprNode)) {
371369
const ast = nodeAstMap.get(exprNode.id)!;
372-
const resultIdx = compileAst(ast);
373-
compiledNodeIndices.set(exprNode.id, resultIdx);
370+
compileAst(ast);
374371
}
375372
}
376373

src/parser.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -207,18 +207,6 @@ class Parser {
207207
const ch = this.peek();
208208

209209
if (ch === "!" || ch === "~" || ch === "+" || ch === "-") {
210-
// 检查是否是一元运算符而非二元运算符
211-
if (ch === "+" || ch === "-") {
212-
this.advance();
213-
this.skipWhitespace();
214-
const argument = this.parseUnary();
215-
return {
216-
type: "UnaryExpr",
217-
operator: ch,
218-
argument,
219-
prefix: true,
220-
};
221-
}
222210
this.advance();
223211
this.skipWhitespace();
224212
const argument = this.parseUnary();

0 commit comments

Comments
 (0)