fix codetest failure - ASSERT_ARGS does not have a ; after and
[parrot.git] / src / pmc / multisub.pmc
blob4c89739c53001747e2f617e3c055366f54396f8c
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 #include "pmc/pmc_callcontext.h"
24 /* HEADERIZER HFILE: none */
25 /* HEADERIZER BEGIN: static */
26 /* HEADERIZER END: static */
28 pmclass MultiSub extends ResizablePMCArray auto_attrs provides array provides invokable {
30     VTABLE STRING * get_string() {
31         PMC * const sub0    = VTABLE_get_pmc_keyed_int(INTERP, SELF, 0);
32         STRING * const name = VTABLE_get_string(INTERP, sub0);
33         return name;
34     }
36     VTABLE void push_pmc(PMC *value) {
37         if (!VTABLE_does(INTERP, value, CONST_STRING(INTERP, "invokable")))
38             Parrot_ex_throw_from_c_args(INTERP, NULL,
39                 EXCEPTION_INVALID_OPERATION, "attempt to push non Sub PMC");
41         SUPER(value);
42     }
44     VTABLE void set_pmc_keyed_int(INTVAL key, PMC *value) {
45         STRING * const _sub = CONST_STRING(INTERP, "Sub");
46         if (!VTABLE_isa(INTERP, value, _sub))
47             Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
48                     "attempt to set non Sub PMC");
49         SUPER(key, value);
50     }
52     VTABLE void set_integer_keyed_int(INTVAL key, INTVAL value) {
53         Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
54                 "attempt to set non Sub PMC");
55     }
57     VTABLE void set_string_keyed_int(INTVAL key, STRING *value) {
58         Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
59                 "attempt to set non Sub PMC");
60     }
62     VTABLE void set_number_keyed_int(INTVAL key, FLOATVAL value) {
63         Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
64                 "attempt to set non Sub PMC");
65     }
67     VTABLE opcode_t *invoke(void *next) {
68         PMC * const sig_obj = CONTEXT(INTERP)->current_sig;
69         PMC * const func    = Parrot_mmd_sort_manhattan_by_sig_pmc(INTERP,
70                 SELF, sig_obj);
72         if (PMC_IS_NULL(func))
73             Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
74                     "No applicable candidates found to dispatch to for '%Ss'",
75                     VTABLE_get_string(INTERP, SELF));
76         return VTABLE_invoke(INTERP, func, next);
77     }
80     /* I don't really know how to implement these if they need something
81        special, so I'll sort the sub list and defer processing to the
82        ResizablePMCArray's VTABLEs of the same names. Hopefully we
83        don't need anything beyond that. */
84     VTABLE PMC *get_pmc_keyed(PMC *key) {
85         PMC * const sig_obj = CONTEXT(INTERP)->current_sig;
86         PMC * const sub     = Parrot_mmd_sort_manhattan_by_sig_pmc(INTERP,
87                 SELF, sig_obj);
89         if (PMC_IS_NULL(sub))
90             Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
91                     "No applicable candidates found to dispatch to for '%Ss'",
92                     VTABLE_get_string(INTERP, SELF));
93         return SUPER(key);
94     }
96     VTABLE PMC *get_pmc_keyed_str(STRING *s) {
97         PMC * const sig_obj = CONTEXT(INTERP)->current_sig;
98         PMC * const sub     = Parrot_mmd_sort_manhattan_by_sig_pmc(INTERP,
99                 SELF, sig_obj);
101         if (PMC_IS_NULL(sub))
102             Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
103                     "No applicable candidates found to dispatch to for '%Ss'",
104                     VTABLE_get_string(INTERP, SELF));
105         return SUPER(s);
106     }
108     /* get_iter method should take one of two inputs: either an array of
109        arguments, or a string with a whitespace delimited function signature
110        (N, I, S, P). It should sort the argument list according to closeness
111        to this input argument list and return an iterator over that list. */
113     METHOD get_iter(PMC *args) {
114         STRING * const _array  = CONST_STRING(INTERP, "Array");
115         STRING * const _string = CONST_STRING(INTERP, "String");
117         if (VTABLE_isa(INTERP, args, _array)){
118             /* TODO: What goes here? */
119         }
120         else if (VTABLE_isa(INTERP, args, _string)) {
121             STRING * const s = VTABLE_get_string(INTERP, args);
122             /* TODO: What goes here? */
123         }
124         else
125             Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
126                     "attempt to call get_iter method with invalid arg type.\n");
127     }
132 =back
134 =head1 SEE ALSO
136 F<src/multidispatch.c>,
137 F<$perl6/doc/trunk/design/apo/A12.pod>,
138 F<$perl6/doc/trunk/design/syn/S12.pod>
140 =cut
145  * Local variables:
146  *   c-file-style: "parrot"
147  * End:
148  * vim: expandtab shiftwidth=4:
149  */