2 Copyright (C) 2006-2008, The Perl Foundation.
7 pmc/luaany.pmc - Lua abstract base class
11 C<LuaAny> provides an abstract base class for some Lua types.
13 =head2 PMC Inheritance Summary
16 -----------------------------------------------
17 LuaBoolean LuaAny, Default
18 LuaClosure Closure, LuaAny, Default
19 LuaFunction Sub, LuaAny, Default
20 LuaNil LuaAny, Default
21 LuaNumber LuaAny, Default
22 LuaString LuaAny, Default
23 LuaTable LuaAny, Default
24 LuaThread LuaAny, Default
25 LuaUserdata LuaAny, Default
27 =head2 PMC "Attribute" Summary
29 Class Metatable Environment Userdata
30 accessor get_metatable getfenv get_attr_str (getattribute)
31 mutator set_metatable setfenv set_attr_str (setattribute)
32 default value nil nil NULL
33 ------------------------------------------------------------------
39 LuaString yes (common) - -
42 LuaUserdata yes yes yes
44 The metatable supports the OO mecanism.
54 #include "lua_private.h"
58 find_meth(PARROT_INTERP, PMC *obj, const char *name) {
60 INTVAL type = PMC_type(obj);
62 if (dynpmc_LuaString == type) {
63 meta = Parrot_find_global_s(interp,
64 const_string(interp, "Lua::string"),
65 const_string(interp, "mt_string"));
68 if (dynpmc_LuaClosure != type && dynpmc_LuaFunction != type) {
70 meta = PMC_metadata(obj);
72 if (meta && dynpmc_LuaTable != PMC_type(meta))
78 PMC *key = pmc_new(interp, dynpmc_LuaString);
79 VTABLE_set_string_native(interp, key, const_string(interp, name));
81 method = VTABLE_get_pmc_keyed(interp, meta, key);
83 if (dynpmc_LuaNil != PMC_type(method))
98 =item C<void morph(INTVAL type)>
100 Changes the PMC to a PMC of a new type
105 void morph(INTVAL type) {
106 if (PMC_type(SELF) == type)
108 pmc_reuse(INTERP, SELF, type, 0);
113 =item C<INTVAL get_bool()>
126 =item C<void *get_pointer()>
128 Returns the address of the PMC.
133 void* get_pointer() {
139 =item C<void assign_pmc(PMC *value)>
144 void assign_pmc(PMC *value) {
145 VTABLE_morph(INTERP, SELF, PMC_type(value));
146 if (PMC_type(value) != dynpmc_LuaNil)
152 =item C<PMC* get_pmc_keyed(PMC *key)>
159 PMC* get_pmc_keyed(PMC *key) {
160 PMC *meth = find_meth(INTERP, SELF, "__index");
163 if (dynpmc_LuaClosure == PMC_type(meth)
164 || dynpmc_LuaFunction == PMC_type(meth)) {
165 PMC *retval = Parrot_runops_fromc_args(INTERP, meth, "PPP",
170 return pmc_new(INTERP, dynpmc_LuaNil);
173 return VTABLE_get_pmc_keyed(INTERP, meth, key);
175 real_exception(INTERP, NULL, ILL_INHERIT,
176 "attempt to index a %Ss value", SELF.name());
181 =item C<void set_pmc_keyed(PMC* key, PMC* value)>
188 void set_pmc_keyed(PMC *key, PMC *value) {
189 PMC *meth = find_meth(INTERP, SELF, "__newindex");
192 real_exception(INTERP, NULL, ILL_INHERIT,
193 "attempt to index a %Ss value", SELF.name());
195 if (dynpmc_LuaClosure == PMC_type(meth)
196 || dynpmc_LuaFunction == PMC_type(meth)) {
197 Parrot_runops_fromc_args(INTERP, meth, "vPPP",
201 VTABLE_set_pmc_keyed(INTERP, meth, key, value);
206 =item C<PMC* neg(PMC *dest)>
208 =item C<void i_neg()>
215 PMC* neg(PMC *dest) {
216 PMC *meth = find_meth(INTERP, SELF, "__unm");
219 real_exception(INTERP, NULL, ILL_INHERIT,
220 "attempt to perform arithmetic on a %Ss value", SELF.name());
222 dest = Parrot_runops_fromc_args(INTERP, meth, "PP", SELF);
224 if (PMC_IS_NULL(dest))
225 return pmc_new(INTERP, dynpmc_LuaNil);
231 PMC *meth = find_meth(INTERP, SELF, "__unm");
234 real_exception(INTERP, NULL, ILL_INHERIT,
235 "attempt to perform arithmetic on a %Ss value", SELF.name());
237 SELF = Parrot_runops_fromc_args(INTERP, meth, "PP", SELF);
239 if (PMC_IS_NULL(SELF))
240 SELF = pmc_new(INTERP, dynpmc_LuaNil);
245 =item C<PMC* logical_not(PMC *dest)>
247 Common implementation
252 PMC* logical_not(PMC *dest) {
253 dest = pmc_new(INTERP, dynpmc_LuaBoolean);
254 VTABLE_set_bool(INTERP, dest, ! SELF.get_bool());
260 =item C<INTVAL defined()>
273 =item C<void* invoke(void* next)>
280 opcode_t* invoke(void *next) {
281 PMC *meth = find_meth(INTERP, SELF, "__call");
285 real_exception(INTERP, NULL, ILL_INHERIT,
286 "attempt to call a %Ss value", SELF.name());
290 retval = Parrot_runops_fromc_args(INTERP, meth, "PP", SELF);
292 retval = pmc_new(INTERP, dynpmc_LuaNil);
294 next = VTABLE_invoke(INTERP, meth, next);
296 return (opcode_t *)next;
303 =head2 non-Vtable Methods
307 =item C<void add(PMC *value, PMC *dest)>
309 =item C<void i_add(PMC *value)>
311 =item C<void subtract(PMC *value, PMC *dest)>
313 =item C<void i_substract (PMC *value)>
315 =item C<void multiply(PMC *value, PMC *dest)>
317 =item C<void i_multiply(PMC *value)>
319 =item C<void divide(PMC *value, PMC *dest)>
321 =item C<void i_divide(PMC *value)>
323 =item C<PMC* modulus(PMC *value, PMC *dest)>
325 =item C<void i_modulus(PMC *value)>
327 =item C<PMC* pow(PMC *value, PMC *dest)>
329 =item C<void i_pow(PMC *value)>
331 =item C<PMC* concatenate(PMC *value, PMC *dest)>
333 =item C<void i_concatenate(PMC *value)>
340 PMC* add(PMC *value, PMC *dest) {
341 PMC *meth = find_meth(INTERP, SELF, "__add");
343 real_exception(INTERP, NULL, ILL_INHERIT,
344 "attempt to perform arithmetic on a %Ss value", SELF.name());
346 dest = Parrot_runops_fromc_args(INTERP, meth, "PPP", SELF, value);
348 if (PMC_IS_NULL(dest))
349 return pmc_new(INTERP, dynpmc_LuaNil);
354 void i_add(PMC *value) {
355 PMC *meth = find_meth(INTERP, SELF, "__add");
358 real_exception(INTERP, NULL, ILL_INHERIT,
359 "attempt to perform arithmetic on a %Ss value", SELF.name());
361 SELF = Parrot_runops_fromc_args(INTERP, meth, "PPP", SELF, value);
362 if (PMC_IS_NULL(SELF))
363 SELF = pmc_new(INTERP, dynpmc_LuaNil);
366 PMC* subtract(PMC *value, PMC *dest) {
367 PMC *meth = find_meth(INTERP, SELF, "__sub");
369 real_exception(INTERP, NULL, ILL_INHERIT,
370 "attempt to perform arithmetic on a %Ss value", SELF.name());
372 dest = Parrot_runops_fromc_args(INTERP, meth, "PPP", SELF, value);
374 if (PMC_IS_NULL(dest))
375 return pmc_new(INTERP, dynpmc_LuaNil);
380 void i_subtract(PMC *value) {
381 PMC *meth = find_meth(INTERP, SELF, "__sub");
383 real_exception(INTERP, NULL, ILL_INHERIT,
384 "attempt to perform arithmetic on a %Ss value", SELF.name());
386 SELF = Parrot_runops_fromc_args(INTERP, meth, "PPP", SELF, value);
388 if (PMC_IS_NULL(SELF))
389 SELF = pmc_new(INTERP, dynpmc_LuaNil);
392 PMC* multiply(PMC *value, PMC *dest) {
393 PMC *meth = find_meth(INTERP, SELF, "__mul");
396 real_exception(INTERP, NULL, ILL_INHERIT,
397 "attempt to perform arithmetic on a %Ss value", SELF.name());
399 dest = Parrot_runops_fromc_args(INTERP, meth, "PPP", SELF, value);
401 if (PMC_IS_NULL(dest))
402 return pmc_new(INTERP, dynpmc_LuaNil);
407 void i_multiply(PMC *value) {
408 PMC *meth = find_meth(INTERP, SELF, "__mul");
411 real_exception(INTERP, NULL, ILL_INHERIT,
412 "attempt to perform arithmetic on a %Ss value", SELF.name());
414 SELF = Parrot_runops_fromc_args(INTERP, meth, "PPP", SELF, value);
416 if (PMC_IS_NULL(SELF))
417 SELF = pmc_new(INTERP, dynpmc_LuaNil);
420 PMC* divide(PMC *value, PMC *dest) {
421 PMC *meth = find_meth(INTERP, SELF, "__div");
424 real_exception(INTERP, NULL, ILL_INHERIT,
425 "attempt to perform arithmetic on a %Ss value", SELF.name());
427 dest = Parrot_runops_fromc_args(INTERP, meth, "PPP", SELF, value);
429 if (PMC_IS_NULL(dest))
430 return pmc_new(INTERP, dynpmc_LuaNil);
435 void i_divide(PMC *value) {
436 PMC *meth = find_meth(INTERP, SELF, "__div");
439 real_exception(INTERP, NULL, ILL_INHERIT,
440 "attempt to perform arithmetic on a %Ss value", SELF.name());
442 SELF = Parrot_runops_fromc_args(INTERP, meth, "PPP", SELF, value);
444 if (PMC_IS_NULL(SELF))
445 SELF = pmc_new(INTERP, dynpmc_LuaNil);
448 PMC* modulus(PMC *value, PMC *dest) {
449 PMC *meth = find_meth(INTERP, SELF, "__mod");
452 real_exception(INTERP, NULL, ILL_INHERIT,
453 "attempt to perform arithmetic on a %Ss value", SELF.name());
455 dest = Parrot_runops_fromc_args(INTERP, meth, "PPP", SELF, value);
457 if (PMC_IS_NULL(dest))
458 return pmc_new(INTERP, dynpmc_LuaNil);
463 void i_modulus(PMC *value) {
464 PMC *meth = find_meth(INTERP, SELF, "__mod");
467 real_exception(INTERP, NULL, ILL_INHERIT,
468 "attempt to perform arithmetic on a %Ss value", SELF.name());
470 SELF = Parrot_runops_fromc_args(INTERP, meth, "PPP", SELF, value);
472 if (PMC_IS_NULL(SELF))
473 SELF = pmc_new(INTERP, dynpmc_LuaNil);
476 PMC* pow(PMC *value, PMC *dest) {
477 PMC *meth = find_meth(INTERP, SELF, "__pow");
480 real_exception(INTERP, NULL, ILL_INHERIT,
481 "attempt to perform arithmetic on a %Ss value", SELF.name());
483 dest = Parrot_runops_fromc_args(INTERP, meth, "PPP", SELF, value);
485 if (PMC_IS_NULL(dest))
486 return pmc_new(INTERP, dynpmc_LuaNil);
491 void i_pow(PMC *value) {
492 PMC *meth = find_meth(INTERP, SELF, "__pow");
495 real_exception(INTERP, NULL, ILL_INHERIT,
496 "attempt to perform arithmetic on a %Ss value", SELF.name());
498 SELF = Parrot_runops_fromc_args(INTERP, meth, "PPP", SELF, value);
500 if (PMC_IS_NULL(SELF))
501 SELF = pmc_new(INTERP, dynpmc_LuaNil);
504 PMC* concatenate(PMC *value, PMC *dest) {
505 PMC *meth = find_meth(INTERP, SELF, "__concat");
508 real_exception(INTERP, NULL, ILL_INHERIT,
509 "attempt to concatenate a %Ss value", SELF.name());
511 dest = Parrot_runops_fromc_args(INTERP, meth, "PPP", SELF, value);
513 if (PMC_IS_NULL(dest))
514 return pmc_new(INTERP, dynpmc_LuaNil);
519 void i_concatenate(PMC *value) {
520 PMC *meth = find_meth(INTERP, SELF, "__concat");
522 real_exception(INTERP, NULL, ILL_INHERIT,
523 "attempt to concatenate a %Ss value", SELF.name());
525 SELF = Parrot_runops_fromc_args(INTERP, meth, "PPP", SELF, value);
527 if (PMC_IS_NULL(SELF))
528 SELF = pmc_new(INTERP, dynpmc_LuaNil);
533 =item C<INTVAL is_equal(PMC *value)>
538 INTVAL is_equal(PMC *value) {
544 =item C<INTVAL cmp(PMC *value)>
549 INTVAL cmp(PMC *value) {
550 STRING *self_name = SELF.name();
551 STRING *val_name = VTABLE_name(INTERP, value);
553 if (string_compare(INTERP, self_name, val_name) != 0)
554 real_exception(INTERP, NULL, ILL_INHERIT,
555 "attempt to compare %Ss with %Ss", self_name, val_name);
557 real_exception(INTERP, NULL, ILL_INHERIT,
558 "attempt to compare two %Ss values", self_name);
565 =head2 Specific Methods
569 =item C<PMC *get_metatable()>
574 METHOD PMC* get_metatable() {
575 PMC *nil = pmc_new(INTERP, dynpmc_LuaNil);
588 PMC *meth = find_meth(INTERP, SELF, "__len");
592 real_exception(INTERP, NULL, ILL_INHERIT,
593 "attempt to get length of a %Ss value", SELF.name());
595 retval = Parrot_runops_fromc_args(INTERP, meth, "PP", SELF);
597 if (PMC_IS_NULL(retval))
598 retval = pmc_new(INTERP, dynpmc_LuaNil);
605 =item C<PMC* tonumber()>
612 METHOD PMC* tonumber() {
613 PMC *nil = pmc_new(INTERP, dynpmc_LuaNil);
619 =item C<PMC* tostring()>
621 Return a Lua C<string>.
623 Common implementation (use C<__tostring> or C<get_string>).
628 METHOD PMC* tostring() {
629 PMC *meth = find_meth(INTERP, SELF, "__tostring");
633 retval = Parrot_runops_fromc_args(INTERP, meth, "PP", SELF);
635 if (PMC_IS_NULL(retval))
636 retval = pmc_new(INTERP, dynpmc_LuaNil);
639 retval = pmc_new(INTERP, dynpmc_LuaString);
640 VTABLE_set_string_native(INTERP, retval, SELF.get_string());
662 * c-file-style: "parrot"
664 * vim: expandtab shiftwidth=4: