🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

1 total messages Started by Stephen Crawley Tue, 31 Jan 1989 10:00
Generalised integer unparse routine.
#31
Author: Stephen Crawley
Date: Tue, 31 Jan 1989 10:00
111 lines
3583 bytes
I found that I needed a routine for unparsing integers in hexadecimal with
leading zero padding.  The MIT libraries include a routine i_hunparse,
but it is too simple minded for the job in hand.  So I've written a routine
i_unparse() that solves the general problem.  

-- Steve

================
%% Unparse an integer into a string.
%%   'i' is the number to be unparsed.
%%   'base' is the base for the number which must be in the
%%       range 2 <= base <= 36.
%%   'width' is the minimum width for the result string.
%%   If 'zero_fill' is TRUE the result is padded with zeros to the left.
%%   If 'left_adjust' is TRUE the result is padded with spaces to the right.
%%   Otherwise the result is padded with spaces to the left hand.


i_unparse = PROC (i, base, width: int, zero_fill, left_adjust: bool) 
	    RETURNS (string) SIGNALS (bad_args)
  ac = array[char]
  OWN digits: string := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

  IF base <= 1 COR base > string$size(digits) COR 
     width < 0 COR width > 2**16 - 1 THEN
    SIGNAL bad_args
    END
  
  hi: int := width
  fill: char := ' '
  IF width = 0 THEN
      hi := 20
      left_adjust := FALSE
      zero_fill := FALSE
    ELSEIF zero_fill THEN
      fill := '0'
      left_adjust := FALSE
    END
  chars: ac := ac$fill(1, hi, fill)
  pos: int := hi
  IF i = 0 THEN
      chars[pos] := '0'
      pos := pos - 1
    ELSE
      negative: bool := i < 0
      IF negative THEN i := -i END
	EXCEPT WHEN overflow:
	  %% Phooey!!! MIN_INT can't be negated!
	  %% Do the 1st loop iteration by steam.
	  i := -(i + 1)
	  d: int := i // base + 1
	  i := i / base
	  IF d = base THEN
	    d := 0
	    i := i + 1
	    END
	  chars[pos] := digits[d + 1]
	  pos := pos - 1
          END

      %% Build the digits
      WHILE i > 0 DO
	digit: char := digits[i // base + 1]
	i := i / base
	IF pos > 0 THEN
            chars[pos] := digit
	  ELSE
            ac$addl(chars, digit)
	  END
        pos := pos - 1
        END

      %% Prepend the '-' sign before the 1st digit
      IF negative THEN
        IF pos <= 0 THEN
	    ac$addl(chars, '-')
	    pos := pos - 1
          ELSEIF zero_fill THEN
	    chars[1] := '-'
	    pos := 0
	  ELSE
	    chars[pos] := '-'
	    pos := pos - 1
	  END
	END 
    END

  %% Left adjust by shuffling the chars down and filling with ' 's
  IF left_adjust CAND pos > 0 THEN
    FOR j: int IN int$from_to(1, hi - pos) DO
      chars[j] := chars[j + pos]
      END
    FOR j: int IN int$from_to(hi - pos + 1, hi) DO
      chars[j] := ' '
      END
    END
  IF width = 0 CAND pos > 0 THEN ac$trim(chars, pos + 1, hi - pos) END
  RETURN (string$ac2s(chars))
  END i_unparse
================
%% Unparse an integer in hexadecimal

i_hunparse = PROC (i: int) RETURNS (string)
  RETURN (i_unparse(i, 16, 0, FALSE, FALSE))
  END i_hunparse
================
%% Unparse an integer in octal

i_ounparse = PROC (i: int) RETURNS (string)
  RETURN (i_unparse(i, 8, 0, FALSE, FALSE))
  END i_ounparse
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads