diff --git a/lexer/numbers.go b/lexer/numbers.go index 3c7316c..2bfec05 100644 --- a/lexer/numbers.go +++ b/lexer/numbers.go @@ -4,21 +4,23 @@ import "github.com/sashakoshka/arf/file" // tokenizeSymbolBeginning lexes a token that starts with a number. func (lexer *LexingOperation) tokenizeNumberBeginning (negative bool) (err error) { - var number uint64 + var number uint64 + var fragment float64 + var isFloat bool if lexer.char == '0' { lexer.nextRune() if lexer.char == 'x' { lexer.nextRune() - number, err = lexer.tokenizeNumber(16) + number, fragment, isFloat, err = lexer.tokenizeNumber(16) } else if lexer.char == 'b' { lexer.nextRune() - number, err = lexer.tokenizeNumber(2) + number, fragment, isFloat, err = lexer.tokenizeNumber(2) } else if lexer.char == '.' { - number, err = lexer.tokenizeNumber(10) + number, fragment, isFloat, err = lexer.tokenizeNumber(10) } else if lexer.char >= '0' && lexer.char <= '9' { - number, err = lexer.tokenizeNumber(8) + number, fragment, isFloat, err = lexer.tokenizeNumber(8) } else { return file.NewError ( lexer.file.Location(), 1, @@ -26,19 +28,30 @@ func (lexer *LexingOperation) tokenizeNumberBeginning (negative bool) (err error file.ErrorKindError) } } else { - number, err = lexer.tokenizeNumber(10) + number, fragment, isFloat, err = lexer.tokenizeNumber(10) } if err != nil { return } token := Token { } - if negative { - token.kind = TokenKindInt - token.value = int64(number) * -1 + if isFloat { + floatNumber := float64(number) + fragment + + token.kind = TokenKindFloat + if negative { + token.value = floatNumber * -1 + } else { + token.value = floatNumber + } } else { - token.kind = TokenKindUInt - token.value = uint64(number) + if negative { + token.kind = TokenKindInt + token.value = int64(number) * -1 + } else { + token.kind = TokenKindUInt + token.value = uint64(number) + } } 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. -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 { digit, worked := runeToDigit(lexer.char, radix) if !worked { break } @@ -77,5 +97,25 @@ func (lexer *LexingOperation) tokenizeNumber (radix uint64) (number uint64, err err = lexer.nextRune() 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 }