From 8d3d5f726a4a596f1c0ef2a740428f299fb6b3fb Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 29 Apr 2021 00:11:41 +0200 Subject: [PATCH] removed Datatype.STRUCT --- .../compiler/BeforeAsmGenerationAstChanger.kt | 8 ++-- .../compiler/astprocessing/AstChecker.kt | 26 ++++++------ .../astprocessing/LiteralsToAutoVars.kt | 2 +- .../astprocessing/StatementReorderer.kt | 4 +- .../compiler/astprocessing/TypecastsAdder.kt | 12 +++--- .../astprocessing/VerifyFunctionArgTypes.kt | 2 +- .../compiler/functions/BuiltinFunctions.kt | 12 +++--- .../compiler/target/cpu6502/codegen/AsmGen.kt | 3 +- .../cpu6502/codegen/BuiltinFunctionsAsmGen.kt | 40 +++++++++---------- .../cpu6502/codegen/ExpressionsAsmGen.kt | 14 +++---- .../target/cpu6502/codegen/ForLoopsAsmGen.kt | 8 ++-- .../cpu6502/codegen/FunctionCallAsmGen.kt | 4 +- .../cpu6502/codegen/PostIncrDecrAsmGen.kt | 4 +- .../codegen/assignment/AsmAssignment.kt | 12 +++--- .../codegen/assignment/AssignmentAsmGen.kt | 6 +-- .../assignment/AugmentableAssignmentAsmGen.kt | 6 +-- compiler/src/prog8/optimizer/CallGraph.kt | 2 +- .../optimizer/ConstantFoldingOptimizer.kt | 8 ++-- .../prog8/optimizer/ExpressionSimplifier.kt | 16 ++++---- .../src/prog8/optimizer/StatementOptimizer.kt | 2 +- compilerAst/src/prog8/ast/AstToSourceCode.kt | 1 - .../src/prog8/ast/antlr/Antr2Kotlin.kt | 12 +++--- compilerAst/src/prog8/ast/base/Base.kt | 4 +- .../prog8/ast/expressions/AstExpressions.kt | 19 +++++---- .../prog8/ast/expressions/InferredTypes.kt | 3 +- .../src/prog8/ast/statements/AstStatements.kt | 2 +- docs/source/todo.rst | 3 +- 27 files changed, 115 insertions(+), 120 deletions(-) diff --git a/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt b/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt index aaebf6ac2..ec6915200 100644 --- a/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt +++ b/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt @@ -147,7 +147,7 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, val errors: I // see if we can remove superfluous typecasts (outside of expressions) // such as casting byte<->ubyte, word<->uword // Also the special typecast of a reference type (str, array) to an UWORD will be changed into address-of. - val sourceDt = typecast.expression.inferType(program).typeOrElse(DataType.STRUCT) + val sourceDt = typecast.expression.inferType(program).typeOrElse(DataType.UNDEFINED) if (typecast.type in ByteDatatypes && sourceDt in ByteDatatypes || typecast.type in WordDatatypes && sourceDt in WordDatatypes) { if(typecast.parent !is Expression) { @@ -225,7 +225,7 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, val errors: I } // private fun addIfOperandVar(sub: Subroutine, side: String, operand: Expression): Triple { -// val dt = operand.inferType(program).typeOrElse(DataType.STRUCT) +// val dt = operand.inferType(program).typeOrElse(DataType.UNDEFINED) // val varname = "prog8_ifvar_${side}_${dt.name.toLowerCase()}" // val tgt = AssignTarget(IdentifierReference(listOf(varname), operand.position), null, null, operand.position) // val assign = Assignment(tgt, operand, operand.position) @@ -267,8 +267,8 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, val errors: I // if the datatype of the arguments of cmp() are different, cast the byte one to word. val arg1 = functionCallStatement.args[0] val arg2 = functionCallStatement.args[1] - val dt1 = arg1.inferType(program).typeOrElse(DataType.STRUCT) - val dt2 = arg2.inferType(program).typeOrElse(DataType.STRUCT) + val dt1 = arg1.inferType(program).typeOrElse(DataType.UNDEFINED) + val dt2 = arg2.inferType(program).typeOrElse(DataType.UNDEFINED) if(dt1 in ByteDatatypes) { if(dt2 in ByteDatatypes) return noModifications diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index 4942d688d..1d06e725f 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -78,7 +78,7 @@ internal class AstChecker(private val program: Program, if(!valueDt.isKnown) { errors.err("return value type mismatch or unknown symbol", returnStmt.value!!.position) } else { - if (expectedReturnValues[0] != valueDt.typeOrElse(DataType.STRUCT)) + if (expectedReturnValues[0] != valueDt.typeOrElse(DataType.UNDEFINED)) errors.err("type $valueDt of return value doesn't match subroutine's return type ${expectedReturnValues[0]}", returnStmt.value!!.position) } } @@ -86,7 +86,7 @@ internal class AstChecker(private val program: Program, } override fun visit(ifStatement: IfStatement) { - if(ifStatement.condition.inferType(program).typeOrElse(DataType.STRUCT) !in IntegerDatatypes) + if(ifStatement.condition.inferType(program).typeOrElse(DataType.UNDEFINED) !in IntegerDatatypes) errors.err("condition value should be an integer type", ifStatement.condition.position) super.visit(ifStatement) } @@ -386,13 +386,13 @@ internal class AstChecker(private val program: Program, } override fun visit(untilLoop: UntilLoop) { - if(untilLoop.condition.inferType(program).typeOrElse(DataType.STRUCT) !in IntegerDatatypes) + if(untilLoop.condition.inferType(program).typeOrElse(DataType.UNDEFINED) !in IntegerDatatypes) errors.err("condition value should be an integer type", untilLoop.condition.position) super.visit(untilLoop) } override fun visit(whileLoop: WhileLoop) { - if(whileLoop.condition.inferType(program).typeOrElse(DataType.STRUCT) !in IntegerDatatypes) + if(whileLoop.condition.inferType(program).typeOrElse(DataType.UNDEFINED) !in IntegerDatatypes) errors.err("condition value should be an integer type", whileLoop.condition.position) super.visit(whileLoop) } @@ -421,7 +421,7 @@ internal class AstChecker(private val program: Program, val targetDt = assignment.target.inferType(program) val valueDt = assignment.value.inferType(program) if(valueDt.isKnown && !(valueDt isAssignableTo targetDt)) { - if(targetDt.typeOrElse(DataType.STRUCT) in IterableDatatypes) + if(targetDt.typeOrElse(DataType.UNDEFINED) in IterableDatatypes) errors.err("cannot assign value to string or array", assignment.value.position) else if(!(valueDt.istype(DataType.STR) && targetDt.istype(DataType.UWORD))) errors.err("type of value doesn't match target", assignment.value.position) @@ -735,11 +735,11 @@ internal class AstChecker(private val program: Program, override fun visit(array: ArrayLiteralValue) { if(array.type.isKnown) { - if (!compilerOptions.floats && array.type.typeOrElse(DataType.STRUCT) in setOf(DataType.FLOAT, DataType.ARRAY_F)) { + if (!compilerOptions.floats && array.type.typeOrElse(DataType.UNDEFINED) in setOf(DataType.FLOAT, DataType.ARRAY_F)) { errors.err("floating point used, but that is not enabled via options", array.position) } val arrayspec = ArrayIndex.forArray(array) - checkValueTypeAndRangeArray(array.type.typeOrElse(DataType.STRUCT), arrayspec, array) + checkValueTypeAndRangeArray(array.type.typeOrElse(DataType.UNDEFINED), arrayspec, array) } fun isPassByReferenceElement(e: Expression): Boolean { @@ -771,7 +771,7 @@ internal class AstChecker(private val program: Program, if(!idt.isKnown) return // any error should be reported elsewhere - val dt = idt.typeOrElse(DataType.STRUCT) + val dt = idt.typeOrElse(DataType.UNDEFINED) if(expr.operator=="-") { if (dt != DataType.BYTE && dt != DataType.WORD && dt != DataType.FLOAT) { errors.err("can only take negative of a signed number type", expr.position) @@ -796,8 +796,8 @@ internal class AstChecker(private val program: Program, if(!leftIDt.isKnown || !rightIDt.isKnown) return // hopefully this error will be detected elsewhere - val leftDt = leftIDt.typeOrElse(DataType.STRUCT) - val rightDt = rightIDt.typeOrElse(DataType.STRUCT) + val leftDt = leftIDt.typeOrElse(DataType.UNDEFINED) + val rightDt = rightIDt.typeOrElse(DataType.UNDEFINED) when(expr.operator){ "/", "%" -> { @@ -998,7 +998,7 @@ internal class AstChecker(private val program: Program, errors.err("swap requires 2 variables, not constant value(s)", position) else if(args[0] isSameAs args[1]) errors.err("swap should have 2 different args", position) - else if(dt1.typeOrElse(DataType.STRUCT) !in NumericDatatypes) + else if(dt1.typeOrElse(DataType.UNDEFINED) !in NumericDatatypes) errors.err("swap requires args of numerical type", position) } else if(target.name=="all" || target.name=="any") { @@ -1103,7 +1103,7 @@ internal class AstChecker(private val program: Program, } override fun visit(whenStatement: WhenStatement) { - val conditionType = whenStatement.condition.inferType(program).typeOrElse(DataType.STRUCT) + val conditionType = whenStatement.condition.inferType(program).typeOrElse(DataType.UNDEFINED) if(conditionType !in IntegerDatatypes) errors.err("when condition must be an integer value", whenStatement.position) val tally = mutableSetOf() @@ -1135,7 +1135,7 @@ internal class AstChecker(private val program: Program, when { constvalue == null -> errors.err("choice value must be a constant", whenChoice.position) constvalue.type !in IntegerDatatypes -> errors.err("choice value must be a byte or word", whenChoice.position) - constvalue.type != conditionType.typeOrElse(DataType.STRUCT) -> errors.err("choice value datatype differs from condition value", whenChoice.position) + constvalue.type != conditionType.typeOrElse(DataType.UNDEFINED) -> errors.err("choice value datatype differs from condition value", whenChoice.position) } } } else { diff --git a/compiler/src/prog8/compiler/astprocessing/LiteralsToAutoVars.kt b/compiler/src/prog8/compiler/astprocessing/LiteralsToAutoVars.kt index 4dbf449d6..705939bcf 100644 --- a/compiler/src/prog8/compiler/astprocessing/LiteralsToAutoVars.kt +++ b/compiler/src/prog8/compiler/astprocessing/LiteralsToAutoVars.kt @@ -38,7 +38,7 @@ internal class LiteralsToAutoVars(private val program: Program) : AstWalker() { val arrayDt = array.guessDatatype(program) if(arrayDt.isKnown) { // this array literal is part of an expression, turn it into an identifier reference - val litval2 = array.cast(arrayDt.typeOrElse(DataType.STRUCT)) + val litval2 = array.cast(arrayDt.typeOrElse(DataType.UNDEFINED)) if(litval2!=null) { val vardecl2 = VarDecl.createAuto(litval2) val identifier = IdentifierReference(listOf(vardecl2.name), vardecl2.position) diff --git a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt index 4ed174968..b88acd189 100644 --- a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt +++ b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt @@ -124,7 +124,7 @@ internal class StatementReorderer(val program: Program, val errors: IErrorReport is Assignment -> { val targetDt = parent.target.inferType(program) if(leftDt != targetDt) { - val cast = TypecastExpression(expr.left, targetDt.typeOrElse(DataType.STRUCT), true, parent.position) + val cast = TypecastExpression(expr.left, targetDt.typeOrElse(DataType.UNDEFINED), true, parent.position) return listOf(IAstModification.ReplaceNode(expr.left, cast, expr)) } } @@ -208,7 +208,7 @@ internal class StatementReorderer(val program: Program, val errors: IErrorReport val valueType = assignment.value.inferType(program) val targetType = assignment.target.inferType(program) - if(targetType.typeOrElse(DataType.STRUCT) in ArrayDatatypes && valueType.typeOrElse(DataType.STRUCT) in ArrayDatatypes ) { + if(targetType.typeOrElse(DataType.UNDEFINED) in ArrayDatatypes && valueType.typeOrElse(DataType.UNDEFINED) in ArrayDatatypes ) { if (assignment.value is ArrayLiteralValue) { errors.err("cannot assign array literal here, use separate assignment per element", assignment.position) } else { diff --git a/compiler/src/prog8/compiler/astprocessing/TypecastsAdder.kt b/compiler/src/prog8/compiler/astprocessing/TypecastsAdder.kt index cda4bef5b..9043b38b3 100644 --- a/compiler/src/prog8/compiler/astprocessing/TypecastsAdder.kt +++ b/compiler/src/prog8/compiler/astprocessing/TypecastsAdder.kt @@ -25,7 +25,7 @@ class TypecastsAdder(val program: Program, val errors: IErrorReporter) : AstWalk if(!valueDt.istype(decl.datatype)) { // don't add a typecast on an array initializer value - if(valueDt.typeOrElse(DataType.STRUCT) in IntegerDatatypes && decl.datatype in ArrayDatatypes) + if(valueDt.typeOrElse(DataType.UNDEFINED) in IntegerDatatypes && decl.datatype in ArrayDatatypes) return noModifications // don't add a typecast if the initializer value is inherently not assignable @@ -47,7 +47,7 @@ class TypecastsAdder(val program: Program, val errors: IErrorReporter) : AstWalk val rightDt = expr.right.inferType(program) if(leftDt.isKnown && rightDt.isKnown && leftDt!=rightDt) { // determine common datatype and add typecast as required to make left and right equal types - val (commonDt, toFix) = BinaryExpression.commonDatatype(leftDt.typeOrElse(DataType.STRUCT), rightDt.typeOrElse(DataType.STRUCT), expr.left, expr.right) + val (commonDt, toFix) = BinaryExpression.commonDatatype(leftDt.typeOrElse(DataType.UNDEFINED), rightDt.typeOrElse(DataType.UNDEFINED), expr.left, expr.right) if(toFix!=null) { return when { toFix===expr.left -> listOf(IAstModification.ReplaceNode( @@ -66,8 +66,8 @@ class TypecastsAdder(val program: Program, val errors: IErrorReporter) : AstWalk val valueItype = assignment.value.inferType(program) val targetItype = assignment.target.inferType(program) if(targetItype.isKnown && valueItype.isKnown) { - val targettype = targetItype.typeOrElse(DataType.STRUCT) - val valuetype = valueItype.typeOrElse(DataType.STRUCT) + val targettype = targetItype.typeOrElse(DataType.UNDEFINED) + val valuetype = valueItype.typeOrElse(DataType.UNDEFINED) if (valuetype != targettype) { if (valuetype isAssignableTo targettype) { if(valuetype in IterableDatatypes && targettype==DataType.UWORD) @@ -126,7 +126,7 @@ class TypecastsAdder(val program: Program, val errors: IErrorReporter) : AstWalk sub.parameters.zip(call.args).forEachIndexed { index, pair -> val argItype = pair.second.inferType(program) if(argItype.isKnown) { - val argtype = argItype.typeOrElse(DataType.STRUCT) + val argtype = argItype.typeOrElse(DataType.UNDEFINED) val requiredType = pair.first.type if (requiredType != argtype) { if (argtype isAssignableTo requiredType) { @@ -159,7 +159,7 @@ class TypecastsAdder(val program: Program, val errors: IErrorReporter) : AstWalk func.parameters.zip(call.args).forEachIndexed { index, pair -> val argItype = pair.second.inferType(program) if (argItype.isKnown) { - val argtype = argItype.typeOrElse(DataType.STRUCT) + val argtype = argItype.typeOrElse(DataType.UNDEFINED) if (pair.first.possibleDatatypes.all { argtype != it }) { for (possibleType in pair.first.possibleDatatypes) { if (argtype isAssignableTo possibleType) { diff --git a/compiler/src/prog8/compiler/astprocessing/VerifyFunctionArgTypes.kt b/compiler/src/prog8/compiler/astprocessing/VerifyFunctionArgTypes.kt index edaaab6ba..234f67040 100644 --- a/compiler/src/prog8/compiler/astprocessing/VerifyFunctionArgTypes.kt +++ b/compiler/src/prog8/compiler/astprocessing/VerifyFunctionArgTypes.kt @@ -44,7 +44,7 @@ class VerifyFunctionArgTypes(val program: Program) : IAstVisitor { val firstUnknownDt = argITypes.indexOfFirst { it.isUnknown } if(firstUnknownDt>=0) return "argument ${firstUnknownDt+1} invalid argument type" - val argtypes = argITypes.map { it.typeOrElse(DataType.STRUCT) } + val argtypes = argITypes.map { it.typeOrElse(DataType.UNDEFINED) } val target = call.target.targetStatement(program) if (target is Subroutine) { if(call.args.size != target.parameters.size) diff --git a/compiler/src/prog8/compiler/functions/BuiltinFunctions.kt b/compiler/src/prog8/compiler/functions/BuiltinFunctions.kt index 55e154602..5e440b1a6 100644 --- a/compiler/src/prog8/compiler/functions/BuiltinFunctions.kt +++ b/compiler/src/prog8/compiler/functions/BuiltinFunctions.kt @@ -164,7 +164,7 @@ fun builtinFunctionReturnType(function: String, args: List, program: fun datatypeFromIterableArg(arglist: Expression): DataType { if(arglist is ArrayLiteralValue) { - val dt = arglist.value.map {it.inferType(program).typeOrElse(DataType.STRUCT)}.toSet() + val dt = arglist.value.map {it.inferType(program).typeOrElse(DataType.UNDEFINED)}.toSet() if(dt.any { it !in NumericDatatypes }) { throw FatalAstException("fuction $function only accepts array of numeric values") } @@ -178,7 +178,7 @@ fun builtinFunctionReturnType(function: String, args: List, program: val idt = arglist.inferType(program) if(!idt.isKnown) throw FatalAstException("couldn't determine type of iterable $arglist") - return when(val dt = idt.typeOrElse(DataType.STRUCT)) { + return when(val dt = idt.typeOrElse(DataType.UNDEFINED)) { DataType.STR, in NumericDatatypes -> dt in ArrayDatatypes -> ArrayElementTypes.getValue(dt) else -> throw FatalAstException("function '$function' requires one argument which is an iterable") @@ -195,7 +195,7 @@ fun builtinFunctionReturnType(function: String, args: List, program: return when (function) { "abs" -> { val dt = args.single().inferType(program) - return if(dt.typeOrElse(DataType.STRUCT) in NumericDatatypes) + return if(dt.typeOrElse(DataType.UNDEFINED) in NumericDatatypes) dt else InferredTypes.InferredType.unknown() @@ -300,13 +300,13 @@ private fun builtinSizeof(args: List, position: Position, program: P ?: throw CannotEvaluateException("sizeof", "no target") return when { - dt.typeOrElse(DataType.STRUCT) in ArrayDatatypes -> { + dt.typeOrElse(DataType.UNDEFINED) in ArrayDatatypes -> { val length = (target as VarDecl).arraysize!!.constIndex() ?: throw CannotEvaluateException("sizeof", "unknown array size") - val elementDt = ArrayElementTypes.getValue(dt.typeOrElse(DataType.STRUCT)) + val elementDt = ArrayElementTypes.getValue(dt.typeOrElse(DataType.UNDEFINED)) numericLiteral(memsizer.memorySize(elementDt) * length, position) } dt.istype(DataType.STR) -> throw SyntaxError("sizeof str is undefined, did you mean len?", position) - else -> NumericLiteralValue(DataType.UBYTE, memsizer.memorySize(dt.typeOrElse(DataType.STRUCT)), position) + else -> NumericLiteralValue(DataType.UBYTE, memsizer.memorySize(dt.typeOrElse(DataType.UNDEFINED)), position) } } else { throw SyntaxError("sizeof invalid argument type", position) diff --git a/compiler/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt b/compiler/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt index 64cdd4d21..9871ca5fa 100644 --- a/compiler/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt @@ -290,7 +290,6 @@ internal class AsmGen(private val program: Program, DataType.UWORD -> out("$name\t.word 0") DataType.WORD -> out("$name\t.sint 0") DataType.FLOAT -> out("$name\t.byte 0,0,0,0,0 ; float") - DataType.STRUCT -> {} // is flattened DataType.STR -> { val str = decl.value as StringLiteralValue outputStringvar(decl, compTarget.encodeString(str.value, str.altEncoding).plus(0)) @@ -990,7 +989,7 @@ internal class AsmGen(private val program: Program, val dt = stmt.iterations!!.inferType(program) if(!dt.isKnown) throw AssemblyError("unknown dt") - when (dt.typeOrElse(DataType.STRUCT)) { + when (dt.typeOrElse(DataType.UNDEFINED)) { in ByteDatatypes -> { assignExpressionToRegister(stmt.iterations!!, RegisterOrPair.A) repeatByteCountInA(null, repeatLabel, endLabel, stmt.body) diff --git a/compiler/src/prog8/compiler/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt b/compiler/src/prog8/compiler/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt index db1a4b6f2..e7b6bfa83 100644 --- a/compiler/src/prog8/compiler/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt @@ -177,8 +177,8 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val private fun funcCmp(fcall: IFunctionCall) { val arg1 = fcall.args[0] val arg2 = fcall.args[1] - val dt1 = arg1.inferType(program).typeOrElse(DataType.STRUCT) - val dt2 = arg2.inferType(program).typeOrElse(DataType.STRUCT) + val dt1 = arg1.inferType(program).typeOrElse(DataType.UNDEFINED) + val dt2 = arg2.inferType(program).typeOrElse(DataType.UNDEFINED) if(dt1 in ByteDatatypes) { if(dt2 in ByteDatatypes) { when (arg2) { @@ -368,7 +368,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val private fun funcRor2(fcall: IFunctionCall) { val what = fcall.args.single() val dt = what.inferType(program) - when (dt.typeOrElse(DataType.STRUCT)) { + when (dt.typeOrElse(DataType.UNDEFINED)) { DataType.UBYTE -> { when (what) { is ArrayIndexedExpression -> { @@ -411,7 +411,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val private fun funcRor(fcall: IFunctionCall) { val what = fcall.args.single() val dt = what.inferType(program) - when (dt.typeOrElse(DataType.STRUCT)) { + when (dt.typeOrElse(DataType.UNDEFINED)) { DataType.UBYTE -> { when (what) { is ArrayIndexedExpression -> { @@ -469,7 +469,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val private fun funcRol2(fcall: IFunctionCall) { val what = fcall.args.single() val dt = what.inferType(program) - when (dt.typeOrElse(DataType.STRUCT)) { + when (dt.typeOrElse(DataType.UNDEFINED)) { DataType.UBYTE -> { when (what) { is ArrayIndexedExpression -> { @@ -512,7 +512,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val private fun funcRol(fcall: IFunctionCall) { val what = fcall.args.single() val dt = what.inferType(program) - when (dt.typeOrElse(DataType.STRUCT)) { + when (dt.typeOrElse(DataType.UNDEFINED)) { DataType.UBYTE -> { when (what) { is ArrayIndexedExpression -> { @@ -586,7 +586,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val translateArguments(fcall.args, func, scope) val dt = fcall.args.single().inferType(program) if(resultToStack) { - when (dt.typeOrElse(DataType.STRUCT)) { + when (dt.typeOrElse(DataType.UNDEFINED)) { DataType.UBYTE -> asmgen.out(" jsr prog8_lib.func_sign_ub_stack") DataType.BYTE -> asmgen.out(" jsr prog8_lib.func_sign_b_stack") DataType.UWORD -> asmgen.out(" jsr prog8_lib.func_sign_uw_stack") @@ -595,7 +595,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val else -> throw AssemblyError("weird type $dt") } } else { - when (dt.typeOrElse(DataType.STRUCT)) { + when (dt.typeOrElse(DataType.UNDEFINED)) { DataType.UBYTE -> asmgen.out(" jsr prog8_lib.func_sign_ub_into_A") DataType.BYTE -> asmgen.out(" jsr prog8_lib.func_sign_b_into_A") DataType.UWORD -> asmgen.out(" jsr prog8_lib.func_sign_uw_into_A") @@ -611,14 +611,14 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val outputAddressAndLenghtOfArray(fcall.args[0]) val dt = fcall.args.single().inferType(program) if(resultToStack) { - when (dt.typeOrElse(DataType.STRUCT)) { + when (dt.typeOrElse(DataType.UNDEFINED)) { DataType.ARRAY_B, DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_${function.name}_b_stack") DataType.ARRAY_UW, DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_${function.name}_w_stack") DataType.ARRAY_F -> asmgen.out(" jsr floats.func_${function.name}_f_stack") else -> throw AssemblyError("weird type $dt") } } else { - when (dt.typeOrElse(DataType.STRUCT)) { + when (dt.typeOrElse(DataType.UNDEFINED)) { DataType.ARRAY_B, DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_${function.name}_b_into_A") DataType.ARRAY_UW, DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_${function.name}_w_into_A") DataType.ARRAY_F -> asmgen.out(" jsr floats.func_${function.name}_f_into_A") @@ -632,7 +632,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val outputAddressAndLenghtOfArray(fcall.args[0]) val dt = fcall.args.single().inferType(program) if(resultToStack) { - when (dt.typeOrElse(DataType.STRUCT)) { + when (dt.typeOrElse(DataType.UNDEFINED)) { DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_${function.name}_ub_stack") DataType.ARRAY_B -> asmgen.out(" jsr prog8_lib.func_${function.name}_b_stack") DataType.ARRAY_UW -> asmgen.out(" jsr prog8_lib.func_${function.name}_uw_stack") @@ -641,7 +641,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val else -> throw AssemblyError("weird type $dt") } } else { - when (dt.typeOrElse(DataType.STRUCT)) { + when (dt.typeOrElse(DataType.UNDEFINED)) { DataType.ARRAY_UB, DataType.STR -> { asmgen.out(" jsr prog8_lib.func_${function.name}_ub_into_A") assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, scope, program, asmgen), CpuRegister.A) @@ -671,7 +671,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val outputAddressAndLenghtOfArray(fcall.args[0]) val dt = fcall.args.single().inferType(program) if(resultToStack) { - when (dt.typeOrElse(DataType.STRUCT)) { + when (dt.typeOrElse(DataType.UNDEFINED)) { DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_sum_ub_stack") DataType.ARRAY_B -> asmgen.out(" jsr prog8_lib.func_sum_b_stack") DataType.ARRAY_UW -> asmgen.out(" jsr prog8_lib.func_sum_uw_stack") @@ -680,7 +680,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val else -> throw AssemblyError("weird type $dt") } } else { - when (dt.typeOrElse(DataType.STRUCT)) { + when (dt.typeOrElse(DataType.UNDEFINED)) { DataType.ARRAY_UB, DataType.STR -> { asmgen.out(" jsr prog8_lib.func_sum_ub_into_AY") assignAsmGen.assignRegisterpairWord(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.AY, scope, program, asmgen), RegisterOrPair.AY) @@ -782,7 +782,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val val elementIDt = first.inferType(program) if(!elementIDt.isKnown) throw AssemblyError("unknown dt") - val elementDt = elementIDt.typeOrElse(DataType.STRUCT) + val elementDt = elementIDt.typeOrElse(DataType.UNDEFINED) val firstNum = first.indexer.indexExpr as? NumericLiteralValue val firstVar = first.indexer.indexExpr as? IdentifierReference @@ -815,7 +815,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val } } - val datatype = first.inferType(program).typeOrElse(DataType.STRUCT) + val datatype = first.inferType(program).typeOrElse(DataType.UNDEFINED) when(datatype) { in ByteDatatypes, in WordDatatypes -> { asmgen.assignExpressionToVariable(first, "P8ZP_SCRATCH_W1", datatype, null) @@ -1086,7 +1086,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val private fun funcAbs(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, resultRegister: RegisterOrPair?, scope: Subroutine?) { translateArguments(fcall.args, func, scope) - val dt = fcall.args.single().inferType(program).typeOrElse(DataType.STRUCT) + val dt = fcall.args.single().inferType(program).typeOrElse(DataType.UNDEFINED) if(resultToStack) { when (dt) { in ByteDatatypes -> asmgen.out(" jsr prog8_lib.abs_b_stack") @@ -1321,7 +1321,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val private fun funcMsb(fcall: IFunctionCall, resultToStack: Boolean, resultRegister: RegisterOrPair?) { val arg = fcall.args.single() - if (arg.inferType(program).typeOrElse(DataType.STRUCT) !in WordDatatypes) + if (arg.inferType(program).typeOrElse(DataType.UNDEFINED) !in WordDatatypes) throw AssemblyError("msb required word argument") if (arg is NumericLiteralValue) throw AssemblyError("msb(const) should have been const-folded away") @@ -1365,7 +1365,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val private fun funcLsb(fcall: IFunctionCall, resultToStack: Boolean, resultRegister: RegisterOrPair?) { val arg = fcall.args.single() - if (arg.inferType(program).typeOrElse(DataType.STRUCT) !in WordDatatypes) + if (arg.inferType(program).typeOrElse(DataType.UNDEFINED) !in WordDatatypes) throw AssemblyError("lsb required word argument") if (arg is NumericLiteralValue) throw AssemblyError("lsb(const) should have been const-folded away") @@ -1429,7 +1429,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val } private fun translateArguments(args: MutableList, signature: FSignature, scope: Subroutine?) { - val callConv = signature.callConvention(args.map { it.inferType(program).typeOrElse(DataType.STRUCT) }) + val callConv = signature.callConvention(args.map { it.inferType(program).typeOrElse(DataType.UNDEFINED) }) fun getSourceForFloat(value: Expression): AsmAssignSource { return when (value) { diff --git a/compiler/src/prog8/compiler/target/cpu6502/codegen/ExpressionsAsmGen.kt b/compiler/src/prog8/compiler/target/cpu6502/codegen/ExpressionsAsmGen.kt index 179ad7919..3046c8c9c 100644 --- a/compiler/src/prog8/compiler/target/cpu6502/codegen/ExpressionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/cpu6502/codegen/ExpressionsAsmGen.kt @@ -57,7 +57,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge val idt = left.inferType(program) if(!idt.isKnown) throw AssemblyError("unknown dt") - val dt = idt.typeOrElse(DataType.STRUCT) + val dt = idt.typeOrElse(DataType.UNDEFINED) when (operator) { "==" -> { // if the left operand is an expression, and the right is 0, we can just evaluate that expression, @@ -1625,7 +1625,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge private fun translateExpression(typecast: TypecastExpression) { translateExpression(typecast.expression) - when(typecast.expression.inferType(program).typeOrElse(DataType.STRUCT)) { + when(typecast.expression.inferType(program).typeOrElse(DataType.UNDEFINED)) { DataType.UBYTE -> { when(typecast.type) { DataType.UBYTE, DataType.BYTE -> {} @@ -1756,7 +1756,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge private fun translateExpression(expr: IdentifierReference) { val varname = asmgen.asmVariableName(expr) - when(expr.inferType(program).typeOrElse(DataType.STRUCT)) { + when(expr.inferType(program).typeOrElse(DataType.UNDEFINED)) { DataType.UBYTE, DataType.BYTE -> { asmgen.out(" lda $varname | sta P8ESTACK_LO,x | dex") } @@ -1780,8 +1780,8 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge if(!leftIDt.isKnown || !rightIDt.isKnown) throw AssemblyError("can't infer type of both expression operands") - val leftDt = leftIDt.typeOrElse(DataType.STRUCT) - val rightDt = rightIDt.typeOrElse(DataType.STRUCT) + val leftDt = leftIDt.typeOrElse(DataType.UNDEFINED) + val rightDt = rightIDt.typeOrElse(DataType.UNDEFINED) // see if we can apply some optimized routines // TODO avoid using evaluation on stack everywhere when(expr.operator) { @@ -2107,7 +2107,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge val itype = expr.inferType(program) if(!itype.isKnown) throw AssemblyError("unknown dt") - val type = itype.typeOrElse(DataType.STRUCT) + val type = itype.typeOrElse(DataType.UNDEFINED) when(expr.operator) { "+" -> {} "-" -> { @@ -2145,7 +2145,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge val elementIDt = arrayExpr.inferType(program) if(!elementIDt.isKnown) throw AssemblyError("unknown dt") - val elementDt = elementIDt.typeOrElse(DataType.STRUCT) + val elementDt = elementIDt.typeOrElse(DataType.UNDEFINED) val arrayVarName = asmgen.asmVariableName(arrayExpr.arrayvar) val constIndexNum = arrayExpr.indexer.constIndex() if(constIndexNum!=null) { diff --git a/compiler/src/prog8/compiler/target/cpu6502/codegen/ForLoopsAsmGen.kt b/compiler/src/prog8/compiler/target/cpu6502/codegen/ForLoopsAsmGen.kt index 425200e29..fefe491e8 100644 --- a/compiler/src/prog8/compiler/target/cpu6502/codegen/ForLoopsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/cpu6502/codegen/ForLoopsAsmGen.kt @@ -21,13 +21,13 @@ internal class ForLoopsAsmGen(private val program: Program, private val asmgen: is RangeExpr -> { val range = (stmt.iterable as RangeExpr).toConstantIntegerRange() if(range==null) { - translateForOverNonconstRange(stmt, iterableDt.typeOrElse(DataType.STRUCT), stmt.iterable as RangeExpr) + translateForOverNonconstRange(stmt, iterableDt.typeOrElse(DataType.UNDEFINED), stmt.iterable as RangeExpr) } else { - translateForOverConstRange(stmt, iterableDt.typeOrElse(DataType.STRUCT), range) + translateForOverConstRange(stmt, iterableDt.typeOrElse(DataType.UNDEFINED), range) } } is IdentifierReference -> { - translateForOverIterableVar(stmt, iterableDt.typeOrElse(DataType.STRUCT), stmt.iterable as IdentifierReference) + translateForOverIterableVar(stmt, iterableDt.typeOrElse(DataType.UNDEFINED), stmt.iterable as IdentifierReference) } else -> throw AssemblyError("can't iterate over ${stmt.iterable.javaClass} - should have been replaced by a variable") } @@ -588,5 +588,5 @@ $loopLabel""") } private fun assignLoopvar(stmt: ForLoop, range: RangeExpr) = - asmgen.assignExpressionToVariable(range.from, asmgen.asmVariableName(stmt.loopVar), stmt.loopVarDt(program).typeOrElse(DataType.STRUCT), stmt.definingSubroutine()) + asmgen.assignExpressionToVariable(range.from, asmgen.asmVariableName(stmt.loopVar), stmt.loopVarDt(program).typeOrElse(DataType.UNDEFINED), stmt.definingSubroutine()) } diff --git a/compiler/src/prog8/compiler/target/cpu6502/codegen/FunctionCallAsmGen.kt b/compiler/src/prog8/compiler/target/cpu6502/codegen/FunctionCallAsmGen.kt index 8e1a1264c..0ced5d947 100644 --- a/compiler/src/prog8/compiler/target/cpu6502/codegen/FunctionCallAsmGen.kt +++ b/compiler/src/prog8/compiler/target/cpu6502/codegen/FunctionCallAsmGen.kt @@ -244,7 +244,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg val valueIDt = value.inferType(program) if(!valueIDt.isKnown) throw AssemblyError("unknown dt") - val valueDt = valueIDt.typeOrElse(DataType.STRUCT) + val valueDt = valueIDt.typeOrElse(DataType.UNDEFINED) if(!isArgumentTypeCompatible(valueDt, parameter.value.type)) throw AssemblyError("argument type incompatible") @@ -257,7 +257,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg val valueIDt = value.inferType(program) if(!valueIDt.isKnown) throw AssemblyError("unknown dt") - val valueDt = valueIDt.typeOrElse(DataType.STRUCT) + val valueDt = valueIDt.typeOrElse(DataType.UNDEFINED) if(!isArgumentTypeCompatible(valueDt, parameter.value.type)) throw AssemblyError("argument type incompatible") diff --git a/compiler/src/prog8/compiler/target/cpu6502/codegen/PostIncrDecrAsmGen.kt b/compiler/src/prog8/compiler/target/cpu6502/codegen/PostIncrDecrAsmGen.kt index 7b689fc31..da2f82fee 100644 --- a/compiler/src/prog8/compiler/target/cpu6502/codegen/PostIncrDecrAsmGen.kt +++ b/compiler/src/prog8/compiler/target/cpu6502/codegen/PostIncrDecrAsmGen.kt @@ -19,7 +19,7 @@ internal class PostIncrDecrAsmGen(private val program: Program, private val asmg when { targetIdent!=null -> { val what = asmgen.asmVariableName(targetIdent) - when (stmt.target.inferType(program).typeOrElse(DataType.STRUCT)) { + when (stmt.target.inferType(program).typeOrElse(DataType.UNDEFINED)) { in ByteDatatypes -> asmgen.out(if (incr) " inc $what" else " dec $what") in WordDatatypes -> { if(incr) @@ -65,7 +65,7 @@ internal class PostIncrDecrAsmGen(private val program: Program, private val asmg } targetArrayIdx!=null -> { val asmArrayvarname = asmgen.asmVariableName(targetArrayIdx.arrayvar) - val elementDt = targetArrayIdx.inferType(program).typeOrElse(DataType.STRUCT) + val elementDt = targetArrayIdx.inferType(program).typeOrElse(DataType.UNDEFINED) val constIndex = targetArrayIdx.indexer.constIndex() if(constIndex!=null) { val indexValue = constIndex * program.memsizer.memorySize(elementDt) diff --git a/compiler/src/prog8/compiler/target/cpu6502/codegen/assignment/AsmAssignment.kt b/compiler/src/prog8/compiler/target/cpu6502/codegen/assignment/AsmAssignment.kt index 536e2bb8c..38a1c0dd8 100644 --- a/compiler/src/prog8/compiler/target/cpu6502/codegen/assignment/AsmAssignment.kt +++ b/compiler/src/prog8/compiler/target/cpu6502/codegen/assignment/AsmAssignment.kt @@ -59,7 +59,7 @@ internal class AsmAssignTarget(val kind: TargetStorageKind, val idt = inferType(program) if(!idt.isKnown) throw AssemblyError("unknown dt") - val dt = idt.typeOrElse(DataType.STRUCT) + val dt = idt.typeOrElse(DataType.UNDEFINED) when { identifier != null -> AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, dt, assign.definingSubroutine(), variableAsmName = asmgen.asmVariableName(identifier!!), origAstTarget = this) arrayindexed != null -> AsmAssignTarget(TargetStorageKind.ARRAY, program, asmgen, dt, assign.definingSubroutine(), array = arrayindexed, origAstTarget = this) @@ -132,7 +132,7 @@ internal class AsmAssignSource(val kind: SourceStorageKind, is StringLiteralValue -> throw AssemblyError("string literal value should not occur anymore for asm generation") is ArrayLiteralValue -> throw AssemblyError("array literal value should not occur anymore for asm generation") is IdentifierReference -> { - val dt = value.inferType(program).typeOrElse(DataType.STRUCT) + val dt = value.inferType(program).typeOrElse(DataType.UNDEFINED) val varName=asmgen.asmVariableName(value) // special case: "cx16.r[0-15]" are 16-bits virtual registers of the commander X16 system if(dt==DataType.UWORD && varName.toLowerCase().startsWith("cx16.r")) { @@ -147,7 +147,7 @@ internal class AsmAssignSource(val kind: SourceStorageKind, AsmAssignSource(SourceStorageKind.MEMORY, program, asmgen, DataType.UBYTE, memory = value) } is ArrayIndexedExpression -> { - val dt = value.inferType(program).typeOrElse(DataType.STRUCT) + val dt = value.inferType(program).typeOrElse(DataType.UNDEFINED) AsmAssignSource(SourceStorageKind.ARRAY, program, asmgen, dt, array = value) } is FunctionCall -> { @@ -162,7 +162,7 @@ internal class AsmAssignSource(val kind: SourceStorageKind, val returnType = value.inferType(program) if(!returnType.isKnown) throw AssemblyError("unknown dt") - AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, returnType.typeOrElse(DataType.STRUCT), expression = value) + AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, returnType.typeOrElse(DataType.UNDEFINED), expression = value) } else -> { throw AssemblyError("weird call") @@ -173,7 +173,7 @@ internal class AsmAssignSource(val kind: SourceStorageKind, val dt = value.inferType(program) if(!dt.isKnown) throw AssemblyError("unknown dt") - AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, dt.typeOrElse(DataType.STRUCT), expression = value) + AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, dt.typeOrElse(DataType.UNDEFINED), expression = value) } } } @@ -206,7 +206,7 @@ internal class AsmAssignment(val source: AsmAssignSource, init { if(target.register !in setOf(RegisterOrPair.XY, RegisterOrPair.AX, RegisterOrPair.AY)) - require(source.datatype != DataType.STRUCT) { "must not be placeholder datatype" } + require(source.datatype != DataType.UNDEFINED) { "must not be placeholder/undefined datatype" } require(memsizer.memorySize(source.datatype) <= memsizer.memorySize(target.datatype)) { "source storage size must be less or equal to target datatype storage size" } diff --git a/compiler/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt b/compiler/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt index 6539d2381..2375dd588 100644 --- a/compiler/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt +++ b/compiler/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt @@ -217,7 +217,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen val returntype = builtinFunctionReturnType(sub.name, value.args, program) if(!returntype.isKnown) throw AssemblyError("unknown dt") - when(returntype.typeOrElse(DataType.STRUCT)) { + when(returntype.typeOrElse(DataType.UNDEFINED)) { in ByteDatatypes -> assignRegisterByte(assign.target, CpuRegister.A) // function's byte result is in A in WordDatatypes -> assignRegisterpairWord(assign.target, RegisterOrPair.AY) // function's word result is in AY DataType.STR -> { @@ -299,7 +299,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen val valueIDt = value.inferType(program) if(!valueIDt.isKnown) throw AssemblyError("unknown dt") - val valueDt = valueIDt.typeOrElse(DataType.STRUCT) + val valueDt = valueIDt.typeOrElse(DataType.UNDEFINED) if(valueDt==targetDt) throw AssemblyError("type cast to identical dt should have been removed") @@ -359,7 +359,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen // special case optimizations if(target.kind== TargetStorageKind.VARIABLE) { - if(value is IdentifierReference && valueDt != DataType.STRUCT) + if(value is IdentifierReference && valueDt != DataType.UNDEFINED) return assignTypeCastedIdentifier(target.asmVarname, targetDt, asmgen.asmVariableName(value), valueDt) when (valueDt) { diff --git a/compiler/src/prog8/compiler/target/cpu6502/codegen/assignment/AugmentableAssignmentAsmGen.kt b/compiler/src/prog8/compiler/target/cpu6502/codegen/assignment/AugmentableAssignmentAsmGen.kt index dac370cf2..5cac960ea 100644 --- a/compiler/src/prog8/compiler/target/cpu6502/codegen/assignment/AugmentableAssignmentAsmGen.kt +++ b/compiler/src/prog8/compiler/target/cpu6502/codegen/assignment/AugmentableAssignmentAsmGen.kt @@ -25,7 +25,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, val itype = value.inferType(program) if(!itype.isKnown) throw AssemblyError("unknown dt") - val type = itype.typeOrElse(DataType.STRUCT) + val type = itype.typeOrElse(DataType.UNDEFINED) when (value.operator) { "+" -> {} "-" -> inplaceNegate(assign.target, type) @@ -280,7 +280,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, val childIDt = value.expression.inferType(program) if(!childIDt.isKnown) throw AssemblyError("unknown dt") - val childDt = childIDt.typeOrElse(DataType.STRUCT) + val childDt = childIDt.typeOrElse(DataType.UNDEFINED) if (value.type!=DataType.FLOAT && (value.type.equalsSize(childDt) || value.type.largerThan(childDt))) { // this typecast is redundant here; the rest of the code knows how to deal with the uncasted value. // (works for integer types, not for float.) @@ -1225,7 +1225,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, val valueiDt = value.inferType(program) if(!valueiDt.isKnown) throw AssemblyError("unknown dt") - val valueDt = valueiDt.typeOrElse(DataType.STRUCT) + val valueDt = valueiDt.typeOrElse(DataType.UNDEFINED) fun multiplyVarByWordInAY() { asmgen.out(""" diff --git a/compiler/src/prog8/optimizer/CallGraph.kt b/compiler/src/prog8/optimizer/CallGraph.kt index d33c09345..1e670a104 100644 --- a/compiler/src/prog8/optimizer/CallGraph.kt +++ b/compiler/src/prog8/optimizer/CallGraph.kt @@ -175,7 +175,7 @@ class CallGraph(private val program: Program) : IAstVisitor { } fun unused(decl: VarDecl): Boolean { - if(decl.type!=VarDeclType.VAR || decl.datatype==DataType.STRUCT || decl.autogeneratedDontRemove) + if(decl.type!=VarDeclType.VAR || decl.autogeneratedDontRemove) return false if(decl.definingBlock() !in usedBlocks) diff --git a/compiler/src/prog8/optimizer/ConstantFoldingOptimizer.kt b/compiler/src/prog8/optimizer/ConstantFoldingOptimizer.kt index 965b9db1b..d0315a620 100644 --- a/compiler/src/prog8/optimizer/ConstantFoldingOptimizer.kt +++ b/compiler/src/prog8/optimizer/ConstantFoldingOptimizer.kt @@ -106,7 +106,7 @@ internal class ConstantFoldingOptimizer(private val program: Program, private va // optimize various simple cases of ** : // optimize away 1 ** x into just 1 and 0 ** x into just 0 // optimize 2 ** x into (1< { val value = NumericLiteralValue(leftDt, 0, expr.position) @@ -121,11 +121,11 @@ internal class ConstantFoldingOptimizer(private val program: Program, private va val value = NumericLiteralValue(leftDt, 2.0.pow(rightconst.number.toDouble()), expr.position) modifications += IAstModification.ReplaceNode(expr, value, parent) } else { - val rightDt = expr.right.inferType(program).typeOrElse(DataType.STRUCT) + val rightDt = expr.right.inferType(program).typeOrElse(DataType.UNDEFINED) if(leftDt in IntegerDatatypes && rightDt in IntegerDatatypes) { val targetDt = when (parent) { - is Assignment -> parent.target.inferType(program).typeOrElse(DataType.STRUCT) + is Assignment -> parent.target.inferType(program).typeOrElse(DataType.UNDEFINED) is VarDecl -> parent.datatype else -> leftDt } @@ -187,7 +187,7 @@ internal class ConstantFoldingOptimizer(private val program: Program, private va } else { val arrayDt = array.guessDatatype(program) if (arrayDt.isKnown) { - val newArray = array.cast(arrayDt.typeOrElse(DataType.STRUCT)) + val newArray = array.cast(arrayDt.typeOrElse(DataType.UNDEFINED)) if (newArray != null && newArray != array) return listOf(IAstModification.ReplaceNode(array, newArray, parent)) } diff --git a/compiler/src/prog8/optimizer/ExpressionSimplifier.kt b/compiler/src/prog8/optimizer/ExpressionSimplifier.kt index f2e16a81a..39d0d15e8 100644 --- a/compiler/src/prog8/optimizer/ExpressionSimplifier.kt +++ b/compiler/src/prog8/optimizer/ExpressionSimplifier.kt @@ -134,8 +134,8 @@ internal class ExpressionSimplifier(private val program: Program) : AstWalker() )) } - val leftDt = leftIDt.typeOrElse(DataType.STRUCT) - val rightDt = rightIDt.typeOrElse(DataType.STRUCT) + val leftDt = leftIDt.typeOrElse(DataType.UNDEFINED) + val rightDt = rightIDt.typeOrElse(DataType.UNDEFINED) if (expr.operator == "+" || expr.operator == "-" && leftVal == null && rightVal == null @@ -489,7 +489,7 @@ internal class ExpressionSimplifier(private val program: Program) : AstWalker() val idt = expr.inferType(program) if(!idt.isKnown) throw FatalAstException("unknown dt") - return NumericLiteralValue(idt.typeOrElse(DataType.STRUCT), 0, expr.position) + return NumericLiteralValue(idt.typeOrElse(DataType.UNDEFINED), 0, expr.position) } else if (cv in powersOfTwo) { expr.operator = "&" expr.right = NumericLiteralValue.optimalInteger(cv!!.toInt()-1, expr.position) @@ -513,7 +513,7 @@ internal class ExpressionSimplifier(private val program: Program) : AstWalker() val leftIDt = expr.left.inferType(program) if (!leftIDt.isKnown) return null - val leftDt = leftIDt.typeOrElse(DataType.STRUCT) + val leftDt = leftIDt.typeOrElse(DataType.UNDEFINED) when (cv) { -1.0 -> { // '/' -> -left @@ -590,14 +590,14 @@ internal class ExpressionSimplifier(private val program: Program) : AstWalker() return expr2.left } in powersOfTwo -> { - if (leftValue.inferType(program).typeOrElse(DataType.STRUCT) in IntegerDatatypes) { + if (leftValue.inferType(program).typeOrElse(DataType.UNDEFINED) in IntegerDatatypes) { // times a power of two => shift left val numshifts = log2(cv).toInt() return BinaryExpression(expr2.left, "<<", NumericLiteralValue.optimalInteger(numshifts, expr.position), expr.position) } } in negativePowersOfTwo -> { - if (leftValue.inferType(program).typeOrElse(DataType.STRUCT) in IntegerDatatypes) { + if (leftValue.inferType(program).typeOrElse(DataType.UNDEFINED) in IntegerDatatypes) { // times a negative power of two => negate, then shift left val numshifts = log2(-cv).toInt() return BinaryExpression(PrefixExpression("-", expr2.left, expr.position), "<<", NumericLiteralValue.optimalInteger(numshifts, expr.position), expr.position) @@ -621,7 +621,7 @@ internal class ExpressionSimplifier(private val program: Program) : AstWalker() val targetIDt = expr.left.inferType(program) if(!targetIDt.isKnown) throw FatalAstException("unknown dt") - when (val targetDt = targetIDt.typeOrElse(DataType.STRUCT)) { + when (val targetDt = targetIDt.typeOrElse(DataType.UNDEFINED)) { DataType.UBYTE, DataType.BYTE -> { if (amount >= 8) { return NumericLiteralValue(targetDt, 0, expr.position) @@ -656,7 +656,7 @@ internal class ExpressionSimplifier(private val program: Program) : AstWalker() val idt = expr.left.inferType(program) if(!idt.isKnown) throw FatalAstException("unknown dt") - when (idt.typeOrElse(DataType.STRUCT)) { + when (idt.typeOrElse(DataType.UNDEFINED)) { DataType.UBYTE -> { if (amount >= 8) { return NumericLiteralValue.optimalInteger(0, expr.position) diff --git a/compiler/src/prog8/optimizer/StatementOptimizer.kt b/compiler/src/prog8/optimizer/StatementOptimizer.kt index 323f12b99..fb26690c4 100644 --- a/compiler/src/prog8/optimizer/StatementOptimizer.kt +++ b/compiler/src/prog8/optimizer/StatementOptimizer.kt @@ -333,7 +333,7 @@ internal class StatementOptimizer(private val program: Program, throw FatalAstException("can't infer type of assignment target") // optimize binary expressions a bit - val targetDt = targetIDt.typeOrElse(DataType.STRUCT) + val targetDt = targetIDt.typeOrElse(DataType.UNDEFINED) val bexpr=assignment.value as? BinaryExpression if(bexpr!=null) { val rightCv = bexpr.right.constValue(program)?.number?.toDouble() diff --git a/compilerAst/src/prog8/ast/AstToSourceCode.kt b/compilerAst/src/prog8/ast/AstToSourceCode.kt index e26bf2a77..640c78ab2 100644 --- a/compilerAst/src/prog8/ast/AstToSourceCode.kt +++ b/compilerAst/src/prog8/ast/AstToSourceCode.kt @@ -86,7 +86,6 @@ class AstToSourceCode(val output: (text: String) -> Unit, val program: Program): DataType.ARRAY_UW -> "uword[" DataType.ARRAY_W -> "word[" DataType.ARRAY_F -> "float[" - DataType.STRUCT -> "" // TODO STRUCT DOESN'T EXIST ANYMORE else -> "?????" } } diff --git a/compilerAst/src/prog8/ast/antlr/Antr2Kotlin.kt b/compilerAst/src/prog8/ast/antlr/Antr2Kotlin.kt index 205f70b14..b721a78c1 100644 --- a/compilerAst/src/prog8/ast/antlr/Antr2Kotlin.kt +++ b/compilerAst/src/prog8/ast/antlr/Antr2Kotlin.kt @@ -62,7 +62,7 @@ private fun prog8Parser.VariabledeclarationContext.toAst(encoding: IStringEncodi val vd = it.vardecl() return VarDecl( VarDeclType.VAR, - vd.datatype()?.toAst() ?: DataType.STRUCT, + vd.datatype()?.toAst() ?: DataType.UNDEFINED, if (vd.ZEROPAGE() != null) ZeropageWish.PREFER_ZEROPAGE else ZeropageWish.DONTCARE, vd.arrayindex()?.toAst(encoding), vd.varname.text, @@ -78,7 +78,7 @@ private fun prog8Parser.VariabledeclarationContext.toAst(encoding: IStringEncodi val vd = cvarinit.vardecl() return VarDecl( VarDeclType.CONST, - vd.datatype()?.toAst() ?: DataType.STRUCT, + vd.datatype()?.toAst() ?: DataType.UNDEFINED, if (vd.ZEROPAGE() != null) ZeropageWish.PREFER_ZEROPAGE else ZeropageWish.DONTCARE, vd.arrayindex()?.toAst(encoding), vd.varname.text, @@ -94,7 +94,7 @@ private fun prog8Parser.VariabledeclarationContext.toAst(encoding: IStringEncodi val vd = mvarinit.vardecl() return VarDecl( VarDeclType.MEMORY, - vd.datatype()?.toAst() ?: DataType.STRUCT, + vd.datatype()?.toAst() ?: DataType.UNDEFINED, if (vd.ZEROPAGE() != null) ZeropageWish.PREFER_ZEROPAGE else ZeropageWish.DONTCARE, vd.arrayindex()?.toAst(encoding), vd.varname.text, @@ -255,7 +255,7 @@ private fun prog8Parser.Asmsub_returnsContext.toAst(): List private fun prog8Parser.Asmsub_paramsContext.toAst(): List = asmsub_param().map { val vardecl = it.vardecl() - val datatype = vardecl.datatype()?.toAst() ?: DataType.STRUCT + val datatype = vardecl.datatype()?.toAst() ?: DataType.UNDEFINED val register = it.register().text var registerorpair: RegisterOrPair? = null var statusregister: Statusflag? = null @@ -321,7 +321,7 @@ private fun prog8Parser.Sub_return_partContext.toAst(): List { private fun prog8Parser.Sub_paramsContext.toAst(): List = vardecl().map { - val datatype = it.datatype()?.toAst() ?: DataType.STRUCT + val datatype = it.datatype()?.toAst() ?: DataType.UNDEFINED SubroutineParameter(it.varname.text, datatype, it.toPosition()) } @@ -594,7 +594,7 @@ private fun prog8Parser.When_choiceContext.toAst(encoding: IStringEncoding): Whe private fun prog8Parser.VardeclContext.toAst(encoding: IStringEncoding): VarDecl { return VarDecl( VarDeclType.VAR, - datatype()?.toAst() ?: DataType.STRUCT, + datatype()?.toAst() ?: DataType.UNDEFINED, if(ZEROPAGE() != null) ZeropageWish.PREFER_ZEROPAGE else ZeropageWish.DONTCARE, arrayindex()?.toAst(encoding), varname.text, diff --git a/compilerAst/src/prog8/ast/base/Base.kt b/compilerAst/src/prog8/ast/base/Base.kt index 42a570070..6ff5533e3 100644 --- a/compilerAst/src/prog8/ast/base/Base.kt +++ b/compilerAst/src/prog8/ast/base/Base.kt @@ -17,7 +17,7 @@ enum class DataType { ARRAY_UW, // pass by reference ARRAY_W, // pass by reference ARRAY_F, // pass by reference - STRUCT; // pass by reference + UNDEFINED; /** * is the type assignable to the given other type (perhaps via a typecast) without loss of precision? @@ -140,7 +140,7 @@ val IterableDatatypes = setOf( DataType.ARRAY_F ) val PassByValueDatatypes = NumericDatatypes -val PassByReferenceDatatypes = IterableDatatypes.plus(DataType.STRUCT) +val PassByReferenceDatatypes = IterableDatatypes val ArrayElementTypes = mapOf( DataType.STR to DataType.UBYTE, DataType.ARRAY_B to DataType.BYTE, diff --git a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt index e620fa1f4..9b9b5ebd8 100644 --- a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt +++ b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt @@ -89,14 +89,14 @@ class PrefixExpression(val operator: String, var expression: Expression, overrid return when(operator) { "+" -> inferred "~", "not" -> { - when(inferred.typeOrElse(DataType.STRUCT)) { + when(inferred.typeOrElse(DataType.UNDEFINED)) { in ByteDatatypes -> InferredTypes.knownFor(DataType.UBYTE) in WordDatatypes -> InferredTypes.knownFor(DataType.UWORD) else -> inferred } } "-" -> { - when(inferred.typeOrElse(DataType.STRUCT)) { + when(inferred.typeOrElse(DataType.UNDEFINED)) { in ByteDatatypes -> InferredTypes.knownFor(DataType.BYTE) in WordDatatypes -> InferredTypes.knownFor(DataType.WORD) else -> inferred @@ -567,7 +567,7 @@ class ArrayLiteralValue(val type: InferredTypes.InferredType, // inferred be fun memsize(memsizer: IMemSizer): Int { if(type.isKnown) { - val eltType = ArrayElementTypes.getValue(type.typeOrElse(DataType.STRUCT)) + val eltType = ArrayElementTypes.getValue(type.typeOrElse(DataType.UNDEFINED)) return memsizer.memorySize(eltType) * value.size } else throw IllegalArgumentException("array datatype is not yet known") @@ -580,17 +580,17 @@ class ArrayLiteralValue(val type: InferredTypes.InferredType, // inferred be if(forloop != null) { val loopvarDt = forloop.loopVarDt(program) if(loopvarDt.isKnown) { - return if(loopvarDt.typeOrElse(DataType.STRUCT) !in ElementArrayTypes) + return if(loopvarDt.typeOrElse(DataType.UNDEFINED) !in ElementArrayTypes) InferredTypes.InferredType.unknown() else - InferredTypes.InferredType.known(ElementArrayTypes.getValue(loopvarDt.typeOrElse(DataType.STRUCT))) + InferredTypes.InferredType.known(ElementArrayTypes.getValue(loopvarDt.typeOrElse(DataType.UNDEFINED))) } } // otherwise, select the "biggegst" datatype based on the elements in the array. val datatypesInArray = value.map { it.inferType(program) } require(datatypesInArray.isNotEmpty() && datatypesInArray.all { it.isKnown }) { "can't determine type of empty array" } - val dts = datatypesInArray.map { it.typeOrElse(DataType.STRUCT) } + val dts = datatypesInArray.map { it.typeOrElse(DataType.UNDEFINED) } return when { DataType.FLOAT in dts -> InferredTypes.InferredType.known(DataType.ARRAY_F) DataType.STR in dts -> InferredTypes.InferredType.known(DataType.ARRAY_UW) @@ -602,8 +602,7 @@ class ArrayLiteralValue(val type: InferredTypes.InferredType, // inferred be DataType.ARRAY_W in dts || DataType.ARRAY_UB in dts || DataType.ARRAY_B in dts || - DataType.ARRAY_F in dts || - DataType.STRUCT in dts -> InferredTypes.InferredType.known(DataType.ARRAY_UW) + DataType.ARRAY_F in dts -> InferredTypes.InferredType.known(DataType.ARRAY_UW) else -> InferredTypes.InferredType.unknown() } } @@ -677,8 +676,8 @@ class RangeExpr(var from: Expression, fromDt istype DataType.WORD || toDt istype DataType.WORD -> InferredTypes.knownFor(DataType.ARRAY_W) fromDt istype DataType.BYTE || toDt istype DataType.BYTE -> InferredTypes.knownFor(DataType.ARRAY_B) else -> { - val fdt = fromDt.typeOrElse(DataType.STRUCT) - val tdt = toDt.typeOrElse(DataType.STRUCT) + val fdt = fromDt.typeOrElse(DataType.UNDEFINED) + val tdt = toDt.typeOrElse(DataType.UNDEFINED) if(fdt largerThan tdt) InferredTypes.knownFor(ElementArrayTypes.getValue(fdt)) else diff --git a/compilerAst/src/prog8/ast/expressions/InferredTypes.kt b/compilerAst/src/prog8/ast/expressions/InferredTypes.kt index 953e63bb1..c98361892 100644 --- a/compilerAst/src/prog8/ast/expressions/InferredTypes.kt +++ b/compilerAst/src/prog8/ast/expressions/InferredTypes.kt @@ -57,8 +57,7 @@ object InferredTypes { DataType.ARRAY_B to InferredType.known(DataType.ARRAY_B), DataType.ARRAY_UW to InferredType.known(DataType.ARRAY_UW), DataType.ARRAY_W to InferredType.known(DataType.ARRAY_W), - DataType.ARRAY_F to InferredType.known(DataType.ARRAY_F), - DataType.STRUCT to InferredType.known(DataType.STRUCT) + DataType.ARRAY_F to InferredType.known(DataType.ARRAY_F) ) fun void() = voidInstance diff --git a/compilerAst/src/prog8/ast/statements/AstStatements.kt b/compilerAst/src/prog8/ast/statements/AstStatements.kt index e5c2fb6d5..48a2a0327 100644 --- a/compilerAst/src/prog8/ast/statements/AstStatements.kt +++ b/compilerAst/src/prog8/ast/statements/AstStatements.kt @@ -179,7 +179,7 @@ open class VarDecl(val type: VarDeclType, if(!array.type.isKnown) throw FatalAstException("unknown dt") else - array.type.typeOrElse(DataType.STRUCT) + array.type.typeOrElse(DataType.UNDEFINED) val declaredType = ArrayElementTypes.getValue(arrayDt) val arraysize = ArrayIndex.forArray(array) return VarDecl(VarDeclType.VAR, declaredType, ZeropageWish.NOT_IN_ZEROPAGE, arraysize, autoVarName, array, diff --git a/docs/source/todo.rst b/docs/source/todo.rst index df48d4cfe..95b87878f 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -2,11 +2,9 @@ TODO ==== -- get rid of Datatype.STRUCT - fix problem that unused vars are no longer properly removed - BeforeAsmGenerationAstChanger no longer needs to move vardecls?? - - simplify cx16.joystick_get2() once this cx16 rom issue is resolved: https://github.com/commanderx16/x16-rom/issues/203 - c64: make the graphics.BITMAP_ADDRESS configurable (VIC banking) - get rid of all other TODO's in the code ;-) @@ -14,6 +12,7 @@ TODO Low prio ^^^^^^^^ +- see if we can improve the ".typeOrElse(DataType.UNDEFINED)" to not depend on the DEFINED anymore or at least less - optimize several inner loops in gfx2 even further? - add modes 2 and 3 to gfx2 (lowres 4 color and 16 color)? - add a flood fill routine to gfx2?