All --

I've created a varargs-ish example by making a new op, print_s_v.
This is pretty rough, and I haven't updated the assembler, but it
seems to work.

I'm attaching a patch, and a test program (pt.pasm).


Enjoy!
 
-- Gregor
 _____________________________________________________________________ 
/     perl -e 'srand(-2091643526); print chr rand 90 for (0..4)'      \

   Gregor N. Purdy                          [EMAIL PROTECTED]
   Focus Research, Inc.                http://www.focusresearch.com/
   8080 Beckett Center Drive #203                   513-860-3570 vox
   West Chester, OH 45069                           513-860-3579 fax
\_____________________________________________________________________/
Index: assemble.pl
===================================================================
RCS file: /home/perlcvs/parrot/assemble.pl,v
retrieving revision 1.45
diff -u -r1.45 assemble.pl
--- assemble.pl 2001/09/24 16:01:58     1.45
+++ assemble.pl 2001/09/24 21:25:57
@@ -303,19 +303,55 @@
            error("No opcode $opcode ( tried " . join(', ', @tests) . ") in 
<$pline>",$file,$line);
        }
     }
-    if (@args != $opcodes{$opcode}{ARGS}) {
-      error("Wrong arg count--got ".scalar(@args)." needed 
".$opcodes{$opcode}{ARGS}." in <$_>" ,$file,$line);
+
+    my $varop = $opcode =~m/_v$/;
+
+    if ($varop) {
+      if (@args < $opcodes{$opcode}{ARGS}) {
+        error("Wrong arg count--got ".scalar(@args)." needed at 
+least".$opcodes{$opcode}{ARGS}." in <$_>" ,$file,$line);
+      }
+    } else {
+      if (@args != $opcodes{$opcode}{ARGS}) {
+        error("Wrong arg count--got ".scalar(@args)." needed 
+".$opcodes{$opcode}{ARGS}." in <$_>" ,$file,$line);
+      }
     }
+
     $bytecode .= pack_op($opcodes{$opcode}{CODE});
     $op_pc=$pc;
     $pc+=sizeof('op');
     
+    if ($varop) {
+      splice(@args, $opcodes{$opcode}{ARGS} - 1, 0, scalar(@args)); # Splice in the 
+arg count.
+    }
+
     foreach (0..$#args) {
        my($rtype)=$opcodes{$opcode}{TYPES}[$_];
+
+        if ($varop) {
+          if (not defined $rtype) {
+            if ($args[$_] =~ m/^([INPS])(\d+)$/) {
+              $rtype = $1;
+            } elsif ($args[$_] =~ m/^\d+\.\d+$/) {
+              $rtype = 'n';
+            } elsif ($args[$_] =~ m/^\d+$/) {
+              $rtype = 'i';
+            } elsif ($args[$_] =~ m/^\[\d+\]$/) {
+              $rtype = 's';
+            } else {
+              $rtype = '*';
+              warn "Could not infer arg type!";
+            }
+          } elsif ($rtype eq 'v') {
+            $rtype = 'i';
+          }
+        }
+
        if($rtype eq "I" || $rtype eq "N" || $rtype eq "P" || $rtype eq "S") {
            # its a register argument
-           $args[$_]=~s/^[INPS](\d+)$/$1/i;
-           error("Register $1 out of range (should be 0-31) in 
'$opcode'",$file,$line) if $1 < 0 or $1 > 31;
+           $args[$_] =~ m/^[INPS](\d+)$/i;
+           error("Register '" . $args[$_] . "' unparseable in '$opcode'",$file,$line) 
+unless defined $1;
+           error("Register '$args[$_]' out of range (should be 0-31) in 
+'$opcode'",$file,$line) if $1 < 0 or $1 > 31;
+           $args[$_] = $1;
        } elsif($rtype eq "D") {
            # a destination
            if($args[$_]=~/^\$/) {
Index: basic_opcodes.ops
===================================================================
RCS file: /home/perlcvs/parrot/basic_opcodes.ops,v
retrieving revision 1.24
diff -u -r1.24 basic_opcodes.ops
--- basic_opcodes.ops   2001/09/24 16:27:48     1.24
+++ basic_opcodes.ops   2001/09/24 21:25:57
@@ -6,7 +6,10 @@
 
 #include "parrot/parrot.h"
 #include <math.h>
+#include <stdarg.h>
 
+#define VP(n) cur_opcode[(n) + 2]
+
 /* SET Ix, CONSTANT */
 AUTO_OP set_i_ic {
   INT_REG(P1) = P2;
@@ -141,6 +144,89 @@
 /* TIME Ix */
 AUTO_OP time_i {
   INT_REG(P1) = time(NULL);
+}
+
+/* PRINTF Sx, Vz */
+MANUAL_OP print_s_v {
+  const char * fmt       = STR_REG(P1)->bufstart;
+  IV           fmt_len   = string_length(STR_REG(P1));
+  IV           fmt_idx;
+  char         fmt_last  = '\0';
+  int          in_format = 0;
+  STRING *     s;
+  IV           arg       = 0; /* No args so far */
+  const char * str;
+  IV           str_len;
+
+  /* TODO: Grab P2 (argc) and make sure we don't overrun it!!! */
+
+  for(fmt_idx = 0; fmt_idx < fmt_len; fmt_idx++) {
+    if (fmt[fmt_idx] == '%' && fmt_last != '\\') {
+      in_format = fmt_idx + 1; /* the char after '%' */
+      continue;
+    }
+ 
+    /* TODO: DANGER: Assumes IV-sized NVs!!! */
+
+    if (in_format) {
+      switch (fmt[fmt_idx]) {
+        case 'i':
+          /* TODO: inherit the precision, etc. */
+          arg++;
+          printf("%d", VP(arg));
+          in_format = 0;
+          break; 
+
+        case 'I':
+          /* TODO: inherit the precision, etc. */
+          arg++;
+          printf("%d", INT_REG(VP(arg)));
+          in_format = 0;
+          break; 
+
+        case 'n':
+          /* TODO: inherit the precision, etc. */
+          arg++;
+          printf("%f", VP(arg));
+          in_format = 0;
+          break; 
+
+        case 'N':
+          /* TODO: inherit the precision, etc. */
+          arg++;
+          printf("%f", NUM_REG(VP(arg)));
+          in_format = 0;
+          break; 
+
+        case 's':
+          /* TODO: inherit the precision, etc. */
+          arg++;
+          str     = Parrot_string_constants[VP(arg)]->bufstart;
+          str_len = string_length(Parrot_string_constants[VP(arg)]);
+          printf("%*s", str_len, str);
+          in_format = 0;
+          break; 
+
+        case 'S':
+          arg++;
+          /* TODO: inherit the precision, etc. */
+          str     = STR_REG(VP(arg))->bufstart;
+          str_len = string_length(STR_REG(VP(arg)));
+          printf("%*s", str_len, str);
+          in_format = 0;
+          break; 
+
+        default:
+          /* Just keep scanning until we get a final 'type' character... */
+          break;
+      }
+    } else {
+      putchar(fmt[fmt_idx]);
+      continue;
+    }
+  }
+
+  RETURN(arg + 2);
 }
 
 /* PRINT Ix */
Index: opcode_table
===================================================================
RCS file: /home/perlcvs/parrot/opcode_table,v
retrieving revision 1.22
diff -u -r1.22 opcode_table
--- opcode_table        2001/09/24 16:27:48     1.22
+++ opcode_table        2001/09/24 21:25:57
@@ -57,8 +57,6 @@
 # String ops
 
 set_s_sc       2       S s
-print_s        1       S
-print_sc       1       s
 length_i_s     2       I S
 chopn_s_ic     2       S i
 substr_s_s_i   4       S S I I
@@ -107,12 +105,18 @@
 # Miscellaneous and debugging ops
 
 time_i 1       I
+time_n 1       N
+noop   0
+
+# Printing ops
+
 print_i        1       I
 print_ic       1       i
-time_n 1       N
 print_n        1       N
 print_nc       1       n
-noop   0
+print_s        1       S
+print_sc       1       s
+print_s_v      2       S       v
 
 # Register ops
 
Index: process_opfunc.pl
===================================================================
RCS file: /home/perlcvs/parrot/process_opfunc.pl,v
retrieving revision 1.16
diff -u -r1.16 process_opfunc.pl
--- process_opfunc.pl   2001/09/23 00:03:45     1.16
+++ process_opfunc.pl   2001/09/24 21:25:57
@@ -53,6 +53,7 @@
             D => 1,
             S => 1,
             s => 1,
+            v => 0,
             );
 
 
set S1, "%s, %s! (%s)\n"
print_s_v S1, "Hello", "world", "How are you doing?"
end

Reply via email to