fix byte array iteration for bb in [1,2,3]

improved array literal datatype detection
This commit is contained in:
Irmen de Jong 2020-02-09 00:45:53 +01:00
parent fd240899bd
commit a0bc97b90c
4 changed files with 40 additions and 11 deletions

View File

@ -63,7 +63,27 @@ class PrefixExpression(val operator: String, var expression: Expression, overrid
override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(visitor: IAstVisitor) = visitor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun referencesIdentifiers(vararg name: String) = expression.referencesIdentifiers(*name) override fun referencesIdentifiers(vararg name: String) = expression.referencesIdentifiers(*name)
override fun inferType(program: Program): InferredTypes.InferredType = expression.inferType(program) override fun inferType(program: Program): InferredTypes.InferredType {
val inferred = expression.inferType(program)
return when(operator) {
"+" -> inferred
"~", "not" -> {
when(inferred.typeOrElse(DataType.STRUCT)) {
in ByteDatatypes -> InferredTypes.knownFor(DataType.UBYTE)
in WordDatatypes -> InferredTypes.knownFor(DataType.UWORD)
else -> inferred
}
}
"-" -> {
when(inferred.typeOrElse(DataType.STRUCT)) {
in ByteDatatypes -> InferredTypes.knownFor(DataType.BYTE)
in WordDatatypes -> InferredTypes.knownFor(DataType.WORD)
else -> inferred
}
}
else -> throw FatalAstException("weird prefix expression operator")
}
}
override fun toString(): String { override fun toString(): String {
return "Prefix($operator $expression)" return "Prefix($operator $expression)"

View File

@ -144,7 +144,6 @@ internal class AstChecker(private val program: Program,
checkResult.add(ExpressionError("uword loop variable can only loop over unsigned bytes, words or strings", forLoop.position)) checkResult.add(ExpressionError("uword loop variable can only loop over unsigned bytes, words or strings", forLoop.position))
} }
DataType.BYTE -> { DataType.BYTE -> {
// TODO fix this, it should allow: for bb in [1,2,3]
if(iterableDt!= DataType.BYTE && iterableDt!= DataType.ARRAY_B) if(iterableDt!= DataType.BYTE && iterableDt!= DataType.ARRAY_B)
checkResult.add(ExpressionError("byte loop variable can only loop over bytes", forLoop.position)) checkResult.add(ExpressionError("byte loop variable can only loop over bytes", forLoop.position))
} }
@ -1200,6 +1199,10 @@ internal class AstChecker(private val program: Program,
when (it) { when (it) {
is NumericLiteralValue -> it.number.toInt() is NumericLiteralValue -> it.number.toInt()
is AddressOf -> it.identifier.heapId(program.namespace) is AddressOf -> it.identifier.heapId(program.namespace)
is TypecastExpression -> {
val constVal = it.expression.constValue(program)
constVal?.cast(it.type)?.number?.toInt() ?: -9999999
}
else -> -9999999 else -> -9999999
} }
} }

View File

@ -235,10 +235,12 @@ internal class AstIdentifiersChecker(private val program: Program) : IAstModifyi
// fix the datatype of the array (also on the heap) to the 'biggest' datatype in the array // fix the datatype of the array (also on the heap) to the 'biggest' datatype in the array
// (we don't know the desired datatype here exactly so we guess) // (we don't know the desired datatype here exactly so we guess)
val datatype = determineArrayDt(array.value) val datatype = determineArrayDt(array.value)
val litval2 = array.cast(datatype)!! val litval2 = array.cast(datatype)
if(litval2!=null) {
litval2.parent = array.parent litval2.parent = array.parent
// finally, replace the literal array by a identifier reference. // finally, replace the literal array by a identifier reference.
makeIdentifierFromRefLv(litval2) makeIdentifierFromRefLv(litval2)
} else array
} }
} }
return array return array
@ -366,12 +368,17 @@ internal fun fixupArrayEltDatatypes(array: ArrayLiteralValue, program: Program):
// convert values and array type // convert values and array type
val elementType = ArrayElementTypes.getValue(dt) val elementType = ArrayElementTypes.getValue(dt)
val allNumerics = array.value.all { it is NumericLiteralValue }
if(allNumerics) {
val values = array.value.map { (it as NumericLiteralValue).cast(elementType) as Expression }.toTypedArray() val values = array.value.map { (it as NumericLiteralValue).cast(elementType) as Expression }.toTypedArray()
val array2 = ArrayLiteralValue(dt, values, array.position) val array2 = ArrayLiteralValue(dt, values, array.position)
array2.linkParents(array.parent) array2.linkParents(array.parent)
return array2 return array2
} }
return array
}
internal fun fixupArrayEltDatatypesFromVardecl(array: ArrayLiteralValue, vardecl: VarDecl): ArrayLiteralValue { internal fun fixupArrayEltDatatypesFromVardecl(array: ArrayLiteralValue, vardecl: VarDecl): ArrayLiteralValue {
val arrayDt = array.type val arrayDt = array.type
if(arrayDt!=vardecl.datatype) { if(arrayDt!=vardecl.datatype) {

View File

@ -4,7 +4,6 @@ TODO
- @"zzz" screencode encoded strings + add this to docs too - @"zzz" screencode encoded strings + add this to docs too
- add 'void' keyword to explicitly ignore subroutine return values - add 'void' keyword to explicitly ignore subroutine return values
- allow: for bb in [1,2,3] + docs?
Memory Block Operations integrated in language? Memory Block Operations integrated in language?