positions introduced
This commit is contained in:
		
							
								
								
									
										6
									
								
								pos_rune.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								pos_rune.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| package bufr | ||||
|  | ||||
| type posRune struct { | ||||
| 	Rune rune | ||||
| 	Pos  Position | ||||
| } | ||||
							
								
								
									
										17
									
								
								position.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								position.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| package bufr | ||||
|  | ||||
| type Position struct { | ||||
| 	Index  int | ||||
| 	Line   int | ||||
| 	Column int | ||||
| } | ||||
|  | ||||
| func (p *Position) Advance(rn rune) { | ||||
| 	p.Index++ | ||||
| 	if rn == '\n' { | ||||
| 		p.Line++ | ||||
| 		p.Column = 0 | ||||
| 	} else { | ||||
| 		p.Column++ | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										27
									
								
								reader.go
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								reader.go
									
									
									
									
									
								
							| @ -9,22 +9,36 @@ import ( | ||||
| ) | ||||
|  | ||||
| type Reader struct { | ||||
| 	buf *dstruct.Stack[rune] | ||||
| 	buf *dstruct.Stack[posRune] | ||||
| 	src *bufio.Reader | ||||
| 	pos *Position | ||||
| } | ||||
|  | ||||
| func NewReader(r io.Reader) *Reader { | ||||
| 	return &Reader{ | ||||
| 		buf: new(dstruct.Stack[rune]), | ||||
| 		buf: new(dstruct.Stack[posRune]), | ||||
| 		src: bufio.NewReader(r), | ||||
| 		pos: &Position{}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (r *Reader) psrn(rn rune) posRune { | ||||
| 	return posRune{ | ||||
| 		Rune: rn, | ||||
| 		Pos:  *r.pos, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (r *Reader) Pos() (index, line, column int) { | ||||
| 	return r.pos.Index, r.pos.Line, r.pos.Column | ||||
| } | ||||
|  | ||||
| // Rune returns the next rune in r | ||||
| func (r *Reader) Rune() (rune, error) { | ||||
| 	rn, _, err := r.src.ReadRune() | ||||
| 	if err == nil { | ||||
| 		r.buf.Push(rn) | ||||
| 		r.buf.Push(r.psrn(rn)) | ||||
| 		r.pos.Advance(rn) | ||||
| 	} | ||||
| 	return rn, err | ||||
| } | ||||
| @ -38,9 +52,12 @@ func (r *Reader) UnreadRune() error { | ||||
| 	} | ||||
|  | ||||
| 	if err := r.src.UnreadRune(); err == nil { | ||||
| 		r.buf.Pop() | ||||
| 		rn := r.buf.Pop() | ||||
| 		*r.pos = rn.Pos | ||||
| 	} else { | ||||
| 		r.src = prependRune(r.buf.Pop(), r.src) | ||||
| 		rn := r.buf.Pop() | ||||
| 		*r.pos = rn.Pos | ||||
| 		r.src = prependRune(rn.Rune, r.src) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
|  | ||||
							
								
								
									
										24
									
								
								reader_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								reader_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| package bufr | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| ) | ||||
|  | ||||
| func TestPos(t *testing.T) { | ||||
| 	r := NewReader(strings.NewReader("hello world\nsecond line")) | ||||
|  | ||||
| 	unread := false | ||||
| 	for rn, err := r.Rune(); err == nil; rn, err = r.Rune() { | ||||
| 		index, line, col := r.Pos() | ||||
| 		fmt.Println(string(rn), index, line, col) | ||||
|  | ||||
| 		if !unread && rn == '\n' { | ||||
| 			for i := 0; i < 5; i++ { | ||||
| 				r.UnreadRune() | ||||
| 			} | ||||
| 			unread = true | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Timon Ringwald
					Timon Ringwald