pass-test-tokenize-all #1
| @ -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 | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user