some fixes in syntaxchecking array initializer values

This commit is contained in:
Irmen de Jong 2019-04-16 01:50:12 +02:00
parent e384822b2c
commit 390043e9e8
4 changed files with 28 additions and 5 deletions

View File

@ -492,7 +492,7 @@ private class AstChecker(private val namespace: INameScope,
checkResult.add(SyntaxError("floating point used, but that is not enabled via options", decl.position))
}
// ARRAY without size specifier MUST have an initializer value
// ARRAY without size specifier MUST have an iterable initializer value
if(decl.isUnsizedArray) {
if(decl.type==VarDeclType.MEMORY)
checkResult.add(SyntaxError("memory mapped array must have a size specification", decl.position))
@ -500,6 +500,12 @@ private class AstChecker(private val namespace: INameScope,
checkResult.add(SyntaxError("array variable is missing a size specification or an initialization value", decl.position))
return decl
}
if(decl.value is LiteralValue && !(decl.value as LiteralValue).isArray) {
checkResult.add(SyntaxError("unsized array declaration cannot use a single literal initialization value", decl.position))
return decl
}
if(decl.value is RangeExpr)
throw FatalAstException("range expressions in vardecls should have been converted into array values during constFolding $decl")
}
when(decl.type) {

View File

@ -45,6 +45,24 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
}
}
DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_UW, DataType.ARRAY_W -> {
val rangeExpr = decl.value as? RangeExpr
if(rangeExpr!=null) {
// convert the initializer range expression to an actual array
val constRange = rangeExpr.toConstantIntegerRange(heap)
if(constRange!=null) {
val eltType = rangeExpr.resultingDatatype(namespace, heap)!!
if(eltType in ByteDatatypes) {
decl.value = LiteralValue(decl.datatype,
arrayvalue = constRange.map { LiteralValue(eltType, bytevalue=it.toShort(), position = decl.value!!.position ) }
.toTypedArray(), position=decl.value!!.position)
} else {
decl.value = LiteralValue(decl.datatype,
arrayvalue = constRange.map { LiteralValue(eltType, wordvalue= it, position = decl.value!!.position ) }
.toTypedArray(), position=decl.value!!.position)
}
decl.value!!.linkParents(decl)
}
}
if(litval?.type==DataType.FLOAT)
errors.add(ExpressionError("arraysize requires only integers here", litval.position))
if(decl.arraysize==null)

View File

@ -60,7 +60,7 @@ of values together (and use it multiple times). Something like::
struct Point {
ubyte color
word[3] vec = [0,0,0]
word[] vec = [0,0,0]
}
Point p1

View File

@ -4,16 +4,15 @@
sub start() {
; @todo documentation on array without size
ubyte[5] array2 = 20 to 100 ; @todo fix this initializer value
word[5] array3 = 3000 to 3100 ; @todo fix this initializer value
byte[] derp = 99 ; @todo better ast error
c64scr.print_uw(len(array2))
c64.CHROUT('\n')
c64scr.print_uw(len(array3))
c64.CHROUT('\n')
c64scr.print_uw(len(array4))
c64.CHROUT('\n')
c64.CHROUT('\n')
c64scr.print_ub(array2[0])
c64.CHROUT(',')