view array.rhope @ 168:d2b941f82d74

Fix type of list constants in inference pass and return type of some Array related workers
author Mike Pavone <pavone@retrodev.com>
date Sun, 01 May 2011 18:41:17 -0700
parents 65ebd1ce2611
children
line wrap: on
line source


Blueprint Array
{
	Eltype(Blueprint)
	Length(Int32,Naked)
	Storage(Int32,Naked)
}

Blueprint Boxed Array
{
	Length(Int32,Naked)
	Storage(Int32,Naked)
}

Blueprint Empty Array
{
}

Foreign C:runtime
{
	_internal_array_copyout[array(Array), index(Int32,Naked), dest(Any Type,Boxed,Mutable):dest]
	_internal_array_copyin[array(Array,Boxed,Mutable), index(Int32,Naked), val:array]
	_internal_array_copychunk[source(Array), sindex(Int32,Naked), dest(Array,Boxed,Mutable), dindex(Int32,Naked), len(Int32,Naked):dest]
	_internal_array_getboxed[array(Boxed Array), index(Int32,Naked):out]
	_internal_array_setboxed[array(Boxed Array,Boxed,Mutable), index(Int32,Naked), val:array]
	_internal_array_allocboxed[size(Int32,Naked):out(Boxed Array)]
	_internal_array_allocboxedcopy[source(Boxed Array),size(Int32,Naked):out(Boxed Array)]
	_internal_array_allocnaked[size(Int32,Naked),type(Blueprint):out]
	_internal_array_allocnakedcopy[source(Array),size(Int32,Naked):out(Array)]
}

Array[:out(Empty Array)]
{
	out <- Build[Empty Array()]
}

First@Empty Array[array:out,empty]
{
	empty <- array
}

First@Array[array:out(Int32),empty]
{
	,empty <- If[[array]Length >>]
	{ out <- 0 }
}

First@Boxed Array[array:out(Int32),empty]
{
	,empty <- If[[array]Length >>]
	{ out <- 0 }
}

Next@Empty Array[array:out,empty]
{
	empty <- array
}

Next@Array[array,current:out(Int32),empty]
{
	next <- [current]+[1]
	,empty <- If[[next] < [[array]Length >>]]
	{
		out <- Val[next]
	}
}

Next@Boxed Array[array,current:out(Int32),empty]
{
	next <- [current]+[1]
	,empty <- If[[next] < [[array]Length >>]]
	{
		out <- Val[next]
	}
}

Last@Empty Array[array:out,empty]
{
	empty <- array
}

Last@Array[array:out(Int32),empty]
{
	,empty <- If[[array]Length >>]
	{ out <-  [[array]Length >>] - [1] }
}

Last@Boxed Array[array:out(Int32),empty]
{
	,empty <- If[[array]Length >>]
	{ out <-  [[array]Length >>] - [1] }
}

Append@Empty Array[array,newval:out]
{
	out <- [array]Set[0, newval]
}

Append@Array[array,newval:out]
{
	out <- [array]Set[[array]Length >>, newval]
}

Append@Boxed Array[array,newval:out(Boxed Array)]
{
	out <- [array]Set[[array]Length >>, newval]
}

Index@Empty Array[array:out,notfound]
{
	notfound <- array
}

Index@Array[array,index(Int32):out,notfound]
{
	,notfound <- If[[index] >= [0]]
	{
		,notfound <- If[[index] < [[array]Length >>]]
		{
			out <- _internal_array_copyout[array, index, Build[[array]Eltype >>]]
		}
	}	
}

Index@Boxed Array[array,index(Int32):out,notfound]
{
	,notfound <- If[[index] >= [0]]
	{
		,notfound <- If[[index] < [[array]Length >>]]
		{
			out <- _internal_array_getboxed[array, index]
		}
	}	
}

_Copy to Boxed[source,dest,current:out]
{
	ndest <- _internal_array_setboxed[dest, current, [source]Index[current]]
	
	[source]Next[current]
	{
		out <- _Copy to Boxed[source, ndest, ~]
	}{
		out <- Val[ndest]
	}
}

_Copy Naked[source,dest,current:out]
{
	ndest <- _internal_array_copyin[dest, current, [source]Index[current]]
	
	[source]Next[current]
	{
		out <- _Copy Naked[source, ndest, ~]
	}{
		out <- Val[ndest]
	}
}

Set@Array[array,index(Int32),val:out,invalid]
{
	invalid <- If[[index]<[0]] {}
	{
		len <- [array]Length >>
		If[[index]>[len]]
		{
			out <- [[array]Set[[index]-[1],val]]Set[index, val]
		}{
			If[[Blueprint Of[val]]=[[array]Eltype >>]]
			{
				If[[index]<[[array]Storage >>]]
				{
					out <- [_internal_array_copyin[array, index, val]]Length <<[Max[len, [index]+[1]]]
				}{
					//Does this make sense given the copies we may have to make?
					If[[index] < [4]]
					{
						new storage <- [index]+[index]
					}{
						new storage <- [index]+[[index]RShift[1]]
					}
					out <- [_internal_array_copyin[_internal_array_allocnakedcopy[array, new storage], index, val]]Length <<[[index]+[1]]
				}
			}{
				out <-[[_Copy to Boxed[array, _internal_array_allocboxed[[array]Storage >>], [array]First]]Length <<[[array]Length >>]]Set[index, val]
			}
		}
	}
}

Set@Boxed Array[array,index(Int32),val:out(Boxed Array),invalid]
{
	invalid <- If[[index]<[0]] {}
	{
		len <- [array]Length >>
		If[[index]>[len]]
		{
			out <- [[array]Set[[index]-[1],val]]Set[index, val]
		}{
			If[[index]<[[array]Storage >>]]
			{
				out <- [_internal_array_setboxed[array, index, val]]Length <<[Max[len, [index]+[1]]]
			}{
				//Does this make sense given the copies we may have to make?
				If[[index] < [4]]
				{
					new storage <- [index]+[index]
				}{
					new storage <- [index]+[[index]RShift[1]]
				}
				out <- [_internal_array_setboxed[_internal_array_allocboxedcopy[array, new storage], index, val]]Length <<[[index]+[1]]
			}
		}
	}
}

Set@Empty Array[array,index(Int32),val:out,invalid]
{
	invalid <- If[[index]<[0]] {}
	{
		out <- [_internal_array_allocnaked[1, Blueprint Of[val]]]Set[index, val]
	}
}

Slice@Array[array,slicepoint:left,right]
{
	If[[slicepoint]<=[0]]
	{
		left <- Array[]
		right <- array
	}{
		arrlen <- [array]Length >>
		If[[slicepoint]>=[arrlen]]
		{
			left <- array
			right <- Array[]
		}{
			left <- [_internal_array_copychunk[array, 0, _internal_array_allocnaked[slicepoint,[array]Eltype >>], 0, slicepoint]]Length <<[slicepoint]
			rightlen <- [arrlen]-[slicepoint]
			right <- [_internal_array_copychunk[array, slicepoint, _internal_array_allocnaked[rightlen,[array]Eltype >>], 0, rightlen]]Length <<[rightlen]
		}
	}
}

Slice@Empty Array[array,slicepoint:left,right]
{
	left <- array
	right <- array
}

Length@Empty Array[arr:out]
{
	out <- 0
}

Length@Array[arr:out]
{
	out <- [arr]Length >>
}

Length@Boxed Array[arr:out]
{
	out <- [arr]Length >>
}

Call@Array[arr,index(Int32):out,not found]
{
	out,not found <- [arr]Index[index]
}

Call@Boxed Array[arr,index(Int32):out,not found]
{
	out,not found <- [arr]Index[index]
}