Skip to content

Commit

Permalink
Change pm_integer_t structure
Browse files Browse the repository at this point in the history
  • Loading branch information
tompng authored and kddnewton committed Mar 7, 2024
1 parent ae4fb6b commit 588acf8
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 206 deletions.
14 changes: 9 additions & 5 deletions ext/prism/extension.c
Original file line number Diff line number Diff line change
Expand Up @@ -1047,12 +1047,16 @@ integer_parse(VALUE self, VALUE source) {
pm_integer_t integer = { 0 };
pm_integer_parse(&integer, PM_INTEGER_BASE_UNKNOWN, start, start + length);

VALUE number = UINT2NUM(integer.head.value);
size_t shift = 0;
VALUE number;

for (pm_integer_word_t *node = integer.head.next; node != NULL; node = node->next) {
VALUE receiver = rb_funcall(UINT2NUM(node->value), rb_intern("<<"), 1, ULONG2NUM(++shift * 32));
number = rb_funcall(receiver, rb_intern("|"), 1, number);
if (integer.values == NULL) {
number = UINT2NUM(integer.value);
} else {
number = UINT2NUM(0);
for (size_t i = 0; i < integer.length; i++) {
VALUE receiver = rb_funcall(UINT2NUM(integer.values[i]), rb_intern("<<"), 1, ULONG2NUM(i * 32));
number = rb_funcall(receiver, rb_intern("|"), 1, number);
}
}

if (integer.negative) number = rb_funcall(number, rb_intern("-@"), 0);
Expand Down
29 changes: 12 additions & 17 deletions include/prism/util/pm_integer.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,25 @@
#include <stdlib.h>

/**
* A node in the linked list of a pm_integer_t.
* A structure represents an arbitrary-sized integer.
*/
typedef struct pm_integer_word {
/** A pointer to the next node in the list. */
struct pm_integer_word *next;

/** The value of the node. */
typedef struct {
/**
* Embedded value for small integer. This value is set to 0 if the value
* does not fit into uint32_t.
*/
uint32_t value;
} pm_integer_word_t;

/**
* This structure represents an arbitrary-sized integer. It is implemented as a
* linked list of 32-bit integers, with the least significant digit at the head
* of the list.
*/
typedef struct {
/** The number of nodes in the linked list that have been allocated. */
/**
* The number of allocated values. length is set to 0 if the integer fits
* into uint32_t.
*/
size_t length;

/**
* The head of the linked list, embedded directly so that allocations do not
* need to be performed for small integers.
* List of 32-bit integers. Set to NULL if the integer fits into uint32_t.
*/
pm_integer_word_t head;
uint32_t *values;

/**
* Whether or not the integer is negative. It is stored this way so that a
Expand Down
15 changes: 7 additions & 8 deletions src/static_literals.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,11 @@ node_hash(const pm_parser_t *parser, const pm_node_t *node) {
case PM_INTEGER_NODE: {
// Integers hash their value.
const pm_integer_t *integer = &((const pm_integer_node_t *) node)->value;
const uint32_t *value = &integer->head.value;

uint32_t hash = murmur_hash((const uint8_t *) value, sizeof(uint32_t));
for (const pm_integer_word_t *word = integer->head.next; word != NULL; word = word->next) {
value = &word->value;
hash ^= murmur_hash((const uint8_t *) value, sizeof(uint32_t));
uint32_t hash;
if (integer->values) {
hash = murmur_hash((const uint8_t *) integer->values, sizeof(uint32_t) * integer->length);
} else {
hash = murmur_hash((const uint8_t *) &integer->value, sizeof(uint32_t));
}

if (integer->negative) {
Expand Down Expand Up @@ -204,9 +203,9 @@ pm_int64_value(const pm_parser_t *parser, const pm_node_t *node) {
switch (PM_NODE_TYPE(node)) {
case PM_INTEGER_NODE: {
const pm_integer_t *integer = &((const pm_integer_node_t *) node)->value;
if (integer->length > 0) return integer->negative ? INT64_MIN : INT64_MAX;
if (integer->values) return integer->negative ? INT64_MIN : INT64_MAX;

int64_t value = (int64_t) integer->head.value;
int64_t value = (int64_t) integer->value;
return integer->negative ? -value : value;
}
case PM_SOURCE_LINE_NODE:
Expand Down

0 comments on commit 588acf8

Please sign in to comment.