Broken site based impl
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
// The number natives: conversions between numbers and strings
|
||||
#pragma once
|
||||
|
||||
#include "str.h"
|
||||
|
||||
#ifdef JSRT_IMPLEMENTATION
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// JS's Number::toString: the fewest digits that give the number back. Plain
|
||||
// notation while the decimal point is within 21 places, else exponential
|
||||
string_t __native_number_to_string(double x) {
|
||||
if (isnan(x)) return jsrt_string_lit("NaN");
|
||||
if (isinf(x)) return jsrt_string_lit(x < 0 ? "-Infinity" : "Infinity");
|
||||
if (x == 0) return jsrt_string_lit("0");
|
||||
|
||||
// The fewest digits: buf is [-]d[.ddd]e±xx
|
||||
char buf[64];
|
||||
|
||||
for (int precision = 0; precision < 17; precision++) {
|
||||
snprintf(buf, sizeof buf, "%.*e", precision, x);
|
||||
|
||||
if (strtod(buf, NULL) == x) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char digits[32], out[64];
|
||||
char *p = buf, *o = out;
|
||||
int n = 0;
|
||||
|
||||
if (*p == '-') {
|
||||
*o++ = *p++;
|
||||
}
|
||||
|
||||
for (; *p != 'e'; p++) {
|
||||
if (*p != '.') {
|
||||
digits[n++] = *p;
|
||||
}
|
||||
}
|
||||
|
||||
digits[n] = 0;
|
||||
|
||||
// The decimal point goes after the first `point` digits
|
||||
int point = atoi(p + 1) + 1;
|
||||
|
||||
if (n <= point && point <= 21) {
|
||||
o += sprintf(o, "%s", digits);
|
||||
for (int i = n; i < point; i++) *o++ = '0';
|
||||
*o = 0;
|
||||
} else if (0 < point && point <= 21) {
|
||||
sprintf(o, "%.*s.%s", point, digits, digits + point);
|
||||
} else if (-6 < point && point <= 0) {
|
||||
o += sprintf(o, "0.");
|
||||
for (int i = point; i < 0; i++) *o++ = '0';
|
||||
sprintf(o, "%s", digits);
|
||||
} else {
|
||||
int e = point - 1;
|
||||
sprintf(o, "%c%s%se%c%d", digits[0], n > 1 ? "." : "", digits + 1, e < 0 ? '-' : '+', abs(e));
|
||||
}
|
||||
|
||||
return jsrt_string_lit(out);
|
||||
}
|
||||
|
||||
string_t __native_number_to_fixed(double x, int32_t digits) {
|
||||
char buf[400];
|
||||
snprintf(buf, sizeof buf, "%.*f", digits, x);
|
||||
return jsrt_string_lit(buf);
|
||||
}
|
||||
|
||||
// JS's ToNumber on a string: a decimal number with whitespace around it, or
|
||||
// only whitespace, which is 0. Anything else is NaN
|
||||
double __native_string_to_number(string_t s) {
|
||||
char *utf8 = jsrt_string_utf8(s);
|
||||
char *start = utf8, *end;
|
||||
|
||||
while (*start == ' ' || (*start >= '\t' && *start <= '\r')) start++;
|
||||
|
||||
double x = 0;
|
||||
|
||||
if (*start) {
|
||||
x = strtod(start, &end);
|
||||
while (*end == ' ' || (*end >= '\t' && *end <= '\r')) end++;
|
||||
if (*end || start == end) x = NAN;
|
||||
}
|
||||
|
||||
free(utf8);
|
||||
return x;
|
||||
}
|
||||
|
||||
#endif // JSRT_IMPLEMENTATION
|
||||
Reference in New Issue
Block a user