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

    Joined:
    May 16, 2008
    Messages:
    42
    Likes Received:
    2
    Migrated From JP Software Wiki

    Description

    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

    Code:
    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:

    Code:
    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:

    Code:
    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

    Array.btm

    Code:
    @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
    
    
    :InitLib
    :: 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
    
    
    :ArrayNames
    :: return name of arrays without trailing . delimiters
    echo %@trim[%@replace[.,,%arrayNames]]
    return
    
    
    :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%.
    return
    
    
    :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
    return
    
    
    :Set [arrayName, position, value]
    :: Set an array position to a value
    set array_%arrayName%_%position%=%value
    return
    
    
    :Get [arrayName, position]
    :: Get a value from an array position
    echo %[array_%arrayName%_%position%]
    return
    
    
    :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
    else
       :: Get/set an array/position value
       iff %@len[%value] GT 0 then
          set array_%arrayName%_%position%=%value
       else
          echo %[array_%arrayName%_%position%]
       endiff
    endiff
    return
    
    
    :TermLib
    :: 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]]
    enddo
    :: 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=
    return
    
    :End
    ArrayTest.btm

    Code:
    @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[]
    
    :end
    REM Shut down array library
    arrayTermLib
    
     

Share This Page