[t][TT #1517] Commented out test for comparing Rational PMC to Integer PMC via =...
[parrot.git] / docs / vtables.pod
blob5eeba8a62be7681464d2480d80b5726acb1b6724
1 # Copyright (C) 2001-2007, Parrot Foundation.
2 # $Id$
4 =head1 NAME
6 docs/vtables.pod - Parrot Vtables
8 =head1 Implementing Variable Types with Vtables
10 This is a guide to creating your own PMC (Polymorphic Container) classes.  It
11 tells you what you need to write in order to add new variable types to Parrot.
13 =head2 Overview
15 The guts of the Parrot interpreter are by design ignorant (or, if you want to
16 be less disparaging, agnostic) of the intricacies of variable type behavior.
17 The standard example is the difference between Perl scalars and Python scalars.
18 In Perl, if you have
20     $a = "a9";
21     $a++;
23 you end up with C<$a> being C<b0>. This is because of the magic of the Perl
24 increment operator. In Python, on the other hand, you'd get a runtime error.
26 =over 3
28 =item *
30 To be perfectly honest, this is a slightly flawed example, since it's
31 unlikely that there will be a distinct "Python scalar" PMC class.  The
32 Python compiler could well infer variables by their type such that C<a>
33 would be a C<PythonString> and C<b> would be a C<PythonNumber>.  But the
34 point remains - incrementing a C<PythonString> is very different from
35 incrementing a C<PerlScalar>.
37 =back
39 Since the behavior is a function of the "type" of the PMC, it's natural to
40 consider the various different types of PMC as classes in an object-oriented
41 system. The Parrot interpreter calls methods on the individual PMC objects to
42 manipulate them. So the example above would translate to something like:
44 =over 3
46 =item 1.
48 Construct a new PMC in the PerlScalar class.
50 =item 2.
52 Call a method setting its string value to C<"a9">.
54 =item 3.
56 Call a method to tell it to increment itself.
58 =back
60 And if you replace PerlScalar with PythonString, you get different behavior but
61 to the fundamental guts of the interpreter, the instructions are the same. PMCs
62 are an abstract virtual class; the interpreter calls a method, the PMC object
63 does the right thing, and the interpreter shouldn't have to care particularly
64 what that right thing happens to be.
66 Hence, adding a new data type to Parrot is a question of providing methods
67 which implement that data type's expected behavior. Let's now look at how one
68 is supposed to do this.
70 =head2 Starting out
72 If you're adding data types to the core of Parrot, you should be creating a
73 file in the F<src/pmc/> subdirectory; this is where all the built-in PMC
74 classes live. (And a good source of examples to plunder even if you're not
75 writing a core data type.)
77 You should almost always start by running F<tools/dev/gen_class.pl> to
78 generate a skeleton for the class. Let's generate a number type for
79 the beautifully non-existent Fooby language:
81     % perl tools/dev/gen_class.pl FoobyNumber > src/pmc/foobynumber.pmc
83 This will produce a skeleton PMC file (to be preprocessed into ordinary C
84 code by the F<tools/build/pmc2c.pl> program) with stubs for all the methods
85 you need to fill in. Actually, there are more stubs here then you probably
86 I<need> to fill in. Your PMC isn't going to want to support all these
87 methods, and in many cases you may want to fall back to default behavior
88 instead of implementing a dummy method.> The function C<init> allows you to
89 set up anything you need to set up. 
91 Now you'll have to do something a little different depending on whether you're
92 writing a built-in class or an extension class. If you're writing a non-core
93 PMC, called a "dynpmc", you need to add the argument C<dynpmc> to the line
94 that starts with C<pmclass>. Here's an example:
96         pmclass FooByNumber dynpmc {
97                 ...
99 This alerts the PMC compiler that the PMC type should not be hard-coded into
100 Parrot, and that the PMC definition needs to be loaded in to Parrot
101 dynamically when the user requires it.
103 To finish up adding a built-in class:
105 =over 4
107 =item 1.
109 Add src/pmc/YOURCLASS.pmc to the MANIFEST.
111 =item 2.
113 Run C<make realclean>, and then run F<Configure.pl> to add your new PMC to
114 the set of built-in PMCs.
116 =back
118 =head2 What You Can and Cannot Do
120 The usual way to continue from the F<tools/dev/gen_class.pl>-generated
121 skeleton is to define a structure that will hook onto the C<data>, if your
122 data type needs to use that, and then also define some user-defined flags.
124 Flags are accessed by C<< pmc->flags >>. Most of the bits in the flag word are
125 reserved for use by parrot itself, but a number of them have been assigned for
126 general use by individual classes. These are referred to as
127 C<Pobj_private0_FLAG> .. C<Pobj_private7_FLAG>.
129 Normally, you will want to alias these generic bit names to something more
130 meaningful within your class:
132     enum {
133         Foobynumber_is_bignum = Pobj_private0_FLAG,
134         Foobynumber_is_bigint = Pobj_private1_FLAG,
135         ....
136     };
138 To manipulate the flags, use the macros listed in F<pobj.h>.
140 PMCs also have the ability to store an arbitrary number of user-defined
141 attribute values using the C<ATTR> keyword. 
143 =head2 Multimethods
145 One slightly (potentially) tricky element of implementing vtables is that
146 several of the vtable functions have variant forms depending on the type of
147 data that they're being called with.
149 For instance, the C<set_integer> method has multiple forms; the default
150 C<set_integer> means that you are being called with a PMC, and you should
151 probably use the C<get_integer> method of the PMC to find its integer value;
152 C<set_integer_native> means you're being passed an C<INTVAL>. The final form is
153 slightly special; if the interpreter calls C<set_integer_same>, you know that
154 the PMC that you are being passed is of the same type as you. Hence, you can
155 break the class abstraction to save a couple of dereferences - if you want to.
157 Similar shortcuts exist for strings, (C<native> and C<same>) and floating point
158 numbers.
160 =head2 Implementing VTABLE Interfaces
162 The master list of VTABLE interfaces can be found in F<src/vtable.tbl> in
163 the root directory of the Parrot source, with documentation in
164 F<docs/pdds/pdd17_pmc.pod>. A few of these are very important, for
165 instance:
167 =over 3
169 =item C<type>
171 Return the enumeration value of your class.
173 =item C<name>
175 Return a string containing your class name.
177 =item C<init>
179 Initialization.  Parrot makes exactly one call to either C<init> or
180 C<init_pmc> at PMC construction time.
182 =item C<init_pmc>
184 Alternative entry point for initialization that takes a PMC argument.
185 Parrot makes exactly one call to either C<init> or C<init_pmc> at PMC
186 construction time.
188 NOTE: It is strongly suggested that C<init_pmc(PMCNULL)> be equivalent to
189 C<init()>.
191 =item C<is_equal>
193 True if the passed-in PMC has the same B<value> as you. For instance, a Perl
194 integer and a Python integer could have the same value, but could not be the
195 same thing as defined by C<is_same>.
197 =item C<clone>
199 Copy your data and state into the passed-in destination PMC.
201 =back
203 Others are methods you may or may not need, depending on your type:
205 =over 3
207 =item C<morph>
209 Turn yourself into the specified type.
211 =item C<destroy>
213 Do any data shut-down and finalization you need to do. To have this method
214 called, you must set the C<Pobj_custom_destroy_FLAG>.
216 =item C<get_integer>
218 Return an integer representation of yourself.
220 =item C<get_number>
222 Return a floating-point representation of yourself.
224 =item C<get_string>
226 Return a string representation of yourself (a STRING* object), this should be a
227 B<copy> of whatever string you are holding, not just a pointer to your own
228 string so that anything that calls this method can happily modify this value
229 without making a mess of your guts.
231 =item C<get_bool>
233 Return a boolean representation of yourself.
235 =item C<get_value>
237 Return your private data as a raw pointer.
239 =item C<is_same>
241 True if the passed-in PMC refers to exactly the same B<data> as you. (Contrast
242 C<is_equal>)
244 =item C<set_integer>
246 Set yourself to the passed-in integer value. This is an integer multimethod.
248 =item C<set_number>
250 Set yourself to the passed-in float value. This is a floating-point
251 multimethod.
253 =item C<set_string>
255 Set yourself to the passed-in string. This is a string multimethod.
257 =item C<add>
259 Fetch the number part of C<value> and add your numeric value to it, storing the
260 result in C<dest>. (Probably by calling its C<set_integer> or C<set_number>
261 method) This is a numeric multimethod.
263 =item C<subtract>
265 Fetch the number part of C<value> and subtract your numeric value from it,
266 storing the result in C<dest>. (Probably by calling its C<set_integer> or
267 C<set_number> method) This is a numeric multimethod.
269 =item C<multiply>
271 =item C<divide>
273 =item C<modulus>
275 You get the picture.
277 =item C<concatenate>
279 Fetch the string part of C<value> and concatenate it to yourself, storing the
280 result in C<dest>. (Probably by calling its C<set_string> method) This is a
281 string multimethod.
283 =item C<logical_or>
285 =item C<logical_and>
287 Perform the given short-circuiting logical operations between your boolean
288 value and the value passed in, storing the result in C<dest>.
290 =item C<logical_not>
292 Set yourself to be a logical negation of the value passed in.
294 =item C<repeat>
296 Repeat your string representation C<value> times and store the result in
297 C<dest>.
299 =back
301 If any method doesn't fit into your class, just don't implement it and don't
302 provide an empty function body. The default class, which all classes inherit
303 from will throw an exception if the missing method ever gets called.
305 If your class is a modification of an existing class, you may wish to use
306 inheritance. At the beginning of your VTABLE specification in
307 src/pmc/YOURCLASS.pmc, add the C<extends SUPERCLASS> phrase. For example:
309   pmclass PackedArray extends Array { ...
311 See the POD documentation in F<tools/build/pmc2c.pl> for a list of useful
312 keywords that you may use in the .pmc file.
314 =cut