mirror of
https://github.com/pocketpy/pocketpy
synced 2026-06-20 23:47:10 +08:00
Compare commits
4 Commits
cee3228c61
...
99674dfeac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99674dfeac | ||
|
|
c18322444e | ||
|
|
db8d52cab0 | ||
|
|
d527b4dbc9 |
@ -56,8 +56,10 @@ static bool mpack_to_py(mpack_node_t node) {
|
||||
for(size_t i = 0; i < count; i++) {
|
||||
mpack_node_t key_node = mpack_node_map_key_at(node, i);
|
||||
mpack_node_t val_node = mpack_node_map_value_at(node, i);
|
||||
if(mpack_node_type(key_node) != mpack_type_str) {
|
||||
return TypeError("msgpack: key must be strings");
|
||||
mpack_type_t key_type = mpack_node_type(key_node);
|
||||
if(key_type != mpack_type_str && key_type != mpack_type_int &&
|
||||
key_type != mpack_type_uint) {
|
||||
return TypeError("msgpack: key must be string or integer");
|
||||
}
|
||||
if(!mpack_to_py(key_node)) return false;
|
||||
if(!mpack_to_py(val_node)) return false;
|
||||
@ -101,9 +103,14 @@ static bool py_to_mpack(py_Ref object, mpack_writer_t* writer);
|
||||
|
||||
static bool mpack_write_dict_kv(py_Ref k, py_Ref v, void* ctx) {
|
||||
mpack_writer_t* writer = ctx;
|
||||
if(k->type != tp_str) return TypeError("msgpack: key must be strings");
|
||||
c11_sv sv = py_tosv(k);
|
||||
mpack_write_str(writer, sv.data, (size_t)sv.size);
|
||||
if(k->type == tp_str) {
|
||||
c11_sv sv = py_tosv(k);
|
||||
mpack_write_str(writer, sv.data, (size_t)sv.size);
|
||||
} else if(k->type == tp_int) {
|
||||
mpack_write_int(writer, py_toint(k));
|
||||
} else {
|
||||
return TypeError("msgpack: key must be string or integer");
|
||||
}
|
||||
bool ok = py_to_mpack(v, writer);
|
||||
if(!ok) mpack_write_nil(writer);
|
||||
return ok;
|
||||
@ -160,7 +167,10 @@ static bool msgpack_dumps(int argc, py_Ref argv) {
|
||||
mpack_writer_init_growable(&writer, &data, &size);
|
||||
bool ok = py_to_mpack(argv, &writer);
|
||||
if(mpack_writer_destroy(&writer) != mpack_ok) { assert(false); }
|
||||
if(!ok) return false;
|
||||
if(!ok) {
|
||||
MPACK_FREE(data);
|
||||
return false;
|
||||
}
|
||||
assert(size <= INT32_MAX);
|
||||
unsigned char* byte_data = py_newbytes(py_retval(), (int)size);
|
||||
memcpy(byte_data, data, size);
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
void c11_sbuf__ctor(c11_sbuf* self) {
|
||||
@ -53,11 +54,14 @@ void c11_sbuf__write_f64(c11_sbuf* self, double val, int precision) {
|
||||
char b[32];
|
||||
int size;
|
||||
if(precision < 0) {
|
||||
size = snprintf(b, sizeof(b), "%.17g", val);
|
||||
size = snprintf(b, sizeof(b), "%.*g", 15, val);
|
||||
if(strtod(b, NULL) != val) {
|
||||
size = snprintf(b, sizeof(b), "%.*g", 17, val);
|
||||
}
|
||||
c11_sbuf__write_cstr(self, b);
|
||||
bool all_is_digit = true;
|
||||
for(int i = 1; i < size; i++) {
|
||||
if(!isdigit((unsigned char)b[i])) {
|
||||
if(!isdigit(b[i])) {
|
||||
all_is_digit = false;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -37,16 +37,24 @@ static void Lexer__dtor(Lexer* self) {
|
||||
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) {
|
||||
const char* end = lexer_source_end(self);
|
||||
if(self->curr_char > end) return '\0';
|
||||
char c = *self->curr_char;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
self->curr_char++;
|
||||
self->curr_char = (self->curr_char < end) ? self->curr_char + 1 : end + 1;
|
||||
if(c == '\n') {
|
||||
self->current_line++;
|
||||
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;
|
||||
PK_INCREF(self->src);
|
||||
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_start(args, fmt);
|
||||
vsnprintf(err->msg, sizeof(err->msg), fmt, args);
|
||||
|
||||
@ -384,7 +384,10 @@ static bool list_insert(int argc, py_Ref argv) {
|
||||
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);
|
||||
VM* vm = pk_current_vm;
|
||||
// project a
|
||||
@ -416,7 +419,7 @@ static bool list_sort(int argc, py_Ref argv) {
|
||||
bool ok = c11__stable_sort(self->data,
|
||||
self->length,
|
||||
sizeof(py_TValue),
|
||||
(int (*)(const void*, const void*, void*))lt_with_key,
|
||||
lt_with_key,
|
||||
key);
|
||||
if(!ok) return false;
|
||||
|
||||
|
||||
@ -75,4 +75,11 @@ assert res == [42, 42]
|
||||
assert x == 33
|
||||
|
||||
# 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
|
||||
Loading…
x
Reference in New Issue
Block a user