!      Programmer: Chris Dilbeck
!      Course: CS 430
!      Date Due: 9/12/07
!      Language: FORTRAN
!      Compiler: FORCE 2.0
!      Source: PA2P1.f
!      Exe: PA2P1.exe
!      Professor: Dr. Adams

!      Purpose: To convert integers between 1 and 32767 into their
!      binary representation.

!      Input: An integer equal to or between 1 and 32767.

!      Output: A labelled echo of the input and a labelled echo of the
!      binary representation of the input.

!      Comments: This program required some fighting with strings to
!      get the binary string to concatenate correctly. It is much
!      easier to do that in later languages.

!      Syntax: CHARACTER NAME * X means to declare a string NAME
!      with X characters in it.

!      .LT. means < and .GT. means >

!      GOTO X sends the program execution to the given label X

!      .OR. is the boolean or operator

!      .EQ. is an equality comparison operator.

!      STRING(X:Y) is a substring notation. It means only reference the
!      locations in the string up to and including the locations X and Y
!      starting at 1, NOT ZERO, like Java or C++.

!      ** is the exponentation operator.

!      IF (CONDITION) THEN
!      EXPRESSIONS
!      ENDIF is a block conditional.

!      // means concatentation of strings

!-----------------------------------------------------------------------

       CHARACTER BINARY * 16
       CHARACTER ONE*1
       CHARACTER ZERO*1
       
       ONE = '1'
       ZERO = '0'
       BINARY = ' '
       LENBINARY = 1

  20   INPUT = 0
       INITIALPOWER = 15
       
!      Tracks if a one has already been output. Program should not
!      output a zero until a one has already been output to avoid
!      a number being represented as 00000010101 or something similar.
       ISAONE = 0

       CALL PRINTLN('Enter an integer equal to or between 1 and 32767')

       READ(5,10) INPUT
  10   FORMAT(I5)
  
!      Check for bad values
       IF (INPUT .LT. 1 .OR. INPUT .GT. 32767) GOTO 20
  
  
       CALL PRINTLN('Input was:')

       WRITE(6, 21) INPUT
  21   FORMAT(1X, I5)
  
       DO 11 I = INITIALPOWER, 0, -1
       
!      The value of the current slot
       INTSLOTVALUE = 2 ** I

!      Multi-line IF adapted from
!      http://www.nsc.liu.se/~boein/f77to90/a2.html
       IF (INPUT .LT. INTSLOTVALUE) THEN

!      Only output a zero if there's already a one in the string.
       IF (ISAONE .EQ. 1) THEN

!      Sub-string notation adapted from
!      http://www.ibiblio.org/pub/languages/fortran/ch2-13.html

!      BINARY(1:LENBINARY + 1) means to replace the area between and
!      including 1 and the position in the string after the last
!      actual digit, which is what LENBINARY tracks.

       BINARY(1:LENBINARY + 1) = BINARY(1:LENBINARY) // ZERO
       LENBINARY = LENBINARY + 1

       ENDIF
       
       ENDIF
       
!      If you can subtract the slotvalue from the input, output a one
!      and subtrach the slotvalue.
       IF (INPUT .GE. INTSLOTVALUE) THEN
       
       INPUT = INPUT - INTSLOTVALUE
       
       BINARY(1:LENBINARY + 1) = BINARY(1:LENBINARY) // ONE
       
       LENBINARY = LENBINARY + 1
       
       ISAONE = 1
       
       ENDIF
       
  11   CONTINUE
  
       CALL BLANKLINE
       CALL PRINTLN('Binary representation:')
       CALL PRINTLN(BINARY)
  
       STOP
       END
       

       
!      Advances the screen one line
       SUBROUTINE BLANKLINE
       CHARACTER LN
       LN = ' '
       WRITE(6, 29) LN
  29   FORMAT(1X, A)
       RETURN
       END

!      Prints a string
       SUBROUTINE PRINTLN(LN)
       CHARACTER(*) LN
       WRITE(6,30) LN
  30   FORMAT(1X, A)
       RETURN
       END
