Hello,
This weekend I played a little bit with Parrot, and in order to learn
more about vtables I just implemented Scheme Pairs
Here are the changes:
* MANIFEST, Makefile.in, global_setup.c, classes/Makefile.in
include/parrot/pmc.h:
Added SchemePair as described in vtable.pod
* core.ops:
* added new operation set_p_p for copying the pmc-pointer
* added new operations set_p_i_p and set_p_p_i for indirect
setting and getting of pmc values
* added new operation get_type_s_p and get_type_i_p
to get the type-information at runtime and not only at
compiletime
* vtable.tbl:
Added new methods for indirect setting and getting of
pmc-values
* classes/default.pmc
default (non-)implementations of the above methods
* classes/schemepair.pmc:
New File. Implementation of the new indirect PMC get and set
methods. Implementation of a stringfication method.
* classes/perlint.pmc, classes/perlnum.pmc,
classes/perlstring.pmc, classes/perlundef.pmc:
type () returns the korrekt type and not 0
* languages/scheme/Scheme/Generator.pm
Implementation of the following methods:
cons, car, cdr, set-car!, set-cdr!, pair?, null?, list,
length
* languages/scheme/Scheme/Tokenizer.pm
Exclamation marks are valid identifiers
* languages/scheme/t/harness
use directory lists
* languages/scheme/t/lists/basic.t
Some basic list tests
Have fun,
J�rgen
Index: classes/schemepair.pmc
===================================================================
diff -u /dev/null classes/schemepair.pmc
--- /dev/null Fri Nov 12 22:31:31 1999
+++ classes/schemepair.pmc Sun Jan 6 17:41:15 2002
@@ -0,0 +1,473 @@
+/* SchemePair.pmc -*- C -*-
+ * Copyright: (When this is determined...it will go here)
+ * CVS Info
+ * $Id: not yet $
+ * Overview:
+ * These are the vtable functions for the SchemePair base class
+ * Data Structure and Algorithms:
+ * History:
+ * Notes:
+ * References:
+ */
+
+#include "parrot/parrot.h"
+
+static STRING*
+_stringify_key_pair (struct Parrot_Interp* INTERP, KEY_PAIR* key_pair) {
+ STRING* s;
+
+ s = string_make (INTERP, NULL, 80, NULL, 0, NULL);
+
+ switch (key_pair->type) {
+ case enum_key_int:
+ s->bufused = sprintf (s->bufstart, "%ld", key_pair->cache.int_val);
+ string_compute_strlen(s);
+ break;
+ case enum_key_num:
+ s->bufused = sprintf (s->bufstart, "%g", key_pair->cache.struct_val);
+ string_compute_strlen(s);
+ break;
+ case enum_key_string:
+ string_destroy (s);
+ s = key_pair->cache.struct_val;
+ break;
+ default:
+ fprintf (stderr, "*** unknown key_type(%d)\n", key_pair->type);
+ }
+
+ return s;
+}
+
+pmclass SchemePair {
+
+ INTVAL type () {
+ return enum_class_SchemePair;
+ }
+
+ STRING* name () {
+ return whoami;
+ }
+
+ void init () {
+ KEY *key;
+
+ key = key_new (INTERP);
+ key_set_size (INTERP, key, 2);
+ SELF->cache.struct_val = key;
+ }
+
+ void clone (PMC* dest) {
+ KEY *key;
+ KEY *old = SELF->cache.struct_val;
+
+ dest->vtable = SELF->vtable;
+ key = key_new (INTERP);
+ key_set_size (INTERP, key, 2);
+ memcpy (key->keys, old->keys, 2*sizeof(KEY_PAIR));
+ dest->cache.struct_val = key;
+ }
+
+ void morph (INTVAL type) {
+ }
+
+ BOOLVAL move_to (void * destination) {
+ return 0; /* You can't move me, I don't have anything to move! */
+ }
+
+ INTVAL real_size () {
+ return 0; /* ->data is unused */
+ }
+
+ void destroy () {
+ key_destroy(INTERP,SELF->cache.struct_val);
+ }
+
+ INTVAL get_integer () {
+ }
+
+ INTVAL get_integer_index (INTVAL index) {
+ }
+
+ FLOATVAL get_number () {
+ }
+
+ FLOATVAL get_number_index (INTVAL index) {
+ }
+
+ STRING* get_string () {
+ KEY *key = SELF->cache.struct_val;
+ KEY_PAIR *car, *cdr;
+
+ STRING *ret = string_make (INTERP, "(", 1, NULL, 0, NULL);
+
+ do {
+ car = key_element_value_i (INTERP, key, 0);
+ cdr = key_element_value_i (INTERP, key, 1);
+
+ if (car->type == enum_key_pmc) {
+ PMC *pmc = car->cache.pmc_val;
+ VTABLE *vtable = pmc->vtable;
+ INTVAL type = vtable->type (INTERP, pmc);
+
+ if (type == enum_class_PerlUndef) {
+ /* empty list */
+ ret = string_concat (INTERP, ret,
+ string_make (INTERP, "()", 2, NULL, 0, NULL),
+ 0);
+ }
+ else {
+ ret = string_concat (INTERP, ret,
+ vtable->get_string (INTERP, pmc),
+ 0);
+ }
+ }
+ else {
+ ret = string_concat (INTERP, ret,
+ _stringify_key_pair (INTERP, car),
+ 0);
+ }
+
+ if (cdr->type == enum_key_pmc) {
+ PMC *pmc = cdr->cache.pmc_val;
+ VTABLE *vtable = pmc->vtable;
+ INTVAL type = vtable->type (INTERP, pmc);
+
+ if (type == enum_class_PerlUndef) {
+ /* end of list */
+ break;
+ }
+ else if (type == enum_class_SchemePair) {
+ /* next element of list */
+ ret = string_concat (INTERP, ret,
+ string_make (INTERP, " ", 1, NULL, 0, NULL),
+ 0);
+ key = pmc->cache.struct_val;
+ }
+ else {
+ /* improper lists */
+ ret = string_concat (INTERP, ret,
+ string_make (INTERP, " . ", 3, NULL, 0, NULL),
+ 0);
+ ret = string_concat (INTERP, ret,
+ vtable->get_string (INTERP, pmc),
+ 0);
+ break;
+ }
+ }
+ else {
+ ret = string_concat (INTERP, ret,
+ string_make (INTERP, " . ", 3, NULL, 0, NULL),
+ 0);
+ ret = string_concat (INTERP, ret,
+ _stringify_key_pair (INTERP, cdr),
+ 0);
+ break;
+ }
+ } while (1);
+
+ ret = string_concat (INTERP, ret,
+ string_make (INTERP, ")", 1, NULL, 0, NULL),
+ 0);
+
+ return ret;
+ }
+
+ STRING* get_string_index (INTVAL index) {
+ }
+
+ BOOLVAL get_bool () {
+ }
+
+ void* get_value () {
+ }
+
+ BOOLVAL is_same (PMC* pmc2) {
+ }
+
+ void set_integer (PMC * value) {
+ }
+
+ void set_integer_native (INTVAL value) {
+ }
+
+ void set_integer_bigint (BIGINT value) {
+ }
+
+ void set_integer_same (PMC * value) {
+ }
+
+ void set_integer_index (INTVAL value, INTVAL index) {
+ if (index >= 0 && index < 2) {
+ KEY *key = SELF->cache.struct_val;
+ KEY_PAIR key_pair;
+
+ key_pair.type = enum_key_int;
+ key_pair.cache.int_val = value;
+ key_set_element_value_i (INTERP, key, index, &key_pair);
+ }
+ else {
+ fprintf (stderr, "*** set_integer_index index(%d) out of range\n",
+ index);
+ }
+ }
+
+
+ void set_number (PMC * value) {
+ }
+
+ void set_number_native (FLOATVAL value) {
+ }
+
+ void set_number_bigfloat (BIGFLOAT value) {
+ }
+
+ void set_number_same (PMC * value) {
+ }
+
+ void set_number_index (FLOATVAL value, INTVAL index) {
+ if (index >= 0 && index < 2) {
+ KEY *key = SELF->cache.struct_val;
+ KEY_PAIR key_pair;
+
+ key_pair.type = enum_key_num;
+ key_pair.cache.num_val = value;
+ key_set_element_value_i (INTERP, key, index, &key_pair);
+ }
+ else {
+ fprintf (stderr, "*** set_pmc_index index(%d) out of range\n",
+ index);
+ }
+ }
+
+ void set_string (PMC * value) {
+ }
+
+ void set_string_native (STRING * value) {
+ }
+
+ void set_string_unicode (STRING * value) {
+ }
+
+ void set_string_other (STRING * value) {
+ }
+
+ void set_string_same (PMC * value) {
+ }
+
+ void set_string_index (STRING* value, INTVAL index) {
+ }
+
+ void set_value (void* value) {
+ }
+
+ void add (PMC * value, PMC* dest) {
+ }
+
+ void add_int (INTVAL value, PMC* dest) {
+ }
+
+ void add_bigint (BIGINT value, PMC* dest) {
+ }
+
+ void add_float (FLOATVAL value, PMC* dest) {
+ }
+
+ void add_bigfloat (BIGFLOAT value, PMC* dest) {
+ }
+
+ void add_same (PMC * value, PMC* dest) {
+ }
+
+ void subtract (PMC * value, PMC* dest) {
+ }
+
+ void subtract_int (INTVAL value, PMC* dest) {
+ }
+
+ void subtract_bigint (BIGINT value, PMC* dest) {
+ }
+
+ void subtract_float (FLOATVAL value, PMC* dest) {
+ }
+
+ void subtract_bigfloat (BIGFLOAT value, PMC* dest) {
+ }
+
+ void subtract_same (PMC * value, PMC* dest) {
+ }
+
+ void multiply (PMC * value, PMC* dest) {
+ }
+
+ void multiply_int (INTVAL value, PMC* dest) {
+ }
+
+ void multiply_bigint (BIGINT value, PMC* dest) {
+ }
+
+ void multiply_float (FLOATVAL value, PMC* dest) {
+ }
+
+ void multiply_bigfloat (BIGFLOAT value, PMC* dest) {
+ }
+
+ void multiply_same (PMC * value, PMC* dest) {
+ }
+
+ void divide (PMC * value, PMC* dest) {
+ }
+
+ void divide_int (INTVAL value, PMC* dest) {
+ }
+
+ void divide_bigint (BIGINT value, PMC* dest) {
+ }
+
+ void divide_float (FLOATVAL value, PMC* dest) {
+ }
+
+ void divide_bigfloat (BIGFLOAT value, PMC* dest) {
+ }
+
+ void divide_same (PMC * value, PMC* dest) {
+ }
+
+ void modulus (PMC * value, PMC* dest) {
+ }
+
+ void modulus_int (INTVAL value, PMC* dest) {
+ }
+
+ void modulus_bigint (BIGINT value, PMC* dest) {
+ }
+
+ void modulus_float (FLOATVAL value, PMC* dest) {
+ }
+
+ void modulus_bigfloat (BIGFLOAT value, PMC* dest) {
+ }
+
+ void modulus_same (PMC * value, PMC* dest) {
+ }
+
+ void concatenate (PMC * value, PMC* dest) {
+ }
+
+ void concatenate_native (STRING * value, PMC* dest) {
+ }
+
+ void concatenate_unicode (STRING * value, PMC* dest) {
+ }
+
+ void concatenate_other (STRING * value, PMC* dest) {
+ }
+
+ void concatenate_same (PMC * value, PMC* dest) {
+ }
+
+ BOOLVAL is_equal (PMC* value) {
+ }
+
+ void logical_or (PMC* value, PMC* dest) {
+ }
+
+ void logical_and (PMC* value, PMC* dest) {
+ }
+
+ void logical_not (PMC* value) {
+ }
+
+ void match (PMC * value, REGEX* re) {
+ }
+
+ void match_native (STRING * value, REGEX* re) {
+ }
+
+ void match_unicode (STRING * value, REGEX* re) {
+ }
+
+ void match_other (STRING * value, REGEX* re) {
+ }
+
+ void match_same (PMC * value, REGEX* re) {
+ }
+
+ void repeat (PMC * value, PMC* dest) {
+ }
+
+ void repeat_native (STRING * value, PMC* dest) {
+ }
+
+ void repeat_unicode (STRING * value, PMC* dest) {
+ }
+
+ void repeat_other (STRING * value, PMC* dest) {
+ }
+
+ void repeat_same (PMC * value, PMC* dest) {
+ }
+
+ void set_pmc_index (PMC *value, INTVAL index) {
+ if (index >= 0 && index < 2) {
+ KEY *key = SELF->cache.struct_val;
+ KEY_PAIR key_pair;
+
+ key_pair.type = enum_key_pmc;
+ key_pair.cache.pmc_val = value;
+ key_set_element_value_i (INTERP, key, index, &key_pair);
+ }
+ else {
+ fprintf (stderr, "*** set_pmc_index index(%d) out of range\n",
+ index);
+ }
+ }
+
+ PMC* get_pmc_index (INTVAL index) {
+ if (index >= 0 && index < 2) {
+ KEY *key = SELF->cache.struct_val;
+ KEY_PAIR *key_pair = key_element_value_i (INTERP, key, index);
+
+ if (key_pair->type == enum_key_pmc) {
+ return key_pair->cache.pmc_val;
+ }
+ else {
+ PMC* new_pmc = NULL;
+ switch (key_pair->type) {
+ case enum_key_int:
+ new_pmc = pmc_new (INTERP, enum_class_PerlInt);
+ Parrot_PerlInt_set_integer_native (INTERP, new_pmc,
+ key_pair->cache.int_val);
+ break;
+ case enum_key_num:
+ new_pmc = pmc_new (INTERP, enum_class_PerlNum);
+ Parrot_PerlNum_set_number_native (INTERP, new_pmc,
+ key_pair->cache.num_val);
+ break;
+ case enum_key_string:
+ new_pmc = pmc_new (INTERP, enum_class_PerlString);
+ Parrot_PerlString_set_string_native (INTERP, new_pmc,
+ key_pair->cache.struct_val);
+ default:
+ fprintf (stderr, "*** get_pmc_index: unknown type (%d)\n",
+ key_pair->type);
+ }
+ return new_pmc;
+ }
+ }
+ else {
+ fprintf (stderr, "*** get_pmc_index index(%d) out of range\n",
+ index);
+ }
+ }
+ return NULL;
+}
+
+/*
+ * Local variables:
+ * c-indentation-style: bsd
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vim: expandtab shiftwidth=4:
+ */
Index: languages/scheme/t/lists/basic.t
===================================================================
diff -u /dev/null languages/scheme/t/lists/basic.t
--- /dev/null Fri Nov 12 22:31:31 1999
+++ languages/scheme/t/lists/basic.t Sun Jan 6 17:21:18 2002
@@ -0,0 +1,84 @@
+#! perl -w
+
+use Scheme::Test tests => 15;
+
+###
+### Add
+###
+
+output_is(<<'CODE', '(2 . 5)', 'cons');
+(write (cons 2 5))
+CODE
+
+output_is(<<'CODE', '((2 . 3) . 4)', 'cons car');
+(write (cons (cons 2 3) 4))
+CODE
+
+output_is(<<'CODE', '(2 3 . 4)', 'cons cdr');
+(write (cons 2 (cons 3 4)))
+CODE
+
+output_is(<<'CODE', '((1 . 2) 3 . 4)', 'complex cons');
+(write
+ (cons
+ (cons 1 2)
+ (cons 3 4)))
+CODE
+
+output_is(<<'CODE', '1', 'pair?');
+(write
+ (pair? (cons 1 3)))
+CODE
+
+output_is(<<'CODE', '0', 'false pair?');
+(write
+ (pair? 12))
+CODE
+
+output_is(<<'CODE', '(3 2 1 0)', 'list');
+(write
+ (list 3 2 1 0))
+CODE
+
+output_is(<<'CODE', '1', 'pair? list');
+(write
+ (pair? (list 3 2 1)))
+CODE
+
+output_is(<<'CODE', '(1 2 3)', 'lists the hard way');
+(write
+ (cons 1
+ (cons 2
+ (cons 3
+ (list)))))
+CODE
+
+output_is(<<'CODE', '4', 'length');
+(write
+ (length (list 3 2 1 0)))
+CODE
+
+output_is(<<'CODE', '2', 'car');
+(write
+ (car (list 2 1 0)))
+CODE
+
+output_is(<<'CODE', '(1 0)', 'cdr');
+(write
+ (cdr (list 2 1 0)))
+CODE
+
+output_is(<<'CODE', '(4 2 3)', 'set-car!');
+(write
+ (set-car! (list 1 2 3) 4))
+CODE
+
+output_is(<<'CODE', '((4 . 2) 2 3)', 'set-car! II');
+(write
+ (set-car! (list 1 2 3) (cons 4 2)))
+CODE
+
+output_is(<<'CODE', '(1 4 2)', 'set-cdr!');
+(write
+ (set-cdr! (list 1 2 3) (list 4 2)))
+CODE
Index: MANIFEST
===================================================================
RCS file: /cvs/public/parrot/MANIFEST,v
retrieving revision 1.84
diff -u -r1.84 MANIFEST
--- MANIFEST 4 Jan 2002 03:57:37 -0000 1.84
+++ MANIFEST 6 Jan 2002 19:17:54 -0000
@@ -43,6 +43,7 @@
classes/perlstring.pmc
classes/perlundef.pmc
classes/pmc2c.pl
+classes/schemepair.pmc
config_h.in
core.ops
disassemble.pl
@@ -161,6 +162,7 @@
languages/scheme/t/arith/nested.t
languages/scheme/t/harness
languages/scheme/t/io/basic.t
+languages/scheme/t/lists/basic.t
languages/scheme/t/logic/basic.t
make.pl
make_vtable_ops.pl
Index: Makefile.in
===================================================================
RCS file: /cvs/public/parrot/Makefile.in,v
retrieving revision 1.101
diff -u -r1.101 Makefile.in
--- Makefile.in 4 Jan 2002 16:44:44 -0000 1.101
+++ Makefile.in 6 Jan 2002 19:17:54 -0000
@@ -66,7 +66,8 @@
$(INC)/interp_guts.h ${jit_h} ${jit_struct_h}
CLASS_O_FILES = classes/default$(O) classes/perlint$(O) classes/perlstring$(O) \
-classes/perlnum$(O) classes/perlarray$(O) classes/perlundef$(O)
+classes/perlnum$(O) classes/perlarray$(O) classes/perlundef$(O) \
+classes/schemepair$(O)
ENCODING_O_FILES = encodings/singlebyte$(O) encodings/utf8$(O) encodings/utf16$(O) \
encodings/utf32$(O)
Index: core.ops
===================================================================
RCS file: /cvs/public/parrot/core.ops,v
retrieving revision 1.68
diff -u -r1.68 core.ops
--- core.ops 4 Jan 2002 02:36:25 -0000 1.68
+++ core.ops 6 Jan 2002 19:17:55 -0000
@@ -554,8 +554,15 @@
Set $1 to $2.
-=cut
+=item B<set>(p, i|ic, p)
+
+Set $1[$2] to $3
+=item B<set>(p, p, i|ic)
+
+Set $1 to $2[$3]
+
+=cut
inline op set(i, i|ic) {
$1 = $2;
@@ -614,6 +621,11 @@
goto NEXT();
}
+inline op set(p, p) {
+ $1 = $2;
+ goto NEXT();
+}
+
inline op set(p, i|ic, i|ic) {
$1->vtable->set_integer_index(interpreter, $1, $2, $3);
goto NEXT();
@@ -644,6 +656,16 @@
goto NEXT();
}
+inline op set(p, i|ic, p) { /* FIXME: Order of arguments diffrent from above */
+ $1->vtable->set_pmc_index (interpreter, $1, $3, $2);
+ goto NEXT();
+}
+
+inline op set(p, p, i|ic) {
+ $1 = $2->vtable->get_pmc_index (interpreter, $2, $3);
+ goto NEXT();
+}
+
=back
=cut
@@ -2581,6 +2603,28 @@
}
newpmc = pmc_new(interpreter, $2);
$1 = newpmc;
+ goto NEXT();
+}
+
+=item B<get_type>(i, p)
+
+get the type of the PMC C<p> and store it in C<i>
+
+=cut
+
+op get_type (i, p) {
+ $1 = $2->vtable->type(interpreter, $2);
+ goto NEXT();
+}
+
+=item B<get_type>(s, p)
+
+get the typename of the PMC C<p> and store it in C<s>
+
+=cut
+
+op get_type (s, p) {
+ $1 = $2->vtable->name(interpreter, $2);
goto NEXT();
}
Index: global_setup.c
===================================================================
RCS file: /cvs/public/parrot/global_setup.c,v
retrieving revision 1.12
diff -u -r1.12 global_setup.c
--- global_setup.c 1 Jan 2002 03:46:40 -0000 1.12
+++ global_setup.c 6 Jan 2002 19:17:55 -0000
@@ -15,20 +15,24 @@
#include "parrot/parrot.h"
/* Needed because this might get compiled before pmcs have been built */
+void Parrot_PerlUndef_class_init(void);
void Parrot_PerlInt_class_init(void);
void Parrot_PerlNum_class_init(void);
void Parrot_PerlString_class_init(void);
void Parrot_PerlArray_class_init(void);
+void Parrot_SchemePair_class_init(void);
void
init_world(void) {
string_init(); /* Set up the string subsystem */
/* Call base vtable class constructor methods! */
+ Parrot_PerlUndef_class_init();
Parrot_PerlInt_class_init();
Parrot_PerlNum_class_init();
Parrot_PerlString_class_init();
Parrot_PerlArray_class_init();
+ Parrot_SchemePair_class_init();
}
/*
Index: vtable.tbl
===================================================================
RCS file: /cvs/public/parrot/vtable.tbl,v
retrieving revision 1.10
diff -u -r1.10 vtable.tbl
--- vtable.tbl 18 Dec 2001 07:05:00 -0000 1.10
+++ vtable.tbl 6 Jan 2002 19:17:55 -0000
@@ -51,3 +51,7 @@
unique void logical_not PMC* value
str void match PMC* value REGEX* re
str void repeat PMC* value PMC* dest
+
+unique void set_pmc_index PMC* value INTVAL index
+unique PMC* get_pmc_index INTVAL index
+
Index: classes/.cvsignore
===================================================================
RCS file: /cvs/public/parrot/classes/.cvsignore,v
retrieving revision 1.2
diff -u -r1.2 .cvsignore
--- classes/.cvsignore 11 Dec 2001 12:03:23 -0000 1.2
+++ classes/.cvsignore 6 Jan 2002 19:17:55 -0000
@@ -1,3 +1,4 @@
Makefile
*.c
default.h
+*.h
Index: classes/Makefile.in
===================================================================
RCS file: /cvs/public/parrot/classes/Makefile.in,v
retrieving revision 1.12
diff -u -r1.12 Makefile.in
--- classes/Makefile.in 4 Jan 2002 02:29:18 -0000 1.12
+++ classes/Makefile.in 6 Jan 2002 19:17:55 -0000
@@ -5,7 +5,7 @@
H_FILES = $(INC)/parrot.h default.h
-O_FILES = default$(O) perlint$(O) perlstring$(O) perlnum$(O) perlarray$(O)
perlundef$(O)
+O_FILES = default$(O) perlint$(O) perlstring$(O) perlnum$(O) perlarray$(O)
+perlundef$(O) schemepair$(O)
#DO NOT ADD C COMPILER FLAGS HERE
#Add them in Configure.pl--look for the
@@ -52,6 +52,11 @@
$(PERL) pmc2c.pl perlundef.pmc
perlundef$(O): $(H_FILES)
+
+schemepair.c schemepair.h: schemepair.pmc
+ $(PERL) pmc2c.pl schemepair.pmc
+
+schemepair$(O): $(H_FILES)
clean:
$(RM_F) *.c *$(O) default.h
Index: classes/default.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/default.pmc,v
retrieving revision 1.5
diff -u -r1.5 default.pmc
--- classes/default.pmc 1 Jan 2002 22:55:47 -0000 1.5
+++ classes/default.pmc 6 Jan 2002 19:17:56 -0000
@@ -544,4 +544,10 @@
value->vtable->get_integer(INTERP, value), NULL) );
}
+ void set_pmc_index (PMC * value, INTVAL index) {
+ }
+
+ PMC* get_pmc_index (INTVAL index) {
+ }
+
}
Index: classes/perlarray.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/perlarray.pmc,v
retrieving revision 1.2
diff -u -r1.2 perlarray.pmc
--- classes/perlarray.pmc 4 Jan 2002 16:09:01 -0000 1.2
+++ classes/perlarray.pmc 6 Jan 2002 19:17:56 -0000
@@ -15,7 +15,7 @@
pmclass PerlArray {
INTVAL type () {
- return 0;
+ return enum_class_PerlArray;
}
STRING* name() {
Index: classes/perlint.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/perlint.pmc,v
retrieving revision 1.12
diff -u -r1.12 perlint.pmc
--- classes/perlint.pmc 4 Jan 2002 16:09:01 -0000 1.12
+++ classes/perlint.pmc 6 Jan 2002 19:17:56 -0000
@@ -15,7 +15,7 @@
pmclass PerlInt {
INTVAL type () {
- return 0;
+ return enum_class_PerlInt;
}
STRING* name() {
Index: classes/perlnum.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/perlnum.pmc,v
retrieving revision 1.13
diff -u -r1.13 perlnum.pmc
--- classes/perlnum.pmc 4 Jan 2002 16:09:01 -0000 1.13
+++ classes/perlnum.pmc 6 Jan 2002 19:17:56 -0000
@@ -15,7 +15,7 @@
pmclass PerlNum {
INTVAL type () {
- return 0;
+ return enum_class_PerlNum;
}
STRING* name() {
Index: classes/perlstring.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/perlstring.pmc,v
retrieving revision 1.13
diff -u -r1.13 perlstring.pmc
--- classes/perlstring.pmc 4 Jan 2002 16:09:01 -0000 1.13
+++ classes/perlstring.pmc 6 Jan 2002 19:17:56 -0000
@@ -15,7 +15,7 @@
pmclass PerlString {
INTVAL type () {
- return 0;
+ return enum_class_PerlString;
}
STRING* name() {
Index: classes/perlundef.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/perlundef.pmc,v
retrieving revision 1.3
diff -u -r1.3 perlundef.pmc
--- classes/perlundef.pmc 4 Jan 2002 16:09:01 -0000 1.3
+++ classes/perlundef.pmc 6 Jan 2002 19:17:57 -0000
@@ -15,6 +15,7 @@
pmclass PerlUndef {
INTVAL type () {
+ return enum_class_PerlUndef;
}
STRING* name () {
Index: include/parrot/pmc.h
===================================================================
RCS file: /cvs/public/parrot/include/parrot/pmc.h,v
retrieving revision 1.9
diff -u -r1.9 pmc.h
--- include/parrot/pmc.h 18 Dec 2001 07:05:01 -0000 1.9
+++ include/parrot/pmc.h 6 Jan 2002 19:17:57 -0000
@@ -19,6 +19,7 @@
enum_class_PerlNum,
enum_class_PerlString,
enum_class_PerlArray,
+ enum_class_SchemePair,
enum_class_max
};
VAR_SCOPE VTABLE Parrot_base_vtables[enum_class_max];
Index: languages/scheme/Scheme/Generator.pm
===================================================================
RCS file: /cvs/public/parrot/languages/scheme/Scheme/Generator.pm,v
retrieving revision 1.1
diff -u -r1.1 Generator.pm
--- languages/scheme/Scheme/Generator.pm 24 Oct 2001 19:27:20 -0000 1.1
+++ languages/scheme/Scheme/Generator.pm 6 Jan 2002 19:17:58 -0000
@@ -3,6 +3,9 @@
use strict;
use Data::Dumper;
+sub PerlUndef { 0 }
+sub SchemePair { 5 }
+
sub _gensym {
return sprintf "G%04d",shift->{gensym}++;
}
@@ -11,7 +14,6 @@
my $self = shift;
push @{$self->{instruction}},[@_];
}
-
#------------------------------------
my $regs = {
@@ -39,6 +41,12 @@
@temp;
}
+sub _save_1 {
+ my $type = shift || 'I';
+ my @temp = _save 1, $type;
+ $temp[0];
+}
+
sub _restore {
die "Nothing to restore"
unless defined @_;
@@ -92,7 +100,7 @@
my $return;
my $label = $self->_gensym();
- $return = "I"._save(1,'I');
+ $return = "I"._save(1,'I');
my $cond = $self->_generate($node->{children}[0]);
$self->_add_inst('','eq',[$cond,0,"FALSE_$label"]);
my $true = $self->_generate($node->{children}[1]);
@@ -194,34 +202,206 @@
sub _op_equal_p {
}
-sub _op_pair {
+sub _op_pair_p {
+ my ($self,$node) = @_;
+ my $return;
+
+ print STDERR "pair?: wrong number of arguments\n"
+ unless $#{$node->{children}} == 0;
+
+ $return = $self->_constant(0);
+
+ my $temp = $self->_generate($node->{children}->[0]);
+ if ($temp =~ m/^P/) {
+ my $type = _save_1('I');
+ my $label = $self->_gensym();
+
+ $self->_add_inst ('', 'get_type', [$type,$temp]);
+ $self->_add_inst ('', 'ne', [SchemePair,$type,"DONE_$label"]);
+ $self->_add_inst ('', 'set', [$return,'1']);
+ $self->_add_inst("DONE_$label");
+ _restore ($type);
+ }
+
+ _restore($temp);
+ return $return;
}
sub _op_cons {
+ my ($self, $node) = @_;
+ my $return;
+
+ print STDERR "cons: wrong number of arguments\n"
+ unless $#{$node->{children}} == 1;
+
+ my $car = $self->_generate($node->{children}->[0]);
+ $return = _save_1('P');
+ $self->_add_inst ('', 'new', [$return,'SchemePair']);
+ if ($car =~ m/^P/) { # FIXME: This is for the strange order index in set
+ $self->_add_inst ('', 'set', [$return,'0',$car]);
+ }
+ else {
+ $self->_add_inst ('', 'set', [$return,$car,'0']);
+ }
+ _restore ($car);
+
+ my $cdr = $self->_generate($node->{children}->[1]);
+ if ($cdr =~ m/^P/) {
+ $self->_add_inst ('', 'set', [$return,'1',$cdr]);
+ }
+ else {
+ $self->_add_inst ('', 'set', [$return,$cdr,'1']);
+ }
+ _restore ($cdr);
+
+ return $return;
}
sub _op_car {
+ my ($self, $node) = @_;
+ my $return;
+
+ print STDERR "car: wrong number of arguments\n"
+ unless $#{$node->{children}} == 0;
+
+ my $temp = $self->_generate($node->{children}->[0]);
+ $return = _save_1('P');
+ $self->_add_inst ('', 'set', [$return,$temp,'0']);
+ _restore ($temp);
+
+ return $return;
}
sub _op_cdr {
+ my ($self, $node) = @_;
+ my $return;
+
+ print STDERR "cdr: wrong number of arguments\n"
+ unless $#{$node->{children}} == 0;
+
+ my $temp = $self->_generate($node->{children}->[0]);
+ $return = _save_1('P');
+ $self->_add_inst ('', 'set', [$return,$temp,'1']);
+ _restore ($temp);
+
+ return $return;
}
sub _op_set_car {
+ my ($self, $node) = @_;
+
+ print STDERR "set-cdr!: wrong number of arguments\n"
+ unless $#{$node->{children}} == 1;
+
+ my $pair = $self->_generate($node->{children}->[0]);
+ my $value = $self->_generate($node->{children}->[1]);
+
+ if ($value =~ m/^P/) {
+ $self->_add_inst ('', 'set', [$pair, '0', $value]);
+ }
+ else {
+ $self->_add_inst ('', 'set', [$pair, $value, '0']);
+ }
+ _restore ($value);
+
+ return $pair; # FIXME: This value should be unspecified
}
sub _op_set_cdr {
+ my ($self, $node) = @_;
+
+ print STDERR "set-cdr!: wrong number of arguments\n"
+ unless $#{$node->{children}} == 1;
+
+ my $pair = $self->_generate($node->{children}->[0]);
+ my $value = $self->_generate($node->{children}->[1]);
+
+ if ($value =~ m/^P/) {
+ $self->_add_inst ('', 'set', [$pair, '1', $value]);
+ }
+ else {
+ $self->_add_inst ('', 'set', [$pair, $value, '1']);
+ }
+ _restore ($value);
+
+ return $pair; # FIXME: This value should be unspecified
}
-sub _op_null {
+sub _op_null_p {
+ my ($self, $node) = @_;
+ my $return;
+
+ print STDERR "null?: wrong number of arguments\n"
+ unless $#{$node->{children}} == 0;
+
+ my $temp = $self->_generate($self->{children}->[0]);
+ $return = $self->constant(0);
+ if ( $temp =~ m/^P/) {
+ my $label = $self->_gensym();
+ my $type = _save_1('1');
+
+ $self->_add_inst ('', 'get_type', [$type, $temp]);
+ $self->_add_inst ('', 'ne', [$type, PerlUndef, "DONE_$label"]);
+ $self->_add_inst ('', 'set', [$return, '1']);
+ _restore ($type);
+ }
+
+ _restore ($temp);
+
+ return $return;
}
sub _op_list_p {
}
sub _op_list {
+ my ($self, $node) = @_;
+ my $return = _save_1 ('P');
+
+ $self->_add_inst ('', 'new', [$return, 'PerlUndef']);
+
+ if ($node->{children}) {
+ my $item;
+ my $lastitem;
+ for (my $i = $#{$node->{children}}; $i >= 0; $i--) {
+ $item = $self->_generate ($node->{children}->[$i]);
+ $lastitem = _save_1 ('P');
+ $self->_add_inst ('', 'new', [$lastitem, 'SchemePair']);
+ $self->_add_inst ('', 'set', [$lastitem, '1', $return]);
+ if ($item =~ m/^P/) {
+ $self->_add_inst ('', 'set', [$lastitem, '0', $item]);
+ } else {
+ $self->_add_inst ('', 'set', [$lastitem, $item, '0']);
+ }
+ $self->_add_inst ('', 'set', [$return, $lastitem]);
+ _restore ($item, $lastitem);
+ }
+ }
+
+ return $return;
}
sub _op_length {
+ my ($self,$node) = @_;
+ my $return;
+ my $label = $self->_gensym();
+
+ print STDERR "length: wrong number of arguments\n"
+ unless $#{$node->{children}} == 0;
+
+ $return = $self->_constant(0);
+
+ my $list = $self->_generate($node->{children}->[0]);
+ my $type = _save_1('I');
+ $self->_add_inst("LOOP_$label", 'get_type', [$type,$list]);
+ $self->_add_inst('', 'ne', [$type,SchemePair,"DONE_$label"]);
+ $self->_add_inst('', 'inc', [$return]);
+ $self->_add_inst('', 'set', [$list,$list,'1']);
+ $self->_add_inst('', 'branch', ["LOOP_$label"]);
+ $self->_add_inst("DONE_$label");
+ _restore ($list, $type);
+
+ return $return
}
sub _op_append {
@@ -1019,8 +1199,8 @@
'cons' => \&_op_cons,
'car' => \&_op_car,
'cdr' => \&_op_cdr,
- 'set-car!' => \&_op_set_car_bang,
- 'set-cdr!' => \&_op_set_cdr_bang,
+ 'set-car!' => \&_op_set_car,
+ 'set-cdr!' => \&_op_set_cdr,
# Not adding caar/cadr/cdar/whatever
'null?' => \&_op_null_p,
'list?' => \&_op_list_p,
@@ -1322,10 +1502,11 @@
sub generate {
my $self = shift;
my @temp = _save(1);
- $self->_generate($self->{tree},$temp[0]);
#die Dumper($self->{tree});
+ $self->_generate($self->{tree},$temp[0]);
_restore(@temp);
$self->_add_inst('',"end");
+# print STDERR Dumper $self->{instruction};
$self->_format_columns();
}
Index: languages/scheme/Scheme/Tokenizer.pm
===================================================================
RCS file: /cvs/public/parrot/languages/scheme/Scheme/Tokenizer.pm,v
retrieving revision 1.1
diff -u -r1.1 Tokenizer.pm
--- languages/scheme/Scheme/Tokenizer.pm 24 Oct 2001 19:27:20 -0000 1.1
+++ languages/scheme/Scheme/Tokenizer.pm 6 Jan 2002 19:17:58 -0000
@@ -34,6 +34,9 @@
} elsif($ch eq '?' and
$token =~ /^[a-z]/) { # Question marks can follow an identifier
$token .= $ch;
+ } elsif($ch eq '!' and
+ $token =~ /^[a-z]/) { # Exclamaition marks can follow an identifier
+ $token .= $ch;
} elsif($ch eq '=' and
$token =~ /^[<>]/) { # Equal sign can follow '<','>'
$token .= $ch;
Index: languages/scheme/t/harness
===================================================================
RCS file: /cvs/public/parrot/languages/scheme/t/harness,v
retrieving revision 1.1
diff -u -r1.1 harness
--- languages/scheme/t/harness 24 Oct 2001 19:27:20 -0000 1.1
+++ languages/scheme/t/harness 6 Jan 2002 19:17:58 -0000
@@ -4,5 +4,5 @@
use Test::Harness qw(runtests);
use lib '../..';
-my @tests = map { glob( "t/$_/*.t" ) } ( qw(io arith logic) );
+my @tests = map { glob( "t/$_/*.t" ) } ( qw(io arith logic lists) );
runtests( @tests );