Page 2 of 3

Re: Counting Items in the DataSection?

Posted: Sun May 04, 2025 1:36 pm
by mk-soft
Just like you shouldn't do it ...

Code: Select all

;-TOP

Global Dim Fruit.s(0) ; <- Read Only

Procedure InitFruit()
  Protected items, *c.Character, *s , *arr.integer
  *c = ?FruitList
  *s = *c
  Repeat
    If *c\c = #ETX
      Break
    EndIf
    If *c\c = 0
      ReDim Fruit(items)
      *arr = @Fruit() + items * SizeOf(integer)
      *arr\i = *s
      *s = *c + SizeOf(character)
      items + 1
    EndIf
    *c + SizeOf(Character)
  ForEver
  ProcedureReturn items
EndProcedure

Procedure ReleaseFruit()
  Protected *arr.integer = @Fruit()
  Protected items = ArraySize(Fruit())
  Protected index
  For index = 0 To items
    *arr\i = 0
    *arr + SizeOf(integer)
  Next
EndProcedure

i = InitFruit()
Debug "Count: " + i
For index = 0 To ArraySize(Fruit())
  Debug "Index " + index + ": " + Fruit(index)
Next

ReleaseFruit()

DataSection
  FruitList:
  Data.s "Apple", "Orange"
  Data.s "Mango", "Apricot"
  Data.s "Banana", "Pear"
  Data.s "Peach", "Tangerine"
  Data.s #ETX$
EndDataSection
PB can not regular free strings

Re: Counting Items in the DataSection?

Posted: Sun May 04, 2025 8:55 pm
by Blue
Why complicate simple things ?
My rewrite of Shardik's simple (and best) solution :


Code: Select all

Procedure CountFruits()
  Count = 0
  Restore FruitList
  Repeat
    Read.S Fruit$
    If #ETX$ = Fruit$ : ProcedureReturn Count : EndIf
    Count + 1
  ForEver
EndProcedure

DataSection
  FruitList:
  Data.s "Apple", "Orange"
  Data.s "Mango", "Mango"
  Data.s #ETX$
EndDataSection

Debug CountFruits()

Re: Counting Items in the DataSection?

Posted: Mon May 05, 2025 5:38 am
by Little John
Another variation of Shardik's code: :-)

Code: Select all

Procedure.i CountFruits()
   Count = -1
   Restore FruitList
   Repeat
      Read.s Fruit$
      Count + 1
   Until Fruit$ = #ETX$
   ProcedureReturn Count
EndProcedure

DataSection
   FruitList:
   Data.s "Apple", "Orange"
   Data.s "Mango", "Pear"
   Data.s #ETX$
EndDataSection

Debug CountFruits()

Re: Counting Items in the DataSection?

Posted: Mon May 05, 2025 1:18 pm
by Blue
Little John wrote: Mon May 05, 2025 5:38 am Another variation of Shardik's code: :-)

Code: Select all

Procedure.i CountFruits()
   Count = -1
   [. . .]
EndProcedure
   [. . .]
Smart ! :thumbsup:
And that’s as good as it gets.

Re: Counting Items in the DataSection?

Posted: Mon May 05, 2025 3:06 pm
by Michael Vogel
You can create tons of variations... :lol:

Code: Select all

Procedure.i CountFruits()

	Protected Count
	Protected *mem=?FruitList
	
	Repeat
		Count+Bool(PeekC(*mem)=0)
		*mem+SizeOf(Character)
	Until *mem=?EndFruitList
	
	ProcedureReturn Count
	
EndProcedure

DataSection
	FruitList:
	Data.s "Apple", "Orange"
	Data.s "Mango", "Pear"
	EndFruitList:
EndDataSection

Debug CountFruits()

Re: Counting Items in the DataSection?

Posted: Mon May 05, 2025 10:42 pm
by AZJIO
Blue wrote: Sun May 04, 2025 8:55 pm Why complicate simple things ?
The code authors gave good ideas for understanding the data section. One of them is that the data are strings ending in zero and following each other. In this regard, you can process the data in any convenient way, not just by reading lines.
The method of counting zeros is not complicated, perhaps the most ideal. This works the same way as the CountString() function.
The idea with #PB_Compiler_Line is also ideal, as it allows you to insert the correct value WITHOUT CALCULATIONS.
So you shouldn't be underestimating the examples.

Code: Select all

DataSection
	FruitList:
	#FruitList_S = #PB_Compiler_Line
	Data.s "Apple", "Orange"
	Data.s "Mango", "Apricot"
	Data.s "Banana", "Pear"
	Data.s "Peach", "Tangerine"
	#FruitList_E = #PB_Compiler_Line
	FruitListend:
	Data.i (#FruitList_E - #FruitList_S - 1) * 2
EndDataSection

Restore FruitListend
Read.i tmp
Debug tmp

Re: Counting Items in the DataSection?

Posted: Tue May 06, 2025 6:42 pm
by mk-soft
Actually, it makes no sense to return only the number of entries.
You also need the content. So you can and should also transfer the content straight away.

Code: Select all

;-TOP

Global Dim Fruit.s(0)

Procedure InitFruit()
  Protected temp.s, count, size
  
  size = ArraySize(Fruit())
  Restore FruitList
  
  Repeat
    Read.s temp
    If temp = #ETX$
      Break
    EndIf
    If size < count
      size + 10
      ReDim Fruit(size)
    EndIf
    Fruit(count) = temp
    count + 1
  ForEver
  If size >= count
    ReDim Fruit(count - 1)
  EndIf
  ProcedureReturn count
EndProcedure

cnt = InitFruit()
Debug "Count: " + cnt
For index = 0 To ArraySize(Fruit())
  Debug "Index " + index + ": " + Fruit(index)
Next

DataSection
  FruitList:
  Data.s "Apple", "Orange"
  Data.s "Mango", "Apricot"
  Data.s "Banana", "Pear"
  Data.s "Peach", "Tangerine"
  Data.s #ETX$
EndDataSection

Re: Counting Items in the DataSection?

Posted: Wed May 07, 2025 8:16 am
by Michael Vogel
Not sure if it does make sense to duplicate the data memory to string memory :)

I'd think there are enough answers for counting the items already - but because Pandora's box was opened...

Code: Select all

Global Dim Fun.s(0)

Procedure.i CountFruits4Fun()

	Protected Count
	Protected *mem=?FruitList

	PokeI(@Fun(),*mem)
	Repeat
		If PeekC(*mem)
			*mem+SizeOf(Character)
		Else
			Count+1
			*mem+SizeOf(Character)
			If *mem=?EndFruitList
				ProcedureReturn Count
			Else
				ReDim Fun(Count)
				PokeI(@fun()+Count*SizeOf(Integer),*mem)
			EndIf
		EndIf
	ForEver

EndProcedure

DataSection
	FruitList:
	Data.s "Apple", "Orange"
	Data.s "Mango", "Pear"
	EndFruitList:
EndDataSection

n=CountFruits4Fun()
For i=0 To n-1
	Debug fun(i)
Next i

Re: Counting Items in the DataSection?

Posted: Wed May 07, 2025 10:07 am
by mk-soft
Michael Vogel wrote: Wed May 07, 2025 8:16 am Not sure if it does make sense to duplicate the data memory to string memory :)

I'd think there are enough answers for counting the items already - but because Pandora's box was opened...
We already had that (from me). But rules must be observed. Read-only access and release the pointers on the string itself.
Otherwise crash

Re: Counting Items in the DataSection?

Posted: Wed May 07, 2025 11:03 am
by Skipper
Call me daft, but why would you want to count the number of items in a data section?
We are the programmers in charge, we (should) know how many items we put in. The data section list is a static list in the source code, after compilation this doesn't change during runtime. Why count these items at all? The programmer has this information already...

Confused
Skipper

Re: Counting Items in the DataSection?

Posted: Wed May 07, 2025 11:16 am
by miso
Confused
Don't be. It's a riddle solving game ;)
(results might come in handy in unexpected circumstances)

Re: Counting Items in the DataSection?

Posted: Wed May 07, 2025 12:44 pm
by Demivec
miso wrote: Wed May 07, 2025 11:16 am
Confused
Don't be. It's a riddle solving game ;)
(results might come in handy in unexpected circumstances)
The situation here reminds me of a children's riddle.

Riddle: Imagine that you are in a room without any doors or windows. How would you get out? :shock:

Answer: Stop imagining. 8)

Re: Counting Items in the DataSection?

Posted: Wed May 07, 2025 12:57 pm
by miso
;)

If you want your datasection items to see, you must answer my riddles of three!

I don't think that anyone here counted his/her datasection items until this topic.
Finding solution is fun, and I'm sure that was the point here.

Re: Counting Items in the DataSection?

Posted: Wed May 07, 2025 3:58 pm
by #NULL
You can define your items with a macro and keep counting. Not at compile time though. This depends on the runtime order of execution, so you will have to define your data before you use the count:

Code: Select all

EnableExplicit

Macro DataSectionLabel(_label_)
  DataSection
    _label_:
  EndDataSection
  Define _label_#_itemCount.i = 0
  CompilerIf Not Defined(*dataSection_current_count, #PB_Variable)
    Define *dataSection_current_count.Integer
  CompilerEndIf
  *dataSection_current_count = @_label_#_itemCount
EndMacro

Macro DataSectionData(_data_)
  DataSection
    _data_
  EndDataSection
  *dataSection_current_count\i + 1
EndMacro

DataSectionLabel(label1)
DataSectionData(Data.s "abc")
DataSectionData(Data.s "xyz")
DataSectionLabel(l2)
DataSectionLabel(my_label_3)
DataSectionData(Data.i 111)
DataSectionData(Data.i 222)
DataSectionData(Data.i 222)

Debug label1_itemCount      ; 2
Debug l2_itemCount          ; 0
Debug my_label_3_itemCount  ; 3
You can go further and store the label names (can't use them at Restore though, needs a hardcoded label) and item types (quite an overhead with a type string for every single item, Read also needs a hardcoded type)..

Code: Select all

EnableExplicit

; #########################################################

Structure S_DataSection
  itemCount.i
  List types.s()
EndStructure

Structure S_DataSections
  sectionCount.i
  Map sections.S_DataSection()
EndStructure

Define dataSections.S_DataSections
Define *dataSection_current.S_DataSection

Macro dq
  "
EndMacro

Macro DataSectionLabel(_label_)
  DataSection
    _label_:
  EndDataSection
  dataSections\sectionCount + 1
  *dataSection_current = AddMapElement(dataSections\sections(), dq#_label_#dq)
EndMacro

Macro DataSectionData(_type_, _data_)
  DataSection
    Data._type_ _data_
  EndDataSection
  *dataSection_current\itemCount + 1
  AddElement(*dataSection_current\types())
  *dataSection_current\types() = dq#_type_#dq
EndMacro

; #########################################################

DataSectionLabel(label1)
DataSectionData(s, "abc")
DataSectionData(s, "xyz")

DataSectionLabel(l2)

DataSectionLabel(my_label_3)
DataSectionData(i, 111)
DataSectionData(b, 2)
DataSectionData(s, "three")
DataSectionData(i, 444)

DataSectionLabel(l4)

; #########################################################

Debug "sections: " + dataSections\sectionCount
ForEach dataSections\sections()
  Debug "    " + MapKey(dataSections\sections()) + " (" + dataSections\sections()\itemCount + " items)"
Next
Debug ""

Define i.i
Define b.b
Define s.s

Debug "my_label_3 (" + dataSections\sections("my_label_3")\itemCount + " items) :"
Restore my_label_3
ForEach dataSections\sections("my_label_3")\types()
  Select dataSections\sections("my_label_3")\types()
      Case "i" : Read.i i : Debug "    " + dataSections\sections("my_label_3")\types() + " : " + i
      Case "b" : Read.b b : Debug "    " + dataSections\sections("my_label_3")\types() + " : " + b
      Case "s" : Read.s s : Debug "    " + dataSections\sections("my_label_3")\types() + " : " + s
    EndSelect
Next

; #########################################################

;   sections: 4
;       my_label_3 (4 items)
;       l2 (0 items)
;       l4 (0 items)
;       label1 (2 items)
;   
;   my_label_3 (4 items) :
;       i : 111
;       b : 2
;       s : three
;       i : 444


Re: Counting Items in the DataSection?

Posted: Wed May 07, 2025 4:51 pm
by Blue
AZJIO wrote: Mon May 05, 2025 10:42 pm
Blue wrote: Sun May 04, 2025 8:55 pm Why complicate simple things ?
[...]
So you shouldn't be underestimating the examples.
[...]
No underestimating. :shock:
I think you're missing the point here.