// read a line from the readByter (only "\n" and "\r\n" are recognized as line endings) func newLine(rb readByter, num int) (l *line, err os.Error) { buf := new([256]byte) pos := 0 // read almost a full line into the buffer c, e := rb.ReadByte() for ; e == nil && c != '\n'; c, e = rb.ReadByte() { if !legalChar(c) { common.HandleFatal(fmt.Sprintf("Unable to handle non-ASCII character %d in line %d!", c, num)) } putChar(c, buf, pos, num) pos++ } // handle last character if e == os.EOF { putChar(common.EOF, buf, pos, num) } else if e != nil { return nil, e } else { putChar(c, buf, pos, num) } return &line{num, buf[0 : pos+1]}, nil }
func any2line(any interface{}) *line { line, ok := any.(*line) if !ok { common.HandleFatal("Internal error (not a line)!") } return line }
// read a new line and append it to the source buffer func (sb *SrcBuffer) readNewLine() { if sb.buf.Len() > MAX_BUFFER_LINES { sb.Error("Buffer overflow; please break up your code into smaller pieces"); } num := 0; if sb.curLine != nil { num = sb.curLine.num + 1; } line, err := newLine(sb.source, num); if err != nil { common.HandleFatal(fmt.Sprintf("While reading line %d: %v", num+1, err.String())); } sb.curLine = line; sb.curElem = sb.buf.PushBack(line); }
// Error - Handle errors by writing a description to STDERR and exiting. func (sb *SrcBuffer) Error(msg string) { common.HandleFatal( common.MakeErrString(msg, sb.curLine.num, sb.curLine.String(), sb.curCol, 1) ); }
func (piece *SrcPiece) Error(msg string) { common.HandleFatal(common.MakeErrString(msg, piece.StartLine(), piece.WholeLine(), piece.StartColumn(), len(piece.Content()) ) ); }
func putChar(c byte, buf []byte, pos int, num int) { if pos >= len(buf) { common.HandleFatal(fmt.Sprintf("Line %d is longer than %d bytes!", num, len(buf))) } buf[pos] = c }