cvsuser 03/07/16 05:53:02
Modified: . interpreter.c object.ops
Added: . objects.c
Log:
Create and subclass classes
Revision Changes Path
1.171 +6 -2 parrot/interpreter.c
Index: interpreter.c
===================================================================
RCS file: /cvs/public/parrot/interpreter.c,v
retrieving revision 1.170
retrieving revision 1.171
diff -u -w -r1.170 -r1.171
--- interpreter.c 14 Jul 2003 09:54:50 -0000 1.170
+++ interpreter.c 16 Jul 2003 12:53:01 -0000 1.171
@@ -1,7 +1,7 @@
/* interpreter.c
- * Copyright: (When this is determined...it will go here)
+ * Copyright: 2001, 2002, 2001 Yet Another Society
* CVS Info
- * $Id: interpreter.c,v 1.170 2003/07/14 09:54:50 leo Exp $
+ * $Id: interpreter.c,v 1.171 2003/07/16 12:53:01 dan Exp $
* Overview:
* The interpreter api handles running the operations
* Data Structure and Algorithms:
@@ -601,6 +601,10 @@
/* setup stdio PMCs */
PIO_init(interpreter);
/* Done. Return and be done with it */
+
+ /* Add in the class hash. Bit of a hack, probably, as there's
+ altogether too much overlap with the PMC classes */
+ interpreter->class_hash = pmc_new(interpreter, enum_class_PerlHash);
/* Okay, we've finished doing anything that might trigger GC.
* Actually, we could enable DOD/GC earlier, but here all setup is
1.3 +53 -2 parrot/object.ops
Index: object.ops
===================================================================
RCS file: /cvs/public/parrot/object.ops,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -w -r1.2 -r1.3
--- object.ops 18 Jun 2003 12:28:50 -0000 1.2
+++ object.ops 16 Jul 2003 12:53:01 -0000 1.3
@@ -92,21 +92,72 @@
=cut
inline op subclass(out PMC, in PMC, in STR) {
+ $1 = Parrot_single_subclass(interpreter, $2, $3);
goto NEXT();
}
inline op subclass(out PMC, in PMC) {
+ $1 = Parrot_single_subclass(interpreter, $2, NULL);
goto NEXT();
}
-inline op subclass(out PMC, in STR, in STR) {
+op subclass(out PMC, in STR, in STR) {
+ PMC *class = VTABLE_get_pmc_keyed(interpreter, interpreter->class_hash,
key_new_string(interpreter, $2));
+ if (!class) {
+ internal_exception(NO_CLASS, "Class doesn't exist");
+ }
+ $1 = Parrot_single_subclass(interpreter, class, $3);
+ goto NEXT();
+}
+
+op subclass(out PMC, in STR) {
+ PMC *class = VTABLE_get_pmc_keyed(interpreter, interpreter->class_hash,
key_new_string(interpreter, $2));
+ if (!class) {
+ internal_exception(NO_CLASS, "Class doesn't exist");
+ }
+ $1 = Parrot_single_subclass(interpreter, class, NULL);
goto NEXT();
}
-inline op subclass(out PMC, in STR) {
+=item B<newclass>(out PMC, in STR)
+
+Create a new base class named $2
+
+=cut
+
+inline op newclass(out PMC, in STR) {
+ $1 = Parrot_new_class(interpreter, $2)
+}
+
+=item B<findclass>(out INT, in STR)
+
+Returns 1 if the class exists, 0 if it does not.
+
+=cut
+
+inline op findclass(out INT, in STR) {
+ if (VTABLE_get_pmc_keyed(interpreter, interpreter->class_hash,
key_new_string(interpreter, $2))) {
+ $1 = 1;
+ } else {
+ $1 = 0;
+ }
goto NEXT();
}
+=item B<getclass>(out PMC, in STR)
+
+Find the PMC for a class, by name. Note that this is a one-level hash, so for
+classes that have some structure you need to impose that structure externally.
+
+Parrot's conventions are that level separators are noted with the NULL
+character, so Perl's Foo::Bar would be Foo\0Bar.
+
+=cut
+
+inline op findclass(out PMC, in STR) {
+ $1 = VTABLE_get_pmc_keyed(interpreter, interpreter->class_hash,
key_new_string(interpreter, $2));
+ goto NEXT();
+}
=item B<singleton>(in PMC)
1.1 parrot/objects.c
Index: objects.c
===================================================================
/* objects.c
* Copyright: 2003, Yet Another Society
* CVS Info
* $Id: objects.c,v 1.1 2003/07/16 12:53:01 dan Exp $
* Overview:
* Handles class and object manipulation
* Data Structure and Algorithms:
* History:
* Notes:
* References:
*/
#include "parrot/parrot.h"
/* Subclass a class. Single parent class, nice and
straightforward. If child_class is NULL, this is an anonymous
subclass we're creating, which happens commonly enough to warrant
an actual single-subclass function
*/
PMC *
Parrot_single_subclass(Parrot_Interp interpreter, PMC *base_class,
STRING *child_class_name) {
PMC *child_class;
PMC *child_class_array;
PMC *classname_pmc;
PMC *temp_pmc;
if (!PObj_is_class_TEST(base_class)) {
internal_exception(NO_CLASS, "Can't subclass a non-class!");
}
child_class = pmc_new(interpreter, enum_class_ParrotClass);
child_class_array = PMC_data(child_class);
/* We have the same number of attributes as our parent */
child_class->obj.u.int_val = base_class->obj.u.int_val;
/* Our parent class array has a single member in it */
temp_pmc = pmc_new(interpreter, enum_class_Array);
VTABLE_set_pmc_keyed_int(interpreter, child_class_array, 0, temp_pmc);
VTABLE_set_pmc_keyed_int(interpreter, temp_pmc, 0, base_class);
/* Our penultimate parent list is a clone of our parent's parent
list, with our parent unshifted onto the beginning */
temp_pmc = pmc_new(interpreter, enum_class_PerlUndef);
VTABLE_clone(interpreter,
VTABLE_get_pmc_keyed_int(interpreter,
(PMC *)PMC_data(base_class), 1),
temp_pmc);
VTABLE_unshift_pmc(interpreter, temp_pmc, base_class);
VTABLE_set_pmc_keyed_int(interpreter, child_class_array, 1, temp_pmc);
/* Our attribute list is our parent's attribute list */
temp_pmc = pmc_new(interpreter, enum_class_PerlUndef);
VTABLE_clone(interpreter,
VTABLE_get_pmc_keyed_int(interpreter,
(PMC *)PMC_data(base_class), 2),
temp_pmc);
VTABLE_set_pmc_keyed_int(interpreter, child_class_array, 2, temp_pmc);
/* And our full keyed attribute list is our parent's */
temp_pmc = pmc_new(interpreter, enum_class_PerlUndef);
VTABLE_clone(interpreter,
VTABLE_get_pmc_keyed_int(interpreter,
(PMC *)PMC_data(base_class), 3),
temp_pmc);
VTABLE_set_pmc_keyed_int(interpreter, child_class_array, 3, temp_pmc);
/* Set the classname, if we have one */
classname_pmc = pmc_new(interpreter, enum_class_PerlString);
if (child_class_name) {
VTABLE_set_string_native(interpreter, classname_pmc, child_class_name);
} else {
VTABLE_set_string_native(interpreter, classname_pmc,
string_make(interpreter, "\0\0anonymous", 11, NULL, 0,
NULL));
}
VTABLE_set_pmc_keyed_int(interpreter, child_class_array, 4, classname_pmc);
return(child_class);
}
/* Create a brand new class, named what we pass in.
*/
PMC *
Parrot_new_class(Parrot_Interp interpreter, STRING *class_name) {
PMC *new_class;
PMC *new_class_array;
PMC *classname_pmc;
PMC *temp_pmc;
new_class = pmc_new(interpreter, enum_class_ParrotClass);
new_class_array = PMC_data(new_class);
/* We have the same number of attributes as our parent */
new_class->obj.u.int_val = 0;
/* Our parent class array nothing in it */
VTABLE_set_pmc_keyed_int(interpreter, new_class_array, 0,
pmc_new(interpreter, enum_class_Array));
VTABLE_set_pmc_keyed_int(interpreter, new_class_array, 1,
pmc_new(interpreter, enum_class_Array));
VTABLE_set_pmc_keyed_int(interpreter, new_class_array, 2,
pmc_new(interpreter, enum_class_PerlHash));
VTABLE_set_pmc_keyed_int(interpreter, new_class_array, 3,
pmc_new(interpreter, enum_class_PerlHash));
/* Set the classname, if we have one */
classname_pmc = pmc_new(interpreter, enum_class_PerlString);
VTABLE_set_string_native(interpreter, classname_pmc, class_name);
VTABLE_set_pmc_keyed_int(interpreter, new_class_array, 4, classname_pmc);
return(new_class);
}
/*
* Local variables:
* c-indentation-style: bsd
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*
* vim: expandtab shiftwidth=4:
*/