diff --git a/src/codegen/types/objects/class.ts b/src/codegen/types/objects/class.ts index e46ec41d..f2df64d7 100644 --- a/src/codegen/types/objects/class.ts +++ b/src/codegen/types/objects/class.ts @@ -79,8 +79,7 @@ export class ClassGenerator { } } for (let i = 0; i < classNode.fields.length; i++) { - // Static fields are globals, not part of the instance struct - if (classNode.fields[i].isStatic) continue; + if ((classNode.fields[i] as ClassField).isStatic) continue; allFields.push(classNode.fields[i]); } return allFields; @@ -524,7 +523,7 @@ export class ClassGenerator { // Emit static fields as LLVM globals for (let fi = 0; fi < classNode.fields.length; fi++) { - const field = classNode.fields[fi]; + const field = classNode.fields[fi] as ClassField; if (!field || !field.isStatic) continue; const globalName = `@${this.ctx.mangleUserName(className)}_${field.name}`; const llvmType = this.fieldToLlvmType(field); @@ -686,7 +685,7 @@ export class ClassGenerator { } for (let fi = 0; fi < fields.length; fi++) { - const classField = fields[fi]; + const classField = fields[fi] as ClassField; if (!classField) continue; if (!classField.initializer) continue; const initType = classField.initializer.type; @@ -809,7 +808,7 @@ export class ClassGenerator { this.ctx.setThisPointer(objPtr); this.ctx.setCurrentClassName(className); for (let fi = 0; fi < classFields.length; fi++) { - const cf = classFields[fi]; + const cf = classFields[fi] as ClassField; if (!cf) continue; if (!cf.initializer) continue; const initType = cf.initializer.type; diff --git a/src/parser-native/transformer.ts b/src/parser-native/transformer.ts index df1a2cbf..a3469d05 100644 --- a/src/parser-native/transformer.ts +++ b/src/parser-native/transformer.ts @@ -2796,7 +2796,13 @@ function transformClassDeclaration(node: TreeSitterNode): ClassNode | null { } } if (alreadyExists === false) { - const newField: ClassField = { name: propName, fieldType, tsType }; + const newField: ClassField = { + name: propName, + fieldType, + tsType, + initializer: undefined, + isStatic: false, + }; fields.push(newField); } } @@ -2872,11 +2878,8 @@ function transformClassField(node: TreeSitterNode): ClassField | null { } } - const result: ClassField = { name, fieldType, tsType }; - if (isStatic) result.isStatic = true; - if (valueNode) { - result.initializer = transformExpression(valueNode); - } + const initializer = valueNode ? transformExpression(valueNode) : undefined; + const result: ClassField = { name, fieldType, tsType, initializer, isStatic }; return result; } diff --git a/src/parser-ts/handlers/declarations.ts b/src/parser-ts/handlers/declarations.ts index d7eac1bb..a1dbf83a 100644 --- a/src/parser-ts/handlers/declarations.ts +++ b/src/parser-ts/handlers/declarations.ts @@ -190,14 +190,8 @@ function transformPropertyDeclaration( } const isStatic = node.modifiers?.some((m) => m.kind === ts.SyntaxKind.StaticKeyword) ?? false; - const result: ClassField = { name, fieldType, tsType }; - if (node.initializer) { - result.initializer = transformExpression(node.initializer, checker); - } - if (isStatic) { - result.isStatic = true; - } - return result; + const initializer = node.initializer ? transformExpression(node.initializer, checker) : undefined; + return { name, fieldType, tsType, initializer, isStatic }; } function transformMethodDeclaration( @@ -298,7 +292,13 @@ function transformConstructorDeclaration( tsType = typeStr; } } - parameterProperties.push({ name, fieldType, tsType }); + parameterProperties.push({ + name, + fieldType, + tsType, + initializer: undefined, + isStatic: false, + }); } } diff --git a/tests/fixtures/arrays/boolean-array-basic.ts b/tests/fixtures/arrays/boolean-array-basic.ts new file mode 100644 index 00000000..a816dc38 --- /dev/null +++ b/tests/fixtures/arrays/boolean-array-basic.ts @@ -0,0 +1,4 @@ +const flags: boolean[] = [true, false, true]; +if (flags[0] === true && flags[1] === false && flags[2] === true) { + console.log("TEST_PASSED"); +} diff --git a/tests/fixtures/arrays/boolean-array-index-assign.ts b/tests/fixtures/arrays/boolean-array-index-assign.ts new file mode 100644 index 00000000..1a0b455e --- /dev/null +++ b/tests/fixtures/arrays/boolean-array-index-assign.ts @@ -0,0 +1,6 @@ +const flags: boolean[] = [false, false, false, false]; +flags[0] = true; +flags[2] = true; +if (flags[0] === true && flags[1] === false && flags[2] === true && flags[3] === false) { + console.log("TEST_PASSED"); +} diff --git a/tests/fixtures/arrays/boolean-array-push.ts b/tests/fixtures/arrays/boolean-array-push.ts new file mode 100644 index 00000000..5d9e7b5b --- /dev/null +++ b/tests/fixtures/arrays/boolean-array-push.ts @@ -0,0 +1,7 @@ +const flags: boolean[] = []; +flags.push(true); +flags.push(false); +flags.push(true); +if (flags.length === 3 && flags[0] === true && flags[1] === false) { + console.log("TEST_PASSED"); +} diff --git a/tests/fixtures/arrays/boolean-array-sieve.ts b/tests/fixtures/arrays/boolean-array-sieve.ts new file mode 100644 index 00000000..4d1fb6f6 --- /dev/null +++ b/tests/fixtures/arrays/boolean-array-sieve.ts @@ -0,0 +1,39 @@ +const limit = 50; +const sieve: boolean[] = []; +let i = 0; +while (i < limit) { + sieve.push(true); + i = i + 1; +} +sieve[0] = false; +sieve[1] = false; + +i = 2; +while (i * i < limit) { + if (sieve[i]) { + let j = i * i; + while (j < limit) { + sieve[j] = false; + j = j + i; + } + } + i = i + 1; +} + +let primes = ""; +i = 2; +while (i < limit) { + if (sieve[i]) { + if (primes.length > 0) { + primes = primes + ","; + } + primes = primes + i.toString(); + } + i = i + 1; +} + +if (primes === "2,3,5,7,11,13,17,19,23,29,31,37,41,43,47") { + console.log("TEST_PASSED"); +} else { + console.log("FAIL: " + primes); +} diff --git a/tests/fixtures/classes/class-field-init.ts b/tests/fixtures/classes/class-field-init.ts index 049dea45..8e390e1d 100644 --- a/tests/fixtures/classes/class-field-init.ts +++ b/tests/fixtures/classes/class-field-init.ts @@ -1,5 +1,3 @@ -// @test-skip -// native compiler's tree-sitter parser doesn't populate field initializers yet class Config { maxRetries: number = 5; name: string = "default"; diff --git a/tests/fixtures/control-flow/switch-string-toplevel.ts b/tests/fixtures/control-flow/switch-string-toplevel.ts index 2abbf22e..3490ec9f 100644 --- a/tests/fixtures/control-flow/switch-string-toplevel.ts +++ b/tests/fixtures/control-flow/switch-string-toplevel.ts @@ -1,4 +1,5 @@ // @test-skip +// native switch string matching fails in self-hosted stages on linux const s = "b"; switch (s) { case "a":