program realnums;

{$I ":Include/Math.i"}
{$I ":Include/MathTrans.i"}

var
   s : real;

{
	Eventually real numbers will be fully supported by PCQ, and
I'll need to write input/output routines for them.  These are an
interim solution.  The example just writes to stdout.  There are also
routines present that read from stdin and read and write from files.
Note that the read from stdin routine actually eats one character
that it shouldn't.  The read-from-file routine doesn't, since it can
access the buffered char.  Once I get these routines into the
lanugage there won't be this problem, of course.
	Be sure to read MathTrans.i before you use it.

	Later note: Real numbers are now integrated into the language,
but I left this in....for no reason whatsoever.
}

procedure writereal(r : real; i, f : short);

	{ sorry about the cryptic variable names.  'r' is the number
	  to write, 'i' is the field width to the left of the decimal
	  point (the integer part), and 'f' is the field width to the
	  right of the decimal point (fractional part).  Note that 'i'
	  is rudely ignored in this version, since field widths must
	  be constant expressions. }

var
    t : integer;
    exponent : integer;
    index : integer;
begin
    exponent := 0;
    if spcmp(r, spfloat(100000)) < 0 then begin
	while spcmp(r, spfloat(10)) < 0 do begin
	    exponent := exponent + 1;
	    r := spdiv(r, spfloat(10));
	end;
    end;
    if sptst(r) < 0 then begin
	r := spabs(r);
	write('-');
	if i > 1 then
	    i := i - 1;
    end;
    t := spfix(r);
    r := spsub(r, spfloat(t));
    write(t);
    if f > 0 then begin
	write('.');
	for index := 1 to f do begin
	    r := spmul(r, spfloat(10));
	    t := spfix(r);
	    r := spsub(r, spfloat(t));
	    write(chr(t + ord('0')));
	end;
    end;
    if exponent > 0 then
	write('+E', exponent);
end;

procedure writerealfile(var filevar : text; r : real; i, f : short);

   { read writefile() for an explanation of the variable names.  'i'
     is still ignored. }

var
    t : integer;
    exponent : integer;
    index : integer;
begin
    exponent := 0;
    if spcmp(r, spfloat(100000)) < 0 then begin
	while spcmp(r, spfloat(10)) < 0 do begin
	    exponent := exponent + 1;
	    r := spdiv(r, spfloat(10));
	end;
    end;
    if sptst(r) < 0 then begin
	r := spabs(r);
	write(filevar, '-');
	if i > 1 then
	    i := i - 1;
    end;
    t := spfix(r);
    r := spsub(r, spfloat(t));
    write(filevar, t);
    if f > 0 then begin
	write(filevar, '.');
	for index := 1 to f do begin
	    r := spmul(r, spfloat(10));
	    t := spfix(r);
	    r := spsub(r, spfloat(t));
	    write(filevar, chr(t + ord('0')));
	end;
    end;
    if exponent > 0 then
	write(filevar, '+E', exponent);
end;

procedure readreal(var r : real);
var
    t : integer;
    c : char;
    pow : real;
begin
    read(t);
    r := spfloat(t);
    read(c);
    if c = '.' then begin
	read(c);
	pow := spfloat(10);
	while (c >= '0') and (c <= '9') do begin
	    r := spadd(spdiv(spfloat(ord(c) - ord('0')), pow), r);
	    pow := spmul(pow, spfloat(10));
	    read(c);
	end;
    end;
end;

procedure readrealfile(var f : text; var r : real);
var
    t : integer;
    pow : real;
begin
    read(f, t);
    r := spfloat(t);
    if f^ = '.' then begin
	get(f);
	pow := spfloat(10);
	while (f^ >= '0') and (f^ <= '9') do begin
	    r := spadd(spdiv(spfloat(ord(f^) - ord('0')), pow), r);
	    pow := spmul(pow, spfloat(10));
	    get(f);
	end;
    end;
end;

begin
    if not OpenMathTrans() then begin
	writeln('Could not open disk-based MathTrans.library');
	exit(20);
    end;
    s := spfloat(0);
    writeln("radians\tsine\tcosine\tlog");
    while spcmp(s, spfloat(7)) > 0 do begin
	writereal(s, 1, 2);
	write(chr(9));
	writereal(spsin(s), 1, 4);
	write(chr(9));
	writereal(spcos(s), 1, 4);
	write(chr(9));
	if spcmp(s, spfloat(0)) = 0 then
	    write('Undefined')
	else
	    writereal(splog(s), 1, 4);
	writeln;
	s := spadd(s, spdiv(spfloat(1), spfloat(10)));
    end;
    FlushMathTrans;
end.
