Perhaps I don't understand how :multi works (and I would love to see more 
documentation and will even write tests, as I don't think the existing ones 
cover all of the cases).

I added a custom Cons class to Pheme, as that's what a Lisp/Scheme needs.  
This means that I also need some more logic for is_deeply() to compare two 
Cons objects appropriately.

The attached patch is my first attempt.  It doesn't work and I'm not sure why.  
I don't know if installing is() from Test::More (it's a multi sub) overrides 
the multi is() in Pheme::Test.  I don't know if dispatch even *gets* to my 
custom is() either.

I don't even know if what I'm trying to do should be possible, at least the 
way I'm doing it.

I'm stumped and I appreciate any advice, especially from someone who knows how 
multi dispatch ought to work in Parrot and someone who knows how the current 
system does work.

-- c
=== lib/PhemeSymbols.pir
==================================================================
--- lib/PhemeSymbols.pir	(revision 16710)
+++ lib/PhemeSymbols.pir	(local)
@@ -15,14 +15,77 @@
 	.return()
 .end
 
+.namespace [ 'Pheme::Cons' ]
+
+.sub _initialize :load
+	.local pmc cons_class
+	newclass cons_class, 'Pheme::Cons'
+
+	addattribute cons_class, 'head'
+	addattribute cons_class, 'tail'
+.end
+
+.sub 'head' :method
+	.param pmc new_head  :optional
+	.param int have_head :opt_flag
+
+	unless have_head goto return_head
+	setattribute self, 'head', new_head
+	.return( new_head )
+
+  return_head:
+	.local pmc head
+	head = getattribute self, 'head'
+	.return( head )
+.end
+
+.sub __get_integer :method
+	.local pmc elem
+	elem  = self.'head'()
+
+	.local int elem_defined
+	elem_defined = defined elem
+
+	if elem_defined goto count_tail
+	.return( 0 )
+
+  count_tail:
+	.local int count
+	count = 0
+	elem  = self
+
+  loop_start:
+	inc count
+	elem         = elem.'tail'()
+	elem_defined = defined elem
+	if elem_defined goto loop_start
+
+  loop_end:
+	.return( count )
+.end
+
+.sub 'tail' :method
+	.param pmc new_tail  :optional
+	.param int have_tail :opt_flag
+
+	unless have_tail goto return_tail
+	setattribute self, 'tail', new_tail
+	.return( new_tail )
+
+  return_tail:
+	.local pmc tail
+	tail = getattribute self, 'tail'
+	.return( tail )
+.end
+
 .namespace [ 'Pheme' ]
 
-.sub __resolve_at_runtime :multi( ResizablePMCArray )
-	.param pmc args
-	.param pmc more_args :slurpy
+.sub __resolve_at_runtime :multi( Pheme::Cons )
+	.param pmc args :slurpy
 
-	unshift more_args, args
-	.return( more_args )
+	.local pmc result
+	result = __list_to_cons( args :flat ) 
+	.return( result )
 .end
 
 .sub __resolve_at_runtime :multi( string )
@@ -40,48 +103,50 @@
 	.return( result )
 
   return_list:
-	unshift args, symbol_name
-  	.return( args )
+
+	result = __list_to_cons( symbol_name, args :flat )
+  	.return( result )
 .end
 
-.sub car
-	.param pmc list
+.sub __list_to_cons
+	.param pmc args :slurpy
 
-	.local int count
-	count = list
+	.local int cons_type
+	cons_type = find_type 'Pheme::Cons'
 
-	if count > 0 goto really_car
-	.return( list )
+	.local pmc result
+	result = new cons_type
 
-  really_car:
-	.local pmc first_item
-	first_item = list[0]
+	.local int args_count
+	.local pmc arg
 
-	.return( first_item )
+  loop_start:
+	args_count = args
+	unless args_count goto loop_end
+	arg        = pop args
+	result     = cons( arg, result )
+	goto loop_start
+
+  loop_end:
+  	.return( result )
 .end
 
-.sub cdr
-	.param pmc list
+.sub car
+	.param pmc cons
 
-	.local pmc iter
-	iter = new .Iterator, list
-	iter = 0
+	.local pmc head
+	head = cons.'head'()
 
-	.local pmc result
-	result = new .ResizablePMCArray
+	.return( head )
+.end
 
-	# skip the first element
-	.local pmc elem
-	elem = shift iter
+.sub cdr
+	.param pmc cons
 
-  iter_loop:
-	unless iter goto iter_end
-	elem = shift iter
-	push result, elem
-	goto iter_loop
+	.local pmc tail
+	tail = cons.'tail'()
 
-  iter_end:
-	.return( result )
+	.return( tail )
 .end
 
 .sub include_file
@@ -98,9 +163,16 @@
 	.param pmc l
 	.param pmc r
 
-	unshift r, l
+	.local int cons_type
+	cons_type = find_type 'Pheme::Cons'
 
-	.return( r )
+	.local pmc result
+	result = new cons_type
+
+	result.'head'( l )
+	result.'tail'( r )
+
+	.return( result )
 .end
 
 .sub 'write' :multi()
@@ -130,6 +202,11 @@
 
 .sub __make_empty_cons
 	.local pmc result
-	result = new .ResizablePMCArray
+
+	.local int cons_type
+	cons_type = find_type 'Pheme::Cons'
+
+	.local pmc result
+	result = new cons_type
 	.return( result )
 .end
=== lib/PhemeTest.pir
==================================================================
--- lib/PhemeTest.pir	(revision 16710)
+++ lib/PhemeTest.pir	(local)
@@ -13,78 +13,20 @@
 	diag      = find_global 'Test::More', 'diag'
 	is_deeply = find_global 'Test::More', 'is_deeply'
 
-	store_global 'Pheme', 'plan', plan
-	store_global 'Pheme', 'is', is
-	store_global 'Pheme', 'ok', ok
-	store_global 'Pheme', 'diag', diag
+	store_global 'Pheme', 'plan',      plan
+	store_global 'Pheme', 'is',        is
+	store_global 'Pheme', 'ok',        ok
+	store_global 'Pheme', 'diag',      diag
 	store_global 'Pheme', 'is_deeply', is_deeply
 .end
 
-=cut
-
 .namespace[ 'Pheme' ]
 
-.sub _is :multi( ResizablePMCArray, ResizablePMCArray )
-	.param pmc    l_list
-	.param pmc    r_list
+.sub is :multi( Pheme::Cons, Pheme::Cons )
+	.param pmc    l_cons
+	.param pmc    r_cons
 	.param string diagnostic :optional
 
-	.local int l_count
-	.local int r_count
-	l_count = l_list
-	r_count = r_list
-
-	.local string explanation
-	.local string num_to_s
-
-	if l_count == r_count goto check_items
-
-	explanation  = 'Expected has '
-	num_to_s     = l_count
-	explanation .= num_to_s
-	explanation .= ' elements, Received has '
-	num_to_s     = r_count
-	explanation .= num_to_s
-	explanation .= ' elements'
-
-	ok( 0, diagnostic )
-	diag( explanation )
-	.return()
-
-  check_items:
-  	.local int i
-	i = 0
-
-	.local pmc l_elem
-	.local pmc r_elem
-
-  loop_start:
-	if i == l_count goto loop_end
-	l_elem = l_list[i]
-	r_elem = r_list[i]
-	eq l_elem, r_elem, pass_this_index
-	ok( 0, diagnostic )
-
-	explanation  = 'Elements mismatched at index '
-	num_to_s   = i
-	explanation .= num_to_s
-	explanation .= ', ('
-	num_to_s   = l_elem
-	explanation .= num_to_s
-	explanation .= '), ('
-	num_to_s   = r_elem
-	explanation .= num_to_s
-	explanation .= ')'
-	diag( explanation )
-	.return()
-
-  pass_this_index:
-  	inc i
-  	goto loop_start
-
-  loop_end:
-  	ok( 1, diagnostic )
-	.return()
+	print "Found correct is!\n"
+	.return( 0 )
 .end
-
-=cut
=== lib/post2pir.tg
==================================================================
--- lib/post2pir.tg	(revision 16710)
+++ lib/post2pir.tg	(local)
@@ -4,7 +4,7 @@
 .namespace [ 'Pheme' ]
 
 .sub __onload :anon :load
-	load_bytecode 'lib/PhemeSymbols.pbc'
+#	load_bytecode 'lib/PhemeSymbols.pbc'
 	main()
 .end
 

Reply via email to