From e0e01f794ea507ed976728df73e593f2a940b4ae Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 17 Nov 2024 17:39:36 +0100 Subject: [PATCH] fix dt compiler crash --- .../NotExpressionAndIfComparisonExprChanger.kt | 8 +++++--- .../compiler/astprocessing/VariousCleanups.kt | 4 ++-- compiler/test/ast/TestVariousCompilerAst.kt | 18 ++++++++++++++++++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/compiler/src/prog8/compiler/astprocessing/NotExpressionAndIfComparisonExprChanger.kt b/compiler/src/prog8/compiler/astprocessing/NotExpressionAndIfComparisonExprChanger.kt index d1d77073c..b321723ca 100644 --- a/compiler/src/prog8/compiler/astprocessing/NotExpressionAndIfComparisonExprChanger.kt +++ b/compiler/src/prog8/compiler/astprocessing/NotExpressionAndIfComparisonExprChanger.kt @@ -148,9 +148,11 @@ internal class NotExpressionAndIfComparisonExprChanger(val program: Program, val // not(~x) -> x!=0 if((expr.expression as? PrefixExpression)?.operator=="~") { val x = (expr.expression as PrefixExpression).expression - val dt = x.inferType(program).getOrElse { throw FatalAstException("invalid dt ${x.position}") } - val notZero = BinaryExpression(x, "!=", NumericLiteral(dt, 0.0, expr.position), expr.position) - return listOf(IAstModification.ReplaceNode(expr, notZero, parent)) + val dt = x.inferType(program).getOr(DataType.UNDEFINED) + if(dt != DataType.UNDEFINED) { + val notZero = BinaryExpression(x, "!=", NumericLiteral(dt, 0.0, expr.position), expr.position) + return listOf(IAstModification.ReplaceNode(expr, notZero, parent)) + } } // not X Y -> X Y diff --git a/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt b/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt index 6f66c32c9..898023082 100644 --- a/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt +++ b/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt @@ -58,8 +58,8 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter, return listOf(IAstModification.ReplaceNode(typecast, typecast.expression, parent)) if(parent is Assignment) { - val targetDt = parent.target.inferType(program).getOrElse { throw FatalAstException("invalid dt ${parent.target.position}") } - if(sourceDt istype targetDt) { + val targetDt = parent.target.inferType(program).getOr(DataType.UNDEFINED) + if(targetDt!=DataType.UNDEFINED && sourceDt istype targetDt) { // we can get rid of this typecast because the type is already the target type return listOf(IAstModification.ReplaceNode(typecast, typecast.expression, parent)) } diff --git a/compiler/test/ast/TestVariousCompilerAst.kt b/compiler/test/ast/TestVariousCompilerAst.kt index e843a2832..c172eb631 100644 --- a/compiler/test/ast/TestVariousCompilerAst.kt +++ b/compiler/test/ast/TestVariousCompilerAst.kt @@ -1,6 +1,7 @@ package prog8tests.ast import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.comparables.shouldBeGreaterThan import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldNotBe import io.kotest.matchers.string.shouldContain @@ -459,6 +460,23 @@ main { } context("various") { + test("no crash for all sorts of undefined variables in complex expression") { + val src = """ +%import floats + +main { + sub start() { + x_position = (((floats.cos(CORNER_ANGLE + theta) * distance_to_corner) + (position_offset as float)) * 256.0) as word + } +}""" + val errors = ErrorReporterForTests() + compileText(C64Target(), optimize=false, src, writeAssembly=false, errors = errors) shouldBe null + errors.errors.size shouldBeGreaterThan 1 + errors.clear() + compileText(C64Target(), optimize=true, src, writeAssembly=false, errors = errors) shouldBe null + errors.errors.size shouldBeGreaterThan 1 + } + test("symbol names in inline assembly blocks") { val names1 = InlineAssembly("""