Added float support

This commit is contained in:
Sasha Koshka 2022-08-11 02:17:35 -05:00
parent 40ad569870
commit 3768e3454f
1 changed files with 52 additions and 12 deletions

View File

@ -4,21 +4,23 @@ import "github.com/sashakoshka/arf/file"
// tokenizeSymbolBeginning lexes a token that starts with a number. // tokenizeSymbolBeginning lexes a token that starts with a number.
func (lexer *LexingOperation) tokenizeNumberBeginning (negative bool) (err error) { func (lexer *LexingOperation) tokenizeNumberBeginning (negative bool) (err error) {
var number uint64 var number uint64
var fragment float64
var isFloat bool
if lexer.char == '0' { if lexer.char == '0' {
lexer.nextRune() lexer.nextRune()
if lexer.char == 'x' { if lexer.char == 'x' {
lexer.nextRune() lexer.nextRune()
number, err = lexer.tokenizeNumber(16) number, fragment, isFloat, err = lexer.tokenizeNumber(16)
} else if lexer.char == 'b' { } else if lexer.char == 'b' {
lexer.nextRune() lexer.nextRune()
number, err = lexer.tokenizeNumber(2) number, fragment, isFloat, err = lexer.tokenizeNumber(2)
} else if lexer.char == '.' { } else if lexer.char == '.' {
number, err = lexer.tokenizeNumber(10) number, fragment, isFloat, err = lexer.tokenizeNumber(10)
} else if lexer.char >= '0' && lexer.char <= '9' { } else if lexer.char >= '0' && lexer.char <= '9' {
number, err = lexer.tokenizeNumber(8) number, fragment, isFloat, err = lexer.tokenizeNumber(8)
} else { } else {
return file.NewError ( return file.NewError (
lexer.file.Location(), 1, lexer.file.Location(), 1,
@ -26,19 +28,30 @@ func (lexer *LexingOperation) tokenizeNumberBeginning (negative bool) (err error
file.ErrorKindError) file.ErrorKindError)
} }
} else { } else {
number, err = lexer.tokenizeNumber(10) number, fragment, isFloat, err = lexer.tokenizeNumber(10)
} }
if err != nil { return } if err != nil { return }
token := Token { } token := Token { }
if negative { if isFloat {
token.kind = TokenKindInt floatNumber := float64(number) + fragment
token.value = int64(number) * -1
token.kind = TokenKindFloat
if negative {
token.value = floatNumber * -1
} else {
token.value = floatNumber
}
} else { } else {
token.kind = TokenKindUInt if negative {
token.value = uint64(number) token.kind = TokenKindInt
token.value = int64(number) * -1
} else {
token.kind = TokenKindUInt
token.value = uint64(number)
}
} }
lexer.addToken(token) lexer.addToken(token)
@ -66,7 +79,14 @@ func runeToDigit (char rune, radix uint64) (digit uint64, worked bool) {
} }
// tokenizeNumber reads and tokenizes a number with the specified radix. // tokenizeNumber reads and tokenizes a number with the specified radix.
func (lexer *LexingOperation) tokenizeNumber (radix uint64) (number uint64, err error) { func (lexer *LexingOperation) tokenizeNumber (
radix uint64,
) (
number uint64,
fragment float64,
isFloat bool,
err error,
) {
for { for {
digit, worked := runeToDigit(lexer.char, radix) digit, worked := runeToDigit(lexer.char, radix)
if !worked { break } if !worked { break }
@ -77,5 +97,25 @@ func (lexer *LexingOperation) tokenizeNumber (radix uint64) (number uint64, err
err = lexer.nextRune() err = lexer.nextRune()
if err != nil { return } if err != nil { return }
} }
if lexer.char == '.' {
isFloat = true
err = lexer.nextRune()
if err != nil { return }
coef := 1 / float64(radix)
for {
digit, worked := runeToDigit(lexer.char, radix)
if !worked { break }
fragment += float64(digit) * coef
coef /= float64(radix)
err = lexer.nextRune()
if err != nil { return }
}
}
return return
} }