1
0
mirror of https://github.com/janet-lang/janet synced 2025-10-20 10:17:40 +00:00

Add 64 bit signed integers as a basic type. Will enable

more native bitwise operations and c integration at the expense
of complicating arithmetic.
This commit is contained in:
Calvin Rose
2017-04-24 16:02:54 -04:00
parent 81987dca45
commit a54548eaa0
10 changed files with 299 additions and 413 deletions

View File

@@ -50,6 +50,7 @@
* Byte 215: LUdata - [value meta][u32 length]*[u8... bytes]
* Byte 216: CFunc - [u32 length]*[u8... idstring]
* Byte 217: Ref - [u32 id]
* Byte 218: Integer - [i64 value]
*/
/* Error at buffer end */
@@ -76,7 +77,7 @@ static uint16_t bytes2u16(const uint8_t *bytes) {
}
/* Read 8 bytes as a double */
static uint32_t bytes2dbl(const uint8_t *bytes) {
static double bytes2dbl(const uint8_t *bytes) {
union {
uint8_t bytes[8];
double dbl;
@@ -85,6 +86,16 @@ static uint32_t bytes2dbl(const uint8_t *bytes) {
return u.dbl;
}
/* Read 8 bytes as a integer */
static int64_t bytes2int(const uint8_t *bytes) {
union {
uint8_t bytes[8];
int64_t i;
} u;
gst_memcpy(u.bytes, bytes, 8 * sizeof(uint8_t));
return u.i;
}
/* Read a string and turn it into a gst value. Returns
* an error message if there is an error message during
* deserialization. If successful, the resulting value is
@@ -116,14 +127,15 @@ static const char *gst_deserialize_impl(
#define read_u32(out) do{deser_datacheck(4); (out)=bytes2u32(data); data += 4; }while(0)
#define read_u16(out) do{deser_datacheck(2); (out)=bytes2u16(data); data += 2; }while(0)
#define read_dbl(out) do{deser_datacheck(8); (out)=bytes2dbl(data); data += 8; }while(0)
#define read_i64(out) do{deser_datacheck(8); (out)=bytes2int(data); data += 8; }while(0)
/* Check enough buffer left to read one byte */
if (data >= end) deser_error(UEB);
/* Small integer */
if (*data < 201) {
ret.type = GST_NUMBER;
ret.data.number = *data - 100;
ret.type = GST_INTEGER;
ret.data.integer = *data - 100;
*newData = data + 1;
*out = ret;
return NULL;
@@ -150,8 +162,8 @@ static const char *gst_deserialize_impl(
break;
case 204: /* Long number (double) */
ret.type = GST_NUMBER;
read_dbl(ret.data.number);
ret.type = GST_REAL;
read_dbl(ret.data.real);
break;
case 205: /* String */
@@ -410,6 +422,11 @@ static const char *gst_deserialize_impl(
deser_assert(visited->count > length, "invalid reference");
ret = visited->data[length];
break;
case 218: /* Integer */
ret.type = GST_INTEGER;
read_i64(ret.data.integer);
break;
}
/* Handle a successful return */
@@ -435,8 +452,8 @@ const char *gst_deserialize(
}
/* Allow appending other types to buffers */
BUFFER_DEFINE(number, GstNumber)
/*BUFFER_DEFINE(u16, uint16_t)*/
BUFFER_DEFINE(real, GstReal)
BUFFER_DEFINE(integer, GstInteger)
BUFFER_DEFINE(u32, uint32_t)
/* Serialize a value and write to a buffer. Returns possible
@@ -455,7 +472,8 @@ const char *gst_serialize_impl(
#define write_byte(b) gst_buffer_push(vm, buffer, (b))
#define write_u32(b) gst_buffer_push_u32(vm, buffer, (b))
#define write_u16(b) gst_buffer_push_u16(vm, buffer, (b))
#define write_dbl(b) gst_buffer_push_number(vm, buffer, (b))
#define write_dbl(b) gst_buffer_push_real(vm, buffer, (b))
#define write_int(b) gst_buffer_push_integer(vm, buffer, (b))
/* Check non reference types - if successful, return NULL */
switch (x.type) {
@@ -465,17 +483,16 @@ const char *gst_serialize_impl(
case GST_BOOLEAN:
write_byte(x.data.boolean ? 202 : 203);
return NULL;
case GST_NUMBER:
{
GstNumber number = x.data.number;
int32_t int32Num = (int32_t) number;
if (number == (GstNumber) int32Num &&
int32Num <= 100 && int32Num >= -100) {
write_byte(int32Num + 100);
} else {
write_byte(204);
write_dbl(number);
}
case GST_REAL:
write_byte(204);
write_dbl(x.data.real);
return NULL;
case GST_INTEGER:
if (x.data.integer <= 100 && x.data.integer >= -100) {
write_byte(x.data.integer + 100);
} else {
write_byte(218);
write_int(x.data.integer);
}
return NULL;
case GST_CFUNCTION:
@@ -487,9 +504,9 @@ const char *gst_serialize_impl(
/* Check if already seen - if so, use reference */
check = gst_object_get(visited, x);
if (check.type == GST_NUMBER) {
if (check.type == GST_INTEGER) {
write_byte(217);
write_u32((uint32_t) check.data.number);
write_u32((uint32_t) check.data.integer);
return NULL;
}
@@ -549,8 +566,8 @@ const char *gst_serialize_impl(
}
/* Record reference */
check.type = GST_NUMBER;
check.data.number = *nextId++;
check.type = GST_INTEGER;
check.data.integer = *nextId++;
gst_object_put(vm, visited, x, check);
/* Return success */