Push and Pop added
This commit is contained in:
		| @ -6,4 +6,5 @@ import ( | ||||
|  | ||||
| var ( | ||||
| 	ErrNothingToUnread = adverr.NewErrTmpl("ErrNothingToUnread", "Unreading failed because there wasn't any Read yet") | ||||
| 	ErrPopFailed       = adverr.NewErrTmpl("ErrPopFailed", "stack cannot be popped. It was never pushed") | ||||
| ) | ||||
|  | ||||
							
								
								
									
										3
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								go.mod
									
									
									
									
									
								
							| @ -5,4 +5,7 @@ go 1.19 | ||||
| require ( | ||||
| 	git.milar.in/milarin/adverr v1.1.0 | ||||
| 	git.milar.in/milarin/ds v0.0.2 | ||||
| 	git.milar.in/milarin/slices v0.0.8 | ||||
| ) | ||||
|  | ||||
| require git.milar.in/milarin/gmath v0.0.3 // indirect | ||||
|  | ||||
							
								
								
									
										8
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								go.sum
									
									
									
									
									
								
							| @ -1,8 +1,8 @@ | ||||
| git.milar.in/milarin/adverr v1.1.0 h1:jD9WnOvs40lfMhvqQ7cllOaRJNBMWr1f07/s9jAadp0= | ||||
| git.milar.in/milarin/adverr v1.1.0/go.mod h1:joU9sBb7ySyNv4SpTXB0Z4o1mjXsArBw4N27wjgzj9E= | ||||
| git.milar.in/milarin/ds v0.0.0-20230120204927-7dc44b9cd222 h1:r7gcMqltPqk9U2/+LzEN5dooZ5wiQ8C7SI/nK6T0KjA= | ||||
| git.milar.in/milarin/ds v0.0.0-20230120204927-7dc44b9cd222/go.mod h1:HJK7QERcRvV9j7xzEocrKUtW+1q4JB1Ly4Bj54chfwI= | ||||
| git.milar.in/milarin/ds v0.0.1 h1:ov4Rp+QiB3xtmV0a4eC+LluxWEOvbykgW+wCchYEp9o= | ||||
| git.milar.in/milarin/ds v0.0.1/go.mod h1:HJK7QERcRvV9j7xzEocrKUtW+1q4JB1Ly4Bj54chfwI= | ||||
| git.milar.in/milarin/ds v0.0.2 h1:vCA3mDxZUNfvHpzrdz7SeBUKiPn74NTopo915IUG7I0= | ||||
| git.milar.in/milarin/ds v0.0.2/go.mod h1:HJK7QERcRvV9j7xzEocrKUtW+1q4JB1Ly4Bj54chfwI= | ||||
| git.milar.in/milarin/gmath v0.0.3 h1:ii6rKNItS55O/wtIFhD1cTN2BMwDZjTBmiOocKURvxM= | ||||
| git.milar.in/milarin/gmath v0.0.3/go.mod h1:HDLftG5RLpiNGKiIWh+O2G1PYkNzyLDADO8Cd/1abiE= | ||||
| git.milar.in/milarin/slices v0.0.8 h1:qN9TE3tkArdTixMKSnwvNPcApwAjxpLVwA5a9k1rm2s= | ||||
| git.milar.in/milarin/slices v0.0.8/go.mod h1:qMhdtMnfWswc1rHpwgNw33lB84aNEkdBn5BDiYA+G3k= | ||||
|  | ||||
							
								
								
									
										52
									
								
								reader.go
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								reader.go
									
									
									
									
									
								
							| @ -6,10 +6,13 @@ import ( | ||||
| 	"strings" | ||||
|  | ||||
| 	"git.milar.in/milarin/ds" | ||||
| 	"git.milar.in/milarin/slices" | ||||
| ) | ||||
|  | ||||
| type Reader struct { | ||||
| 	buf     ds.Stack[posRune] | ||||
| 	indices ds.Stack[uint64] | ||||
| 	index   uint64 | ||||
| 	src     *bufio.Reader | ||||
| 	pos     *Position | ||||
| } | ||||
| @ -19,6 +22,8 @@ func New(r io.Reader) *Reader { | ||||
| 		buf:     ds.NewArrayStack[posRune](), | ||||
| 		src:     bufio.NewReader(r), | ||||
| 		pos:     &Position{Index: 0, Line: 1, Column: 1}, | ||||
| 		index:   0, | ||||
| 		indices: ds.NewArrayStack[uint64](), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -43,6 +48,7 @@ func (r *Reader) Rune() (rune, error) { | ||||
| 	if err == nil { | ||||
| 		r.buf.Push(r.psrn(rn)) | ||||
| 		r.pos.Advance(rn) | ||||
| 		r.index++ | ||||
| 	} | ||||
| 	return rn, err | ||||
| } | ||||
| @ -99,6 +105,8 @@ func (r *Reader) UnreadRune() error { | ||||
| 		r.src = prependRune(rn.Rune, r.src) | ||||
| 	} | ||||
|  | ||||
| 	r.index-- | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @ -250,8 +258,44 @@ func (r *Reader) ExpectOneOfString(str ...string) (string, bool, error) { | ||||
| 	return "", false, nil | ||||
| } | ||||
|  | ||||
| // Commit clears the internal buffer and therefore removes all data which were already read. | ||||
| // After calling Commit any unreads will return ErrNothingToUnread until another read occured. | ||||
| func (r *Reader) Commit() { | ||||
| 	r.buf.Clear() | ||||
| func (r *Reader) Push() { | ||||
| 	r.indices.Push(r.index) | ||||
| } | ||||
|  | ||||
| func (r *Reader) Pop() ([]rune, error) { | ||||
| 	if r.indices.Empty() { | ||||
| 		return nil, ErrPopFailed.New() | ||||
| 	} | ||||
|  | ||||
| 	lastIndex := r.indices.Pop() | ||||
| 	currentIndex := r.index | ||||
| 	if lastIndex < currentIndex { | ||||
| 		values := make([]rune, 0, int(currentIndex-lastIndex)) | ||||
| 		for i := 0; i < int(currentIndex-lastIndex); i++ { | ||||
| 			err := r.UnreadRune() | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
|  | ||||
| 			value, err := r.PeekRune() | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
|  | ||||
| 			values = append(values, value) | ||||
| 		} | ||||
| 		return slices.Reverse(values), nil | ||||
| 	} else if lastIndex > currentIndex { | ||||
| 		values := make([]rune, 0, int(lastIndex-currentIndex)) | ||||
| 		for i := 0; i < int(lastIndex-currentIndex); i++ { | ||||
| 			value, err := r.Rune() | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			values = append(values, value) | ||||
| 		} | ||||
| 		return values, nil | ||||
| 	} | ||||
|  | ||||
| 	return []rune{}, nil | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 milarin
					milarin