Skip to content

Commit d45a7f8

Browse files
committed
feat: ad support for error value
1 parent be18410 commit d45a7f8

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed

ast.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const (
2828
Number
2929
String
3030
BoolLiteral // TRUE or FALSE
31+
EValue // Error value (e.g., #DIV/0!, #VALUE!, etc)
3132
Exclamation // !
3233
BraceOpen // {
3334
BraceClose // }

lexer.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ func (l *lexer) next() (*Token, error) {
116116
default:
117117
return newToken(start, l.pos, GreaterThan, ">"), nil
118118
}
119+
case '#':
120+
return l.errValue()
119121
default:
120122
if isDigit(l.ch) {
121123
return l.number()
@@ -150,6 +152,12 @@ func (l *lexer) nextch() {
150152
}
151153
}
152154

155+
func (l *lexer) eat(n int) {
156+
for i := 0; i < n; i++ {
157+
l.nextch()
158+
}
159+
}
160+
153161
func (l *lexer) absoluteReference() (*Token, error) {
154162
var start = l.pos
155163
var startOffset = l.offset - 1 // Start at the current character
@@ -205,6 +213,33 @@ func (l *lexer) absoluteReference() (*Token, error) {
205213
return nil, newLexError(l.pos, "invalid absolute reference after '$'")
206214
}
207215

216+
func (l *lexer) errValue() (*Token, error) {
217+
var values = []string{
218+
"#NULL!",
219+
"#DIV/0!",
220+
"#VALUE!",
221+
"#REF!",
222+
"#NAME?",
223+
"#NUM!",
224+
"#N/A",
225+
}
226+
for _, value := range values {
227+
// check length
228+
if l.offset-1+len(value) > len(l.src) {
229+
continue // Not enough characters left for this error value
230+
}
231+
if string(l.src[l.offset-1:l.offset-1+len(value)]) == value {
232+
var start = l.pos
233+
l.eat(len(value) - 1) // Consume the error value
234+
var end = l.pos
235+
l.offset += len(value) - 1 // Adjust offset to skip the error value
236+
l.ch = l.peekChar() // Update current character
237+
return newToken(start, end, EValue, value), nil
238+
}
239+
}
240+
return nil, newLexError(l.pos, "unrecognized error value")
241+
}
242+
208243
func (l *lexer) stringLiteral(quote rune) (*Token, error) {
209244
var start = l.pos
210245
var end = start

lexer_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ func TestLexer(t *testing.T) {
1010
src string
1111
expected TokenType
1212
}{
13+
{"#DIV/0!", EValue},
14+
{"#VALUE!", EValue},
15+
{"#N/A", EValue},
1316
{"A$123", Cell},
1417
{"$A$1", Cell},
1518
{"A1", Cell},

0 commit comments

Comments
 (0)