Goose  Artifact [bb2b13bc58]

Artifact bb2b13bc58af2fc8a2cd9ff0397ee7e9b32d191c379712aed3563473e4db71eb:

  • File samples/mandelbrot.g — part of check-in [91a6550edb] at 2021-06-11 11:42:36 on branch trunk —
    • Removed the Conversion step, it could all be done using PostProcessing callback, there were just TypeChecking rules missing to unwrap the callbacks...
    • Fixed some ill defined reference type checking rules
    • Runtime integers no longer have a default initializer of 0. This isn't that useful considering that 0 may not be valid depending on the refinement conditions applied to the type
    (user: achavasse size: 2108)
  • File samples/mandelbrot.g1 — part of check-in [45f663093d] at 2021-09-12 13:42:15 on branch trunk — Adopted a new convention for source extensions: .g0 for prelude code (where most language features won't be available), .g1 for user code (user: achavasse size: 2108)

// Renders an ascii art mandelbrot.
// This uses integer based fixed point because
// float support is not yet implemented.

using s32 = sint(32)
using u32 = uint(32)
using u8 = uint(8)

s32 IntToFixedWidthDec( s32 i )
    // Restrict the input range to avoid overflows
    requires [
        i < ( 1 << 12 )
        i > ( -1 << 12 )
    ]
{
    return i << 12
}

using width = 100
using height = 32

using minU = IntToFixedWidthDec( -2 )
using maxU = IntToFixedWidthDec( 1 )

using minV = IntToFixedWidthDec( -1 )
using maxV = IntToFixedWidthDec( 1 )

using maxIterations = 50
using threshold = 4 << 24

using fflush = ExternalFunction( u32 ( pointer(void) stream ), "fflush" )

using putchar = ExternalFunction( u32 ( u8 c ), "putchar" )
void put( $c )
{
    putchar( cast( ct_int, $c ) )
}

void renderPixel( s32 x, s32 y )
    requires [
        width > 0
        height > 0
        x < width
        y < height
    ]
{
    // Using tuples to declare and initialize both variables
    // at once isn't really necessary here but it serves as
    // a drive-by test for that feature.
    var cr, var ci = minU + x * ( maxU - minU ) / width,
                     minV + y * ( maxV - minV ) / height

    s32 zr = 0 s32 zi = 0

    u32 i = 0
    while i < maxIterations
    {
        // By using a tuple assignment, we compute
        // the new values of both zr and zi first, and only after
        // we update the variables. With individual assignemnts,
        // we'd need to create temporary variables to compute
        // the new values of zr and zi and then copy
        // the results back in zr and zi.
        zr, zi = ( zr*zr - zi*zi ) >> 12,
                 2 * zr * zi >> 12

        zr, zi += cr, ci

        if ( zr*zr + zi*zi ) > threshold
        {
            if ( i & 1 ) == 0
                put( ' ' )
            else
                put( '.' )
            return
        }

        i += 1
    }

    put( '#' )
}

s32 y = 0
while y < height
{
    s32 x = 0
    while x < width
    {
        renderPixel( x, y )
        x += 1
    }

    put( '\n' )
    y += 1
}

fflush( nullptr )