add "X in [1,2,3]" expression (efficient containment check)

This commit is contained in:
Irmen de Jong
2021-12-29 16:21:37 +01:00
parent 7a9e5afb93
commit de6ce4a46e
31 changed files with 615 additions and 150 deletions

View File

@@ -283,6 +283,8 @@ It's possible to assign a new array to another array, this will overwrite all el
array with those in the value array. The number and types of elements have to match.
For large arrays this is a slow operation because every element is copied over. It should probably be avoided.
Using the ``in`` operator you can easily check if a value is present in an array,
example: ``if choice in [1,2,3,4] {....}``
**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.
@@ -332,6 +334,11 @@ as newlines, quote characters themselves, and so on. The ones used most often ar
``\\``, ``\"``, ``\n``, ``\r``. For a detailed description of all of them and what they mean,
read the syntax reference on strings.
Using the ``in`` operator you can easily check if a characater is present in a string,
example: ``if '@' in email_address {....}`` (however this gives no clue about the location
in the string where the character is present, if you need that, use the ``string.find()``
library function instead)
.. hint::
Strings/arrays and uwords (=memory address) can often be interchanged.
An array of strings is actually an array of uwords where every element is the memory
@@ -542,6 +549,9 @@ The when-*value* can be any expression but the choice values have to evaluate to
compile-time constant integers (bytes or words). They also have to be the same
datatype as the when-value, otherwise no efficient comparison can be done.
.. note::
Instead of chaining several value equality checks together using ``or`` (ex.: ``if x==1 or xx==5 or xx==9``),
consider using a ``when`` statement or ``in`` containment check instead. These are more efficient.
Assignments
-----------
@@ -587,6 +597,9 @@ Expressions can contain procedure and function calls.
There are various built-in functions such as sin(), cos(), min(), max() that can be used in expressions (see :ref:`builtinfunctions`).
You can also reference idendifiers defined elsewhere in your code.
Read the :ref:`syntaxreference` chapter for all details on the available operators and kinds of expressions you can write.
.. attention::
**Floating points used in expressions:**

View File

@@ -497,6 +497,24 @@ range creation: ``to``
; i loops 0, 1, 2, ... 127
}
containment check: ``in``
Tests if a value is present in a list of values, which can be a string or an array.
The result is a simple boolean ``true`` or ``false``.
Consider using this instead of chaining multiple value tests with ``or``, because the
containment check is more efficient.
Examples::
ubyte cc
if cc in [' ', '@', 0] {
txt.print("cc is one of the values")
}
str email_address = "?????????"
if '@' in email_address {
txt.print("email address seems ok")
}
address of: ``&``
This is a prefix operator that can be applied to a string or array variable or literal value.
It results in the memory address (UWORD) of that string or array in memory: ``uword a = &stringvar``
@@ -799,4 +817,3 @@ case you have to use { } to enclose them::
}
else -> txt.print("don't know")
}

View File

@@ -3,11 +3,7 @@ TODO
For next compiler release (7.6)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
add "if X in [1,2,3] {...}" syntax , as an alternative to when X { 1,2,3-> {...} }
if the array is not a literal, do a normal containment test instead in an array or string or range
change "consider using when statement..." to "consider using if X in [..] or when statement..."
also add to the docs!
...
Blocked by an official Commander-x16 v39 release
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -20,6 +16,7 @@ Future
- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as ``v_``
then we can get rid of the instruction lists in the machinedefinitions as well?
- fix the asm-labels problem (github issue #62)
- make (an option) to let 64tass produce a listing file as well as output.
- simplifyConditionalExpression() should not split expression if it still results in stack-based evaluation
- get rid of all TODO's in the code
- improve testability further, add more tests