document new bool datatype and removal of boolean() conversion function

This commit is contained in:
Irmen de Jong 2022-07-06 01:22:07 +02:00
parent 65daf29acd
commit 9500fc11ac
5 changed files with 49 additions and 57 deletions

View File

@ -191,7 +191,7 @@ class BinaryExpression(var left: Expression, var operator: String, var right: Ex
return when (parent) {
is TypecastExpression -> InferredTypes.InferredType.known((parent as TypecastExpression).type)
is Assignment -> (parent as Assignment).target.inferType(program)
else -> InferredTypes.InferredType.known(DataType.UBYTE)
else -> InferredTypes.InferredType.known(DataType.UBYTE) // note: don't use BOOL type here to avoid type errors later! Will be replaced anyway.
}
}
@ -214,7 +214,7 @@ class BinaryExpression(var left: Expression, var operator: String, var right: Ex
}
}
"&", "|", "^" -> if(leftDt istype DataType.BOOL) InferredTypes.knownFor(DataType.UBYTE) else leftDt
"and", "or", "xor", "not" -> InferredTypes.knownFor(DataType.UBYTE)
"and", "or", "xor", "not" -> InferredTypes.knownFor(DataType.UBYTE) // note: don't use BOOL type here to avoid type errors later! Will be replaced anyway.
"<", ">",
"<=", ">=",
"==", "!=", "in" -> dynamicBooleanType()

View File

@ -237,6 +237,20 @@ The signed integers integers are in the range -128..127 for bytes,
and -32768..32767 for words.
Boolean values
^^^^^^^^^^^^^^
These values are only ``true`` or ``false``, or 1 or 0. An integer's "truthy" value (i.e. a number
converted to boolean) is ``false`` (0) when it is zero and ``true`` (1) for all other values.
Logical expressions, comparisons and some other code might compile more efficiently if
you explicitly use ``bool`` types instead of integers there because that will avoid this conversion.
In the end the compiler translates boolean variables to a byte that stores just 0 or 1.
If you find that you need a whole bunch of boolean variables or perhaps even an array of them,
consider using bit masks in regular integer variables instead.
This saves a lot of memory and may be faster as well.
Floating point numbers
^^^^^^^^^^^^^^^^^^^^^^
@ -645,7 +659,9 @@ Arithmetic and Logical expressions
Arithmetic expressions are expressions that calculate a numeric result (integer or floating point).
Many common arithmetic operators can be used and follow the regular precedence rules.
Logical expressions are expressions that calculate a boolean result: true or false
(which in reality are just a 1 or 0 integer value).
(which in reality are just a 1 or 0 integer value). When using variables of the type ``bool``,
logical expressions will compile more efficiently than when you're using regular integer type operands
(because these have to be converted to 0 or 1 every time)
You can use parentheses to group parts of an expresion to change the precedence.
Usually the normal precedence rules apply (``*`` goes before ``+`` etc.) but subexpressions
@ -775,10 +791,6 @@ sort(array)
Miscellaneous
^^^^^^^^^^^^^
boolean(x)
Returns a byte value representing the boolean (truthy) value of x, where x can be any numeric type.
This means it returns 0 (false) when x equals 0, and 1 otherwise.
cmp(x,y)
Compare the integer value x to integer value y. Doesn't return a value or boolean result, only sets the processor's status bits!
You can use a conditional jumps (``if_cc`` etcetera) to act on this.

View File

@ -300,7 +300,7 @@ type identifier type storage size example var declara
=============== ======================= ================= =========================================
``byte`` signed byte 1 byte = 8 bits ``byte myvar = -22``
``ubyte`` unsigned byte 1 byte = 8 bits ``ubyte myvar = $8f``, ``ubyte c = 'a'``
-- boolean 1 byte = 8 bits ``byte myvar = true`` or ``byte myvar == false``
``bool`` boolean 1 byte = 8 bits ``bool myvar = true`` or ``bool myvar == false``
The true and false are actually just aliases
for the byte values 1 and 0.
``word`` signed word 2 bytes = 16 bits ``word myvar = -12345``
@ -312,11 +312,13 @@ type identifier type storage size example var declara
``word[x]`` signed word array 2*x bytes ``word[4] myvar``
``uword[x]`` unsigned word array 2*x bytes ``uword[4] myvar``
``float[x]`` floating-point array 5*x bytes ``float[4] myvar``
``bool[x]`` boolean array 5*x bytes ``bool[4] myvar`` note: consider using bit flags in a byte or word instead to save space
``byte[]`` signed byte array depends on value ``byte[] myvar = [1, 2, 3, 4]``
``ubyte[]`` unsigned byte array depends on value ``ubyte[] myvar = [1, 2, 3, 4]``
``word[]`` signed word array depends on value ``word[] myvar = [1, 2, 3, 4]``
``uword[]`` unsigned word array depends on value ``uword[] myvar = [1, 2, 3, 4]``
``float[]`` floating-point array depends on value ``float[] myvar = [1.1, 2.2, 3.3, 4.4]``
``bool[]`` boolean array depends on value ``bool[] myvar = [true, false, true]`` note: consider using bit flags in a byte or word instead to save space
``str[]`` array with string ptrs 2*x bytes + strs ``str[] names = ["ally", "pete"]``
``str`` string (petscii) varies ``str myvar = "hello."``
implicitly terminated by a 0-byte
@ -488,6 +490,11 @@ logical: ``not`` ``and`` ``or`` ``xor``
(which in reality is just a byte value of 1 or 0).
Notice that the expression ``not x`` is equivalent to ``x==0``, and the compiler will treat it as such.
.. note::
You can use regular integers directly in logical expressions but these have to be converted to
the boolean value 0 or 1 every time, resulting in larger and slower code. Consider using
the ``bool`` variable type instead, where this conversion doesn't need to occur.
.. note::
Unlike most other programming languages, there is no short-cirquit or McCarthy-evaluation
for the logical ``and`` and ``or`` operators. This means that prog8 currently always evaluates

View File

@ -3,6 +3,13 @@ TODO
For next release
^^^^^^^^^^^^^^^^
- add compiler error when using boolean with operators <,<=,>,>= (== and != are ok!)
- add compiler error when using boolean on lhs of operators -,*,/,% (+ is ok!)
- add compiler error when using boolean on rhs operators /,%
- test various scenarios of using bool type vs byte actually produces tighter code
make unit test of them?
...

View File

@ -3,59 +3,25 @@
main {
sub value(word input) -> word {
return input-999
}
sub boolfunc(bool data) -> bool {
return not data
}
bool boolvalue1 = true
bool boolvalue2 = false
ubyte ubvalue1 = true
ubyte ubvalue2 = false
sub start() {
if ubvalue1<44 or ubvalue1>99
txt.print("0\n")
ubyte ubb
if boolvalue1 or boolvalue2
txt.print("1\n")
if ubb and 10
ubb++
if boolvalue1 and boolvalue2
txt.print("2\n")
bool b1 = 1
bool b2 = 0
bool b3 = true
bool b4 = false
bool bb5 = -99
bool bb6 = 123
txt.print_ub(b1)
txt.spc()
txt.print_ub(b2)
txt.spc()
txt.print_ub(b3)
txt.spc()
txt.print_ub(b4)
txt.spc()
txt.print_b(bb5)
txt.spc()
txt.print_b(bb6)
txt.nl()
b1 = value(99) as bool
txt.print_ub(b1) ; should be 1
txt.spc()
txt.print_ub(value(99) as ubyte) ; should be 124
txt.spc()
txt.print_ub(value(99) as bool) ; should be 1
txt.nl()
txt.print_ub(boolfunc(true))
txt.spc()
txt.print_ub(boolfunc(false))
txt.nl()
ubb = ubb != 0
ubb++
ubb = bb6 != 0
txt.print_ub(ubb)
txt.nl()
; if ubvalue1 or ubvalu2
; txt.print("3\n")
;
; if ubvalue1 and ubvalu2
; txt.print("4\n")
}
}