collection problem

BlitzMax Forums/BlitzMax Programming/collection problem

rdodson41(Posted 2005) [#1]
Im making my own collection data structure, and I set up the object enumerator and other functions needed as per the intructions in the language reference. But when I try to run a ForNext loop:

Local list:RList=Rlist.Create()

For Local link:RLink=EachIn list
Print "asdf"
Next

End

It gives me the error:
Compile Error:ForEach collection expression error
[/Users/rich/Games/RichPrgms/list.bmx;7;1]
Build Error: failed to compile /Users/rich/Games/RichPrgms/list.bmx

What is wrong here? BlitzMax 1.04, Mac OS X


rdodson41(Posted 2005) [#2]
The error is on the line that begins with the For


skn3(Posted 2005) [#3]
Does Rlist extend TList ?


rdodson41(Posted 2005) [#4]
No it is my own type of data structure that I made, and it works fine except for this. But this code gives a compile error. And btw, I changed link:Object to link:RLink which is what it should be, I had been testing if Object would work, and forgot to change it back.


rdodson41(Posted 2005) [#5]
If I need to post the entire code I will, but its kinda long. Im just wondering why this doesn't work, considereing I effectivly copied the TList code for this.


rdodson41(Posted 2005) [#6]
bump


skn3(Posted 2005) [#7]
Well I tried getting this to work by following the example in the docs, and it worked fine. So I dunno what you are doing wrong. =/


rdodson41(Posted 2005) [#8]
Here's my entire code:
[edited out]



skidracer(Posted 2005) [#9]
sp?

Method NextObjec:RLink()

there are other problems with your code also, but that should get you going again...


Shambler(Posted 2005) [#10]
In your RList type you have a data member pos:RLink but you do not create a new RLink you leave pos uninitialised 'Null' which is why it fails.


rdodson41(Posted 2005) [#11]
@Skidracer- Thanks that was the main problem, I should have picked up on that. I'm not a great speller cause I usually just don't pay attention to it and make simple mistakes like that.

@Shambler- pos is supposed to be null if there is no data in the list. The _head is there for the internal workings of the list and the user isn't supposed to know about it, just like you don't interact with the head in TList. Since there is no data in the list and the head is essentially invisable, pos is just set to null for now. I don't know why you would need the position if there is no data in the list.

Skidracer you said there were other problems with my code, I fixed up some basic ones I saw, but could you tell me any others?

Strict

Local list:RList=RList.Create()

list.AddLast("asdf")
list.AddLast("fdsa")
list.AddLast("1234")
list.AddLast("4321")


For Local l:RLink=EachIn list
	Print String(l.value)
Next


Type RList
	Field _head:RLink
	Field pos:RLink
	Field count:Int
	
	
	Function Create:RList()
		Local _l:RList=New RList
		_l._head=New RLink
		_l._head.list=_l
		_l._head.value=_l._head
		_l._head.prec=_l._head
		_l._head.succ=_l._head
		Return _l
	EndFunction
	
	Method ObjectEnumerator:REnum()
		Return REnum.Create(_head)
	EndMethod
	
	
	Method InsertBefore:RLink(_value:Object,_l:RLink)
		If _l=Null Then RuntimeError("Invalid RLink.")
		Local _rl:RLink=New RLink
		_rl.list=Self
		_rl.value=_value
		_rl.prec=_l.prec
		_rl.succ=_l
		_rl.prec.succ=_rl
		_rl.succ.prec=_rl
		Return _rl
	EndMethod
	
	Method InsertAfter:RLink(_value:Object,_l:RLink)
		If _l=Null Then RuntimeError("Invalid RLink.")
		Local _rl:RLink=New RLink
		_rl.list=Self
		_rl.value=_value
		_rl.prec=_l
		_rl.succ=_l.succ
		_rl.prec.succ=_rl
		_rl.succ.prec=_rl
		Return _rl
	EndMethod
	
	Method AddFirst:RLink(_value:Object)
		Return InsertAfter(_value,_head)
	EndMethod
	
	Method AddLast:RLink(_value:Object)
		Return InsertBefore(_value,_head)
	EndMethod
	
	
	Method Remove:Object(_l:RLink)
		If _l=Null Then RuntimeError("Invalid RLink.")
		Return _l.Remove()
	EndMethod
	
	Method RemoveFirst:Object()
		Return Remove(First())
	EndMethod
	
	Method RemoveLast:Object()
		Return Remove(Last())
	EndMethod
	
	Method Clear()	'supposed to be fornext loop here
		If count=0 Then Return
		SetFirst()
		Repeat
			pos.Remove()
		Until pos=Null
	EndMethod
	
	
	Method First:RLink()
		If _head.succ=_head Then RuntimeError("Empty RList.")
		Return _head.succ
	EndMethod
	
	Method Last:RLink()
		If _head.prec=_head Then RuntimeError("Empty RList.")
		Return _head.prec
	EndMethod
	
	
	Method SetPos(_l:RLink)
		If _l=Null Then RuntimeError("Invalid RLink.")
		_l.SetAsPos()
	EndMethod
	
	Method SetFirst()
		SetPos(First())
	EndMethod
	
	Method SetLast()
		SetPos(Last())
	EndMethod
	
	Method NextPos()
		SetPos(pos.succ)
	EndMethod
	
	Method PrevPos()
		SetPos(pos.prec)
	EndMethod
	
	
	Method Index:Int(_l:RLink)
		If _l=Null Then RuntimeError("Invalid RLink.")
		Return _l.Index()
	EndMethod
	
	Method Link:RLink(_i:Int)	'supposed to be fornext loop here
		If count=0 Then Return
		Local _idx:Int=1
		SetFirst()
		Repeat
			If _idx=_i Then Return pos
			NextPos()
			_idx:+1
		Until _idx>count
	EndMethod
EndType

Type RLink
	Field list:RList
	Field value:Object
	Field prec:RLink
	Field succ:RLink
	
	Method Remove:Object()
		If Self=list._head Then RuntimeError("Invalid RLink.")
		If Self=list.pos Then
			If succ<>list._head Then list.NextPos()
			If prec<>list._head Then list.PrevPos()
			list.pos=Null
		EndIf
		prec.succ=succ
		succ.prec=prec
		list.count:-1
		Return value
	EndMethod
	
	Method SetAsPos()
		If Self=list._head Then RuntimeError("Invalid RLink.")
	EndMethod
	
	Method Index:Int()
		If Self=list._head Then RuntimeError("Invalid RLink.")
		If prec=list._head Then Return 1
		Return prec.Index()+1
	EndMethod	
EndType

Type REnum
	Field _link:RLink
	
	Function Create:REnum(_l:RLink)
		Local _r:REnum=New REnum
		_r._link=_l
		Return _r
	EndFunction
	
	Method HasNext:Int()
		If _link.succ<>_link.list._head Then Return True
	EndMethod
	
	Method NextObject:RLink()
		If HasNext() Then
			_link=_link.succ
			Return _link
		EndIf
	EndMethod
EndType