feat: implement floating-point number literal parsing and arithmetic operations
Add support for floating-point number literals in the parser by detecting decimal points with trailing digits in `readNumber()`, and switch the compiler's `number()` function from `strtol` to `strtod` for proper double conversion. Update the `num_abs` primitive to use `fabs()` instead of manual negation. Extend test coverage across arithmetic, comparison, equality, modulus, and string conversion tests with floating-point cases, and add a new test for decimal point at end-of-file error detection.
This commit is contained in:
+18
-2
@@ -179,6 +179,14 @@ static char peekChar(Parser* parser)
|
||||
return parser->source[parser->currentChar];
|
||||
}
|
||||
|
||||
// Returns the character after the current character.
|
||||
static char peekNextChar(Parser* parser)
|
||||
{
|
||||
// If we're at the end of the source, don't read past it.
|
||||
if (peekChar(parser) == '\0') return '\0';
|
||||
return parser->source[parser->currentChar + 1];
|
||||
}
|
||||
|
||||
// Advances the parser forward one character.
|
||||
static char nextChar(Parser* parser)
|
||||
{
|
||||
@@ -227,6 +235,14 @@ static void readNumber(Parser* parser)
|
||||
// TODO(bob): Floating point, hex, scientific, etc.
|
||||
while (isDigit(peekChar(parser))) nextChar(parser);
|
||||
|
||||
// See if it has a floating point. Make sure there is a digit after the "."
|
||||
// so we don't get confused by method calls on number literals.
|
||||
if (peekChar(parser) == '.' && isDigit(peekNextChar(parser)))
|
||||
{
|
||||
nextChar(parser);
|
||||
while (isDigit(peekChar(parser))) nextChar(parser);
|
||||
}
|
||||
|
||||
makeToken(parser, TOKEN_NUMBER);
|
||||
}
|
||||
|
||||
@@ -696,8 +712,8 @@ static void number(Compiler* compiler)
|
||||
{
|
||||
Token* token = &compiler->parser->previous;
|
||||
char* end;
|
||||
// TODO(bob): Parse actual double!
|
||||
long value = strtol(compiler->parser->source + token->start, &end, 10);
|
||||
|
||||
double value = strtod(compiler->parser->source + token->start, &end);
|
||||
// TODO(bob): Check errno == ERANGE here.
|
||||
if (end == compiler->parser->source + token->start)
|
||||
{
|
||||
|
||||
+1
-4
@@ -77,10 +77,7 @@ DEF_PRIMITIVE(fn_bangeq)
|
||||
|
||||
DEF_PRIMITIVE(num_abs)
|
||||
{
|
||||
double value = AS_NUM(args[0]);
|
||||
if (value < 0) value = -value;
|
||||
|
||||
return (Value)makeNum(value);
|
||||
return (Value)makeNum(fabs(AS_NUM(args[0])));
|
||||
}
|
||||
|
||||
DEF_PRIMITIVE(num_toString)
|
||||
|
||||
Reference in New Issue
Block a user