Contributed by Chris Rathman
type Shape:class var x:int32; var y:int32; procedure create; @returns("esi"); @external; procedure getX; @returns("eax"); @external; procedure getY; @returns("eax"); @external; method setX(newx:int32); @external; method setY(newy:int32); @external; method moveTo(newx:int32; newy:int32); @external; method rMoveTo(deltax:int32; deltay:int32); @external; method draw; @abstract; endclass; |
unit Shapes; #include("stdlib.hhf"); #includeonce("Shape.hhf"); static vmt(Shape); // constructor procedure Shape.create; begin create; if (esi = 0) then mov(malloc(@size(Shape)), esi); endif; mov(&Shape._VMT_, this._pVMT_); this.setX(0); this.setY(0); push(esi); end create; // accessors for x & y procedure Shape.getX; begin getX; mov(this.x, eax); push(eax); end getX; procedure Shape.getY; begin getY; mov(this.y, eax); push(eax); end getY; method Shape.setX(newx:int32); begin setX; mov(newx, this.x); end setX; method Shape.setY(newy:int32); begin setY; mov(newy, this.y); end setY; // move the shape position method Shape.moveTo(newx:int32; newy:int32); begin moveTo; this.setX(newx); this.setY(newy); end moveTo; method Shape.rMoveTo(deltax:int32; deltay:int32); begin rMoveTo; push(eax); push(ebx); mov(this.x, eax); add(deltax, eax); mov(this.y, ebx); add(deltay, ebx); this.moveTo(eax, ebx); pop(ebx); pop(eax); end rMoveTo; end Shapes; |
type Rectangle:class inherits(Shape) var width:int32; var height:int32; override procedure create; @external; procedure getWidth; @returns("eax"); @external; procedure getHeight; @returns("eax"); @external; method setWidth(newwidth:int32); @external; method setHeight(newheight:int32); @external; override method draw; @external; endclass; procedure makeRectangle(newx:int32; newy:int32; newwidth:int32; newheight:int32); @returns("esi"); @external; |
unit Rectangles; #include("stdlib.hhf"); #includeonce("Shape.hhf"); #includeonce("Rectangle.hhf"); static vmt(Rectangle); // constructor procedure Rectangle.create; begin create; if (esi = 0) then mov(malloc(@size(Rectangle)), esi); endif; call Shape.create; mov(&Rectangle._VMT_, this._pVMT_); this.setWidth(0); this.setHeight(0); push(esi); end create; // accessors for width & height procedure Rectangle.getWidth; begin getWidth; mov(this.width, eax); push(eax); end getWidth; procedure Rectangle.getHeight; begin getHeight; mov(this.height, eax); push(eax); end getHeight; method Rectangle.setWidth(newwidth:int32); begin setWidth; mov(newwidth, this.width); end setWidth; method Rectangle.setHeight(newheight:int32); begin setHeight; mov(newheight, this.height); end setHeight; // draw the rectangle method Rectangle.draw; begin draw; push(eax); mov(this.getX(), eax); stdout.put("Drawing a Rectangle at:(", (type int32 eax), ","); mov(this.getY(), eax); stdout.put((type int32 eax), ") "); mov(this.getWidth(), eax); stdout.put("width ", (type int32 eax), ", "); mov(this.getHeight(), eax); stdout.put("height ", (type int32 eax), nl); pop(eax); end draw; // make a Rectangle object procedure makeRectangle(newx:int32; newy:int32; newwidth:int32; newheight:int32); begin makeRectangle; Rectangle.create(); (type Rectangle [esi]).moveTo(newx, newy); (type Rectangle [esi]).setWidth(newwidth); (type Rectangle [esi]).setHeight(newheight); push(esi); end makeRectangle; end Rectangles; |
type Circle:class inherits(Shape) var radius:int32; override procedure create; @external; procedure getRadius; @returns("eax"); @external; method setRadius(newradius:int32); @external; override method draw; @external; endclass; procedure makeCircle(newx:int32; newy:int32; newradius:int32); @returns("esi"); @external; |
unit Circles; #include("stdlib.hhf"); #includeonce("Shape.hhf"); #includeonce("Circle.hhf"); static vmt(Circle); // constructor procedure Circle.create; begin create; if (esi = 0) then mov(malloc(@size(Circle)), esi); endif; call Shape.create; mov(&Circle._VMT_, this._pVMT_); this.setRadius(0); push(esi); end create; // accessors for radius procedure Circle.getRadius; begin getRadius; mov(this.radius, eax); push(eax); end getRadius; method Circle.setRadius(newradius:int32); begin setRadius; mov(newradius, this.radius); end setRadius; // draw the circle method Circle.draw; begin draw; push(eax); mov(this.getX(), eax); stdout.put("Drawing a Circle at:(", (type int32 eax), ","); mov(this.getY(), eax); stdout.put((type int32 eax), ") "); mov(this.getRadius(), eax); stdout.put("radius ", (type int32 eax), nl); pop(eax); end draw; // make a circle object procedure makeCircle(newx:int32; newy:int32; newradius:int32); begin makeCircle; Circle.create(); (type Circle [esi]).moveTo(newx, newy); (type Circle [esi]).setRadius(newradius); push(esi); end makeCircle; end Circles; |
program Polymorph; #includeonce("stdlib.hhf"); #includeonce("Shape.hhf"); #includeonce("Circle.hhf"); #includeonce("Rectangle.hhf"); type pShape: pointer to Shape; static scribble: pShape[2]; static rect: pointer to Rectangle; begin Polymorph; // set up some shape instances mov(makeRectangle(10, 20, 5, 6), scribble[0*4]); mov(makeCircle(15, 25, 8), scribble[1*4]); // iterate through some shapes and handle polymorphically for (mov(0, ebx); ebx < 2; inc(ebx)) do scribble.draw[ebx*4](); scribble.rMoveTo[ebx*4](100, 100); scribble.draw[ebx*4](); endfor; // access a rectangle specific function mov(makeRectangle(0, 0, 15, 15), rect); rect.setWidth(30); rect.draw(); end Polymorph; |
Drawing a Rectangle at:(10,20) width 5, height 6 Drawing a Rectangle at:(110,120) width 5, height 6 Drawing a Circle at:(15,25) radius 8 Drawing a Circle at:(115,125) radius 8 Drawing a Rectangle at:(0,0) width 30, height 15 |