Jump to content

Interpreter and Syntax-Checker report different Problem on To-dimensional Array Initialization


Recommended Posts

Consider this simple One-Liner:

Local $test[][] = [[11, 12], [21, 22], MouseGetPos()]

the interpreter (3.3.14.5) exits with the error "Missing subscript dimensions in "Dim" statement."
the Syntax-Checker complains about "wrong nesting in initializer."
And i think it should work...

Here's what i think that should happen:

I declare a local two-dimensional Array called $test, whose sizes are determined from the Initializer.
The Initializer fills $test[0] with [11, 12]
$test[1] with [21, 22] and
$test[2] with the return value of MouseGetPos(), which is a One-Dimensional Array with two Elements, so something like [320, 481]

So why the hell is it not working?
And why are the interpreter and Syntax-Checker complaining about different Errors?

 

(And off-topic: i would be really grateful if somebody could tell me how to remove a Quote-Block from the Editor...)

Quote

 

Quote

 

 

Link to comment
Share on other sites

Yeah, It is one element at top level. And an element in the top level array is an array itself, just like $test[0] is an array.

What i need at that position is an array and that's exactly what GetMousePos() returns...

We can even replace the call to GetMousePos() by a second simple array:

Local $subtest = [42, 43]
Local $test[][] = [[11, 12], [21, 22], $subtest]

This produces the same errors, just as the following does:

Local $subtest1 = [42, 43]
Local $subtest2 = [42, 43]
Local $subtest3 = [42, 43]
Local $test[][] = [$subtest1, $subtest2, $subtest3]

But they should all be valid definitions ('should' as in common sense and general possibility, not in a language-definition kind of way)

And it get's really fucked up when you look at the following example, which is fine by the Syntax-Checker but raises an Error when executed

Local $subtest1 = [42, 43]
Local $subtest2 = [42, 43]
Local $subtest3 = [42, 43]
Local $test[] = [$subtest1, $subtest2, $subtest3]

Local $ignored = $test[0][0]

because this should work, no matter how AutoIt treats these structures internally (either as nested 'normal'-Arrays or a special Multi-DimensionalArray

Link to comment
Share on other sites

You don't seem to understand that AutoIt allows arrays of arrays.  So when you define Local $test[][] = [[11, 12], [21, 22], MouseGetPos()], it is badly formatted.

MouseGetPos returns a single items which is an array.  $Test is 2D array, so it needs a second item to respect the dimensions of the array.  In my first reply I told you how to do it...

Link to comment
Share on other sites

Why does it "need a second item to respect the dimensions of the array"?

at that position, we are at the third Element in the first dimension, so there is only one dimension left/free, so putting any non-Array-thing there would of course be an error, because it lacks the needed second dimension.

But the return value of GetMousePos() (or one of the sub-Arrays) is an array, so it provides the necessary second dimension for out two-dimensional array.

 

If i understand you correctly, what you are trying to tell me is that when i set

$x = [1, 2, 3]

Then, $x is NOT equal to [1, 2, 3], which - no offense - doesn't make sense since that is exactly what above line means:
"Set Variable $x to [1, 2, 3]"
So if $x is not [1, 2, 3] afterwards, there is definitely something wrong.

Link to comment
Share on other sites

Arrays are interesting in AutoIt.  There are ways to do what you want to do.  Below are some examples using the examples that you had issues with.  

#include <Array.au3>
#include <Debug.au3>

Global $aSubtest = [42, 43] ;AutoIt sees this as a 1 dimensional array.

;Don't use.
;~ Global $aTest[][] = [[11, 12], [21, 22], $aSubtest]

;Use this
Global $aTest[][] = [[11, 12], [21, 22], [$aSubtest[0], $aSubtest[1]]]
_DebugArrayDisplay($aTest, "Example 1")

;or this.
Global $aTest[][] = [[11, 12], [21, 22]]
_DebugArrayDisplay($aTest, "Example 2 Before")
_ArrayTranspose($aSubtest) ;Convert to a 1 row 2 dimensional array.
_ArrayConcatenate($aTest, $aSubtest)
_DebugArrayDisplay($aTest, "Example 2 After")


;Defined as 1 dimensional arrays.
Global $aSubtest1 = [42, 43]
Global $aSubtest2 = [42, 43]
Global $aSubtest3 = [42, 43]

;Don't use.
;~ Global $aTest[][] = [$aSubtest1, $aSubtest2, $aSubtest3]

;Use this.
;Convert to a 1 row 2 dimensional arrays.
_ArrayTranspose($aSubtest1)
_ArrayTranspose($aSubtest2)
_ArrayTranspose($aSubtest3)

Global $aTest = $aSubtest1
_ArrayConcatenate($aTest, $aSubtest2)
_ArrayConcatenate($aTest, $aSubtest3)
_DebugArrayDisplay($aTest, "Example 3")

;or you could define 1 row 2 dimensional arrays.
Global $aSubtest1 = [[42, 43]]
Global $aSubtest2 = [[42, 43]]
Global $aSubtest3 = [[42, 43]]

Global $aTest = $aSubtest1
_ArrayConcatenate($aTest, $aSubtest2)
_ArrayConcatenate($aTest, $aSubtest3)
_DebugArrayDisplay($aTest, "Example 4")


;This is arrays in array. Not a 2 dimensional array. 
Global $aSubtest1 = [42, 43]
Global $aSubtest2 = [42, 43]
Global $aSubtest3 = [42, 43]
Global $aTest[] = [$aSubtest1, $aSubtest2, $aSubtest3]
_DebugArrayDisplay($aTest, "Example 5") ;See "{Array}" in the elements.

;Show sub-arrays contents. They are 1 dimensional arrays.
For $aArray In $aTest
    _DebugArrayDisplay($aArray, "Ex 5 Sub-Arrays")
Next

Adam

Link to comment
Share on other sites

2 hours ago, Sorontik said:

Why does it "need a second item to respect the dimensions of the array"?

at that position, we are at the third Element in the first dimension, so there is only one dimension left/free, so putting any non-Array-thing there would of course be an error, because it lacks the needed second dimension.

But the return value of GetMousePos() (or one of the sub-Arrays) is an array, so it provides the necessary second dimension for out two-dimensional array.

AutoIt doesn't have support for array literals.  AutoIt array initializers seem to allow that but their syntax is just syntatic sugar.

 

Local $a = [[1, 2], [3,4], MouseGetPos()]

is flagged as invalid (Missing subscript dimensions) because MouseGetPos() is one variable (an array) but the initializer expects [$FirstVariable, $SecondVariable] there.  It needs to find square brackets around every level where at least one value is provided.
Of course 1D arrays (call them lists) don't allow internal square brackets in the init part.

Local $a = [[1, 2], [3,4], [MouseGetPos()]]

is valid: here's a dump of $a:

Array[3][2]
      [0][0] => Int32              1
      [0][1] => Int32              2
      [1][0] => Int32              3
      [1][1] => Int32              4
      [2][0] => Array[2]
            [0] => Int32              211
            [1] => Int32              695
      [2][1] => String (0)         ''

Above, the cell $a[2][1] is initialized (by default) as an empy string, like any uninitialized variable. Incomplete init of an array is possible as long as initializer syntax is used, meaning it finds [<something or not>].

Examples:

Local $a[3][3] = [[1, 2], [3]]

Content of above:

Array[3][3]
      [0][0] => Int32              1
      [0][1] => Int32              2
      [0][2] => String (0)         ''
      [1][0] => Int32              3
      [1][1] => String (0)         ''
      [1][2] => String (0)         ''
      [2][0] => String (0)         ''
      [2][1] => String (0)         ''
      [2][2] => String (0)         ''

Another example:

Local $a[][3] = [[], [1, Null]]

Its content:

Array[2][3]
      [0][0] => String (0)         ''
      [0][1] => String (0)         ''
      [0][2] => String (0)         ''
      [1][0] => Int32              1
      [1][1] => Keyword            Null
      [1][2] => String (0)         ''

Last example:

Local $a = [[], [1, Null]]

Its content:

Array[2][2]
      [0][0] => String (0)         ''
      [0][1] => String (0)         ''
      [1][0] => Int32              1
      [1][1] => Keyword            Null

In short, the initializer deduces (if necessary) the dimensions of the array being declared by examining the structure and number of square brackets in the explicit init part.  Explicit dimensions sizes set limits.

 

If you want a correct init, just do as recommended:

Local $a = [[1, 2], [3,4], [MouseGetPos()[0], MouseGetPos()[1]]]

and the content of $a is now:

Array[3][2]
      [0][0] => Int32              1
      [0][1] => Int32              2
      [1][0] => Int32              3
      [1][1] => Int32              4
      [2][0] => Int32              649
      [2][1] => Int32              381

 

Edited by jchd

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Oh my god...
That's horriffic...
That's so incredibly ugly...

Why would anyone even think about doing this like so?

I have a bunch of vars to store some rectangles, each of those is an array where the first dimension selects the points and the second dimension selects the axis-coordinate of the point.

So if i want to replace the values with mouse coordinates (which come from a helper function that does some other stuff like waiting for certain conditions) i first have to store all points of my rectangle in temporary vars and then unpack the points (which are arrays of coordinates) into single values just to stuff them toghether again, almost exactly the way they were...

I'm sorry but that's bu****
I'm sure the developers had some reasons to do it that way - but i can't imagine a single one...

Link to comment
Share on other sites

Remember AutoIt is one-person work, who wrote it long ago to ease typical PC administration.  So you're a bit excessive in your adjectives about the language.

Also remember you have the choice to store arrays in array(s), albeit with a less convenient access.

Finally, be sure you have read forum rules ;)

 

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...