mirror of
https://github.com/pocketpy/pocketpy
synced 2026-06-23 00:47:11 +08:00
Merge c18322444e7d046e1e97da3763201e45a472ab93 into d527b4dbc97235986f32accf34b246ec1a758dc2
This commit is contained in:
commit
99674dfeac
@ -7,6 +7,7 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
void c11_sbuf__ctor(c11_sbuf* self) {
|
void c11_sbuf__ctor(c11_sbuf* self) {
|
||||||
@ -53,21 +54,23 @@ void c11_sbuf__write_f64(c11_sbuf* self, double val, int precision) {
|
|||||||
char b[32];
|
char b[32];
|
||||||
int size;
|
int size;
|
||||||
if(precision < 0) {
|
if(precision < 0) {
|
||||||
int prec = 17 - 1; // std::numeric_limits<double>::max_digits10 == 17
|
size = snprintf(b, sizeof(b), "%.*g", 15, val);
|
||||||
size = snprintf(b, sizeof(b), "%.*g", prec, val);
|
if(strtod(b, NULL) != val) {
|
||||||
} else {
|
size = snprintf(b, sizeof(b), "%.*g", 17, val);
|
||||||
int prec = precision;
|
|
||||||
size = snprintf(b, sizeof(b), "%.*f", prec, val);
|
|
||||||
}
|
|
||||||
c11_sbuf__write_cstr(self, b);
|
|
||||||
bool all_is_digit = true;
|
|
||||||
for(int i = 1; i < size; i++) {
|
|
||||||
if(!isdigit(b[i])) {
|
|
||||||
all_is_digit = false;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
c11_sbuf__write_cstr(self, b);
|
||||||
|
bool all_is_digit = true;
|
||||||
|
for(int i = 1; i < size; i++) {
|
||||||
|
if(!isdigit(b[i])) {
|
||||||
|
all_is_digit = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(all_is_digit) c11_sbuf__write_cstr(self, ".0");
|
||||||
|
} else {
|
||||||
|
size = snprintf(b, sizeof(b), "%.*f", precision, val);
|
||||||
|
c11_sbuf__write_cstr(self, b);
|
||||||
}
|
}
|
||||||
if(all_is_digit) c11_sbuf__write_cstr(self, ".0");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void c11_sbuf__write_sv(c11_sbuf* self, c11_sv sv) {
|
void c11_sbuf__write_sv(c11_sbuf* self, c11_sv sv) {
|
||||||
|
|||||||
@ -37,16 +37,24 @@ static void Lexer__dtor(Lexer* self) {
|
|||||||
c11_vector__dtor(&self->indents);
|
c11_vector__dtor(&self->indents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* lexer_source_end(Lexer* self) {
|
||||||
|
return self->src->source->data + self->src->source->size;
|
||||||
|
}
|
||||||
|
|
||||||
static char eatchar(Lexer* self) {
|
static char eatchar(Lexer* self) {
|
||||||
|
const char* end = lexer_source_end(self);
|
||||||
|
if(self->curr_char > end) return '\0';
|
||||||
char c = *self->curr_char;
|
char c = *self->curr_char;
|
||||||
assert(c != '\n'); // eatchar() cannot consume a newline
|
assert(c != '\n'); // eatchar() cannot consume a newline
|
||||||
self->curr_char++;
|
self->curr_char = (self->curr_char < end) ? self->curr_char + 1 : end + 1;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char eatchar_include_newline(Lexer* self) {
|
static char eatchar_include_newline(Lexer* self) {
|
||||||
|
const char* end = lexer_source_end(self);
|
||||||
|
if(self->curr_char > end) return '\0';
|
||||||
char c = *self->curr_char;
|
char c = *self->curr_char;
|
||||||
self->curr_char++;
|
self->curr_char = (self->curr_char < end) ? self->curr_char + 1 : end + 1;
|
||||||
if(c == '\n') {
|
if(c == '\n') {
|
||||||
self->current_line++;
|
self->current_line++;
|
||||||
c11_vector__push(const char*, &self->src->line_starts, self->curr_char);
|
c11_vector__push(const char*, &self->src->line_starts, self->curr_char);
|
||||||
@ -189,7 +197,8 @@ static Error* LexerError(Lexer* self, const char* fmt, ...) {
|
|||||||
err->src = self->src;
|
err->src = self->src;
|
||||||
PK_INCREF(self->src);
|
PK_INCREF(self->src);
|
||||||
err->lineno = self->current_line;
|
err->lineno = self->current_line;
|
||||||
if(*self->curr_char == '\n') { err->lineno--; }
|
const char* end = lexer_source_end(self);
|
||||||
|
if(self->curr_char <= end && *self->curr_char == '\n') { err->lineno--; }
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
vsnprintf(err->msg, sizeof(err->msg), fmt, args);
|
vsnprintf(err->msg, sizeof(err->msg), fmt, args);
|
||||||
|
|||||||
@ -102,7 +102,7 @@ static bool json__write_namedict_kv(py_Name k, py_Ref v, void* ctx_) {
|
|||||||
static bool json__write_object(c11_sbuf* buf, py_TValue* obj, int indent, int depth) {
|
static bool json__write_object(c11_sbuf* buf, py_TValue* obj, int indent, int depth) {
|
||||||
switch(obj->type) {
|
switch(obj->type) {
|
||||||
case tp_NoneType: c11_sbuf__write_cstr(buf, "null"); return true;
|
case tp_NoneType: c11_sbuf__write_cstr(buf, "null"); return true;
|
||||||
case tp_int: c11_sbuf__write_int(buf, obj->_i64); return true;
|
case tp_int: c11_sbuf__write_i64(buf, obj->_i64); return true;
|
||||||
case tp_float: {
|
case tp_float: {
|
||||||
if(dmath_isnan(obj->_f64)) {
|
if(dmath_isnan(obj->_f64)) {
|
||||||
c11_sbuf__write_cstr(buf, "NaN");
|
c11_sbuf__write_cstr(buf, "NaN");
|
||||||
|
|||||||
@ -384,7 +384,10 @@ static bool list_insert(int argc, py_Ref argv) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lt_with_key(py_TValue* a, py_TValue* b, py_TValue* key) {
|
static int lt_with_key(const void* a_, const void* b_, void* extra) {
|
||||||
|
py_TValue* a = (py_TValue*)a_;
|
||||||
|
py_TValue* b = (py_TValue*)b_;
|
||||||
|
py_TValue* key = (py_TValue*)extra;
|
||||||
if(!key) return py_less(a, b);
|
if(!key) return py_less(a, b);
|
||||||
VM* vm = pk_current_vm;
|
VM* vm = pk_current_vm;
|
||||||
// project a
|
// project a
|
||||||
@ -416,7 +419,7 @@ static bool list_sort(int argc, py_Ref argv) {
|
|||||||
bool ok = c11__stable_sort(self->data,
|
bool ok = c11__stable_sort(self->data,
|
||||||
self->length,
|
self->length,
|
||||||
sizeof(py_TValue),
|
sizeof(py_TValue),
|
||||||
(int (*)(const void*, const void*, void*))lt_with_key,
|
lt_with_key,
|
||||||
key);
|
key);
|
||||||
if(!ok) return false;
|
if(!ok) return false;
|
||||||
|
|
||||||
|
|||||||
@ -64,6 +64,7 @@ assert f'{a:010f}' == '010.000000'
|
|||||||
assert f'{a:010.2f}' == '0000010.00'
|
assert f'{a:010.2f}' == '0000010.00'
|
||||||
assert f'{a:.2f}' == '10.00'
|
assert f'{a:.2f}' == '10.00'
|
||||||
assert f'{a:.5f}' == '10.00000'
|
assert f'{a:.5f}' == '10.00000'
|
||||||
|
assert f'{2.5:.0f}' == '2'
|
||||||
|
|
||||||
b = '123'
|
b = '123'
|
||||||
assert f'{b:10}' == '123 '
|
assert f'{b:10}' == '123 '
|
||||||
|
|||||||
@ -75,4 +75,11 @@ assert res == [42, 42]
|
|||||||
assert x == 33
|
assert x == 33
|
||||||
|
|
||||||
# test removing trailing newlines
|
# test removing trailing newlines
|
||||||
assert eval('[1, 2, 3]\n \n') == [1, 2, 3]
|
assert eval('[1, 2, 3]\n \n') == [1, 2, 3]
|
||||||
|
|
||||||
|
# lexer doesn't read past NUL on error at end of input
|
||||||
|
try:
|
||||||
|
eval('"\\x4')
|
||||||
|
exit(1)
|
||||||
|
except SyntaxError:
|
||||||
|
pass
|
||||||
@ -48,6 +48,9 @@ _j = json.dumps(c)
|
|||||||
_c = json.loads(_j)
|
_c = json.loads(_j)
|
||||||
assert c == _c
|
assert c == _c
|
||||||
|
|
||||||
|
assert json.dumps(9223372036854775807) == '9223372036854775807'
|
||||||
|
assert json.loads(json.dumps(0.1 + 0.2)) == 0.1 + 0.2
|
||||||
|
|
||||||
d = True
|
d = True
|
||||||
_j = json.dumps(d)
|
_j = json.dumps(d)
|
||||||
_d = json.loads(_j)
|
_d = json.loads(_j)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user