In message <[EMAIL PROTECTED]> Dan Sugalski <[EMAIL PROTECTED]> wrote:
> At 05:21 PM 10/16/2001 +0100, Tom Hughes wrote: > >I have a plan to semi-automate it which I nearly implemted the other > >day but didn't get around to. Basically the idea is to extend things > >so an ops file can contain this: > > It sounds interesting, certainly. Give it a go and we'll see how it looks. > (As long as it doesn't interfere with generating the switch statement or > function table the oploop needs...) As Gregor said, the expansion code is in the OpsFile module so anything which uses that to read the .ops file will never know anything about it. I have knocked up a first pass at a patch, which is attached for comments. I did discover one limitation of my scheme when I started using it to eliminate redundancy, namely cases like this: sub(i, i, i) sub(i, i, ic) sub(i, ic, i) If I rewrite that using my scheme as: sub(i, i|ic, i|ic) Then we wind up with a fourth variant that subtracts one constant from another. I am wondering whether I should add an extra rule that says that any expansion where there are more than two arguments and all bar the first are constants is ignored, which would allow the above and a number of other cases to be rewritten. Tom -- Tom Hughes ([EMAIL PROTECTED]) http://www.compton.nu/
? t/test.pbc ? t/test1.c ? t/test1 Index: core.ops =================================================================== RCS file: /home/perlcvs/parrot/core.ops,v retrieving revision 1.10 diff -u -w -r1.10 core.ops --- core.ops 2001/10/16 18:35:04 1.10 +++ core.ops 2001/10/16 23:35:32 @@ -136,30 +136,18 @@ =cut -AUTO_OP set(i, i) { +AUTO_OP set(i, i|ic) { $1 = $2; } -AUTO_OP set(i, ic) { +AUTO_OP set(n, n|nc) { $1 = $2; } -AUTO_OP set(n, nc) { - $1 = $2; -} - -AUTO_OP set(n, n) { - $1 = $2; -} - -AUTO_OP set(s, sc) { +AUTO_OP set(s, s|sc) { $1 = string_copy($2); } -AUTO_OP set(s, s) { - $1 = string_copy($2); -} - =back =cut @@ -239,38 +227,20 @@ Branch if $1 is equal to $2. =cut - -AUTO_OP eq(i, i, ic) { - if ($1 == $2) { - RETREL($3); - } -} - -AUTO_OP eq(i, ic, ic) { - if ($1 == $2) { - RETREL($3); - } -} -AUTO_OP eq(n, n, ic) { +AUTO_OP eq(i, i|ic, ic) { if ($1 == $2) { RETREL($3); } } -AUTO_OP eq(n, nc, ic) { +AUTO_OP eq(n, n|nc, ic) { if ($1 == $2) { RETREL($3); } } - -AUTO_OP eq(s, s, ic) { - if (string_compare($1, $2) == 0) { - RETREL($3); - } -} -AUTO_OP eq(s, sc, ic) { +AUTO_OP eq(s, s|sc, ic) { if (string_compare($1, $2) == 0) { RETREL($3); } @@ -295,37 +265,19 @@ =cut -AUTO_OP ne(i, i, ic) { +AUTO_OP ne(i, i|ic, ic) { if ($1 != $2) { RETREL($3); } } -AUTO_OP ne(i, ic, ic) { +AUTO_OP ne(n, n|nc, ic) { if ($1 != $2) { RETREL($3); } } -AUTO_OP ne(n, n, ic) { - if ($1 != $2) { - RETREL($3); - } -} - -AUTO_OP ne(n, nc, ic) { - if ($1 != $2) { - RETREL($3); - } -} - -AUTO_OP ne(s, s, ic) { - if (string_compare($1, $2) != 0) { - RETREL($3); - } -} - -AUTO_OP ne(s, sc, ic) { +AUTO_OP ne(s, s|sc, ic) { if (string_compare($1, $2) != 0) { RETREL($3); } @@ -349,38 +301,20 @@ Branch if $1 is less than $2. =cut - -AUTO_OP lt(i, i, ic) { - if ($1 < $2) { - RETREL($3); - } -} - -AUTO_OP lt(i, ic, ic) { - if ($1 < $2) { - RETREL($3); - } -} -AUTO_OP lt(n, n, ic) { +AUTO_OP lt(i, i|ic, ic) { if ($1 < $2) { RETREL($3); } } -AUTO_OP lt(n, nc, ic) { +AUTO_OP lt(n, n|nc, ic) { if ($1 < $2) { RETREL($3); } } - -AUTO_OP lt(s, s, ic) { - if (string_compare($1, $2) < 0) { - RETREL($3); - } -} -AUTO_OP lt(s, sc, ic) { +AUTO_OP lt(s, s|sc, ic) { if (string_compare($1, $2) < 0) { RETREL($3); } @@ -404,38 +338,20 @@ Branch if $1 is less than or equal to $2. =cut - -AUTO_OP le(i, i, ic) { - if ($1 <= $2) { - RETREL($3); - } -} - -AUTO_OP le(i, ic, ic) { - if ($1 <= $2) { - RETREL($3); - } -} -AUTO_OP le(n, n, ic) { +AUTO_OP le(i, i|ic, ic) { if ($1 <= $2) { RETREL($3); } } -AUTO_OP le(n, nc, ic) { +AUTO_OP le(n, n|nc, ic) { if ($1 <= $2) { RETREL($3); } } - -AUTO_OP le(s, s, ic) { - if (string_compare($1, $2) <= 0) { - RETREL($3); - } -} -AUTO_OP le(s, sc, ic) { +AUTO_OP le(s, s|sc, ic) { if (string_compare($1, $2) <= 0) { RETREL($3); } @@ -459,38 +375,20 @@ Branch if $1 is greater than $2. =cut - -AUTO_OP gt(i, i, ic) { - if ($1 > $2) { - RETREL($3); - } -} - -AUTO_OP gt(i, ic, ic) { - if ($1 > $2) { - RETREL($3); - } -} -AUTO_OP gt(n, n, ic) { +AUTO_OP gt(i, i|ic, ic) { if ($1 > $2) { RETREL($3); } } -AUTO_OP gt(n, nc, ic) { +AUTO_OP gt(n, n|nc, ic) { if ($1 > $2) { RETREL($3); } } - -AUTO_OP gt(s, s, ic) { - if (string_compare($1, $2) > 0) { - RETREL($3); - } -} -AUTO_OP gt(s, sc, ic) { +AUTO_OP gt(s, s|sc, ic) { if (string_compare($1, $2) > 0) { RETREL($3); } @@ -515,42 +413,24 @@ =cut -AUTO_OP ge(i, i, ic) { +AUTO_OP ge(i, i|ic, ic) { if ($1 >= $2) { RETREL($3); } } -AUTO_OP ge(i, ic, ic) { +AUTO_OP ge(n, n|nc, ic) { if ($1 >= $2) { RETREL($3); } } -AUTO_OP ge(n, n, ic) { - if ($1 >= $2) { - RETREL($3); - } -} - -AUTO_OP ge(n, nc, ic) { - if ($1 >= $2) { - RETREL($3); - } -} - -AUTO_OP ge(s, s, ic) { +AUTO_OP ge(s, s|sc, ic) { if (string_compare($1, $2) >= 0) { RETREL($3); } } -AUTO_OP ge(s, sc, ic) { - if (string_compare($1, $2) >= 0) { - RETREL($3); - } -} - ######################################## @@ -607,38 +487,22 @@ Print $1 to standard output. =cut - -AUTO_OP print(i) { - /* TODO: Configure for format */ - printf("%li", (long) $1); -} -AUTO_OP print(ic) { +AUTO_OP print(i|ic) { /* TODO: Configure for format */ printf("%li", (long) $1); } - -AUTO_OP print(n) { - /* TODO: Configure for format */ - printf("%f", $1); -} -AUTO_OP print(nc) { +AUTO_OP print(n|nc) { /* TODO: Configure for format */ printf("%f", $1); } -AUTO_OP print(s) { +AUTO_OP print(s|sc) { STRING *s = $1; if (s) printf("%.*s",(int)string_length(s),(char *) s->bufstart); } -AUTO_OP print(sc) { - STRING *s = $1; - INTVAL l = string_length(s); - printf("%.*s", (int)l, (char *)s->bufstart); -} - =back @@ -670,20 +534,12 @@ Set $1 to the sum of $2 and $3. =cut - -AUTO_OP add(i, i, i) { - $1 = $2 + $3; -} - -AUTO_OP add(i, i, ic) { - $1 = $2 + $3; -} -AUTO_OP add(n, n, n) { +AUTO_OP add(i, i, i|ic) { $1 = $2 + $3; } -AUTO_OP add(n, n, nc) { +AUTO_OP add(n, n, n|nc) { $1 = $2 + $3; } @@ -1070,20 +926,12 @@ Set $1 to the product of $2 and $3. =cut - -AUTO_OP mul(i, i, i) { - $1 = $2 * $3; -} - -AUTO_OP mul(i, i, ic) { - $1 = $2 * $3; -} -AUTO_OP mul(n, n, n) { +AUTO_OP mul(i, i, i|ic) { $1 = $2 * $3; } -AUTO_OP mul(n, n, nc) { +AUTO_OP mul(n, n, n|nc) { $1 = $2 * $3; } @@ -1235,12 +1083,8 @@ TODO: Create a three-argument version of this? Don't force in-place modification. =cut - -AUTO_OP chopn(s, ic) { - (void)string_chopn($1, $2); -} -AUTO_OP chopn(s, i) { +AUTO_OP chopn(s, i|ic) { (void)string_chopn($1, $2); } @@ -1263,13 +1107,8 @@ into $1. =cut - -AUTO_OP concat(s, s) { - STRING *s = string_concat($1, $2, 1); - $1 = s; -} -AUTO_OP concat(s, sc) { +AUTO_OP concat(s, s|sc) { STRING *s = string_concat($1, $2, 1); $1 = s; } @@ -1325,23 +1164,8 @@ length $4. =cut - -AUTO_OP substr(s, s, i, i) { - STRING *s = string_substr($2, $3, $4, &$1); - $1 = s; -} - -AUTO_OP substr(s, s, i, ic) { - STRING *s = string_substr($2, $3, $4, &$1); - $1 = s; -} - -AUTO_OP substr(s, s, ic, i) { - STRING *s = string_substr($2, $3, $4, &$1); - $1 = s; -} -AUTO_OP substr(s, s, ic, ic) { +AUTO_OP substr(s, s, i|ic, i|ic) { STRING *s = string_substr($2, $3, $4, &$1); $1 = s; } @@ -1389,14 +1213,10 @@ =cut -AUTO_OP acos(n, i) { +AUTO_OP acos(n, i|n) { $1 = acos((FLOATVAL)$2); } -AUTO_OP acos(n, n) { - $1 = acos($2); -} - ######################################## @@ -1408,15 +1228,11 @@ =cut -AUTO_OP asec(n, i) { +AUTO_OP asec(n, i|n) { $1 = acos(((FLOATVAL)1) / ((FLOATVAL)$2)); } -AUTO_OP asec(n, n) { - $1 = acos(((FLOATVAL)1.0) / $2); -} - ######################################## =item B<asin>(n, i) @@ -1427,14 +1243,10 @@ =cut -AUTO_OP asin(n, i) { +AUTO_OP asin(n, i|n) { $1 = asin((FLOATVAL)$2); } -AUTO_OP asin(n, n) { - $1 = asin($2); -} - ######################################## @@ -1541,14 +1353,10 @@ =cut -AUTO_OP cos(n, i) { +AUTO_OP cos(n, i|n) { $1 = cos((FLOATVAL)$2); } -AUTO_OP cos(n, n) { - $1 = cos($2); -} - ######################################## @@ -1560,14 +1368,10 @@ =cut -AUTO_OP cosh(n, i) { +AUTO_OP cosh(n, i|n) { $1 = cosh((FLOATVAL)$2); } -AUTO_OP cosh(n, n) { - $1 = cosh($2); -} - ######################################## @@ -1579,14 +1383,10 @@ =cut -AUTO_OP exp(n, i) { +AUTO_OP exp(n, i|n) { $1 = exp((FLOATVAL)$2); } -AUTO_OP exp(n, n) { - $1 = exp($2); -} - ######################################## @@ -1598,14 +1398,10 @@ =cut -AUTO_OP ln(n, i) { +AUTO_OP ln(n, i|n) { $1 = log((FLOATVAL)$2); } -AUTO_OP ln(n, n) { - $1 = log($2); -} - ######################################## @@ -1617,14 +1413,10 @@ =cut -AUTO_OP log10(n, i) { +AUTO_OP log10(n, i|n) { $1 = log10((FLOATVAL)$2); } -AUTO_OP log10(n, n) { - $1 = log10($2); -} - ######################################## @@ -1636,16 +1428,11 @@ =cut -AUTO_OP log2(n, i) { +AUTO_OP log2(n, i|n) { FLOATVAL temp = log((FLOATVAL)2.0); $1 = log((FLOATVAL)$2) / temp; } -AUTO_OP log2(n, n) { - FLOATVAL temp = log((FLOATVAL)2.0); - $1 = log($2) / temp; -} - ######################################## @@ -1658,14 +1445,10 @@ =cut -AUTO_OP sec(n, i) { +AUTO_OP sec(n, i|n) { $1 = ((FLOATVAL)1) / cos((FLOATVAL)$2); } -AUTO_OP sec(n, n) { - $1 = ((FLOATVAL)1) / cos($2); -} - ######################################## @@ -1677,14 +1460,10 @@ =cut -AUTO_OP sech(n, i) { +AUTO_OP sech(n, i|n) { $1 = ((FLOATVAL)1) / cosh((FLOATVAL)$2); } -AUTO_OP sech(n, n) { - $1 = ((FLOATVAL)1.0) / cosh($2); -} - ######################################## @@ -1696,14 +1475,10 @@ =cut -AUTO_OP sin(n, i) { +AUTO_OP sin(n, i|n) { $1 = sin((FLOATVAL)$2); } -AUTO_OP sin(n, n) { - $1 = sin($2); -} - ######################################## @@ -1715,14 +1490,10 @@ =cut -AUTO_OP sinh(n, i) { +AUTO_OP sinh(n, i|n) { $1 = sinh((FLOATVAL)$2); } -AUTO_OP sinh(n, n) { - $1 = sinh($2); -} - ######################################## @@ -1733,14 +1504,10 @@ =cut -AUTO_OP tan(n, i) { +AUTO_OP tan(n, i|n) { $1 = tan((FLOATVAL)$2); } -AUTO_OP tan(n, n) { - $1 = tan($2); -} - ######################################## @@ -1752,14 +1519,10 @@ =cut -AUTO_OP tanh(n, i) { +AUTO_OP tanh(n, i|n) { $1 = tanh((FLOATVAL)$2); } -AUTO_OP tanh(n, n) { - $1 = tanh($2); -} - =back @@ -1786,12 +1549,8 @@ Set the bits of $1 according to the B<and> of the corresponding bits from $2 and $3. =cut - -AUTO_OP and(i, i, i) { - $1 = $2 & $3; -} -AUTO_OP and(i, i, ic) { +AUTO_OP and(i, i, i|ic) { $1 = $2 & $3; } @@ -1818,12 +1577,8 @@ Set the bits of $1 according to the B<or> of the corresponding bits from $2 and $3. =cut - -AUTO_OP or(i, i, i) { - $1 = $2 | $3; -} -AUTO_OP or(i, i, ic) { +AUTO_OP or(i, i, i|ic) { $1 = $2 | $3; } @@ -1837,15 +1592,11 @@ =cut -AUTO_OP shl(i, i, ic) { +AUTO_OP shl(i, i, i|ic) { $1 = $2 << $3; } -AUTO_OP shl(i, i, i) { - $1 = $2 << $3; -} - ######################################## =item B<shr>(i, i, i) @@ -1855,12 +1606,8 @@ Set $1 to the value of $2 shifted right by $3 bits. =cut - -AUTO_OP shr(i, i, ic) { - $1 = $2 >> $3; -} -AUTO_OP shr(i, i, i) { +AUTO_OP shr(i, i, i|ic) { $1 = $2 >> $3; } @@ -1875,15 +1622,11 @@ =cut -AUTO_OP xor(i, i, i) { +AUTO_OP xor(i, i, i|ic) { $1 = $2 ^ $3; } -AUTO_OP xor(i, i, ic) { - $1 = $2 ^ $3; -} - =back =cut @@ -2203,13 +1946,8 @@ stack for later returning. =cut - -MANUAL_OP bsr(i) { - push_generic_entry(interpreter, cur_opcode + 2, STACK_ENTRY_DESTINATION, NULL); - RETREL($1); -} -MANUAL_OP bsr(ic) { +MANUAL_OP bsr(i|ic) { push_generic_entry(interpreter, cur_opcode + 2, STACK_ENTRY_DESTINATION, NULL); RETREL($1); } Index: Parrot/OpsFile.pm =================================================================== RCS file: /home/perlcvs/parrot/Parrot/OpsFile.pm,v retrieving revision 1.2 diff -u -w -r1.2 OpsFile.pm --- Parrot/OpsFile.pm 2001/10/14 20:54:57 1.2 +++ Parrot/OpsFile.pm 2001/10/16 23:35:33 @@ -84,22 +84,18 @@ my ($name, $footer); - my $in_comment = 0; - my $op; - my $code; my $type; my $body; my $short_name; my $args; my @args; - my $op_size; - my $full_name; my $seen_pod; + my $seen_op; while (<OPS>) { $seen_pod = 1 if m|^=|; - unless ($op or m|^AUTO_OP\s+| or m|^MANUAL_OP\s+|) { + unless ($seen_op or m|^AUTO_OP\s+| or m|^MANUAL_OP\s+|) { $self->{PREAMBLE} .= $_ unless $seen_pod or $count; # Lines up to first op def. next; }; @@ -133,20 +129,16 @@ # if (/^(AUTO|MANUAL)_OP\s+([a-zA-Z][a-zA-Z0-9]*)\s*\((.*)\)\s*{/) { - if ($op) { + if ($seen_op) { die "Parrot::OpsFile: Cannot define an op within an op definition!\n"; } - $code = $count++; $type = lc $1; $short_name = lc $2; $args = trim(lc $3); - @args = ('op', split(/\s*,\s*/, $args)); # Prepend 'op' for opcode - $op_size = scalar(@args); - $op = Parrot::Op->new($code, $type, $short_name, @args); - $full_name = $op->full_name; + @args = split(/\s*,\s*/, $args); $body = ''; - $op_size = $op->size; + $seen_op = 1; next; } @@ -160,14 +152,62 @@ # if (/^}\s*$/) { - $op->body($body); - $self->push_op($op); - undef $op; + $count += $self->make_op($count, $type, $short_name, $body, @args); + + $seen_op = 0; next; } # + # Accummulate the code into the op's body: + # + + if ($seen_op) { + $body .= $_; + } else { + die "Parrot::OpsFile: Unrecognized line: '$_'!\n"; + } + } + + if ($seen_op) { + die "Parrot::OpsFile: File ended with incomplete op definition!\n"; + } + + close OPS or die "Could not close ops file '$file' ($!)!"; + + return; +} + + +# +# make_op() +# + +sub make_op +{ + my ($self, $code, $type, $short_name, $body, @args) = @_; + my @fixedargs; + + while (@args) { + my $arg = shift @args; + if ($arg =~ /\|/) { + my $count = 0; + foreach my $variant (split(/\s*\|\s*/, $arg)) { + $count += $self->make_op($code + $count, $type, $short_name, $body, + @fixedargs, $variant, @args); + } + return $count; + } + else { + push @fixedargs, $arg; + } + } + + my $op = Parrot::Op->new($code, $type, $short_name, 'op', @fixedargs); + my $op_size = $op->size; + + # # Macro substitutions: # # We convert the following notations: @@ -188,37 +228,24 @@ # # TODO: Complain about using, e.g. $3 in an op with only 2 args. # - - s/HALT/{{=0}}/g; - s/RESTART\(\*\)/{{=0,+=$op_size}}/g; - s/RESTART\((.*)\)/{{=0,+=$1}}/g; + $body =~ s/HALT/{{=0}}/mg; - s/RETREL\(\*\)/{{+=$op_size}}/g; - s/RETREL\((.*)\)/{{+=$1}}/g; + $body =~ s/RESTART\(\*\)/{{=0,+=$op_size}}/mg; + $body =~ s/RESTART\((.*)\)/{{=0,+=$1}}/mg; - s/RETABS\((.*)\)/{{=$1}}/g; + $body =~ s/RETREL\(\*\)/{{+=$op_size}}/mg; + $body =~ s/RETREL\((.*)\)/{{+=$1}}/mg; - s/\$(\d+)/{{\@$1}}/g; - - # - # Accummulate the code into the op's body: - # + $body =~ s/RETABS\((.*)\)/{{=$1}}/mg; - if ($op) { - $body .= $_; - } else { - die "Parrot::OpsFile: Unrecognized line: '$_'!\n"; - } - } + $body =~ s/\$(\d+)/{{\@$1}}/mg; - if ($op) { - die "Parrot::OpsFile: File ended with incomplete op definition!\n"; - } + $op->body($body); - close OPS or die "Could not close ops file '$file' ($!)!"; + $self->push_op($op); - return; + return 1; }