-
Notifications
You must be signed in to change notification settings - Fork 138
/
multisub.pmc
148 lines (113 loc) · 4.67 KB
/
multisub.pmc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
Copyright (C) 2001-2009, Parrot Foundation.
=head1 NAME
src/pmc/multisub.pmc - A container for multi-dispatched subs
=head1 DESCRIPTION
This class inherits from ResizablePMCArray and provides an Array of
Sub PMCs with the same short name, but different long names.
=head2 Functions
=over 4
=cut
*/
#include "pmc/pmc_callcontext.h"
/* HEADERIZER HFILE: none */
/* HEADERIZER BEGIN: static */
/* HEADERIZER END: static */
pmclass MultiSub extends ResizablePMCArray auto_attrs provides array provides invokable {
VTABLE STRING * get_string() {
PMC * const sub0 = VTABLE_get_pmc_keyed_int(INTERP, SELF, 0);
STRING * const name = VTABLE_get_string(INTERP, sub0);
return name;
}
VTABLE void push_pmc(PMC *value) {
if (!VTABLE_does(INTERP, value, CONST_STRING(INTERP, "invokable")))
Parrot_ex_throw_from_c_args(INTERP, NULL,
EXCEPTION_INVALID_OPERATION, "attempt to push non Sub PMC");
SUPER(value);
}
VTABLE void set_pmc_keyed_int(INTVAL key, PMC *value) {
STRING * const _sub = CONST_STRING(INTERP, "Sub");
if (!VTABLE_isa(INTERP, value, _sub))
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
"attempt to set non Sub PMC");
SUPER(key, value);
}
VTABLE void set_integer_keyed_int(INTVAL key, INTVAL value) {
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
"attempt to set non Sub PMC");
}
VTABLE void set_string_keyed_int(INTVAL key, STRING *value) {
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
"attempt to set non Sub PMC");
}
VTABLE void set_number_keyed_int(INTVAL key, FLOATVAL value) {
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
"attempt to set non Sub PMC");
}
VTABLE opcode_t *invoke(void *next) {
PMC * const sig_obj = CONTEXT(INTERP)->current_sig;
PMC * const func = Parrot_mmd_sort_manhattan_by_sig_pmc(INTERP,
SELF, sig_obj);
if (PMC_IS_NULL(func))
Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
"No applicable candidates found to dispatch to for '%Ss'",
VTABLE_get_string(INTERP, SELF));
return VTABLE_invoke(INTERP, func, next);
}
/* I don't really know how to implement these if they need something
special, so I'll sort the sub list and defer processing to the
ResizablePMCArray's VTABLEs of the same names. Hopefully we
don't need anything beyond that. */
VTABLE PMC *get_pmc_keyed(PMC *key) {
PMC * const sig_obj = CONTEXT(INTERP)->current_sig;
PMC * const sub = Parrot_mmd_sort_manhattan_by_sig_pmc(INTERP,
SELF, sig_obj);
if (PMC_IS_NULL(sub))
Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
"No applicable candidates found to dispatch to for '%Ss'",
VTABLE_get_string(INTERP, SELF));
return SUPER(key);
}
VTABLE PMC *get_pmc_keyed_str(STRING *s) {
PMC * const sig_obj = CONTEXT(INTERP)->current_sig;
PMC * const sub = Parrot_mmd_sort_manhattan_by_sig_pmc(INTERP,
SELF, sig_obj);
if (PMC_IS_NULL(sub))
Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
"No applicable candidates found to dispatch to for '%Ss'",
VTABLE_get_string(INTERP, SELF));
return SUPER(s);
}
/* get_iter method should take one of two inputs: either an array of
arguments, or a string with a whitespace delimited function signature
(N, I, S, P). It should sort the argument list according to closeness
to this input argument list and return an iterator over that list. */
METHOD get_iter(PMC *args) {
STRING * const _array = CONST_STRING(INTERP, "Array");
STRING * const _string = CONST_STRING(INTERP, "String");
if (VTABLE_isa(INTERP, args, _array)){
/* TODO: What goes here? */
}
else if (VTABLE_isa(INTERP, args, _string)) {
STRING * const s = VTABLE_get_string(INTERP, args);
/* TODO: What goes here? */
}
else
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
"attempt to call get_iter method with invalid arg type.\n");
}
}
/*
=back
=head1 SEE ALSO
F<src/multidispatch.c>,
F<$perl6/doc/trunk/design/apo/A12.pod>,
F<$perl6/doc/trunk/design/syn/S12.pod>
=cut
*/
/*
* Local variables:
* c-file-style: "parrot"
* End:
* vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
*/