mirror of
https://github.com/irmen/prog8.git
synced 2025-11-02 13:16:07 +00:00
remove "@split" tag
The default is to split word arrays. If you need your word array to not be split, use @nosplit on the array.
This commit is contained in:
@@ -530,6 +530,5 @@ enum class ZeropageWish {
|
|||||||
|
|
||||||
enum class SplitWish {
|
enum class SplitWish {
|
||||||
DONTCARE,
|
DONTCARE,
|
||||||
SPLIT,
|
|
||||||
NOSPLIT
|
NOSPLIT
|
||||||
}
|
}
|
||||||
@@ -1261,12 +1261,12 @@ $repeatLabel""")
|
|||||||
// print a message when more optimal code is possible for 65C02 cpu
|
// print a message when more optimal code is possible for 65C02 cpu
|
||||||
val variable = symbolTable.lookup(arrayVariable.name)!!
|
val variable = symbolTable.lookup(arrayVariable.name)!!
|
||||||
if(variable is StStaticVariable && variable.length!!<=128u)
|
if(variable is StStaticVariable && variable.length!!<=128u)
|
||||||
errors.info("the jump address array is @split, but @nosplit would create more efficient code here", jump.position)
|
errors.info("the jump address array is split, but @nosplit would create more efficient code here", jump.position)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// print a message when more optimal code is possible for 6502 cpu
|
// print a message when more optimal code is possible for 6502 cpu
|
||||||
if(!arrayIdx.splitWords)
|
if(!arrayIdx.splitWords)
|
||||||
errors.info("the jump address array is @nosplit, but @split would create more efficient code here", jump.position)
|
errors.info("the jump address array is @nosplit, but split would create more efficient code here", jump.position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// we can do the address evaluation right now and just use a temporary pointer variable
|
// we can do the address evaluation right now and just use a temporary pointer variable
|
||||||
|
|||||||
@@ -1038,7 +1038,7 @@ _doplot beq +
|
|||||||
|
|
||||||
; y*40 lookup table. Pretty compact because it all fits in a word and we only need 240 y positions.
|
; y*40 lookup table. Pretty compact because it all fits in a word and we only need 240 y positions.
|
||||||
; a y*80 lookup table would be very large (lo,mid,hi for 480 values...)
|
; a y*80 lookup table would be very large (lo,mid,hi for 480 values...)
|
||||||
uword[240] @split @shared times40 = [
|
uword[240] @shared times40 = [
|
||||||
0, 40, 80, 120, 160, 200, 240, 280, 320, 360, 400, 440, 480, 520, 560, 600,
|
0, 40, 80, 120, 160, 200, 240, 280, 320, 360, 400, 440, 480, 520, 560, 600,
|
||||||
640, 680, 720, 760, 800, 840, 880, 920, 960, 1000, 1040, 1080, 1120, 1160,
|
640, 680, 720, 760, 800, 840, 880, 920, 960, 1000, 1040, 1080, 1120, 1160,
|
||||||
1200, 1240, 1280, 1320, 1360, 1400, 1440, 1480, 1520, 1560, 1600, 1640, 1680,
|
1200, 1240, 1280, 1320, 1360, 1400, 1440, 1480, 1520, 1560, 1600, 1640, 1680,
|
||||||
|
|||||||
@@ -1090,8 +1090,8 @@ internal class AstChecker(private val program: Program,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(decl.datatype.isPointerArray) {
|
if(decl.datatype.isPointerArray) {
|
||||||
if(decl.splitwordarray!= SplitWish.SPLIT)
|
if(decl.splitwordarray==SplitWish.NOSPLIT)
|
||||||
errors.err("pointer arrays can only be @split", decl.position)
|
errors.err("pointer arrays can only be split", decl.position)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(decl.datatype.isStructInstance && decl.origin!=VarDeclOrigin.SUBROUTINEPARAM) {
|
if(decl.datatype.isStructInstance && decl.origin!=VarDeclOrigin.SUBROUTINEPARAM) {
|
||||||
|
|||||||
@@ -71,12 +71,11 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter,
|
|||||||
// check splitting of word arrays
|
// check splitting of word arrays
|
||||||
if(decl.splitwordarray != SplitWish.DONTCARE && !decl.datatype.isWordArray && !decl.datatype.isPointerArray) {
|
if(decl.splitwordarray != SplitWish.DONTCARE && !decl.datatype.isWordArray && !decl.datatype.isPointerArray) {
|
||||||
if(decl.origin != VarDeclOrigin.ARRAYLITERAL)
|
if(decl.origin != VarDeclOrigin.ARRAYLITERAL)
|
||||||
errors.err("@split and @nosplit are for word or pointer arrays only", decl.position)
|
errors.err("@nosplit is for word or pointer arrays only", decl.position)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(decl.datatype.isWordArray) {
|
if(decl.datatype.isWordArray) {
|
||||||
var changeDataType: DataType?
|
var changeDataType: DataType?
|
||||||
var changeSplit: SplitWish = decl.splitwordarray
|
|
||||||
when(decl.splitwordarray) {
|
when(decl.splitwordarray) {
|
||||||
SplitWish.DONTCARE -> {
|
SplitWish.DONTCARE -> {
|
||||||
changeDataType = if(decl.datatype.isSplitWordArray) null else {
|
changeDataType = if(decl.datatype.isSplitWordArray) null else {
|
||||||
@@ -86,16 +85,6 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter,
|
|||||||
else
|
else
|
||||||
DataType.arrayFor(eltDt.base)
|
DataType.arrayFor(eltDt.base)
|
||||||
}
|
}
|
||||||
changeSplit = SplitWish.SPLIT
|
|
||||||
}
|
|
||||||
SplitWish.SPLIT -> {
|
|
||||||
changeDataType = if(decl.datatype.isSplitWordArray) null else {
|
|
||||||
val eltDt = decl.datatype.elementType()
|
|
||||||
if(eltDt.isPointer)
|
|
||||||
TODO("convert array of pointers to split words array type")
|
|
||||||
else
|
|
||||||
DataType.arrayFor(eltDt.base)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
SplitWish.NOSPLIT -> {
|
SplitWish.NOSPLIT -> {
|
||||||
changeDataType = if(decl.datatype.isSplitWordArray && !decl.datatype.elementType().isPointer)
|
changeDataType = if(decl.datatype.isSplitWordArray && !decl.datatype.elementType().isPointer)
|
||||||
@@ -109,7 +98,7 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter,
|
|||||||
value = ArrayLiteral(InferredTypes.knownFor(changeDataType), value.value, value.position)
|
value = ArrayLiteral(InferredTypes.knownFor(changeDataType), value.value, value.position)
|
||||||
}
|
}
|
||||||
val newDecl = VarDecl(decl.type, decl.origin, changeDataType, decl.zeropage,
|
val newDecl = VarDecl(decl.type, decl.origin, changeDataType, decl.zeropage,
|
||||||
changeSplit, decl.arraysize, decl.name, decl.names,
|
decl.splitwordarray, decl.arraysize, decl.name, decl.names,
|
||||||
value, decl.sharedWithAsm, decl.alignment, decl.dirty, decl.position)
|
value, decl.sharedWithAsm, decl.alignment, decl.dirty, decl.position)
|
||||||
return listOf(IAstModification.ReplaceNode(decl, newDecl, parent))
|
return listOf(IAstModification.ReplaceNode(decl, newDecl, parent))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ internal class VerifyFunctionArgTypes(val program: Program, val options: Compila
|
|||||||
if(addrOf!=null) {
|
if(addrOf!=null) {
|
||||||
val identType = addrOf.identifier?.inferType(program)?.getOrUndef()
|
val identType = addrOf.identifier?.inferType(program)?.getOrUndef()
|
||||||
if(identType?.isSplitWordArray==true) {
|
if(identType?.isSplitWordArray==true) {
|
||||||
return Pair("argument ${mismatch + 1} type mismatch, was: $actual (because arg is a @split word array) expected: $expected", call.args[mismatch].position)
|
return Pair("argument ${mismatch + 1} type mismatch, was: $actual (because arg is a split word array) expected: $expected", call.args[mismatch].position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1951,7 +1951,7 @@ main {
|
|||||||
val src="""
|
val src="""
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
uword[10] @split @shared splitarray
|
uword[10] @shared splitarray
|
||||||
uword[10] @nosplit @shared nosplitarray
|
uword[10] @nosplit @shared nosplitarray
|
||||||
|
|
||||||
^^uword ptr1 = &&splitarray
|
^^uword ptr1 = &&splitarray
|
||||||
@@ -1992,9 +1992,9 @@ main {
|
|||||||
errors.errors.size shouldBe 3
|
errors.errors.size shouldBe 3
|
||||||
errors.warnings.size shouldBe 0
|
errors.warnings.size shouldBe 0
|
||||||
errors.infos.size shouldBe 0
|
errors.infos.size shouldBe 0
|
||||||
errors.errors[0] shouldContain "pointer arrays can only be @split"
|
errors.errors[0] shouldContain "pointer arrays can only be split"
|
||||||
errors.errors[1] shouldContain "was: ^^ubyte (because arg is a @split word array) expected: ^^main.Node"
|
errors.errors[1] shouldContain "was: ^^ubyte (because arg is a split word array) expected: ^^main.Node"
|
||||||
errors.errors[2] shouldContain "was: ^^ubyte (because arg is a @split word array) expected: ^^main.Node"
|
errors.errors[2] shouldContain "was: ^^ubyte (because arg is a split word array) expected: ^^main.Node"
|
||||||
}
|
}
|
||||||
|
|
||||||
test("passing split array of structpointers to a subroutine in various forms should be param type ptr to ubyte (the lsb part of the split array)") {
|
test("passing split array of structpointers to a subroutine in various forms should be param type ptr to ubyte (the lsb part of the split array)") {
|
||||||
@@ -2005,7 +2005,7 @@ main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
^^Node[10] @split nodearray
|
^^Node[10] nodearray
|
||||||
func(&&nodearray)
|
func(&&nodearray)
|
||||||
func(&nodearray)
|
func(&nodearray)
|
||||||
func(nodearray)
|
func(nodearray)
|
||||||
|
|||||||
@@ -1129,30 +1129,26 @@ thing {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test("pointer arrays are always split") {
|
test("pointer arrays are split by default") {
|
||||||
val src="""
|
val src="""
|
||||||
%option enable_floats
|
%option enable_floats
|
||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
^^bool[10] @split @shared barray
|
^^bool[10] @shared barray
|
||||||
^^word[10] @split @shared warray
|
^^word[10] @shared warray
|
||||||
^^float[10] @split @shared farray
|
^^float[10] @shared farray
|
||||||
|
|
||||||
^^bool[10] @shared barrayns
|
|
||||||
^^word[10] @shared warrayns
|
|
||||||
^^float[10] @shared farrayns
|
|
||||||
}
|
}
|
||||||
}"""
|
}"""
|
||||||
|
|
||||||
val result = compileText(VMTarget(), optimize=false, src, outputDir, writeAssembly=false)!!
|
val result = compileText(VMTarget(), optimize=false, src, outputDir, writeAssembly=false)!!
|
||||||
val st = result.compilerAst.entrypoint.statements
|
val st = result.compilerAst.entrypoint.statements
|
||||||
st.size shouldBe 7
|
st.size shouldBe 4
|
||||||
val decls = st.filterIsInstance<VarDecl>()
|
val decls = st.filterIsInstance<VarDecl>()
|
||||||
decls.size shouldBe 6
|
decls.size shouldBe 3
|
||||||
decls.all { it.datatype.sub!=null } shouldBe true
|
decls.all { it.datatype.sub!=null } shouldBe true
|
||||||
decls.all { it.datatype.isPointerArray } shouldBe true
|
decls.all { it.datatype.isPointerArray } shouldBe true
|
||||||
decls.all { it.datatype.isPointerArray } shouldBe true
|
decls.all { it.datatype.isSplitWordArray } shouldBe true
|
||||||
}
|
}
|
||||||
|
|
||||||
test("on..call in nested scope compiles correctly with temp variable introduced") {
|
test("on..call in nested scope compiles correctly with temp variable introduced") {
|
||||||
|
|||||||
@@ -80,8 +80,8 @@ def make_test_array(datatype, comparison: C):
|
|||||||
numbers = testnumbers[datatype]
|
numbers = testnumbers[datatype]
|
||||||
print(" sub test_cmp_array() {")
|
print(" sub test_cmp_array() {")
|
||||||
print(f""" {datatype} @shared x
|
print(f""" {datatype} @shared x
|
||||||
{datatype}[] @split values = [0, 0]
|
{datatype}[] values = [0, 0]
|
||||||
{datatype}[] @split sources = [0, 0]
|
{datatype}[] sources = [0, 0]
|
||||||
success = 0""")
|
success = 0""")
|
||||||
expected = 0
|
expected = 0
|
||||||
test_index = 0
|
test_index = 0
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ main {{
|
|||||||
test_is_var()
|
test_is_var()
|
||||||
txt.print("\\n!=var: ")
|
txt.print("\\n!=var: ")
|
||||||
test_not_var()
|
test_not_var()
|
||||||
txt.print("\\n==array[] @split: ")
|
txt.print("\\n==array[] split: ")
|
||||||
test_is_array_splitw()
|
test_is_array_splitw()
|
||||||
txt.print("\\n!=array[] @split: ")
|
txt.print("\\n!=array[] split: ")
|
||||||
test_not_array_splitw()
|
test_not_array_splitw()
|
||||||
txt.print("\\n==expr: ")
|
txt.print("\\n==expr: ")
|
||||||
test_is_expr()
|
test_is_expr()
|
||||||
@@ -97,7 +97,7 @@ nonzero_values = {
|
|||||||
def make_test_is_zero(datatype):
|
def make_test_is_zero(datatype):
|
||||||
print(f"""
|
print(f"""
|
||||||
sub test_is_zero() {{
|
sub test_is_zero() {{
|
||||||
{datatype}[] @split sources = [9999, 9999]
|
{datatype}[] sources = [9999, 9999]
|
||||||
success = 0
|
success = 0
|
||||||
|
|
||||||
sources[1]={zero_values[datatype]}
|
sources[1]={zero_values[datatype]}
|
||||||
@@ -155,7 +155,7 @@ skip4:
|
|||||||
def make_test_not_zero(datatype):
|
def make_test_not_zero(datatype):
|
||||||
print(f"""
|
print(f"""
|
||||||
sub test_not_zero() {{
|
sub test_not_zero() {{
|
||||||
{datatype}[] @split sources = [9999, 9999]
|
{datatype}[] sources = [9999, 9999]
|
||||||
success = 0
|
success = 0
|
||||||
|
|
||||||
sources[1]={nonzero_values[datatype]}
|
sources[1]={nonzero_values[datatype]}
|
||||||
@@ -229,7 +229,7 @@ testnumbers = {
|
|||||||
def make_test_is_number(datatype, equals):
|
def make_test_is_number(datatype, equals):
|
||||||
numbers = testnumbers[datatype]
|
numbers = testnumbers[datatype]
|
||||||
print(" sub test_is_number() {" if equals else " sub test_not_number() {")
|
print(" sub test_is_number() {" if equals else " sub test_not_number() {")
|
||||||
print(f""" {datatype}[] @split sources = [9999, 9999]
|
print(f""" {datatype}[] sources = [9999, 9999]
|
||||||
success = 0""")
|
success = 0""")
|
||||||
expected = 0
|
expected = 0
|
||||||
test_index = 0
|
test_index = 0
|
||||||
@@ -286,8 +286,8 @@ skip{test_index}b:
|
|||||||
def make_test_is_var(datatype, equals):
|
def make_test_is_var(datatype, equals):
|
||||||
numbers = testnumbers[datatype]
|
numbers = testnumbers[datatype]
|
||||||
print(" sub test_is_var() {" if equals else " sub test_not_var() {")
|
print(" sub test_is_var() {" if equals else " sub test_not_var() {")
|
||||||
print(f""" {datatype}[] @split sources = [9999, 9999]
|
print(f""" {datatype}[] sources = [9999, 9999]
|
||||||
{datatype}[] @split values = [8888,8888]
|
{datatype}[] values = [8888,8888]
|
||||||
success = 0""")
|
success = 0""")
|
||||||
expected = 0
|
expected = 0
|
||||||
test_index = 0
|
test_index = 0
|
||||||
@@ -346,8 +346,8 @@ def make_test_is_array(datatype, equals):
|
|||||||
numbers = testnumbers[datatype]
|
numbers = testnumbers[datatype]
|
||||||
print(" sub test_is_array_splitw() {" if equals else " sub test_not_array_splitw() {")
|
print(" sub test_is_array_splitw() {" if equals else " sub test_not_array_splitw() {")
|
||||||
print(f"""
|
print(f"""
|
||||||
{datatype}[] @split values = [9999, 8888]
|
{datatype}[] values = [9999, 8888]
|
||||||
{datatype}[] @split sources = [9999, 8888]
|
{datatype}[] sources = [9999, 8888]
|
||||||
success = 0""")
|
success = 0""")
|
||||||
expected = 0
|
expected = 0
|
||||||
test_index = 0
|
test_index = 0
|
||||||
@@ -441,7 +441,7 @@ skip{test_index}d:
|
|||||||
def make_test_is_expr(datatype, equals):
|
def make_test_is_expr(datatype, equals):
|
||||||
numbers = testnumbers[datatype]
|
numbers = testnumbers[datatype]
|
||||||
print(" sub test_is_expr() {" if equals else " sub test_not_expr() {")
|
print(" sub test_is_expr() {" if equals else " sub test_not_expr() {")
|
||||||
print(f""" {datatype}[] @split sources = [9999, 9999]
|
print(f""" {datatype}[] sources = [9999, 9999]
|
||||||
cx16.r4 = 1
|
cx16.r4 = 1
|
||||||
cx16.r5 = 1
|
cx16.r5 = 1
|
||||||
success = 0""")
|
success = 0""")
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ class Antlr2KotlinVisitor(val source: SourceCode): AbstractParseTreeVisitor<Node
|
|||||||
|
|
||||||
override fun visitVardecl(ctx: VardeclContext): VarDecl {
|
override fun visitVardecl(ctx: VardeclContext): VarDecl {
|
||||||
val tags = ctx.TAG().map { it.text }
|
val tags = ctx.TAG().map { it.text }
|
||||||
val validTags = arrayOf("@zp", "@requirezp", "@nozp", "@split", "@nosplit", "@shared", "@alignword", "@alignpage", "@align64", "@dirty")
|
val validTags = arrayOf("@zp", "@requirezp", "@nozp", "@nosplit", "@shared", "@alignword", "@alignpage", "@align64", "@dirty")
|
||||||
for(tag in tags) {
|
for(tag in tags) {
|
||||||
if(tag !in validTags)
|
if(tag !in validTags)
|
||||||
throw SyntaxError("invalid variable tag '$tag'", ctx.toPosition())
|
throw SyntaxError("invalid variable tag '$tag'", ctx.toPosition())
|
||||||
@@ -167,17 +167,12 @@ class Antlr2KotlinVisitor(val source: SourceCode): AbstractParseTreeVisitor<Node
|
|||||||
DataType.arrayFor(baseDt.base, split!=SplitWish.NOSPLIT)
|
DataType.arrayFor(baseDt.base, split!=SplitWish.NOSPLIT)
|
||||||
}
|
}
|
||||||
|
|
||||||
val splitWords = if(split==SplitWish.DONTCARE) {
|
|
||||||
if(dt.isPointerArray) SplitWish.SPLIT // pointer arrays are always @split by default
|
|
||||||
else split
|
|
||||||
} else split
|
|
||||||
|
|
||||||
return VarDecl(
|
return VarDecl(
|
||||||
VarDeclType.VAR, // can be changed to MEMORY or CONST as required
|
VarDeclType.VAR, // can be changed to MEMORY or CONST as required
|
||||||
VarDeclOrigin.USERCODE,
|
VarDeclOrigin.USERCODE,
|
||||||
dt,
|
dt,
|
||||||
zp,
|
zp,
|
||||||
splitWords,
|
split,
|
||||||
arrayIndex,
|
arrayIndex,
|
||||||
name,
|
name,
|
||||||
if(identifiers.size==1) emptyList() else identifiers,
|
if(identifiers.size==1) emptyList() else identifiers,
|
||||||
@@ -486,7 +481,7 @@ class Antlr2KotlinVisitor(val source: SourceCode): AbstractParseTreeVisitor<Node
|
|||||||
override fun visitSub_param(pctx: Sub_paramContext): SubroutineParameter {
|
override fun visitSub_param(pctx: Sub_paramContext): SubroutineParameter {
|
||||||
val decl = pctx.vardecl()
|
val decl = pctx.vardecl()
|
||||||
val tags = decl.TAG().map { t -> t.text }
|
val tags = decl.TAG().map { t -> t.text }
|
||||||
val validTags = arrayOf("@zp", "@requirezp", "@nozp", "@split", "@nosplit", "@shared")
|
val validTags = arrayOf("@zp", "@requirezp", "@nozp", "@nosplit", "@shared")
|
||||||
for(tag in tags) {
|
for(tag in tags) {
|
||||||
if(tag !in validTags)
|
if(tag !in validTags)
|
||||||
throw SyntaxError("invalid parameter tag '$tag'", pctx.toPosition())
|
throw SyntaxError("invalid parameter tag '$tag'", pctx.toPosition())
|
||||||
@@ -724,7 +719,6 @@ class Antlr2KotlinVisitor(val source: SourceCode): AbstractParseTreeVisitor<Node
|
|||||||
private fun getSplitOption(tags: List<String>): SplitWish {
|
private fun getSplitOption(tags: List<String>): SplitWish {
|
||||||
return when {
|
return when {
|
||||||
"@nosplit" in tags -> SplitWish.NOSPLIT
|
"@nosplit" in tags -> SplitWish.NOSPLIT
|
||||||
"@split" in tags -> SplitWish.SPLIT
|
|
||||||
else -> SplitWish.DONTCARE
|
else -> SplitWish.DONTCARE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -305,7 +305,7 @@ class VarDecl(
|
|||||||
fun createAutoOptionalSplit(array: ArrayLiteral): VarDecl {
|
fun createAutoOptionalSplit(array: ArrayLiteral): VarDecl {
|
||||||
val autoVarName = "auto_heap_value_${++autoHeapValueSequenceNumber}"
|
val autoVarName = "auto_heap_value_${++autoHeapValueSequenceNumber}"
|
||||||
val arrayDt = array.type.getOrElse { throw FatalAstException("unknown dt") }
|
val arrayDt = array.type.getOrElse { throw FatalAstException("unknown dt") }
|
||||||
val split = if(arrayDt.isSplitWordArray) SplitWish.SPLIT else if(arrayDt.isWordArray) SplitWish.NOSPLIT else SplitWish.DONTCARE
|
val split = if(arrayDt.isSplitWordArray) SplitWish.DONTCARE else if(arrayDt.isWordArray) SplitWish.NOSPLIT else SplitWish.DONTCARE
|
||||||
val arraysize = ArrayIndex.forArray(array)
|
val arraysize = ArrayIndex.forArray(array)
|
||||||
return VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, arrayDt, ZeropageWish.NOT_IN_ZEROPAGE,
|
return VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, arrayDt, ZeropageWish.NOT_IN_ZEROPAGE,
|
||||||
split, arraysize, autoVarName, emptyList(), array,
|
split, arraysize, autoVarName, emptyList(), array,
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
remove "@split" tag SplitWish.NOSPLIT
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
LONG TYPE
|
LONG TYPE
|
||||||
---------
|
---------
|
||||||
- implement the other comparison operators (<,>,<=,>=) on longs
|
- implement the other comparison operators (<,>,<=,>=) on longs
|
||||||
|
|||||||
@@ -358,7 +358,7 @@ See also :ref:`pointervars` and the chapter about it :ref:`pointers`.
|
|||||||
|
|
||||||
**LSB/MSB split word and str arrays:**
|
**LSB/MSB split word and str arrays:**
|
||||||
|
|
||||||
As an optimization, (u)word arrays and str arrays are split by the compiler in memory as two separate arrays,
|
As an optimization, (u)word arrays, pointer arrays, and str arrays are split by the compiler in memory as two separate arrays,
|
||||||
one with the LSBs and one with the MSBs of the word values. This is more efficient to access by the 6502 cpu.
|
one with the LSBs and one with the MSBs of the word values. This is more efficient to access by the 6502 cpu.
|
||||||
It also allows a maximum length of 256 for word arrays, where normally it would have been 128.
|
It also allows a maximum length of 256 for word arrays, where normally it would have been 128.
|
||||||
|
|
||||||
@@ -366,13 +366,14 @@ For normal prog8 array indexing, the compiler takes care of the distiction for y
|
|||||||
*But for assembly code, or code that otherwise accesses the array elements directly, you have to be aware of the distinction from 'normal' arrays.*
|
*But for assembly code, or code that otherwise accesses the array elements directly, you have to be aware of the distinction from 'normal' arrays.*
|
||||||
In the assembly code, the array is generated as two byte arrays namely ``name_lsb`` and ``name_msb``, immediately following eachother in memory.
|
In the assembly code, the array is generated as two byte arrays namely ``name_lsb`` and ``name_msb``, immediately following eachother in memory.
|
||||||
|
|
||||||
The ``@nosplit`` tag can be added to the variable declaration to *never* split the array. This is useful for compatibility with
|
The ``@nosplit`` tag can be added to the variable declaration to *not* split the array. This is useful for compatibility with
|
||||||
code that expects the words to be sequentially in memory (such as the cx16.FB_set_palette routine).
|
code that expects the words to be sequentially in memory (such as the cx16.FB_set_palette routine).
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
Most but not all array operations are supported yet on "split word arrays".
|
Some obscure array operations may not yet be supported on "split word arrays".
|
||||||
If you get a compiler error message, simply revert to a regular sequential word array using ``@nosplit``,
|
If you get a compiler error message hinting that this is the case,
|
||||||
and please report the issue.
|
simply revert to a regular sequential word array using ``@nosplit``, and please report the issue so that
|
||||||
|
the missing function can be added.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
Array literals are stored as split arrays if they're initializing a split word array, otherwise,
|
Array literals are stored as split arrays if they're initializing a split word array, otherwise,
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<option name="HAS_STRING_ESCAPES" value="true" />
|
<option name="HAS_STRING_ESCAPES" value="true" />
|
||||||
</options>
|
</options>
|
||||||
<keywords keywords="&;&&;&<;&>;->;@;^^;alias;and;as;asmsub;break;clobbers;continue;do;downto;else;extsub;false;for;goto;if;if_cc;if_cs;if_eq;if_mi;if_ne;if_neg;if_nz;if_pl;if_pos;if_vc;if_vs;if_z;in;inline;not;on;or;repeat;return;step;sub;to;true;unroll;until;when;while;xor;~" ignore_case="false" />
|
<keywords keywords="&;&&;&<;&>;->;@;^^;alias;and;as;asmsub;break;clobbers;continue;do;downto;else;extsub;false;for;goto;if;if_cc;if_cs;if_eq;if_mi;if_ne;if_neg;if_nz;if_pl;if_pos;if_vc;if_vs;if_z;in;inline;not;on;or;repeat;return;step;sub;to;true;unroll;until;when;while;xor;~" ignore_case="false" />
|
||||||
<keywords2 keywords="%address;%align;%asm;%asmbinary;%asminclude;%breakpoint;%encoding;%import;%ir;%jmptable;%launcher;%memtop;%option;%output;%zeropage;%zpallowed;%zpreserved;@align64;@alignpage;@alignword;@bank;@dirty;@nosplit;@nozp;@requirezp;@shared;@split;@zp;atascii:;c64os:;cp437:;default:;iso16:;iso5:;iso:;kata:;petscii:;sc:" />
|
<keywords2 keywords="%address;%align;%asm;%asmbinary;%asminclude;%breakpoint;%encoding;%import;%ir;%jmptable;%launcher;%memtop;%option;%output;%zeropage;%zpallowed;%zpreserved;@align64;@alignpage;@alignword;@bank;@dirty;@nosplit;@nozp;@requirezp;@shared;@zp;atascii:;c64os:;cp437:;default:;iso16:;iso5:;iso:;kata:;petscii:;sc:" />
|
||||||
<keywords3 keywords="^^bool;^^byte;^^float;^^long;^^str;^^ubyte;^^uword;^^word;bool;byte;const;float;long;str;struct;ubyte;uword;void;word" />
|
<keywords3 keywords="^^bool;^^byte;^^float;^^long;^^str;^^ubyte;^^uword;^^word;bool;byte;const;float;long;str;struct;ubyte;uword;void;word" />
|
||||||
<keywords4 keywords="abs;bmx;call;callfar;callfar2;cbm;clamp;cmp;conv;cx16;defer;diskio;divmod;floats;len;lsb;lsw;math;max;memory;min;mkword;msb;msw;offsetof;peek;peekbool;peekf;peekw;poke;pokebool;pokef;pokew;psg;rol;rol2;ror;ror2;rrestore;rrestorex;rsave;rsavex;setlsb;setmsb;sgn;sizeof;sqrt;strings;sys;txt;verafx" />
|
<keywords4 keywords="abs;bmx;call;callfar;callfar2;cbm;clamp;cmp;conv;cx16;defer;diskio;divmod;floats;len;lsb;lsw;math;max;memory;min;mkword;msb;msw;offsetof;peek;peekbool;peekf;peekw;poke;pokebool;pokef;pokew;psg;rol;rol2;ror;ror2;rrestore;rrestorex;rsave;rsavex;setlsb;setmsb;sgn;sizeof;sqrt;strings;sys;txt;verafx" />
|
||||||
</highlighting>
|
</highlighting>
|
||||||
@@ -20,4 +20,4 @@
|
|||||||
<mapping ext="p8" />
|
<mapping ext="p8" />
|
||||||
<mapping ext="prog8" />
|
<mapping ext="prog8" />
|
||||||
</extensionMap>
|
</extensionMap>
|
||||||
</filetype>
|
</filetype>
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ syn region prog8ArrayType matchgroup=prog8Type
|
|||||||
\ start="\<\%(u\?byte\|u\?word\|float\|str\|bool\)\[" end="\]"
|
\ start="\<\%(u\?byte\|u\?word\|float\|str\|bool\)\[" end="\]"
|
||||||
\ transparent
|
\ transparent
|
||||||
syn keyword prog8StorageClass const
|
syn keyword prog8StorageClass const
|
||||||
syn match prog8StorageClass "\(^\|\s\)\(@zp\|@bank\|@shared\|@split\|@nosplit\|@nozp\|@requirezp\|@align64\|@alignword\|@alignpage\|@dirty\)\>"
|
syn match prog8StorageClass "\(^\|\s\)\(@zp\|@bank\|@shared\|@nosplit\|@nozp\|@requirezp\|@align64\|@alignword\|@alignpage\|@dirty\)\>"
|
||||||
|
|
||||||
syn region prog8Block start="{" end="}" transparent
|
syn region prog8Block start="{" end="}" transparent
|
||||||
syn region prog8Expression start="(" end=")" transparent
|
syn region prog8Expression start="(" end=")" transparent
|
||||||
|
|||||||
Reference in New Issue
Block a user