Passing objects in Homespun
mpark
Posts: 1,305
One of the purposes of my Homespun Spin compiler is to experiment with Spin language extensions. People are always bemoaning the inability to pass object pointers in Spin, so I implemented that functionality. However, I haven't heard of anyone who's actually tried it out, which I attribute to several possible causes:
1. No one knows about this Homespun feature
2. No one uses Homespun
3. Object-passing in Homespun doesn't do what people want
This post is intended to address point 1. Perhaps it will inspire people to get past point 2, and then maybe I'll find out about point 3, which is what I'm really interested in. Since this feature seems so important to people, I'd like to try to get it right. It's in an early stage of development (see caveats below) so there's plenty of room for improvement, but first I'd like to know if I'm on the right track. If the ability to pass object pointers is important to you, please let me know what works and what doesn't from your point of view.
The following totally contrived example involves a main object and a child object. The main object will be passing two kinds of object pointers to the child. The first is to a tv_text object, so that both main and child can print to the screen. The second type of object pointer implements the following two functions:
IWorker is an interface, and the main object contains two worker objects that implement the IWorker interface (in other words, each worker contains public methods that match the description in IWorker.spin).
Here's the main object:
The child object:
The first worker object:
The second worker object:
The output:
Caveats:
1. No one knows about this Homespun feature
2. No one uses Homespun
3. Object-passing in Homespun doesn't do what people want
This post is intended to address point 1. Perhaps it will inspire people to get past point 2, and then maybe I'll find out about point 3, which is what I'm really interested in. Since this feature seems so important to people, I'd like to try to get it right. It's in an early stage of development (see caveats below) so there's plenty of room for improvement, but first I'd like to know if I'm on the right track. If the ability to pass object pointers is important to you, please let me know what works and what doesn't from your point of view.
The following totally contrived example involves a main object and a child object. The main object will be passing two kinds of object pointers to the child. The first is to a tv_text object, so that both main and child can print to the screen. The second type of object pointer implements the following two functions:
' IWorker.spin pub FunctionFirst( a, b ) pub FunctionSecond( a, b )
IWorker is an interface, and the main object contains two worker objects that implement the IWorker interface (in other words, each worker contains public methods that match the description in IWorker.spin).
Here's the main object:
' main.spin con _clkmode = xtal1+pll16x _xinfreq = 5_000_000 obj worker1 : "worker1" ' implements IWorker interface worker2 : "worker2" ' implements IWorker interface child : "child" debug : "tv_text" pub Main | r debug.start( 0 ) debug.str( string( "Object-passing test", 13 ) ) ' We want child to be able to print to the screen, so pass it a pointer to the debug object: child.Init( debug ) ' Now pass a pointer to worker1. child is expecting something that ' implements the the IWorker interface, which worker1 does. r := child.TestWorker( worker1, 654, 321 ) debug.dec( r ) debug.out( 13 ) ' Same thing with worker2. r := Child.TestWorker( worker2, 654, 321 ) debug.dec( r ) debug.out( 13 )
The child object:
' child.spin obj worker : "IWorker" pointer debug : "tv_text" pointer pub Init( pDebug ) debug := pDebug pub TestWorker( pWorker, a, b ) | r1, r2 worker := pWorker r1 := worker.FunctionFirst( a, b ) debug.str( string( "r1 = " ) ) debug.dec( r1 ) debug.out( 13 ) r2 := worker.FunctionSecond( a, b ) debug.str( string( "r2 = " ) ) debug.dec( r2 ) debug.out( 13 ) return r1 + r2
The first worker object:
' worker1.spin pri Sum( a, b ) return a + b pub FunctionFirst( a, b ) return Sum( a, b ) pri Multiply( a, b ) return a * b pub FunctionSecond( a, b ) return Multiply( a, b )
The second worker object:
' worker2.spin pri Difference( a, b ) return a - b pub FunctionFirst( a, b ) return Difference( a, b ) pub FunctionSecond( a, b ) return a / b
The output:
Object-passing test r1 = 975 r2 = 209934 210909 r1 = 333 r2 = 2 335
Caveats:
- There's no type-checking
- You can't dynamically create objects (but I have some ideas here).
- Things break if you have two or more child objects; i.e., obj child[noparse][[/noparse] 2 ] : "child" -- passing an object pointer to child[noparse][[/noparse] 0 ] messes up the corresponding pointer in child[noparse][[/noparse] 1 ].
Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Prop Tools under Development or Completed (Index)
http://forums.parallax.com/showthread.php?p=753439
My cruising website http://www.bluemagic.biz
I cannot comment on your pointer to "object" passing... because I do not use spin. Assembly is for me the way to go .
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Using DAT rather than VAR in drivers like TV_Text make it possible to share a resource. I would use an object pointer with a hardware abstraction layer object to specify the device driver. Of course one could just compile the driver to use instead, but that is limiting.
From a maintenance standpoint, passing an object eleminates having to change 15 files that use the object, but that's where the model is breaking I guess. I've tried using a stub file in spin and object index boundary violation overloading, but couldn't seem to make that work.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Output on the screen:
This is the parent.
Child object here.
Done.
Really nice and simple - congratulations
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBlade,·RamBlade, RetroBlade,·TwinBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: Micros eg Altair, and Terminals eg VT100 (Index) ZiCog (Z80) , MoCog (6809)
· Search the Propeller forums·(uses advanced Google search)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm