From 75c6fb066d866e7c8a661c9116a6b8419221cac6 Mon Sep 17 00:00:00 2001 From: cs01 Date: Sun, 8 Mar 2026 13:04:39 -0700 Subject: [PATCH 1/2] fix: use getAllInterfaceFields in remaining sites, for..of loops, track fneg type --- .../expressions/access/chained-access.ts | 11 +++----- src/codegen/expressions/operators/unary.ts | 1 + src/codegen/llvm-generator.ts | 14 +++------- src/codegen/types/objects/class.ts | 26 +++++-------------- 4 files changed, 15 insertions(+), 37 deletions(-) diff --git a/src/codegen/expressions/access/chained-access.ts b/src/codegen/expressions/access/chained-access.ts index b7dc8e7d..c07b06b1 100644 --- a/src/codegen/expressions/access/chained-access.ts +++ b/src/codegen/expressions/access/chained-access.ts @@ -30,13 +30,10 @@ export function handleNestedInterfaceField( const keys: string[] = []; const tsTypes: string[] = []; const types: string[] = []; - if (nestedInterfaceDef.fields) { - for (let i = 0; i < nestedInterfaceDef.fields.length; i++) { - const f = nestedInterfaceDef.fields[i] as { name: string; type: string }; - keys.push(stripOptional(f.name)); - tsTypes.push(f.type); - types.push(tsTypeToLlvm(f.type)); - } + for (const f of ctx.getAllInterfaceFields(nestedInterfaceDef)) { + keys.push(stripOptional(f.name)); + tsTypes.push(f.type); + types.push(tsTypeToLlvm(f.type)); } ctx.setJsonObjectMetadata(fieldItem, { keys, types, tsTypes, interfaceType: undefined }); } diff --git a/src/codegen/expressions/operators/unary.ts b/src/codegen/expressions/operators/unary.ts index d20aaa0c..0299ffd2 100644 --- a/src/codegen/expressions/operators/unary.ts +++ b/src/codegen/expressions/operators/unary.ts @@ -194,6 +194,7 @@ export class UnaryExpressionGenerator { const dblOperand = this.ctx.ensureDouble(operand); const result = this.ctx.nextTemp(); this.ctx.emit(`${result} = fneg double ${dblOperand}`); + this.ctx.setVariableType(result, "double"); return result; } diff --git a/src/codegen/llvm-generator.ts b/src/codegen/llvm-generator.ts index bba64007..95c1cb82 100644 --- a/src/codegen/llvm-generator.ts +++ b/src/codegen/llvm-generator.ts @@ -696,13 +696,10 @@ export class LLVMGenerator extends BaseGenerator implements IGeneratorContext { const keys: string[] = []; const types: string[] = []; const tsTypes: string[] = []; - for (let i = 0; i < this.ast.interfaces.length; i++) { - const iface = this.ast.interfaces[i]; + for (const iface of this.ast.interfaces) { if (!iface) continue; if (iface.name === cleanName) { - if (!iface.fields) continue; - for (let j = 0; j < iface.fields.length; j++) { - const field = iface.fields[j] as InterfaceField; + for (const field of this.getAllInterfaceFields(iface)) { if (!field) continue; let fieldName = field.name; if (fieldName.endsWith("?")) { @@ -805,13 +802,10 @@ export class LLVMGenerator extends BaseGenerator implements IGeneratorContext { return null; } if (!this.ast || !this.ast.interfaces) return null; - for (let i = 0; i < this.ast.interfaces.length; i++) { - const iface = this.ast.interfaces[i]; + for (const iface of this.ast.interfaces) { if (!iface) continue; if (iface.name === interfaceName) { - if (!iface.fields) continue; - for (let j = 0; j < iface.fields.length; j++) { - const f = iface.fields[j] as InterfaceField; + for (const f of this.getAllInterfaceFields(iface)) { if (!f) continue; let fName = f.name; if (fName.endsWith("?")) { diff --git a/src/codegen/types/objects/class.ts b/src/codegen/types/objects/class.ts index fa1fa5ef..f92259fe 100644 --- a/src/codegen/types/objects/class.ts +++ b/src/codegen/types/objects/class.ts @@ -1672,28 +1672,15 @@ export class ClassGenerator { return { keys: [], types: [] }; } - const firstInterface = interfaces[0] as { - name: string; - extends: string[]; - fields: { name: string; type: string }[]; - methods: { name: string }[]; - }; - const firstFields = firstInterface.fields; + const firstIface = interfaces[0] as InterfaceDeclaration; + const firstFields = this.ctx.getAllInterfaceFields(firstIface); const commonFields: CommonField[] = []; - for (let fi = 0; fi < firstFields.length; fi++) { - const field = firstFields[fi] as { name: string; type: string }; + for (const field of firstFields) { let isCommon = true; - for (let ii = 0; ii < interfaces.length; ii++) { - const ifaceTyped = interfaces[ii] as { - name: string; - extends: string[]; - fields: { name: string; type: string }[]; - methods: { name: string }[]; - }; + for (const ifaceTyped of interfaces) { let found = false; - for (let fj = 0; fj < ifaceTyped.fields.length; fj++) { - const f = ifaceTyped.fields[fj] as { name: string; type: string }; + for (const f of this.ctx.getAllInterfaceFields(ifaceTyped as InterfaceDeclaration)) { if (f.name === field.name && this.areTypesCompatible(f.type, field.type)) { found = true; break; @@ -1711,8 +1698,7 @@ export class ClassGenerator { const keys: string[] = []; const types: string[] = []; - for (let fi = 0; fi < commonFields.length; fi++) { - const f = commonFields[fi] as CommonField; + for (const f of commonFields) { keys.push(stripOptional(f.name)); types.push(this.fieldTypeToLlvm(f.type)); } From 4ff833fe0c5dff9185d56608b68d201563683bf7 Mon Sep 17 00:00:00 2001 From: cs01 Date: Sun, 8 Mar 2026 13:17:25 -0700 Subject: [PATCH 2/2] revert: undo unsafe getAllInterfaceFields cast in class.ts and unary fneg type tracking --- src/codegen/expressions/operators/unary.ts | 1 - src/codegen/types/objects/class.ts | 26 +++++++++++++++++----- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/codegen/expressions/operators/unary.ts b/src/codegen/expressions/operators/unary.ts index 0299ffd2..d20aaa0c 100644 --- a/src/codegen/expressions/operators/unary.ts +++ b/src/codegen/expressions/operators/unary.ts @@ -194,7 +194,6 @@ export class UnaryExpressionGenerator { const dblOperand = this.ctx.ensureDouble(operand); const result = this.ctx.nextTemp(); this.ctx.emit(`${result} = fneg double ${dblOperand}`); - this.ctx.setVariableType(result, "double"); return result; } diff --git a/src/codegen/types/objects/class.ts b/src/codegen/types/objects/class.ts index f92259fe..fa1fa5ef 100644 --- a/src/codegen/types/objects/class.ts +++ b/src/codegen/types/objects/class.ts @@ -1672,15 +1672,28 @@ export class ClassGenerator { return { keys: [], types: [] }; } - const firstIface = interfaces[0] as InterfaceDeclaration; - const firstFields = this.ctx.getAllInterfaceFields(firstIface); + const firstInterface = interfaces[0] as { + name: string; + extends: string[]; + fields: { name: string; type: string }[]; + methods: { name: string }[]; + }; + const firstFields = firstInterface.fields; const commonFields: CommonField[] = []; - for (const field of firstFields) { + for (let fi = 0; fi < firstFields.length; fi++) { + const field = firstFields[fi] as { name: string; type: string }; let isCommon = true; - for (const ifaceTyped of interfaces) { + for (let ii = 0; ii < interfaces.length; ii++) { + const ifaceTyped = interfaces[ii] as { + name: string; + extends: string[]; + fields: { name: string; type: string }[]; + methods: { name: string }[]; + }; let found = false; - for (const f of this.ctx.getAllInterfaceFields(ifaceTyped as InterfaceDeclaration)) { + for (let fj = 0; fj < ifaceTyped.fields.length; fj++) { + const f = ifaceTyped.fields[fj] as { name: string; type: string }; if (f.name === field.name && this.areTypesCompatible(f.type, field.type)) { found = true; break; @@ -1698,7 +1711,8 @@ export class ClassGenerator { const keys: string[] = []; const types: string[] = []; - for (const f of commonFields) { + for (let fi = 0; fi < commonFields.length; fi++) { + const f = commonFields[fi] as CommonField; keys.push(stripOptional(f.name)); types.push(this.fieldTypeToLlvm(f.type)); }