The mandelbrot benchmark looked like it'd be an easy one to implement, and lo and behold, it was! I haven't optimized this at all really, but it seems to run fairly quickly anyhow.
-- Peter Baylies
=head1 NAME examples/shootout/mandelbrot.pir - Print the Mandelbrot set =head1 SYNOPSIS % ./parrot examples/shootout/mandelbrot.pir 200 > out.pbm =head1 DESCRIPTION This outputs a pbm file of the Mandelbrot set. Defaults to 200x200. Translated from C code by Greg Buchholz into PIR by Peter Baylies <[EMAIL PROTECTED]>. The C code is: /* The Great Computer Language Shootout http://shootout.alioth.debian.org/ contributed by Greg Buchholz compile: gcc -O2 -o mandelbrot mandelbrot.c run: mandelbrot 200 > out.pbm */ #include<stdio.h> int main (int argc, char **argv) { int w, h, x, y, bit_num = 0; char byte_acc = 0; int i, iter = 50; double limit = 2.0; double Zr, Zi, Cr, Ci, Tr, Ti; w = atoi(argv[1]); h = w; printf("P4\n%d %d\n",w,h); for(y=0;y<h;y++) { for(x=0;x<w;x++) { Zr = 0.0; Zi = 0.0; Cr = (2*(double)x/w - 1.5); Ci=(2*(double)y/h - 1); for (i=0;i<iter;i++) { Tr = Zr*Zr - Zi*Zi + Cr; Ti = 2*Zr*Zi + Ci; Zr = Tr; Zi = Ti; if (Zr*Zr+Zi*Zi > limit*limit) break; } if(Zr*Zr+Zi*Zi > limit*limit) byte_acc = (byte_acc << 1) | 0x00; else byte_acc = (byte_acc << 1) | 0x01; bit_num++; if(bit_num == 8) { putc(byte_acc,stdout); byte_acc = 0; bit_num = 0; } else if(x == w-1) { byte_acc = byte_acc << (8-w%8); putc(byte_acc,stdout); byte_acc = 0; bit_num = 0; } } } return(0); } =cut .sub 'main' :main .param pmc argv # int w, h, x, y, bit_num = 0; # char byte_acc = 0; # int i, iter = 50; # double limit = 2.0; # double Zr, Zi, Cr, Ci, Tr, Ti; .local int w, h, x, y, bit_num, byte_acc, i, iter .local num limit, Zr, Zi, Cr, Ci, Tr, Ti .sym int argc bit_num = 0 byte_acc = 0 iter = 50 limit = 2.0 # slight optimization here -- nothing a decent C compiler wouldn't already do :) limit = limit * limit argc = argv w = 200 if argc <= 1 goto noarg # w = atoi(argv[1]); $S0 = argv[1] w = $S0 # h = w noarg: h = w # printf("P4\n%d %d\n",w,h); print "P4\n" print w print " " print h print "\n" y = 0 YREDO: x = 0 XREDO: # Zr = 0.0; Zi = 0.0; Zr = 0.0 Zi = 0.0 # Cr = (2*(double)x/w - 1.5); Cr = x Cr /= w Cr *= 2 Cr -= 1.5 # Ci=(2*(double)y/h - 1); Ci = y Ci /= h Ci *= 2 Ci -= 1 i = 0 IREDO: # Tr = Zr*Zr - Zi*Zi + Cr; $N1 = Zr * Zr $N2 = Zi * Zi Tr = $N1 - $N2 Tr += Cr # Ti = 2*Zr*Zi + Ci; Ti = 2 Ti *= Zr Ti *= Zi Ti += Ci # Zr = Tr; Zi = Ti; Zr = Tr Zi = Ti # if (Zr*Zr+Zi*Zi > limit*limit) break; # $N1 = Zr * Zr # $N2 = Zi * Zi $N1 += $N2 if $N1 > limit goto IBRK inc i if i < iter goto IREDO IBRK: byte_acc <<= 1 if $N1 <= limit goto SLA byte_acc |= 0 goto SLE SLA: byte_acc |= 1 SLE: inc bit_num if bit_num != 8 goto NTST1 PRINT: chr $S1, byte_acc print $S1 byte_acc = 0 bit_num = 0 goto NTSTE NTST1: $I1 = w dec $I1 goto NTSTE if x != $I1 goto NTSTE $I1 = w $I1 %= 8 $I1 = 8 - $I1 byte_acc <<= $I1 goto PRINT NTSTE: inc x if x < w goto XREDO inc y if y < h goto YREDO end .end