mirror of
https://github.com/irmen/prog8.git
synced 2024-11-27 03:50:27 +00:00
proper error message for arrays that are declared too big
This commit is contained in:
parent
353f1954a5
commit
77c1376d6d
@ -492,8 +492,7 @@ internal class AstChecker(private val program: Program,
|
|||||||
|
|
||||||
when(decl.value) {
|
when(decl.value) {
|
||||||
null -> {
|
null -> {
|
||||||
// a vardecl without an initial value, don't bother with the rest
|
// a vardecl without an initial value, don't bother with it
|
||||||
return super.visit(decl)
|
|
||||||
}
|
}
|
||||||
is RangeExpr -> throw FatalAstException("range expression should have been converted to a true array value")
|
is RangeExpr -> throw FatalAstException("range expression should have been converted to a true array value")
|
||||||
is StringLiteralValue -> {
|
is StringLiteralValue -> {
|
||||||
@ -577,6 +576,26 @@ internal class AstChecker(private val program: Program,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// array length limits
|
||||||
|
if(decl.isArray) {
|
||||||
|
val length = decl.arraysize!!.size() ?: 1
|
||||||
|
when (decl.datatype) {
|
||||||
|
DataType.STR, DataType.ARRAY_UB, DataType.ARRAY_B -> {
|
||||||
|
if(length==0 || length>256)
|
||||||
|
err("string and byte array length must be 1-256")
|
||||||
|
}
|
||||||
|
DataType.ARRAY_UW, DataType.ARRAY_W -> {
|
||||||
|
if(length==0 || length>128)
|
||||||
|
err("word array length must be 1-128")
|
||||||
|
}
|
||||||
|
DataType.ARRAY_F -> {
|
||||||
|
if(length==0 || length>51)
|
||||||
|
err("float array length must be 1-51")
|
||||||
|
}
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
super.visit(decl)
|
super.visit(decl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,7 +266,6 @@ $endLabel inx""")
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun translateForOverIterableVar(stmt: ForLoop, iterableDt: DataType, ident: IdentifierReference) {
|
private fun translateForOverIterableVar(stmt: ForLoop, iterableDt: DataType, ident: IdentifierReference) {
|
||||||
// TODO optimize this more
|
|
||||||
val loopLabel = asmgen.makeLabel("for_loop")
|
val loopLabel = asmgen.makeLabel("for_loop")
|
||||||
val endLabel = asmgen.makeLabel("for_end")
|
val endLabel = asmgen.makeLabel("for_end")
|
||||||
asmgen.loopEndLabels.push(endLabel)
|
asmgen.loopEndLabels.push(endLabel)
|
||||||
@ -291,9 +290,9 @@ $loopLabel lda ${65535.toHex()} ; modified
|
|||||||
$endLabel""")
|
$endLabel""")
|
||||||
}
|
}
|
||||||
DataType.ARRAY_UB, DataType.ARRAY_B -> {
|
DataType.ARRAY_UB, DataType.ARRAY_B -> {
|
||||||
// TODO: optimize loop code when the length of the array is < 256 (i.e. always)
|
// TODO: optimize loop code when the length of the array is 255 or less instead of 256
|
||||||
val length = decl.arraysize!!.size()!!
|
val length = decl.arraysize!!.size()!!
|
||||||
val counterLabel = asmgen.makeLabel("for_counter") // todo allocate dynamically, zero page preferred if iterations >= 8
|
val counterLabel = asmgen.makeLabel("for_counter") // todo allocate dynamically, zero page preferred if len >= 16
|
||||||
val modifiedLabel = asmgen.makeLabel("for_modified")
|
val modifiedLabel = asmgen.makeLabel("for_modified")
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda #<$iterableName
|
lda #<$iterableName
|
||||||
@ -315,9 +314,9 @@ $counterLabel .byte 0
|
|||||||
$endLabel""")
|
$endLabel""")
|
||||||
}
|
}
|
||||||
DataType.ARRAY_W, DataType.ARRAY_UW -> {
|
DataType.ARRAY_W, DataType.ARRAY_UW -> {
|
||||||
// TODO: optimize loop code when the length of the array is < 256 (i.e. always)
|
// TODO: optimize loop code when the length of the array is 255 or less instead of 256
|
||||||
val length = decl.arraysize!!.size()!! * 2
|
val length = decl.arraysize!!.size()!! * 2
|
||||||
val counterLabel = asmgen.makeLabel("for_counter") // todo allocate dynamically, zero page preferred if iterations >= 8
|
val counterLabel = asmgen.makeLabel("for_counter") // todo allocate dynamically, zero page preferred if len >= 16
|
||||||
val modifiedLabel = asmgen.makeLabel("for_modified")
|
val modifiedLabel = asmgen.makeLabel("for_modified")
|
||||||
val modifiedLabel2 = asmgen.makeLabel("for_modified2")
|
val modifiedLabel2 = asmgen.makeLabel("for_modified2")
|
||||||
val loopvarName = asmgen.asmIdentifierName(stmt.loopVar)
|
val loopvarName = asmgen.asmIdentifierName(stmt.loopVar)
|
||||||
|
@ -274,22 +274,16 @@ private fun builtinLen(args: List<Expression>, position: Position, program: Prog
|
|||||||
arraySize = target.arraysize?.size()
|
arraySize = target.arraysize?.size()
|
||||||
if(arraySize==null)
|
if(arraySize==null)
|
||||||
throw CannotEvaluateException("len", "arraysize unknown")
|
throw CannotEvaluateException("len", "arraysize unknown")
|
||||||
if(arraySize>256)
|
|
||||||
throw CompilerException("array length exceeds byte limit ${target.position}")
|
|
||||||
NumericLiteralValue.optimalInteger(arraySize, args[0].position)
|
NumericLiteralValue.optimalInteger(arraySize, args[0].position)
|
||||||
}
|
}
|
||||||
DataType.ARRAY_F -> {
|
DataType.ARRAY_F -> {
|
||||||
arraySize = target.arraysize?.size()
|
arraySize = target.arraysize?.size()
|
||||||
if(arraySize==null)
|
if(arraySize==null)
|
||||||
throw CannotEvaluateException("len", "arraysize unknown")
|
throw CannotEvaluateException("len", "arraysize unknown")
|
||||||
if(arraySize>256)
|
|
||||||
throw CompilerException("array length exceeds byte limit ${target.position}")
|
|
||||||
NumericLiteralValue.optimalInteger(arraySize, args[0].position)
|
NumericLiteralValue.optimalInteger(arraySize, args[0].position)
|
||||||
}
|
}
|
||||||
DataType.STR -> {
|
DataType.STR -> {
|
||||||
val refLv = target.value as StringLiteralValue
|
val refLv = target.value as StringLiteralValue
|
||||||
if(refLv.value.length>255)
|
|
||||||
throw CompilerException("string length exceeds byte limit ${refLv.position}")
|
|
||||||
NumericLiteralValue.optimalInteger(refLv.value.length, args[0].position)
|
NumericLiteralValue.optimalInteger(refLv.value.length, args[0].position)
|
||||||
}
|
}
|
||||||
in NumericDatatypes -> throw SyntaxError("len of weird argument ${args[0]}", position)
|
in NumericDatatypes -> throw SyntaxError("len of weird argument ${args[0]}", position)
|
||||||
|
@ -257,6 +257,16 @@ Note that the various keywords for the data type and variable type (``byte``, ``
|
|||||||
can't be used as *identifiers* elsewhere. You can't make a variable, block or subroutine with the name ``byte``
|
can't be used as *identifiers* elsewhere. You can't make a variable, block or subroutine with the name ``byte``
|
||||||
for instance.
|
for instance.
|
||||||
|
|
||||||
|
**Arrays at a specific memory location:**
|
||||||
|
Using the memory-mapped syntax it is possible to define an array to be located at a specific memory location.
|
||||||
|
For instance to reference the first 5 rows of the Commodore 64's screen matrix as an array, you can define::
|
||||||
|
|
||||||
|
&ubyte[5*40] top5screenrows = $0400
|
||||||
|
|
||||||
|
This way you can set the second character on the second row from the top like this::
|
||||||
|
|
||||||
|
top5screenrows[41] = '!'
|
||||||
|
|
||||||
|
|
||||||
Strings
|
Strings
|
||||||
^^^^^^^
|
^^^^^^^
|
||||||
|
@ -306,6 +306,7 @@ should be allocated by the compiler. Instead, the (mandatory) value assigned to
|
|||||||
should be the *memory address* where the value is located::
|
should be the *memory address* where the value is located::
|
||||||
|
|
||||||
&byte BORDERCOLOR = $d020
|
&byte BORDERCOLOR = $d020
|
||||||
|
&ubyte[5*40] top5screenrows = $0400 ; works for array as well
|
||||||
|
|
||||||
|
|
||||||
Direct access to memory locations
|
Direct access to memory locations
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
|
- optimize assignment codegeneration
|
||||||
- get rid of all TODO's ;-)
|
- get rid of all TODO's ;-)
|
||||||
- allow declaring arrays on specific memory location and page-aligned
|
|
||||||
- option to load the built-in library files from a directory instead of the embedded ones (for easier library development/debugging)
|
- option to load the built-in library files from a directory instead of the embedded ones (for easier library development/debugging)
|
||||||
- aliases for imported symbols for example perhaps '%alias print = c64scr.print' ?
|
- aliases for imported symbols for example perhaps '%alias print = c64scr.print' ?
|
||||||
- investigate support for 8bitguy's Commander X16 platform https://www.commanderx16.com and https://github.com/commanderx16/x16-docs
|
- investigate support for 8bitguy's Commander X16 platform https://www.commanderx16.com and https://github.com/commanderx16/x16-docs
|
||||||
|
@ -24,20 +24,20 @@ main {
|
|||||||
; c64.CHROUT('\n')
|
; c64.CHROUT('\n')
|
||||||
|
|
||||||
|
|
||||||
; ubyte bb
|
ubyte bb
|
||||||
; ubyte from = 10
|
ubyte from = 10
|
||||||
; ubyte end = 20
|
ubyte end = 20
|
||||||
;
|
|
||||||
; for bb in from to end step 3 {
|
for bb in from to end step 3 {
|
||||||
; c64scr.print_ub(bb)
|
c64scr.print_ub(bb)
|
||||||
; c64.CHROUT(',')
|
c64.CHROUT(',')
|
||||||
; }
|
}
|
||||||
; c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
; for bb in end to from step -3 {
|
for bb in end to from step -3 {
|
||||||
; c64scr.print_ub(bb)
|
c64scr.print_ub(bb)
|
||||||
; c64.CHROUT(',')
|
c64.CHROUT(',')
|
||||||
; }
|
}
|
||||||
; c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
word ww
|
word ww
|
||||||
word fromw = -10
|
word fromw = -10
|
||||||
|
Loading…
Reference in New Issue
Block a user