english
version "1.0"
identify "%Z%%M% %I% %E%"

#: Copyright (c) 1994-2005 by Wayne C. Gramlich.
#, All rights reserved.

module float

#: This module implements the 32-bit float base type for STIPPLE:

import
    character
    in_stream
    integer
    logical
    out_stream
    real
    save
    string
    unsigned

define float
    external

define float16
    external

define float_data
    record
	buffer string
	initialized logical
	hyphen character
	lower_b character
	lower_c character
	lower_d character
	lower_digits string
	lower_h character
	lower_l character
	lower_o character
	lower_p character
	lower_s character
	lower_w character
	lower_x character
	percent character
	space character
	upper_digits string
	upper_h character
	upper_o character
	upper_x character
	zero_offset unsigned
    generate allocate, erase, print

object one@float

object zero@float


procedure arc_cosine@float
    takes
	cosine float
    returns float
    no_side_effects
    external float__arc_cosine

    #: This procedure returns the arc cosine of {cosine}, where {cosine}
    #, is between -1 and 1.  The result is between 0 and {pi}.


procedure arc_sine@float
    takes
	sine float
    returns float
    no_side_effects
    external float__arc_sine

    #: This procedure returns the arc sine of {angle}, where {sine}
    #, is between -1 and 1.  The result is between -{pi}/2 and {pi}/2.


procedure arc_tangent@float
    takes
	angle float
    returns float
    no_side_effects
    external float__arc_tangent

    #: This procedure returns the arc tangent of {angle}, where {angle}
    #, is measured in radians.  The result is between -{pi}/2 and {pi}/2.


procedure arc_tangent2@float
    takes
	y float
	x float
    returns float
    no_side_effects
    external float__arc_tangent

    #: This procedure returns the arc tangent of {y} / {x}.  It uses
    #, the signs of {x} and {y} to determine the quadrant of the result.
    #, The result is between -{pi} and {pi}.


procedure absolute@float
    takes
	float float
    returns float

    #: This procedure will return the absolute value of {float}.

    if float < float_convert@(0)
	float := -float
    return float


procedure add@float
    takes
	left float
	right float
    returns float
    no_side_effects
    external float__add


procedure buffer_append@float
    takes
	arg float
	buffer string
    returns_nothing
    external float__buffer_append


procedure ceiling@float
    takes
	arg float
    returns float
    external float__ceiling

    #: This procedure will round {arg} up to the next closest integer
    #, and return it as a {float}.


procedure compare@float
    takes
	float1 float
	float2 float
    no_side_effects
    returns integer

    #: This procedure will return -1, 0, or 1 depending upon whether {float1}
    #, is less than, equal to, or greater than {float2}.

    if float1 > float2
	return integer_convert@(1)
    if float1 < float2
	return -integer_convert@(1)
    return integer_convert@(0)


procedure copy@float
    takes
	arg float
    returns float
    no_side_effects
    external float__copy


procedure cosine@float
    takes
	angle float
    returns float
    no_side_effects
    external float__cosine

    #: This procedure returns the cosine of {angle}, where {angle}
    #, is measured in radians.


procedure divide@float
    takes
	left float
	right float
    returns float
    no_side_effects
    external float__divide


procedure equal@float
    takes
	left float
	right float
    returns logical
    no_side_effects
    external float__equal


procedure floor@float
    takes
	float float
    returns float
    external float__floor

    #: This procedure will round {arg} down to the next closest integer
    #, and return it as a {float}.


procedure format@float
    takes
	float float
	out_stream out_stream
	format string
	offset unsigned
    returns_nothing

    #: This routine will output {float} to {out_stream} using the formatting
    #, characters in {format} starting at {offset} until a terminating "%" is
    #, encountered.  See the {format} module find out more about formatted
    #, output.

    print@(float, out_stream)


procedure greater_than@float
    takes
	left float
	right float
    returns logical
    no_side_effects
    external float__greater_than


procedure hash@float
    takes
	arg float
    returns unsigned
    no_side_effects
    external float__hash


procedure identical@float
    takes
	left float
	right float
    returns logical
    no_side_effects

    #: This procedure will return {true}@{logical} if {left}
    #, is equal to {right}.

    return left = right


procedure input@float
    takes
	input in_stream
    returns float
    assert false


procedure integer_convert@float
    takes
	float float
    returns integer
    no_side_effects
    external float__integer_convert


procedure less_than@float
    takes
	left float
	right float
    returns logical
    no_side_effects
    external float__less_than


procedure log@float
    takes
	arg float
    returns float
    no_side_effects
    external float__log


procedure maximum@float
    takes
	left float
	right float
    returns float

    #: This procedure will return the maximum of {left} and {right}.

    result :@= left
    if right > result
	result := right
    return result


procedure minimum@float
    takes
	left float
	right float
    returns float

    #: This procedure will return the manimum of {left} and {right}.

    result :@= left
    if right < result
	result := right
    return result


procedure minus@float
    takes
	arg float
    returns float
    no_side_effects
    external float__minus


procedure multiply@float
    takes
	left float
	right float
    returns float
    no_side_effects
    external float__multiply


procedure output@float
    takes
	float float
	output out_stream
    returns_nothing
    assert false


procedure parse@float
    takes
	input in_stream
    returns float
    assert false


procedure print@float
    takes
	float float
	out_stream out_stream
    returns_nothing

    #: This procedure will print {float} as a decimal number to
    #, {out_stream}.

    float_print@(out_stream, float)


procedure put@float
    takes
	float float
	out_stream out_stream
    returns_nothing
    assert false


procedure power@float
    takes
	left float
	right float
    returns float
    no_side_effects
    external float__power


procedure random_compute@float
    takes_nothing
    returns float

    #: This procedure will return a pseudo-random number.

    return float_convert@(random_compute@unsigned())


procedure read@float
    takes
	in_stream in_stream
    returns float

    #: This procedure will read a {float} from {in_stream} and return it.
    #, The value should have been previously written using {write}@{float}().

    return float_read@(in_stream)


procedure real_convert@float
    takes
	float float
    returns real
    no_side_effects

    #: This procedure will convrt {float} to a {real} and return
    #, the result.

    return float_to_real@real(float)


procedure remainder@float
    takes
	left float
	right float
    returns float
    no_side_effects
    external float__remainder


procedure rint@float
    takes
	float float
    returns float
    no_side_effects
    external float__rint


procedure round@float
    takes
	float float
    returns float
    no_side_effects
    external float__round


procedure save@float
    takes
	float float
	save save
	offset unsigned
    returns_nothing

    assert false
    # save[offset] := float@(save, float)


procedure sine@float
    takes
	angle float
    returns float
    no_side_effects
    external float__sine

    #: This procedure returns the sine of {angle}, where {angle}
    #, is measured in radians.


procedure square_root@float
    takes
	arg float
    returns float
    no_side_effects
    external float__square_root

    #: This procedure returns the square root of {arg}.


procedure string_convert@float
    takes
	arg float
    returns string

    #: This procedure will create and return {arg} after it has
    #, been converted to a signed decimal floating string.

    buffer :@= allocate@string()
    buffer_append@(arg, buffer)
    return buffer


procedure subtract@float
    takes
	left float
	right float
    returns float
    no_side_effects
    external float__subtract


procedure tangent@float
    takes
	angle float
    returns float
    no_side_effects
    external float__tangent

    #: This procedure returns the tangent of {angle}, where {angle}
    #, is measured in radians.


procedure write@float
    takes
	float float
	out_stream out_stream
    returns_nothing

    #: This procedure will output {float} to {out_stream} in form
    #, that can be read via {read}@{float}().

    float_write@out_stream(out_stream, float)


procedure unsigned_convert@float
    takes
	arg float
    returns unsigned
    no_side_effects
    external unsigned__float_convert


procedure float_convert@integer
    takes
	arg integer
    returns float
    no_side_effects
    external integer__float_convert


# {float16} routines:

procedure create@float16
    takes_nothing
    returns float16
    external float16__create

    #: This procedure will create and return an empty {float16} object.


procedure fetch1@float16
    takes
	float16 float16
	index unsigned
    returns float
    external float16__fetch1

    #: This procedure will return the {index}'th float from {float16}.


procedure store1@float16
    takes
	float16 float16
	index unsigned
	value float
    returns_nothing
    external float16__store1

    #: This procedure will store {value} into {index}'th float of {float16}.


procedure print@float16
    takes
	float16 float16
	out_stream out_stream
    returns_nothing

    #: This procedure will print {float16} to {out_stream}.

    prefix :@= "Float16("
    index :@= 0
    loop
	while index < 16
	put@(prefix, out_stream)
	print@(float16[index], out_stream)
	prefix := ", "
	index :+= 1
    put@(")", out_stream)


