Computer Science Canada

Casting a pointer in Turing

Author:  DemonWasp [ Tue Feb 17, 2009 4:33 pm ]
Post subject:  Casting a pointer in Turing

I searched this forum, but couldn't find anything that makes mention of this. If I'm duplicating something somewhere else, it's by accident.

You may have noticed that Turing doesn't have a way of casting a base-class-pointer to a derived-class-pointer like most other languages. In Java you would just do
code:

DerivedClassName derived = (DerivedClassName)base;


No such luck in Turing. But, there IS a way. It's grisly though, so those with an aversion to horrific implementations may want to avert their eyes.

Turing:

% Pointer-casting Example

class Base
    export baseMember

    var baseMember : int := Rand.Int(1, 10)
end Base

class Derived
    inherit Base
    export derivedMember
   
    var derivedMember : string := "abcdefg"
end Derived

var myDerivedObject : ^Base
new Derived, myDerivedObject

put myDerivedObject->baseMember
% This line gives the warning: "'derivedMember' is not in the export list of base"
% Which is of course correct, but unhelpful. It CAN'T be there, as it's only in the derived class.
%put myDerivedObject->derivedMember

type DerivedPtr : ^Derived
var myDerivedPtr : DerivedPtr := cheat ( DerivedPtr, myDerivedObject )

% Now we've successfully cast a base ptr to a derived ptr. Be warned, cheat is DANGEROUS. Only cast if you're SURE.
put myDerivedPtr -> baseMember
put myDerivedPtr -> derivedMember


Weirdly enough, you can't just use ^Derived in place of DerivedPtr there. Turing expects an identifier, which apparently doesn't include pointers. By making an object-ptr type, however, you can easily cast to that type with just one line.

edit: Quotefail

Author:  saltpro15 [ Tue Feb 17, 2009 4:44 pm ]
Post subject:  RE:Casting a pointer in Turing

Neutral I did not understand more than 3 words of that program, what the heck does a "cheat" do? better yet, what does any of it do ? Razz

Author:  DemonWasp [ Tue Feb 17, 2009 5:03 pm ]
Post subject:  RE:Casting a pointer in Turing

If you haven't read Cervantes' tutorial on Turing Classes, start there. Otherwise...

Basically:

You have two classes, call them "Base" and "Derived". Derived inherits from Base, so we can say "Derived is a Base" but we CANNOT say "Base is a Derived" because that's not always true.

Turing understands that, so any variable you have that is defined as a pointer-to-Derived can access all the methods exported by Base, because it IS a Base.

However, there are numerous circumstances where you have to be more specific. What if you need one of the methods that's only implemented by Derived, but for some reason you have to access it within a variable declared as ^Base (pointer-to-Base)?

Well, then you have to do what's called "casting". This just means "assume that this variable is a pointer-to-Derived, even though we don't know that for sure". Once we've done that (assuming it worked out...), we can access all the more specific fields and elements.

Update: I took a look at what it does if you use cheat() to cast to something that it isn't. It looks like Turing will let you do it, no matter how dangerous it is; the result is something like unions in C. Try the following:

Turing:


% Pointer-casting Example

class Base
    export baseMember

    var baseMember : int := Rand.Int(1, 10)
end Base

class Derived
    inherit Base
    export derivedMember
   
    var derivedMember : string := "abcdefg"
end Derived

class Derived2
    inherit Base
    export derivedMember
   
    var derivedMember : array 1..256 of nat1
end Derived2

var myDerivedObject : ^Base
new Derived, myDerivedObject

put myDerivedObject->baseMember
% This line gives the warning: "'derivedMember' is not in the export list of base"
% Which is of course correct, but unhelpful. It CAN'T be there, as it's only in the derived class.
%put myDerivedObject->derivedMember

type DerivedPtr : ^Derived
var myDerivedPtr : DerivedPtr := cheat ( DerivedPtr, myDerivedObject )

% Now we've successfully cast a base ptr to a derived ptr. Be warned, cheat is DANGEROUS. Only cast if you're SURE.
put myDerivedPtr -> baseMember
put myDerivedPtr -> derivedMember

% Now let's do a (supposedly) illegal cast...
type DerivedPtr2 : ^Derived2
var myDerivedPtr2 : DerivedPtr2 := cheat ( DerivedPtr2, myDerivedObject )

% Whoops, looks like we can output the derivedMember string as if it were a byte array!
put myDerivedPtr2->derivedMember(1)
put myDerivedPtr2->derivedMember(2)
put myDerivedPtr2->derivedMember(3)
put myDerivedPtr2->derivedMember(4)
put myDerivedPtr2->derivedMember(5)
put myDerivedPtr2->derivedMember(6)
put myDerivedPtr2->derivedMember(7)

Author:  saltpro15 [ Tue Feb 17, 2009 6:27 pm ]
Post subject:  RE:Casting a pointer in Turing

ah, thanks

Author:  DemonWasp [ Mon Apr 20, 2009 4:49 pm ]
Post subject:  RE:Casting a pointer in Turing

Resurrects to point something out:

Turing's documentation is full of fail. Turns out there's an anyclass root class (like Java's Object class). In the documentation for that class, it notes the following:

You can make a cast (with type-checking) from base-ptr to derived-ptr as follows:

Turing:

var p : ^anyclass
new stack, p
stack ( p ) . push ( 14 )


It's a little cleaner.

Author:  kalev [ Thu Apr 23, 2009 9:00 am ]
Post subject:  Re: Casting a pointer in Turing

theres an easier way to cheat:

Turing:

var variable1:char
var variable2:int

variable2:= 50

#variable1 := variable2


opposed to:

Turing:

var variable1:char
var variable2:int

variable2:= 2

variable1 := cheat (char, variable2)


note: the first way is shorter, and doesn't need to know the type of variable1 or variable2


: