# New Ticket Created by  Jürgen Bömmels 
# Please include the string:  [perl #17030]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=17030 >


Hello,

The recent discussion of languages independence rememberd me of an
very old patch of mine which implements scheme pairs. (January 2002).
The languages/scheme directory did not change very much since then,
but the key system totally changed since then. 

But neverless, I got it running. The dedicate SchemePair PMC is not
necessary any more, I just used an Array of size 2.

scheme now can create pairs with (cons) and lists with (list), print
them using (write) and access its elements using
(car), (cdr), (set-car!) and (set-cdr!). See lists.t for examples.

BTW: The MANIFEST-patch contains some auxillary files also missing,
which I delibrately haven't edited out. HINT: [perl #16839]

bye
juergen



-- attachment  1 ------------------------------------------------------
url: http://rt.perl.org/rt2/attach/36614/29555/b23eff/scheme.diff

Index: MANIFEST
===================================================================
RCS file: /cvs/public/parrot/MANIFEST,v
retrieving revision 1.207
diff -u -r1.207 MANIFEST
--- MANIFEST	4 Sep 2002 03:48:26 -0000	1.207
+++ MANIFEST	4 Sep 2002 23:53:27 -0000
@@ -58,6 +58,8 @@
 config/gen/config_h/config_h.in
 config/gen/config_pm.pl
 config/gen/config_pm/Config_pm.in
+config/gen/libparrot_def.pl
+config/gen/libparrot_def/libparrot_def.in
 config/gen/makefiles.pl
 config/gen/makefiles/classes.in
 config/gen/makefiles/docs.in
@@ -67,6 +69,7 @@
 config/gen/makefiles/perl6.in
 config/gen/makefiles/root.in
 config/gen/makefiles/scheme.in
+config/gen/makefiles/imcc.in
 config/gen/myconfig.pl
 config/gen/myconfig/myconfig.in
 config/gen/platform.pl
@@ -378,6 +381,7 @@
 languages/perl6/examples/mandel.p6
 languages/perl6/examples/qsort.p6
 languages/perl6/mkdistro.sh
+languages/perl6/overview.pod
 languages/perl6/pconfig.pl
 languages/perl6/perl6
 languages/perl6/perl6re/Perl6RE.bnf
@@ -434,6 +438,7 @@
 languages/perl6/t/parser/speed_3.exp
 languages/perl6/t/parser/speed_3.pl
 languages/perl6/t/rx/basic.t
+languages/perl6/t/rx/call.t
 languages/perl6/t/rx/special.t
 languages/python/python.bnf
 languages/python/python.prd
@@ -487,6 +492,7 @@
 languages/ruby/t/01_terminal.t
 languages/ruby/t/02_expression.t
 languages/scheme/Scheme.pm
+languages/scheme/Scheme/Builtins.pm
 languages/scheme/Scheme/Generator.pm
 languages/scheme/Scheme/Parser.pm
 languages/scheme/Scheme/Test.pm
@@ -498,6 +504,7 @@
 languages/scheme/t/harness
 languages/scheme/t/io/basic.t
 languages/scheme/t/logic/basic.t
+languages/scheme/t/logic/lists.t
 lib/Class/Struct.pm
 lib/Make.pm
 lib/Parrot/BuildUtil.pm
Index: languages/scheme/Scheme/Builtins.pm
===================================================================
RCS file: languages/scheme/Scheme/Builtins.pm
diff -N languages/scheme/Scheme/Builtins.pm
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ languages/scheme/Scheme/Builtins.pm	4 Sep 2002 23:53:28 -0000
@@ -0,0 +1,50 @@
+package Scheme::Builtins;
+
+use strict;
+
+my %built_ins = 
+(
+ write =>
+ [['# Write function', ''],
+  ['write_ENTRY',  'save', 'I0'],
+  ['',             'typeof', 'I0', 'P5'],
+  ['',             'ne', 'I0', '.PerlUndef', 'write_N_UNDEF'],
+  ['',             'print', '"()"'],
+  ['',             'branch', 'write_RET0'],
+  ['write_N_UNDEF','eq', 'I0', '.Array', 'write_ARRAY'],
+  ['',             'print', 'P5'],
+  ['',             'branch', 'write_RET0'],
+  ['write_ARRAY',  'save', 'P5'],
+  ['',             'save', 'P6'],
+  ['',             'print', '"("'],
+  ['write_NEXT',   'set', 'P6', 'P5'],
+  ['',             'set', 'P5', 'P6[0]'],
+  ['',             'bsr', 'write_ENTRY'],
+  ['',             'set', 'P5', 'P6[1]'],
+  ['',             'typeof', 'I0', 'P5'],
+  ['',             'eq', 'I0', '.PerlUndef', 'write_KET'],
+  ['',             'ne', 'I0', '.Array', 'write_DOT'],
+  ['',             'print', '" "'],
+  ['',             'branch', 'write_NEXT'],
+  ['write_DOT',    'print', '" . "'],
+  ['',             'bsr', 'write_ENTRY'],
+  ['write_KET',    'print', '")"'],
+  ['',             'restore', 'P6'],
+  ['',             'restore', 'P5'],
+  ['write_RET0',   'restore', 'I0'],
+  ['',             'ret'],
+ ]
+);
+
+sub generate {
+  my ($self, $name) = @_;
+
+  die "$name: Unknown buildin\n" unless exists $built_ins{$name};
+
+  for (@{$built_ins{$name}}) {
+    my ($label, $op, @args) = @$_;
+    $self->_add_inst ($label, $op, [ @args ]);
+  }
+}
+
+1;
Index: languages/scheme/Scheme/Generator.pm
===================================================================
RCS file: /cvs/public/parrot/languages/scheme/Scheme/Generator.pm,v
retrieving revision 1.2
diff -u -r1.2 Generator.pm
--- languages/scheme/Scheme/Generator.pm	24 Mar 2002 23:42:38 -0000	1.2
+++ languages/scheme/Scheme/Generator.pm	4 Sep 2002 23:53:29 -0000
@@ -2,6 +2,7 @@
 
 use strict;
 use Data::Dumper;
+use Scheme::Builtins;
 
 sub _gensym {
   return sprintf "G%04d",shift->{gensym}++;
@@ -39,6 +40,12 @@
   @temp;
 }
 
+sub _save_1 {
+  my $type = shift || 'I';
+  my @temp = _save 1, $type;
+  $temp[0];
+}
+
 sub _restore {
   die "Nothing to restore"
     unless defined @_;
@@ -50,6 +57,15 @@
   }
 }
 
+sub _num_arg {
+  my ($node, $expected, $name) = @_;
+
+  my $children = scalar @{$node->{children}};
+
+  die "$name: Wrong number of arguments (expected $expected, got $children).\n"
+    if ($children != $expected);
+}
+
 #------------------------------------
 
 my $type_map = {
@@ -194,22 +210,105 @@
 sub _op_equal_p {
 }
 
-sub _op_pair {
+sub _op_pair_p {
+  my ($self, $node) = @_;
+  my $return;
+  my $label = $self->_gensym();
+
+  _num_arg ($node, 1, 'pair?');
+
+  my $item = $self->_generate($node->{children}->[0]);
+
+  $return = _save_1 ('I');
+
+  if ($item =~ /^[INS]/) {
+    $self->_add_inst ('', 'set', [$return,0]);
+  }
+  else {
+    $self->_add_inst ('', 'typeof', [$return,$item]);
+    $self->_add_inst ('', 'ne', [$return,'.Array',"FAIL_$label"]);
+    $self->_add_inst ('', 'set', [$return,$item]);
+    $self->_add_inst ('', 'ne', [$return,2,"FAIL_$label"]);
+    $self->_add_inst ('', 'set', [$return,1]);
+    $self->_add_inst ('', 'branch', ["DONE_$label"]);
+    $self->_add_inst ("FAIL_$label", 'set', [$return,0]);
+    $self->_add_inst ("DONE_$label");
+  }
+
+  return $return;
 }
 
 sub _op_cons {
+  my ($self, $node) = @_;
+  my $return;
+
+  _num_arg ($node, 2, 'cons');
+  
+  my $car = $self->_generate($node->{children}->[0]);
+  $return = _save_1('P');
+
+  $self->_add_inst ('', 'new', [$return,'.Array']);
+  $self->_add_inst ('', 'set', [$return,2]);
+  $self->_add_inst ('', 'set', [$return.'[0]',$car]);
+  _restore ($car);
+
+  my $cdr = $self->_generate($node->{children}->[1]);
+  $self->_add_inst ('', 'set', [$return.'[1]', $cdr]);
+  _restore ($cdr);
+
+  return $return;
 }
 
 sub _op_car {
+  my ($self, $node) = @_;
+
+  _num_arg ($node, 1, 'car');
+
+  my $return = $self->_generate ($node->{children}->[0]);
+  die "car: Element not pair\n" unless $return =~ /^P/;
+  $self->_add_inst ('', 'set', [$return,$return.'[0]']);
+
+  return $return;
 }
 
 sub _op_cdr {
+  my ($self, $node) = @_;
+
+  _num_arg ($node, 1, 'cdr');
+
+  my $return = $self->_generate ($node->{children}->[0]);
+  die "cdr: Element not pair\n" unless $return =~ /^P/;
+  $self->_add_inst ('', 'set', [$return,$return.'[1]']);
+
+  return $return;
 }
 
-sub _op_set_car {
+sub _op_set_car_bang {
+  my ($self, $node) = @_;
+
+  _num_arg ($node, 2, 'set-car!');
+
+  my $return = $self->_generate ($node->{children}->[0]);
+  die "set-car!: Element not pair\n" unless $return =~ /^P/;
+  my $value = $self->_generate ($node->{children}->[1]);
+  $self->_add_inst ('', 'set', [$return.'[0]',$value]);
+  _restore ($value);
+
+  return $return;
 }
 
-sub _op_set_cdr {
+sub _op_set_cdr_bang {
+  my ($self, $node) = @_;
+
+  _num_arg ($node, 2, 'set-cdr!');
+
+  my $return = $self->_generate ($node->{children}->[0]);
+  die "set-cdr!: Element not pair\n" unless $return =~ /^P/;
+  my $value = $self->_generate ($node->{children}->[1]);
+  $self->_add_inst ('', 'set', [$return.'[1]',$value]);
+  _restore ($value);
+
+  return $return;
 }
 
 sub _op_null {
@@ -219,9 +318,53 @@
 }
 
 sub _op_list {
+  my ($self, $node) = @_;
+  my $label = $self->_gensym ();
+  my $return = _save_1 ('P');
+
+  $self->_add_inst ('', 'new',[$return,'.PerlUndef']);
+
+  return $return unless exists $node->{children};
+
+  for (reverse @{$node->{children}}) {
+    my $item = $self->_generate($_);
+    my $pair = _save_1 ('P');
+
+    $self->_add_inst ('', 'new',[$pair,'.Array']);
+    $self->_add_inst ('', 'set',[$pair,2]);
+    $self->_add_inst ('', 'set',[$pair.'[0]',$item]);
+    $self->_add_inst ('', 'set',[$pair.'[1]',$return]);
+    $self->_add_inst ('', 'set',[$return,$pair]);
+
+    _restore($item, $pair);
+  }
+
+  return $return;
 }
 
 sub _op_length {
+  my ($self, $node) = @_;
+  my $label = $self->_gensym ();
+  my $return = _save_1 ('I');
+
+  _num_arg ($node, 1, 'length');
+
+  my $list = $self->_generate($node->{children}->[0]);
+  
+  $self->_add_inst ('', 'set',[$return,'0']);
+  my $type = _save_1 ('I');
+  $self->_add_inst ("NEXT_$label", 'typeof',[$type,$list]);
+  $self->_add_inst ('', 'eq',[$type,'.PerlUndef', "DONE_$label"]);
+  $self->_add_inst ('', 'ne',[$type,'.Array', "ERR_$label"]);
+  $self->_add_inst ('', 'inc',[$return]);
+  $self->_add_inst ('', 'set',[$list,$list.'[1]']);
+  $self->_add_inst ('', 'branch',["NEXT_$label"]);
+  # XXX Use exceptions here
+  $self->_add_inst ("ERR_$label", 'print',['"Object is not a list\n"']);
+
+  $self->_add_inst ("DONE_$label");
+
+  return $return;
 }
 
 sub _op_append {
@@ -903,7 +1046,20 @@
   my ($self,$node) = @_;
   for(@{$node->{children}}) {
     my $temp = $self->_generate($_);
-    $self->_add_inst('','print',[$temp]);
+    if ($temp =~ /[INS]/) {
+      $self->_add_inst('','print',[$temp]);
+    }
+    else {
+      $self->_use_function ('write');
+      if ($temp ne 'P5') {
+	$self->_add_inst('', 'save', ['P5']) if $regs->{P}{5};
+	$self->_add_inst('', 'set', ['P5',$temp]);
+      }
+      $self->_add_inst('', 'bsr', ['write_ENTRY']);
+      if ($temp ne 'P5' && $regs->{P}{5}) {
+	$self->_add_inst('', 'restore', ['P5']);
+      }
+    }
     _restore($temp);
   }
 }
@@ -1264,6 +1420,13 @@
   @max_len;
 }
 
+sub _use_function {
+  my ($self, $name) = @_;
+
+  push @{$self->{functions}}, $name 
+    unless grep { $_ eq $name } @{$self->{functitons}};
+}
+
 sub _format_columns {
   my $self    = shift;
   my $colref  = $self->{instruction};
@@ -1290,6 +1453,7 @@
     tree     => $tree,
     register => [(0) x 32],
     gensym   => 0,
+    functions=> [],
   };
   bless $self,$class;
 }
@@ -1319,6 +1483,14 @@
   $return;
 }
 
+sub _link_buildins {
+  my ($self) = @_;
+
+  for (@{$self->{functions}}) {
+    Scheme::Builtins::generate ($self, $_);
+  }
+}
+
 sub generate {
   my $self = shift;
   my @temp = _save(1);
@@ -1326,6 +1498,7 @@
 #die Dumper($self->{tree});
   _restore(@temp);
   $self->_add_inst('',"end");
+  $self->_link_buildins();
   $self->_format_columns();
 }
 
Index: languages/scheme/Scheme/Tokenizer.pm
===================================================================
RCS file: /cvs/public/parrot/languages/scheme/Scheme/Tokenizer.pm,v
retrieving revision 1.2
diff -u -r1.2 Tokenizer.pm
--- languages/scheme/Scheme/Tokenizer.pm	24 Mar 2002 23:42:38 -0000	1.2
+++ languages/scheme/Scheme/Tokenizer.pm	4 Sep 2002 23:53:29 -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]/) { # Exclamation marks can follow an identifier
+      $token .= $ch;
     } elsif($ch eq '=' and
             $token =~ /^[<>]/) {  # Equal sign can follow '<','>'
       $token .= $ch;
Index: languages/scheme/t/logic/lists.t
===================================================================
RCS file: languages/scheme/t/logic/lists.t
diff -N languages/scheme/t/logic/lists.t
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ languages/scheme/t/logic/lists.t	4 Sep 2002 23:53:29 -0000
@@ -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

Reply via email to