# Mandelbrot set generator: simple example of Miller DSL as programming language. begin { # Set defaults @rcorn = -2.0; @icorn = -2.0; @side = 4.0; @iheight = 50; @iwidth = 100; @maxits = 100; @levelstep = 5; @chars = "@X*o-."; # Palette of characters to print to the screen. @verbose = false; @do_julia = false; @jr = 0.0; # Real part of Julia point, if any @ji = 0.0; # Imaginary part of Julia point, if any } # Here, we can override defaults from an input file (if any). In Miller's # put/filter DSL, absent-null right-hand sides result in no assignment so we # can simply put @rcorn = $rcorn: if there is a field in the input like # 'rcorn = -1.847' we'll read and use it, else we'll keep the default. @rcorn = $rcorn; @icorn = $icorn; @side = $side; @iheight = $iheight; @iwidth = $iwidth; @maxits = $maxits; @levelstep = $levelstep; @chars = $chars; @verbose = $verbose; @do_julia = $do_julia; @jr = $jr; @ji = $ji; end { if (@verbose) { print "RCORN = ".@rcorn; print "ICORN = ".@icorn; print "SIDE = ".@side; print "IHEIGHT = ".@iheight; print "IWIDTH = ".@iwidth; print "MAXITS = ".@maxits; print "LEVELSTEP = ".@levelstep; print "CHARS = ".@chars; } # Iterate over a matrix of rows and columns, printing one character for each cell. for (int ii = @iheight-1; ii >= 0; ii -= 1) { num pi = @icorn + (ii/@iheight) * @side; for (int ir = 0; ir < @iwidth; ir += 1) { num pr = @rcorn + (ir/@iwidth) * @side; printn get_point_plot(pr, pi, @maxits, @do_julia, @jr, @ji); } print; } } # This is a function to approximate membership in the Mandelbrot set (or Julia # set for a given Julia point if do_julia == true) for a given point in the # complex plane. func get_point_plot(pr, pi, maxits, do_julia, jr, ji) { num zr = 0.0; num zi = 0.0; num cr = 0.0; num ci = 0.0; if (!do_julia) { zr = 0.0; zi = 0.0; cr = pr; ci = pi; } else { zr = pr; zi = pi; cr = jr; ci = ji; } int iti = 0; bool escaped = false; num zt = 0; for (iti = 0; iti < maxits; iti += 1) { num mag = zr*zr + zi+zi; if (mag > 4.0) { escaped = true; break; } # z := z^2 + c zt = zr*zr - zi*zi + cr; zi = 2*zr*zi + ci; zr = zt; } if (!escaped) { return "."; } else { # The // operator is Miller's (pythonic) integer-division operator int level = (iti // @levelstep) % strlen(@chars); return substr(@chars, level, level); } }