Skip to content
This repository has been archived by the owner on Jun 13, 2018. It is now read-only.

List library #66

Open
canercandan opened this issue Dec 13, 2014 · 1 comment
Open

List library #66

canercandan opened this issue Dec 13, 2014 · 1 comment

Comments

@canercandan
Copy link

Something that I am quite familiar with other languages such as C++ or Python is the use of list or vector container. I saw on GSL one can use XML data structure instead of that, but sometimes it is even more efficient and reduces drastically code length using a list mechanism since XML can be much more seen as map or dictionary than a single list container.

Therefore, I created a small library of functions that implements functions for such a purpose here is the list of these functions:

  • list_new: create a new list
  • list_exists: check if the passed argument is a list
  • list_empty: does the list empty ?
  • list_append: append a new item into the list
  • list_get: get the i^th item of the list
  • list_delete: delete the i^th item of the list
  • list_foreach: apply a callback function to every single item in the list
  • list_print: standard output the whole list

It is also possible to add a list into another. Here is a GSL script showing a typical usage:

.template 0

l1 = list_new()
l2 = list_new()

list_append(l2, 'aaa')
list_append(l2, 'zzz')

list_append(l1, l2)
list_append(l1, 'bbb')
list_append(l1, 'ccc')

define l2.dummy = 12
list_append(l2, 'www')

list_append(l1, l2)
list_append(l1, 'ddd')
list_append(l1, 'eee')
list_append(l1, 'fff')

list_delete(l1, 0)

list_print(l1)

echo list_get(l1, 1)

.endtemplate

And the result:

gsl/4 M: [[aaa,zzz],ccc,[aaa,zzz,www],ddd,eee,fff]
gsl/4 M: ccc

I don't know if anyone see useful to add them as a builtin GSL feature.

Anyway, here is the source code:

.template 0

function global.check_arg_missing(ctx, key, value)
  if !defined(my.value)
    abort '[$(my.ctx:)] arg "$(my.key:)" is missing'
  endif
endfunction

function global.list_new
  return XML.new('list')
endfunction

function global.list_exists(list)
  check_arg_missing('list_exists', 'list', my.list)

  return name(my.list)?"" = "list"
endfunction

function global.list_empty(list)
  check_arg_missing('list_exists', 'list', my.list)

  return !defined(my.list->.)
endfunction

function global.list_append(list, item)
  check_arg_missing('list_append', 'list', my.list)
  check_arg_missing('list_append', 'item', my.item)

  if list_exists(my.item)
    copy my.item to my.list as list
  else
    new my.list.item as i
      define i. = my.item
    endnew
  endif
endfunction

function global.list_get(list, i)
  check_arg_missing('list_get', 'list', my.list)
  check_arg_missing('list_get', 'i', my.i)

  for my.list. as ii where item() = my.i+1
    return ii
  else
    abort '[list_get] no item found @ $(my.i:)'
  endfor
endfunction

function global.list_delete(list, i)
  check_arg_missing('list_delete', 'list', my.list)
  check_arg_missing('list_delete', 'i', my.i)

  my.item = list_get(my.list, my.i)
  delete my.item
endfunction

function global.list_foreach(list, callback, record)
  check_arg_missing('list_foreach', 'list', my.list)
  check_arg_missing('list_foreach', 'callback', my.callback)

  my.record ?= XML.new('record')

  for my.list. as i
    $(my.callback)(i, my.record)
  endfor

  return my.record
endfunction

function print_callback(item, record)
  check_arg_missing('print_callback', 'item', my.item)
  check_arg_missing('print_callback', 'record', my.record)

  if list_exists(my.item)
    my.sublist_record = list_foreach(my.item, 'print_callback')
    copy my.sublist_record to my.record
  else
    new my.record.field as f
      define f. = my.item.
    endnew
  endif
endfunction

function recursive_print(record)
  check_arg_missing('recursive_print', 'record', my.record)

  my.s = "["

  for my.record. as i
    if name(i)?"" = "record"
      my.s += recursive_print(i)
    else
      my.s += i.
    endif

    if !last(i)
      my.s += ','
    endif
  endfor

  my.s += "]"

  return my.s
endfunction

function global.list_print(list)
  check_arg_missing('list_print', 'list', my.list)

  my.record = list_foreach(my.list, 'print_callback')
  echo recursive_print(my.record)
endfunction

.endtemplate
@jschultz
Copy link
Contributor

It wouldn't be terribly difficult to implement a new list object using a
GXL file. You can probably do a bit of reverse engineering by looking at
the existing GSL files, and the ggfunc.gsl script that processes GXL
files into C. As I wrote this code (many years ago) I can probably give
a hand or advice.

Cheers,
Jonathan

On 14/12/14 04:31, Caner Candan wrote:

Something that I am quite familiar with other languages such as C++ or
Python is the use of list or vector container. I saw on GSL one can use
XML data structure instead of that, but sometimes it is even more
efficient and reduces drastically code length using a list mechanism
since XML can be much more seen as map or dictionary than a single list
container.

Therefore, I created a small library of functions that implements
functions for such a purpose here is the list of these functions:

  • list_new: create a new list
  • list_exists: check if the passed argument is a list
  • list_empty: does the list empty ?
  • list_append: append a new item into the list
  • list_get: get the i^th item of the list
  • list_delete: delete the i^th item of the list
  • list_foreach: apply a callback function to every single item in the list
  • list_print: standard output the whole list

It is also possible to add a list into another. Here is a GSL script
showing a typical usage:

|.template 0

l1 = list_new()
l2 = list_new()

list_append(l2, 'aaa')
list_append(l2, 'zzz')

list_append(l1, l2)
list_append(l1, 'bbb')
list_append(l1, 'ccc')

define l2.dummy = 12
list_append(l2, 'www')

list_append(l1, l2)
list_append(l1, 'ddd')
list_append(l1, 'eee')
list_append(l1, 'fff')
list_delete(l1, 0)
list_print(l1)
echo list_get(l1, 1)

.endtemplate
|

And the result:

|18:25:32: gsl/4 M: [[aaa,zzz],ccc,[aaa,zzz,www],ddd,eee,fff]
18:25:32: gsl/4 M: ccc
|

I don't know if anyone see useful to add them as a builtin GSL feature.

Anyway, here is the source code:

|.template 0

function global.check_arg_missing(ctx, key, value)
if !defined(my.value)
abort '[$(my.ctx:)] arg "$(my.key:)" is missing'
endif
endfunction

function global.list_new
return XML.new('list')
endfunction

function global.list_exists(list)
check_arg_missing('list_exists', 'list', my.list)

return name(my.list)?"" = "list"
endfunction

function global.list_empty(list)
check_arg_missing('list_exists', 'list', my.list)

return !defined(my.list->.)
endfunction

function global.list_append(list, item)
check_arg_missing('list_append', 'list', my.list)
check_arg_missing('list_append', 'item', my.item)

if list_exists(my.item)
copy my.item to my.list as list
else
new my.list.item as i
define i. = my.item
endnew
endif
endfunction

function global.list_get(list, i)
check_arg_missing('list_get', 'list', my.list)
check_arg_missing('list_get', 'i', my.i)

for my.list. as ii where item() = my.i+1
return ii
else
abort '[list_get] no item found @ $(my.i:)'
endfor
endfunction

function global.list_delete(list, i)
check_arg_missing('list_delete', 'list', my.list)
check_arg_missing('list_delete', 'i', my.i)

my.item = list_get(my.list, my.i)
delete my.item
endfunction

function global.list_foreach(list, callback, record)
check_arg_missing('list_foreach', 'list', my.list)
check_arg_missing('list_foreach', 'callback', my.callback)

my.record ?= XML.new('record')

for my.list. as i
$(my.callback)(i, my.record)
endfor

return my.record
endfunction

function print_callback(item, record)
check_arg_missing('print_callback', 'item', my.item)
check_arg_missing('print_callback', 'record', my.record)

if list_exists(my.item)
my.sublist_record = list_foreach(my.item, 'print_callback')
copy my.sublist_record to my.record
else
new my.record.field as f
define f. = my.item.
endnew
endif
endfunction

function recursive_print(record)
check_arg_missing('list_print', 'record', my.record)

my.s = "["

for my.record. as i
if name(i)?"" = "record"
my.s += recursive_print(i)
else
my.s += i.
endif

 if !last(i)
   my.s += ','
 endif

endfor

my.s += "]"

return my.s
endfunction

function global.list_print(list)
check_arg_missing('list_print', 'list', my.list)

my.record = list_foreach(my.list, 'print_callback')
echo recursive_print(my.record)
endfunction

.endtemplate
|


Reply to this email directly or view it on GitHub
#66.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants