~ubuntu-branches/ubuntu/precise/rakudo/precise

« back to all changes in this revision

Viewing changes to src/pmc/p6invocation.pmc

  • Committer: Bazaar Package Importer
  • Author(s): Ryan Niebur
  • Date: 2010-03-29 22:47:34 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100329224734-7bwt61rrhpn6g7m4
Tags: 0.1~2010.01-1
* generate a manpage from docs/running.pod
* update the d/watch file
* New Upstream Version
  - update dependencies

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 
21
21
#include "parrot/parrot.h"
22
22
#include "pmc_perl6multisub.h"
 
23
#include "../binder/bind.h"
23
24
 
24
25
 
25
26
/* Selects whether we're doing a real dispatch or just a test to see if
42
43
 
43
44
/* This does the grunt work of working out what the next candidate is. Takes
44
45
 * account of us maybe needing to look into multi variants and all that lot. */
45
 
static PMC *get_next_candidate(PARROT_INTERP, PMC *SELF, int check_only) {
 
46
static PMC *get_next_candidate(PARROT_INTERP, PMC *SELF, int check_only, INTVAL *is_multi_dispatch) {
46
47
    PMC    *candidates, *current, *search_list;
47
48
    STRING *name;
48
49
    INTVAL  position, resume_point;
85
86
        /* Multi. Ask the multi-dispatcher for all possible variants that we
86
87
         * could call with the current argument, unless we have none in
87
88
         * which we're just gonna have to leave the multi here in the list. */
88
 
        if (interp->current_args) {
 
89
        if (!PMC_IS_NULL(Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp)))) {
89
90
            PMC *possibles = get_all_candidates_with_cur_args(interp, current);
90
91
            if (VTABLE_elements(interp, possibles) == 0) {
91
92
                /* No candidates here; increment the position, and then jump back
100
101
             * list, then continue as normal. This means that deferal will take into
101
102
             * account the other multi-variants. Then our current becomes the first
102
103
             * of the multi candidates. */
 
104
            if (is_multi_dispatch)
 
105
                *is_multi_dispatch = 1;
103
106
            VTABLE_splice(interp, candidates, possibles, position, 1);
104
107
            current = VTABLE_get_pmc_keyed_int(interp, candidates, position);
105
108
        }
115
118
pmclass P6Invocation need_ext dynpmc group perl6_group {
116
119
    ATTR PMC    *first_candidate;
117
120
    ATTR PMC    *candidate_list;
118
 
    ATTR INTVAL  position;
119
121
    ATTR STRING *name;
120
122
    ATTR PMC    *search_list;
121
123
    ATTR INTVAL  resume_point;
 
124
    ATTR INTVAL  position;
122
125
 
123
126
    VTABLE void init() {
124
127
        PMC_data(SELF) = mem_allocate_zeroed_typed(Parrot_P6Invocation_attributes);
140
143
            GETATTR_P6Invocation_search_list(interp, SELF, search_list);
141
144
            GETATTR_P6Invocation_name(interp, SELF, name);
142
145
            if (!PMC_IS_NULL(first_candidate))
143
 
                Parrot_gc_mark_PObj_alive(interp, (PObj*)first_candidate);
 
146
                Parrot_gc_mark_PMC_alive(interp, first_candidate);
144
147
            if (!PMC_IS_NULL(candidate_list))
145
 
                Parrot_gc_mark_PObj_alive(interp, (PObj*)candidate_list);
 
148
                Parrot_gc_mark_PMC_alive(interp, candidate_list);
146
149
            if (!PMC_IS_NULL(search_list))
147
 
                Parrot_gc_mark_PObj_alive(interp, (PObj*)search_list);
 
150
                Parrot_gc_mark_PMC_alive(interp, search_list);
148
151
            if (name)
149
 
                Parrot_gc_mark_PObj_alive(interp, (PObj*)name);
 
152
                Parrot_gc_mark_STRING_alive(interp, name);
150
153
        }
151
154
    }
152
155
 
195
198
            return 1;
196
199
 
197
200
        /* If not, then we see if the dispatcher can potentially find more. */
198
 
        return !PMC_IS_NULL(get_next_candidate(interp, SELF, P6I_MODE_CHECK));
 
201
        Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), NULL);
 
202
        return !PMC_IS_NULL(get_next_candidate(interp, SELF, P6I_MODE_CHECK, NULL));
199
203
    }
200
204
 
201
205
    VTABLE INTVAL get_integer() {
206
210
        PMC *first_candidate;
207
211
        PMC *clone = VTABLE_clone(interp, SELF);
208
212
        GETATTR_P6Invocation_first_candidate(interp, clone, first_candidate);
209
 
        if (PMC_IS_NULL(first_candidate))
210
 
            first_candidate = get_next_candidate(interp, clone, P6I_MODE_CHECK);
 
213
        if (PMC_IS_NULL(first_candidate)) {
 
214
            Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), NULL);
 
215
            first_candidate = get_next_candidate(interp, clone, P6I_MODE_CHECK, NULL);
 
216
        }
211
217
        return first_candidate;
212
218
    }
213
219
 
219
225
        STRING   *lexname = CONST_STRING(interp, "__CANDIDATE_LIST__");
220
226
        PMC      *lexpad, *first_candidate;
221
227
        opcode_t *addr;
 
228
        INTVAL    is_multi_dispatch = 0;
222
229
 
223
230
        /* In the straightforward case, we know our first candidate right off the
224
231
         * bat; if not, use list. We also nullify first candidate so we hit the
225
232
         * candidate list next time we're used. */
226
233
        GETATTR_P6Invocation_first_candidate(interp, SELF, first_candidate);
227
234
        if (PMC_IS_NULL(first_candidate))
228
 
            first_candidate = get_next_candidate(interp, SELF, P6I_MODE_DISPATCH);
 
235
            first_candidate = get_next_candidate(interp, SELF, P6I_MODE_DISPATCH, &is_multi_dispatch);
229
236
        else
230
237
            SETATTR_P6Invocation_first_candidate(interp, SELF, PMCNULL);
231
238
 
247
254
        lexpad = Parrot_pcc_get_lex_pad(INTERP, CURRENT_CONTEXT(interp));
248
255
        if (!PMC_IS_NULL(lexpad) && VTABLE_exists_keyed_str(interp, lexpad, lexname))
249
256
            VTABLE_set_pmc_keyed_str(interp, lexpad, lexname, SELF);
 
257
        if (is_multi_dispatch)
 
258
            PObj_flag_SET(P6S_ALREADY_CHECKED, CURRENT_CONTEXT(interp));
250
259
        return addr;
251
260
    }
252
261
 
258
267
        /* Now shuffle along one candidate. */
259
268
        PMC *first_candidate;
260
269
        GETATTR_P6Invocation_first_candidate(interp, SELF, first_candidate);
261
 
        if (PMC_IS_NULL(first_candidate))
262
 
            get_next_candidate(interp, SELF, P6I_MODE_DISPATCH);
263
 
        else
 
270
        if (PMC_IS_NULL(first_candidate)) {
 
271
            Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), NULL);
 
272
            get_next_candidate(interp, SELF, P6I_MODE_DISPATCH, NULL);
 
273
        }
 
274
        else {
264
275
            SETATTR_P6Invocation_first_candidate(interp, SELF, PMCNULL);
 
276
        }
265
277
 
266
278
        return result;
267
279
    }
268
280
 
 
281
    VTABLE INTVAL does(STRING *what) {
 
282
        if (Parrot_str_equal(interp, what, CONST_STRING(interp, "invokable")))
 
283
            return 1;
 
284
        else
 
285
            return SUPER(what);
 
286
    }
 
287
 
269
288
    METHOD PMC *get() {
270
289
        PMC *result = VTABLE_shift_pmc(interp, SELF);
271
290
        RETURN(PMC *result);