diff --git a/codeCore/src/prog8/code/core/Enumerations.kt b/codeCore/src/prog8/code/core/Enumerations.kt index e1a4eb4f0..ecfb278ee 100644 --- a/codeCore/src/prog8/code/core/Enumerations.kt +++ b/codeCore/src/prog8/code/core/Enumerations.kt @@ -13,6 +13,7 @@ enum class DataType { ARRAY_UW, // pass by reference ARRAY_W, // pass by reference ARRAY_F, // pass by reference + ARRAY_BOOL, // pass by reference UNDEFINED; /** @@ -116,13 +117,13 @@ val WordDatatypes = arrayOf(DataType.UWORD, DataType.WORD) val IntegerDatatypes = arrayOf(DataType.UBYTE, DataType.BYTE, DataType.UWORD, DataType.WORD, DataType.BOOL) val NumericDatatypes = arrayOf(DataType.UBYTE, DataType.BYTE, DataType.UWORD, DataType.WORD, DataType.FLOAT, DataType.BOOL) val SignedDatatypes = arrayOf(DataType.BYTE, DataType.WORD, DataType.FLOAT) -val ArrayDatatypes = arrayOf(DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_UW, DataType.ARRAY_W, DataType.ARRAY_F) +val ArrayDatatypes = arrayOf(DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_UW, DataType.ARRAY_W, DataType.ARRAY_F, DataType.ARRAY_BOOL) val StringlyDatatypes = arrayOf(DataType.STR, DataType.ARRAY_UB, DataType.ARRAY_B, DataType.UWORD) val IterableDatatypes = arrayOf( DataType.STR, DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_UW, DataType.ARRAY_W, - DataType.ARRAY_F + DataType.ARRAY_F, DataType.ARRAY_BOOL ) val PassByValueDatatypes = NumericDatatypes val PassByReferenceDatatypes = IterableDatatypes @@ -132,14 +133,16 @@ val ArrayToElementTypes = mapOf( DataType.ARRAY_UB to DataType.UBYTE, DataType.ARRAY_W to DataType.WORD, DataType.ARRAY_UW to DataType.UWORD, - DataType.ARRAY_F to DataType.FLOAT + DataType.ARRAY_F to DataType.FLOAT, + DataType.ARRAY_BOOL to DataType.BOOL ) val ElementToArrayTypes = mapOf( DataType.BYTE to DataType.ARRAY_B, DataType.UBYTE to DataType.ARRAY_UB, DataType.WORD to DataType.ARRAY_W, DataType.UWORD to DataType.ARRAY_UW, - DataType.FLOAT to DataType.ARRAY_F + DataType.FLOAT to DataType.ARRAY_F, + DataType.BOOL to DataType.ARRAY_BOOL ) val Cx16VirtualRegisters = arrayOf( RegisterOrPair.R0, RegisterOrPair.R1, RegisterOrPair.R2, RegisterOrPair.R3, diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index 4c36145a2..1dd9f515c 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -119,6 +119,10 @@ internal class AstChecker(private val program: Program, checkUnsignedLoopDownto0(forLoop.iterable as? RangeExpression) } + DataType.BOOL -> { + if(iterableDt != DataType.ARRAY_BOOL) + errors.err("bool loop variable can only loop over boolean array", forLoop.position) + } DataType.UWORD -> { if(iterableDt!= DataType.UBYTE && iterableDt!= DataType.UWORD && iterableDt != DataType.STR && iterableDt != DataType.ARRAY_UB && iterableDt!= DataType.ARRAY_UW) diff --git a/compiler/src/prog8/compiler/astprocessing/BeforeAsmAstChanger.kt b/compiler/src/prog8/compiler/astprocessing/BeforeAsmAstChanger.kt index 9c32e3d54..963f83b4d 100644 --- a/compiler/src/prog8/compiler/astprocessing/BeforeAsmAstChanger.kt +++ b/compiler/src/prog8/compiler/astprocessing/BeforeAsmAstChanger.kt @@ -19,8 +19,8 @@ internal class BeforeAsmAstChanger(val program: Program, if(numLiteral.type==DataType.BOOL) return listOf(IAstModification.ReplaceNode(numLiteral, NumericLiteral(DataType.UBYTE, numLiteral.number, numLiteral.position), parent)) return noModifications - } + override fun before(breakStmt: Break, parent: Node): Iterable { throw InternalCompilerException("break should have been replaced by goto $breakStmt") } @@ -72,6 +72,12 @@ internal class BeforeAsmAstChanger(val program: Program, return listOf(IAstModification.ReplaceNode(decl, ubyteDecl, parent)) } + if(decl.datatype==DataType.ARRAY_BOOL) { + val ubyteArrayDecl = VarDecl(decl.type, decl.origin, DataType.ARRAY_UB, decl.zeropage, decl.arraysize, decl.name, + decl.value, decl.isArray, decl.sharedWithAsm, decl.subroutineParameter, decl.position) + return listOf(IAstModification.ReplaceNode(decl, ubyteArrayDecl, parent)) + } + return noModifications } diff --git a/compiler/test/TestTypecasts.kt b/compiler/test/TestTypecasts.kt index 58b0c8ab4..3ca992944 100644 --- a/compiler/test/TestTypecasts.kt +++ b/compiler/test/TestTypecasts.kt @@ -10,16 +10,44 @@ import prog8.ast.IFunctionCall import prog8.ast.expressions.* import prog8.ast.statements.Assignment import prog8.ast.statements.IfElse +import prog8.ast.statements.VarDecl import prog8.code.core.DataType import prog8.code.core.Position import prog8.code.target.C64Target -import prog8.compiler.printProgram import prog8tests.helpers.ErrorReporterForTests import prog8tests.helpers.compileText class TestTypecasts: FunSpec({ + test("bool arrays") { + val text=""" + main { + sub start() { + bool[] barray = [true, false, 1, 0, 222] + bool bb + ubyte xx + + for bb in barray { + if bb + xx++ + } + } + }""" + val result = compileText(C64Target(), false, text, writeAssembly = false)!! + val stmts = result.program.entrypoint.statements + stmts.size shouldBe 6 + val arraydecl = stmts[0] as VarDecl + arraydecl.datatype shouldBe DataType.ARRAY_BOOL + val values = (arraydecl.value as ArrayLiteral).value + values.size shouldBe 5 + values[0] shouldBe NumericLiteral(DataType.UBYTE, 1.0, Position.DUMMY) + values[1] shouldBe NumericLiteral(DataType.UBYTE, 0.0, Position.DUMMY) + values[2] shouldBe NumericLiteral(DataType.UBYTE, 1.0, Position.DUMMY) + values[3] shouldBe NumericLiteral(DataType.UBYTE, 0.0, Position.DUMMY) + values[4] shouldBe NumericLiteral(DataType.UBYTE, 1.0, Position.DUMMY) + } + test("correct handling of bool parameters") { val text=""" main { diff --git a/compilerAst/src/prog8/ast/AstToSourceTextConverter.kt b/compilerAst/src/prog8/ast/AstToSourceTextConverter.kt index e56c1f861..92c2a88f6 100644 --- a/compilerAst/src/prog8/ast/AstToSourceTextConverter.kt +++ b/compilerAst/src/prog8/ast/AstToSourceTextConverter.kt @@ -93,7 +93,8 @@ class AstToSourceTextConverter(val output: (text: String) -> Unit, val program: DataType.ARRAY_UW -> "uword[" DataType.ARRAY_W -> "word[" DataType.ARRAY_F -> "float[" - else -> "?????" + DataType.ARRAY_BOOL -> "bool[" + else -> throw IllegalArgumentException("weird dt: $dt") } } diff --git a/compilerAst/src/prog8/ast/expressions/InferredTypes.kt b/compilerAst/src/prog8/ast/expressions/InferredTypes.kt index de79210de..79891a140 100644 --- a/compilerAst/src/prog8/ast/expressions/InferredTypes.kt +++ b/compilerAst/src/prog8/ast/expressions/InferredTypes.kt @@ -74,7 +74,8 @@ 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.ARRAY_F to InferredType.known(DataType.ARRAY_F), + DataType.ARRAY_BOOL to InferredType.known(DataType.ARRAY_BOOL) ) fun void() = voidInstance diff --git a/compilerAst/src/prog8/ast/statements/AstStatements.kt b/compilerAst/src/prog8/ast/statements/AstStatements.kt index 01aa5ffc6..3b759a062 100644 --- a/compilerAst/src/prog8/ast/statements/AstStatements.kt +++ b/compilerAst/src/prog8/ast/statements/AstStatements.kt @@ -228,6 +228,7 @@ class VarDecl(val type: VarDeclType, DataType.UWORD -> DataType.ARRAY_UW DataType.WORD -> DataType.ARRAY_W DataType.FLOAT -> DataType.ARRAY_F + DataType.BOOL -> DataType.ARRAY_BOOL DataType.STR -> DataType.ARRAY_UW // use memory address of the string instead else -> { datatypeErrors.add(SyntaxError("array can only contain bytes/words/floats/strings(ptrs)", position)) diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 0cddfd5ff..22449c534 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,9 +3,6 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- add ARRAY_OF_BOOL array type - - ... diff --git a/examples/test.p8 b/examples/test.p8 index 5f3de569e..92dc1ec19 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -3,19 +3,15 @@ main { - sub thing(bool b1, bool b2) -> bool { - return (b1 and b2) or b1 - } + bool[] barray = [true, false, 1, 0, 222] sub start() { - bool boolvalue1 = true - bool boolvalue2 = false - uword xx + bool bb + ubyte xx - boolvalue1 = thing(true, false) - boolvalue2 = thing(xx, xx) - - if boolvalue1 and boolvalue2 - boolvalue1=false + for bb in barray { + if bb + xx++ + } } }