[TT #871] Add rand as a dynop, with tests
[parrot.git] / src / pmc / multisub.pmc
blob798ab60e294e570a31c2b8eca1629abc0b7aa1d8
1 /*
2 Copyright (C) 2001-2009, Parrot Foundation.
3 $Id$
5 =head1 NAME
7 src/pmc/multisub.pmc - A container for multi-dispatched subs
9 =head1 DESCRIPTION
11 This class inherits from ResizablePMCArray and provides an Array of
12 Sub PMCs with the same short name, but different long names.
14 =head2 Functions
16 =over 4
18 =cut
22 pmclass MultiSub extends ResizablePMCArray need_ext provides array {
24     VTABLE void push_pmc(PMC *value) {
25         STRING * const _sub = CONST_STRING(interp, "Sub");
26         STRING * const _nci = CONST_STRING(interp, "NCI");
28         if (!VTABLE_isa(interp, value, _sub)
29         &&  !VTABLE_isa(interp, value, _nci))
30             Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
31                     "attempt to push non Sub PMC");
33         SUPER(value);
34     }
36     VTABLE void set_pmc_keyed_int(INTVAL key, PMC *value) {
37         STRING * const _sub = CONST_STRING(interp, "Sub");
38         if (!VTABLE_isa(interp, value, _sub))
39             Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
40                     "attempt to set non Sub PMC");
41         SUPER(key, value);
42     }
44     VTABLE void set_integer_keyed_int(INTVAL key, INTVAL value) {
45         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
46                 "attempt to set non Sub PMC");
47     }
49     VTABLE void set_string_keyed_int(INTVAL key, STRING *value) {
50         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
51                 "attempt to set non Sub PMC");
52     }
54     VTABLE void set_number_keyed_int(INTVAL key, FLOATVAL value) {
55         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
56                 "attempt to set non Sub PMC");
57     }
59     VTABLE opcode_t *invoke(void *next) {
60         PMC * const func = Parrot_mmd_sort_manhattan(interp, SELF);
62         if (PMC_IS_NULL(func))
63             Parrot_ex_throw_from_c_args(INTERP, NULL, 1, "No applicable methods.\n");
65         return VTABLE_invoke(INTERP, func, next);
66     }
68     VTABLE PMC *get_iter() {
69         PMC * const sub = Parrot_mmd_sort_manhattan(INTERP, SELF);
71         if (PMC_IS_NULL(sub))
72             Parrot_ex_throw_from_c_args(INTERP, NULL, 1, "No applicable methods.\n");
73         return SUPER();
74     }
76     /* I don't really know how to implement these if they need something
77        special, so I'll sort the sub list and defer processing to the
78        ResizablePMCArray's VTABLE methods of the same names. Hopefully we
79        don't need anything beyond that. */
80     VTABLE PMC *get_pmc_keyed(PMC *key) {
81         PMC * const sub = Parrot_mmd_sort_manhattan(INTERP, SELF);
82         if (PMC_IS_NULL(sub))
83             Parrot_ex_throw_from_c_args(INTERP, NULL, 1, "No applicable methods.\n");
84         return SUPER(key);
85     }
87     VTABLE PMC *get_pmc_keyed_str(STRING *s) {
88         PMC * const sub = Parrot_mmd_sort_manhattan(INTERP, SELF);
89         if (PMC_IS_NULL(sub))
90             Parrot_ex_throw_from_c_args(INTERP, NULL, 1, "No applicable methods.\n");
91         return SUPER(s);
92     }
94     /* get_iter method should take one of two inputs: either an array of
95        arguments, or a string with a whitespace delimited function signature
96        (N, I, S, P). It should sort the argument list according to closeness
97        to this input argument list and return an iterator over that list. */
99     METHOD get_iter(PMC *args) {
100         STRING * const _array  = CONST_STRING(interp, "Array");
101         STRING * const _string = CONST_STRING(interp, "String");
103         if (VTABLE_isa(INTERP, args, _array)){
104             /* TODO: What goes here? */
105         }
106         else if (VTABLE_isa(INTERP, args, _string)) {
107             STRING * const s = VTABLE_get_string(INTERP, args);
108             /* TODO: What goes here? */
109         }
110         else
111             Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
112                     "attempt to call get_iter method with invalid arg type.\n");
113     }
118 =back
120 =head1 SEE ALSO
122 F<src/multidispatch.c>,
123 F<$perl6/doc/trunk/design/apo/A12.pod>,
124 F<$perl6/doc/trunk/design/syn/S12.pod>
126 =cut
131  * Local variables:
132  *   c-file-style: "parrot"
133  * End:
134  * vim: expandtab shiftwidth=4:
135  */