#!/bin/bash # If this file has already been sourced, just return test $(VARIABLES_ARRAYLIST_SH+true) && return declare -g VARIABLES_ARRAYLIST_SH=true source ${BASH_SOURCE%/*}/common.sh source ${BASH_SOURCE%/*}/logger.sh source ${BASH_SOURCE%/*}/variables.sh source ${BASH_SOURCE%/*}/variables.atom.sh variable::type::define ArrayList # == LIST == # # Lists are represented as just a list of tokens to variables # proc variable::ArrayList::new { variable::new ArrayList $(@) } proc variable::ArrayList::append { if [[ ${VARIABLES_DEBUG} == 1 ]] { stderr "variable::ArrayList::append $(@)" ; } declare list_token=$1 declare value_token=$2 variable::type::instanceOfOrExit $(list_token) ArrayList declare -a list_value=(${VARIABLES_VALUES[$list_token]}) setglobal list_value = ''(${value_token}) compat array-assign VARIABLES_VALUES '$list_token' $(list_value[@]) setglobal RESULT = $(#list_value[@]) } proc variable::ArrayList::prepend { if [[ ${VARIABLES_DEBUG} == 1 ]] { stderr "variable::ArrayList::prepend $(@)" ; } declare list_token=$1 declare value_token=$2 variable::type::instanceOfOrExit $(list_token) ArrayList declare -a list_value=(${VARIABLES_VALUES[$list_token]}) declare -a new_value=("${value_token}" "${list_value[@]:+${list_value[@]}}") compat array-assign VARIABLES_VALUES '$list_token' $(new_value[@]) setglobal RESULT = $(#list_value[@]) } proc variable::ArrayList::length { if [[ ${VARIABLES_DEBUG} == 1 ]] { stderr "variable::ArrayList::length $(@)" ; } declare list_token=$1 variable::type::instanceOfOrExit $(list_token) ArrayList variable::value $(list_token) ; declare -a value=("${RESULT}") setglobal RESULT = $(#value[@]) } proc variable::ArrayList::index { if [[ ${VARIABLES_DEBUG} == 1 ]] { stderr "variables_list::index $(@)" ; } declare list_token=$1 variable::type::instanceOfOrExit $(list_token) ArrayList declare index=$2 variable::value $(list_token) ; declare -a value=(${RESULT}) setglobal RESULT = $(value[$index]) } proc _variable::ArrayList::index_p { variable::ArrayList::index $(@) echo $RESULT } proc variable::ArrayList::first { if [[ ${VARIABLES_DEBUG} == 1 ]] { stderr "variable::ArrayList::first $(@)" ; } declare list_token=$1 variable::type::instanceOfOrExit $(list_token) ArrayList variable::ArrayList::index $(list_token) 0 } proc _variable::ArrayList::first_p { variable::ArrayList::first $(@) echo $(RESULT) } proc variable::ArrayList::rest { if [[ ${VARIABLES_DEBUG} == 1 ]] { stderr "variable::ArrayList::rest $(@)" ; } declare list_token=$1 variable::type::instanceOfOrExit $(list_token) ArrayList variable::value $(list_token) ; declare -a values=($RESULT) setglobal RESULT = $(values[@]:1) } proc _variable::ArrayList::rest_p { variable::ArrayList::rest $(@) echo $(RESULT) } # # Returns code 0 if the list is empty, 1 if not # proc variable::ArrayList::isEmpty_c { if [[ ${VARIABLES_DEBUG} == 1 ]] { stderr "variable::ArrayList::isEmpty_c $(@)" ; } declare token="$(1)" variable::type::instanceOfOrExit $(token) ArrayList variable::value $(token) ; declare -a value=(${RESULT}) [[ ${#value[@]} -eq 0 ]] return $? } # ====================================================== if test $0 != $BASH_SOURCE { return } # == LIST TESTS == # create a new list # test its size is 0 # add an atom to list # test its size is 1 # retrieve value of first item (atom) in list variable::ArrayList::new ; setglobal vCode = $(RESULT) variable::new Identifier "+" ; variable::ArrayList::append $(vCode) $(RESULT) variable::new Integer 5 ; variable::ArrayList::append $(vCode) $(RESULT) variable::new Integer 2 ; variable::ArrayList::append $(vCode) $(RESULT) variable::type $vCode ; \ assert::equals ArrayList $RESULT "List type" variable::ArrayList::index $vCode 0 ; variable::type $(RESULT) ; \ assert::equals Identifier $RESULT "List first item type" variable::ArrayList::index $vCode 1 ; variable::type $(RESULT) ; \ assert::equals Integer $(RESULT) "List first item type" variable::ArrayList::index $vCode 2 ; variable::type $(RESULT) ; \ assert::equals Integer $(RESULT) "List first item type" variable::ArrayList::new ; setglobal vCode = $(RESULT) variable::new String "a" ; setglobal A = $(RESULT) ; variable::ArrayList::append $(vCode) $A variable::new String "b" ; setglobal B = $(RESULT) ; variable::ArrayList::append $(vCode) $B variable::new String "c" ; setglobal C = $(RESULT) ; variable::ArrayList::append $(vCode) $C variable::ArrayList::index $vCode 1 ; \ assert::equals $B $RESULT "index_p" variable::ArrayList::first $vCode ; \ assert::equals $A $RESULT "first_p" variable::ArrayList::rest $vCode 0 ; \ assert::equals "$(B) $(C)" $RESULT "rest_p" variable::new -name "EVAL_RESULT" Integer 4 ; declare varname="$(RESULT)" assert::equals "EVAL_RESULT" $(varname) "Non-auto variable name" variable::type $(varname) ; \ assert::equals Integer $(RESULT) "Non-auto type" variable::value $(varname) ; \ assert::equals 4 $(RESULT) "Non-auto value" variable::ArrayList::new ; setglobal vCode = $(RESULT) variable::ArrayList::isEmpty_c $(vCode) assert::equals 0 $Status "Return code true (0)" variable::new Identifier "+" ; variable::ArrayList::append $(vCode) $(RESULT) variable::ArrayList::isEmpty_c $(vCode) assert::equals 1 $Status "Return code false (1)" # append variable::ArrayList::new ; setglobal vCode = $(RESULT) variable::new Integer 5 ; variable::ArrayList::append $(vCode) $(RESULT) variable::new Integer 2 ; variable::ArrayList::append $(vCode) $(RESULT) variable::ArrayList::index $vCode 0 ; variable::value $(RESULT) ; \ assert::equals 5 $RESULT "append / 0" variable::ArrayList::index $vCode 1 ; variable::value $RESULT ; \ assert::equals 2 $RESULT "append / 1" assert::report if test $(1+isset) && test $1 == "debug" { variable::printMetadata }