1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Array Simulation

Discussion in 'T&T - Scripting' started by nchernoff, Jun 5, 2008.

  1. nchernoff

    nchernoff Administrator
    Staff Member

    May 16, 2008
    Likes Received:
    Migrated From JP Software Wiki


    Arrays are not directly support by 4NT/TCMD, but a syntax similar to arrays can be simulated. The simulation is that, while the usage may be similar to array usage in syntax, standard environment variables are actually used to store the values. The combination of functions and aliases renames the referenced array position to refer to the array_ArrayName_Position environment variable.

    The library file below has general functions for manipulating arrays. The array library is initialized using the

    gosub "file" label
    syntax introduced in version 8.0 of 4NT and TCMD. A similar syntax is used for the aliases and functions created by the InitLib subroutine. Creating an array using the arrayCreate alias (and the called Create subroutine) creates aliases and functions with that array name. For example, creating an array named 'arTest1' creates an alias named 'arTest1' and a function named 'arTest1'. Deleting the array by calling arrayDelete will delete the alias and function for that array. A list of all arrays in use is stored in an arrayNames environment variable. Calling the arrayTermLib alias created by the InitLib subroutine deletes all of the created arrays, aliases, and functions.

    A better name for this library might be collection instead of array. Because this is a simulation of array usage, the position does not need to be strictly numeric. In the example test script, a two-dimensional array is simulated by using a period (.) delimiter as in this line:

    echo arTest1[2.1]=%@arTest1[2.1]
    In fact, any set of characters that are valid in an environment variable name can be used. So, instead of specifying 2.1 for a position, a named position could be used, similar to that of a hash collection, as shown in this example:

    echo arTest1[Height]=%@arTest1[Height]
    In the C/C++ world, this would also be similar to using a #DEFINE for the position name. With that explanantion out of the way, here are the Array.btm and ArrayTest.btm files. Additional comments are within the script code.

    Contributed by: Tim Butterfield


    @echo off
    REM Array library
    REM Library of subroutines, aliases, and functions for manipulating
    REM variables in an array-like fashion.
    :: Subroutines
    :: InitLib - initialize library--create aliases and functions
    :: Aliases
    :: arrayTermLib - terminate library usage--cleans up arrays, aliases, 
    ::       and functions
    :: arrayCreate - create an array and associated aliases and functions
    :: arrayDelete - delete/cleanup an array and associated aliases and functions
    :: arraySet - set the value of an array/position
    :: Functions
    :: arrayGet - get a value from an array/position
    :: arrayNames - return the names of existing arrays
    goto end
    :: Initialize the library
    alias arrayTermLib=^`gosub "%_batchname" TermLib^`
    alias arrayCreate=^`gosub "%_batchname" Create %%$^`
    alias arrayDelete=^`gosub "%_batchname" Delete %%$^`
    alias arraySet=^`gosub "%_batchname" Set %%$^`
    function arrayGet=^`%%@execstr[gosub "%_batchname" Get %%$]^`
    function arrayNames=^`%%@execstr[gosub "%_batchname" ArrayNames %%$]^`
    :: make sure variables are empty
    set arrayNames=
    set arrayName=
    :: return name of arrays without trailing . delimiters
    echo %@trim[%@replace[.,,%arrayNames]]
    :Create [arrayName]
    :: Create an array
    :: Create set-alias and get-function
    alias %arrayName=^`gosub "%_batchname" Value %arrayName %%$^`
    function %arrayName=^`%%@execstr[gosub "%_batchname" Value %arrayName %%$]^`
    :: Add array name to list of existing arrays using trailing . delimiter.
    set arrayNames=%arrayNames% %arrayName%.
    :Delete [arrayName]
    :: Delete an array
    :: Remove array elements
    unset array_%arrayName%_*
    :: Remove array name from the list
    set arrayNames= %@trim[%@replace[ %arrayName.,,%arrayNames]]
    :: Remove get-function and set-alias
    unfunction %arrayName
    unalias %arrayName
    :Set [arrayName, position, value]
    :: Set an array position to a value
    set array_%arrayName%_%position%=%value
    :Get [arrayName, position]
    :: Get a value from an array position
    echo %[array_%arrayName%_%position%]
    :Value [arrayName, position, value]
    :: if the position is 0, return name of environment variable
    iff %position EQ 0 then
       :: return 'set' name  Example:  set %@ar[0,position]=value
       echo array_%arrayName%_%value
       :: Get/set an array/position value
       iff %@len[%value] GT 0 then
          set array_%arrayName%_%position%=%value
          echo %[array_%arrayName%_%position%]
    :: Terminate the array library
    :: Delete all of the existing arrays
    do while %@words[%arrayNames] GT 0
       :: Remove trailing . delimiter from array name before calling delete
       arrayDelete %@replace[.,,%@word[-0,%arrayNames]]
    :: delete aliases and functions
    unalias arrayTermLib
    unalias arrayCreate
    unalias arrayDelete
    unalias arraySet
    unfunction arrayGet
    unfunction arrayNames
    :: make sure variables are empty
    set arrayNames=
    set arrayName=

    @echo off
    REM Initialize array library
    gosub "Array.btm" InitLib
    REM Create a couple of arrays
    arrayCreate arTest1
    arrayCreate arTest2
    REM Set and show an element in the first array using general array set/get
    arraySet arTest1 1 "This is a test"
    echo arTest1[1]=%@arrayGet[arTest1, 1]
    REM Set and show an element in the first array using array name set/get
    arTest1 1 "This is another test"
    echo arTest1[1]=%@arTest1[1]
    REM Simulate two dimensional array position using . delimiter
    arTest1 2.1 "This is position 2.1 of array 1"
    echo arTest1[2.1]=%@arTest1[2.1]
    REM Set and show an element in the second array
    arTest2 1 "This is position 1 of array 2"
    echo arTest2[1]=%@arTest2[1]
    REM Use '0' first parameter of function to get 'name' of variable to set
    set %@arTest2[0,2]="This is position 2 of array 2"
    echo arTest2[2]=%@arTest2[2]
    REM Show existing arrays
    echo Arrays=%@arrayNames[]
    REM Delete an array
    arrayDelete arTest1
    REM Show existing arrays
    echo Arrays=%@arrayNames[]
    REM Shut down array library

Share This Page