github.com/jflude/taocp@v0.0.0-20240210234939-99f2a91af3c2/mixal/object.go (about)

     1  package mixal
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  
     7  	//"log"
     8  
     9  	"github.com/jflude/taocp/mix"
    10  )
    11  
    12  const wordsPerCard = 7
    13  
    14  type object struct {
    15  	start int
    16  	orig  []int
    17  	seg   [][]mix.Word
    18  }
    19  
    20  // see the answer to Ex. 26, Section 1.3.1
    21  var regularLoader = " O O6 Z O6    I C O4 0 EH A  F F CF 0  E   EU 0 IH G BB   EJ  CA. Z EU   EH E BA\n" +
    22  	"   EU 2A-H S BB  C U 1AEH 2AEN V  E  CLU  ABG Z EH E BB J B. A  9               \n"
    23  var interruptLoader = " O O6 Z O6    I C O4 0 EH A  F F CF 0  E   EU 0 IH G BB   EJ  CA. Z EU   EH E BA\n" +
    24  	"   EU 2A-H S BB  C U 1AEH 2AEN V  E  CLU  ABG Z EH E BB J B. A  9               \n" // TODO replace with a version that works
    25  var transfer = "TRANS0%04d                                                                      \n"
    26  
    27  func (o *object) findWord(address int) *mix.Word {
    28  	for i, orig := range o.orig {
    29  		if address >= orig && address < orig+len(o.seg[i]) {
    30  			return &o.seg[i][address-orig]
    31  		}
    32  	}
    33  	return nil
    34  }
    35  
    36  func (o *object) writeCards(w io.Writer, interrupts bool) error {
    37  	var loader = regularLoader
    38  	if interrupts {
    39  		loader = interruptLoader
    40  	}
    41  	if _, err := io.WriteString(w, loader); err != nil {
    42  		return err
    43  	}
    44  	for i := range o.orig {
    45  		if err := o.writeSeg(w, i); err != nil {
    46  			return err
    47  		}
    48  	}
    49  	_, err := io.WriteString(w, fmt.Sprintf(transfer, o.start))
    50  	return err
    51  }
    52  
    53  func (o *object) writeSeg(w io.Writer, n int) error {
    54  	orig := o.orig[n]
    55  	for i := 0; i < len(o.seg[n]); i += wordsPerCard {
    56  		c := len(o.seg[n]) - i
    57  		if c > wordsPerCard {
    58  			c = wordsPerCard
    59  		}
    60  		s := fmt.Sprintf("ABCDE%1d%04d", c, abs(orig))
    61  		if orig < 0 {
    62  			s = overPunchNegative(s)
    63  		}
    64  		if _, err := io.WriteString(w, s); err != nil {
    65  			return err
    66  		}
    67  		for j := 0; j < c; j++ {
    68  			v := o.seg[n][i+j]
    69  			//log.Printf("NewWord(%#o), // %5d:", v.Int(), orig+j)
    70  			s = fmt.Sprintf("%010d", abs(v.Int()))
    71  			if v.Sign() == -1 {
    72  				s = overPunchNegative(s)
    73  			}
    74  			if _, err := io.WriteString(w, s); err != nil {
    75  				return err
    76  			}
    77  		}
    78  		orig += c
    79  		for j := c; j < wordsPerCard; j++ {
    80  			_, err := io.WriteString(w, "          ")
    81  			if err != nil {
    82  				return err
    83  			}
    84  		}
    85  		if _, err := io.WriteString(w, "\n"); err != nil {
    86  			return err
    87  		}
    88  	}
    89  	return nil
    90  }
    91  
    92  func overPunchNegative(n string) string {
    93  	return n[:len(n)-1] + string(mix.OverPunch(rune(n[len(n)-1])))
    94  }