Skip to content

Commit 541539c

Browse files
authored
fix: replace inline anonymous type assertions with named ast types in codegen (#110)
1 parent 6de3904 commit 541539c

29 files changed

Lines changed: 144 additions & 157 deletions

node_modules

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/Users/csmith/git/ChadScript/node_modules

src/codegen/expressions/arrow-functions.ts

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ import {
1818
BlockStatement,
1919
FunctionParameter,
2020
SourceLocation,
21+
BinaryNode,
22+
ReturnStatement,
23+
IfStatement,
24+
Expression,
2125
} from "../../ast/types.js";
2226
import {
2327
ClosureAnalyzer,
@@ -272,7 +276,7 @@ export class ArrowFunctionExpressionGenerator extends BaseGenerator {
272276
return "string";
273277
}
274278
if (bodyTyped.type === "binary") {
275-
const binExpr = body as { type: string; op: string; left: unknown; right: unknown };
279+
const binExpr = body as BinaryNode;
276280
if (binExpr.op === "+") {
277281
const leftType = this.inferReturnTypeFromBody(binExpr.left as ArrowFunctionNode["body"]);
278282
const rightType = this.inferReturnTypeFromBody(binExpr.right as ArrowFunctionNode["body"]);
@@ -310,42 +314,38 @@ export class ArrowFunctionExpressionGenerator extends BaseGenerator {
310314
}
311315
}
312316
if (bodyTyped.type === "block") {
313-
const blockTyped = body as { type: string; statements: unknown[] };
317+
const blockTyped = body as BlockStatement;
314318
const blockStatements = blockTyped.statements;
315319
if (blockStatements) {
316320
for (let i = 0; i < blockStatements.length; i++) {
317321
const stmt = blockStatements[i];
318-
const stmtTyped = stmt as { type: string; value: unknown };
319-
if (stmtTyped.type === "return" && stmtTyped.value) {
320-
const returnValue = stmtTyped.value;
321-
const returnValueTyped = returnValue as { type: string };
322-
if (returnValueTyped.type === "object") {
323-
return "object";
324-
}
325-
if (
326-
returnValueTyped.type === "string" ||
327-
returnValueTyped.type === "string_literal" ||
328-
returnValueTyped.type === "template_literal"
329-
) {
330-
return "string";
322+
const stmtBase = stmt as { type: string };
323+
if (stmtBase.type === "return") {
324+
const stmtTyped = stmt as ReturnStatement;
325+
if (stmtTyped.value) {
326+
const returnValueTyped = stmtTyped.value as { type: string };
327+
if (returnValueTyped.type === "object") {
328+
return "object";
329+
}
330+
if (
331+
returnValueTyped.type === "string" ||
332+
returnValueTyped.type === "string_literal" ||
333+
returnValueTyped.type === "template_literal"
334+
) {
335+
return "string";
336+
}
331337
}
332338
}
333-
if (stmtTyped.type === "if") {
334-
const ifStmt = stmt as {
335-
type: string;
336-
condition: unknown;
337-
thenBlock: unknown;
338-
elseBlock: unknown;
339-
};
340-
const thenBlock = ifStmt.thenBlock as { type: string; statements: unknown[] };
339+
if (stmtBase.type === "if") {
340+
const ifStmt = stmt as IfStatement;
341+
const thenBlock = ifStmt.thenBlock;
341342
const thenBlockStatements = thenBlock ? thenBlock.statements : null;
342343
if (thenBlockStatements) {
343344
for (let j = 0; j < thenBlockStatements.length; j++) {
344345
const innerStmt = thenBlockStatements[j];
345-
const innerStmtTyped = innerStmt as { type: string; value: unknown };
346+
const innerStmtTyped = innerStmt as ReturnStatement;
346347
if (innerStmtTyped.type === "return" && innerStmtTyped.value) {
347-
const innerReturnValue = innerStmtTyped.value;
348-
const innerReturnValueTyped = innerReturnValue as { type: string };
348+
const innerReturnValueTyped = innerStmtTyped.value as { type: string };
349349
if (innerReturnValueTyped.type === "object") {
350350
return "object";
351351
}

src/codegen/expressions/conditionals.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* - Phi node to merge results
1010
*/
1111

12-
import { ConditionalExpressionNode, Expression } from "../../ast/types.js";
12+
import { ConditionalExpressionNode, Expression, ArrayNode } from "../../ast/types.js";
1313
import { IGeneratorContext } from "../infrastructure/generator-context.js";
1414

1515
export class ConditionalExpressionGenerator {
@@ -69,7 +69,7 @@ export class ConditionalExpressionGenerator {
6969

7070
this.emit(`${falseLabel}:`);
7171
const savedExpectedType = this.ctx.getExpectedArrayElementType();
72-
const falseExprTyped = expr.alternate as { type: string; elements?: Expression[] };
72+
const falseExprTyped = expr.alternate as ArrayNode;
7373
if (
7474
falseExprTyped.type === "array" &&
7575
(!falseExprTyped.elements || falseExprTyped.elements.length === 0)

src/codegen/expressions/literals.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,8 @@ export class LiteralExpressionGenerator {
227227
throw new Error("new RegExp() requires at least 1 argument");
228228
}
229229

230-
const patternArg = args[0] as { type: string; value?: string };
231-
const flagsArg = args.length > 1 ? (args[1] as { type: string; value?: string }) : null;
230+
const patternArg = args[0] as StringNode;
231+
const flagsArg = args.length > 1 ? (args[1] as StringNode) : null;
232232

233233
let flags = "";
234234
if (flagsArg && flagsArg.type === "string" && flagsArg.value !== undefined) {

src/codegen/expressions/method-calls/class-dispatch.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
InterfaceField,
99
FunctionNode,
1010
FunctionParameter,
11+
IndexAccessNode,
1112
} from "../../../ast/types.js";
1213
import type { MethodCallGeneratorContext } from "../method-calls.js";
1314

@@ -672,7 +673,7 @@ export function handleClassMethods(
672673
}
673674
}
674675
} else if (exprObjBase.type === "index_access") {
675-
const indexAccess = expr.object as { type: string; object: Expression; index: Expression };
676+
const indexAccess = expr.object as IndexAccessNode;
676677
const baseExpr = indexAccess.object;
677678
const baseExprBase = baseExpr as ExprBase;
678679
if (baseExprBase.type === "member_access") {

src/codegen/expressions/method-calls/console.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Expression, MethodCallNode } from "../../../ast/types.js";
1+
import { Expression, MethodCallNode, StringNode } from "../../../ast/types.js";
22
import type { MethodCallGeneratorContext } from "../method-calls.js";
33

44
function emitPrint(
@@ -163,16 +163,15 @@ function emitSingleArg(
163163
arg: Expression,
164164
params: string[],
165165
): void {
166-
const argTyped = arg as { type: string; value: string | number };
167-
168-
if (argTyped.type === "string") {
169-
const strValue = argTyped.value as string;
166+
if (arg.type === "string") {
167+
const strNode = arg as StringNode;
168+
const strValue = strNode.value;
170169
const strConstPtr = ctx.stringGen.doCreateStringConstant(strValue);
171170
emitPrintStrNoNl(ctx, useStderr, strConstPtr);
172171
return;
173172
}
174173

175-
if (argTyped.type === "number") {
174+
if (arg.type === "number") {
176175
const argValue = ctx.generateExpression(arg, params);
177176
emitPrintNumNoNl(ctx, useStderr, argValue);
178177
return;

src/codegen/expressions/method-calls/string-methods.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ export function handleReplace(
546546
const replaceArg = expr.args[1];
547547

548548
if (searchArg.type === "regex") {
549-
const regexNode = searchArg as { type: string; pattern: string; flags: string };
549+
const regexNode = searchArg as RegexNode;
550550
const isGlobal = regexNode.flags.indexOf("g") !== -1;
551551
const searchStr = ctx.stringGen.doGenerateGlobalString(regexNode.pattern);
552552
const replaceStr = ctx.generateExpression(replaceArg, params);

src/codegen/expressions/operators/binary.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Expression, SourceLocation } from "../../../ast/types.js";
1+
import { Expression, SourceLocation, NumberNode } from "../../../ast/types.js";
22
import type { IStringGenerator } from "../../infrastructure/generator-context.js";
33

44
interface ControlFlowGeneratorLike {
@@ -142,7 +142,7 @@ export class BinaryExpressionGenerator {
142142
}
143143

144144
private isKnownInteger(expr: Expression): boolean {
145-
const exprTyped = expr as { type: string; value?: number };
145+
const exprTyped = expr as NumberNode;
146146
if (exprTyped.type === "number" && typeof exprTyped.value === "number") {
147147
return Number.isInteger(exprTyped.value);
148148
}

src/codegen/expressions/operators/unary.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export class UnaryExpressionGenerator {
7171
if (operand.type !== "variable") {
7272
return this.ctx.emitError("Post-increment/decrement requires a variable operand");
7373
}
74-
const operandVar = operand as { type: string; name: string };
74+
const operandVar = operand as VariableNode;
7575
const varName = operandVar.name;
7676
const allocaReg = this.ctx.getVariableAlloca(varName);
7777
if (!allocaReg) {
@@ -115,7 +115,7 @@ export class UnaryExpressionGenerator {
115115
if (operand.type !== "variable") {
116116
return this.ctx.emitError("Pre-increment/decrement requires a variable operand");
117117
}
118-
const operandVarPre = operand as { type: string; name: string };
118+
const operandVarPre = operand as VariableNode;
119119
const varName = operandVarPre.name;
120120
const allocaReg = this.ctx.getVariableAlloca(varName);
121121
if (!allocaReg) {

src/codegen/expressions/templates.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* - With interpolation: `Hello ${name}` -> concatenate "Hello " with name value
1515
*/
1616

17-
import { Expression, TemplateLiteralNode } from "../../ast/types.js";
17+
import { Expression, TemplateLiteralNode, StringNode } from "../../ast/types.js";
1818
import { IGeneratorContext } from "../infrastructure/generator-context.js";
1919
import {
2020
createStringConstant,
@@ -59,7 +59,7 @@ export class TemplateLiteralGenerator {
5959
}
6060

6161
if (expr.parts.length === 1) {
62-
const firstPart = expr.parts[0] as { type: string; value?: string };
62+
const firstPart = expr.parts[0] as StringNode;
6363
if (firstPart.type === "string") {
6464
return this.ctx.stringGen.doCreateStringConstant(firstPart.value || "");
6565
}
@@ -72,7 +72,7 @@ export class TemplateLiteralGenerator {
7272
const part = expr.parts[_tpi];
7373
let partValue: string;
7474

75-
const partAsObj = part as { type: string; value?: string };
75+
const partAsObj = part as StringNode;
7676
if (partAsObj.type === "string") {
7777
partValue = this.ctx.stringGen.doCreateStringConstant(partAsObj.value || "");
7878
} else {

0 commit comments

Comments
 (0)