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) { return when (parent) {
is TypecastExpression -> InferredTypes.InferredType.known((parent as TypecastExpression).type) is TypecastExpression -> InferredTypes.InferredType.known((parent as TypecastExpression).type)
is Assignment -> (parent as Assignment).target.inferType(program) 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 "&", "|", "^" -> 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() "==", "!=", "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. 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 Floating point numbers
^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
@ -645,7 +659,9 @@ Arithmetic and Logical expressions
Arithmetic expressions are expressions that calculate a numeric result (integer or floating point). 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. 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 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. 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 Usually the normal precedence rules apply (``*`` goes before ``+`` etc.) but subexpressions
@ -775,10 +791,6 @@ sort(array)
Miscellaneous 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) 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! 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. 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`` ``byte`` signed byte 1 byte = 8 bits ``byte myvar = -22``
``ubyte`` unsigned byte 1 byte = 8 bits ``ubyte myvar = $8f``, ``ubyte c = 'a'`` ``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 The true and false are actually just aliases
for the byte values 1 and 0. for the byte values 1 and 0.
``word`` signed word 2 bytes = 16 bits ``word myvar = -12345`` ``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`` ``word[x]`` signed word array 2*x bytes ``word[4] myvar``
``uword[x]`` unsigned word array 2*x bytes ``uword[4] myvar`` ``uword[x]`` unsigned word array 2*x bytes ``uword[4] myvar``
``float[x]`` floating-point array 5*x bytes ``float[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]`` ``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]`` ``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]`` ``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]`` ``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]`` ``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[]`` array with string ptrs 2*x bytes + strs ``str[] names = ["ally", "pete"]``
``str`` string (petscii) varies ``str myvar = "hello."`` ``str`` string (petscii) varies ``str myvar = "hello."``
implicitly terminated by a 0-byte 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). (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. 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:: .. note::
Unlike most other programming languages, there is no short-cirquit or McCarthy-evaluation 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 for the logical ``and`` and ``or`` operators. This means that prog8 currently always evaluates

View File

@ -3,6 +3,13 @@ TODO
For next release 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 { main {
sub value(word input) -> word { bool boolvalue1 = true
return input-999 bool boolvalue2 = false
} ubyte ubvalue1 = true
ubyte ubvalue2 = false
sub boolfunc(bool data) -> bool {
return not data
}
sub start() { 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 if boolvalue1 and boolvalue2
ubb++ txt.print("2\n")
; if ubvalue1 or ubvalu2
bool b1 = 1 ; txt.print("3\n")
bool b2 = 0 ;
bool b3 = true ; if ubvalue1 and ubvalu2
bool b4 = false ; txt.print("4\n")
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()
} }
} }