Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions include/rbs/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "rbs/defines.h"
#include "rbs/util/rbs_allocator.h"
#include "rbs/util/rbs_constant_pool.h"
#include "rbs/util/rbs_buffer.h"
#include "rbs/lexer.h"
#include "rbs/ast.h"

Expand All @@ -27,9 +28,8 @@ typedef struct rbs_comment_t {
rbs_position_t start;
rbs_position_t end;

size_t line_tokens_capacity;
size_t line_tokens_count;
rbs_token_t *line_tokens;
rbs_buffer_t /* of rbs_token_t */ line_tokens;

struct rbs_comment_t *next_comment;
} rbs_comment_t;
Expand Down
14 changes: 6 additions & 8 deletions include/rbs/util/rbs_allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,11 @@ void *rbs_allocator_calloc_impl(rbs_allocator_t *, size_t count, size_t size, si
void *rbs_allocator_realloc_impl(rbs_allocator_t *, void *ptr, size_t old_size, size_t new_size, size_t alignment);

// Use this when allocating memory for a single instance of a type.
#define rbs_allocator_alloc(allocator, type) ((type *) rbs_allocator_malloc_impl((allocator), sizeof(type), rbs_alignof(type)))
// Use this when allocating memory that will be immediately written to in full.
// Such as allocating strings
#define rbs_allocator_alloc_many(allocator, count, type) ((type *) rbs_allocator_malloc_many_impl((allocator), (count), sizeof(type), rbs_alignof(type)))
// Use this when allocating memory that will NOT be immediately written to in full.
// Such as allocating buffers
#define rbs_allocator_calloc(allocator, count, type) ((type *) rbs_allocator_calloc_impl((allocator), (count), sizeof(type), rbs_alignof(type)))
#define rbs_allocator_realloc(allocator, ptr, old_size, new_size, type) ((type *) rbs_allocator_realloc_impl((allocator), (ptr), (old_size), (new_size), rbs_alignof(type)))
#define rbs_alloc(allocator, type) ((type *) rbs_allocator_malloc_impl((allocator), sizeof(type), rbs_alignof(type)))
// Use this when allocating memory that will be immediately written to in full. e.g. allocating strings
#define rbs_alloc_many(allocator, count, type) ((type *) rbs_allocator_malloc_many_impl((allocator), (count), sizeof(type), rbs_alignof(type)))
// Use this when allocating memory that will NOT be immediately written to in full, e.g. pre-allocating buffers
#define rbs_calloc(allocator, count, type) ((type *) rbs_allocator_calloc_impl((allocator), (count), sizeof(type), rbs_alignof(type)))
#define rbs_realloc(allocator, ptr, old_size, new_size, type) ((type *) rbs_allocator_realloc_impl((allocator), (ptr), (old_size), (new_size), rbs_alignof(type)))

#endif
33 changes: 27 additions & 6 deletions include/rbs/util/rbs_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,6 @@
#include <stdlib.h>
#include <string.h>

/**
* The default capacity of a rbs_buffer_t.
* If the buffer needs to grow beyond this capacity, it will be doubled.
*/
#define RBS_BUFFER_DEFAULT_CAPACITY 128

/**
* A rbs_buffer_t is a simple memory buffer that stores data in a contiguous block of memory.
*/
Expand All @@ -37,6 +31,8 @@ typedef struct {
*/
bool rbs_buffer_init(rbs_allocator_t *, rbs_buffer_t *buffer);

bool rbs_buffer_init_with_capacity(rbs_allocator_t *allocator, rbs_buffer_t *buffer, size_t capacity);

/**
* Return the value of the buffer.
*
Expand Down Expand Up @@ -80,4 +76,29 @@ void rbs_buffer_append_string(rbs_allocator_t *, rbs_buffer_t *buffer, const cha
*/
rbs_string_t rbs_buffer_to_string(rbs_buffer_t *buffer);

/**
* Append a value to the buffer.
*
* @param allocator The allocator to use.
* @param buffer The buffer to append to.
* @param value The value to append.
* @param type The type of the value to append, which determines how many bytes to append.
*/
#define rbs_buffer_append_value(allocator, buffer, value, type) \
rbs_buffer_append_string((allocator), (buffer), (char *) (value), sizeof(type))

/**
* Returns a copy of a `type` from the `buffer` at the given `index`.
*
* This cast is unchecked, so it's up to caller to ensure the type is correct.
*
* @param buffer The buffer to get the value from.
* @param index The index of the element to retrieve.
* @param type The element type that the data will be cast to.
* @returns The value at the specified index, cast to the specified type.
*/
#define rbs_buffer_get(buffer, index, type) ( \
((type *) (buffer).value)[index] \
)

#endif
164 changes: 83 additions & 81 deletions src/ast.c

Large diffs are not rendered by default.

22 changes: 14 additions & 8 deletions src/location.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,24 @@ void rbs_loc_alloc_children(rbs_allocator_t *allocator, rbs_location_t *loc, siz

loc->children = rbs_allocator_malloc_impl(allocator, RBS_LOC_CHILDREN_SIZE(capacity), rbs_alignof(rbs_loc_children));

loc->children->len = 0;
loc->children->required_p = 0;
loc->children->cap = capacity;
*loc->children = (rbs_loc_children) {
.len = 0,
.cap = capacity,
.required_p = 0,
.entries = { 0 },
};
}

void rbs_loc_add_optional_child(rbs_location_t *loc, rbs_constant_id_t name, rbs_range_t r) {
rbs_assert(loc->children != NULL, "All children should have been pre-allocated with rbs_loc_alloc_children()");
rbs_assert((loc->children->len + 1 <= loc->children->cap), "Not enough space was pre-allocated for the children. Children: %hu, Capacity: %hu", loc->children->len, loc->children->cap);

unsigned short i = loc->children->len++;
loc->children->entries[i].name = name;
loc->children->entries[i].rg = (rbs_loc_range) { r.start.char_pos, r.end.char_pos };

loc->children->entries[i] = (rbs_loc_entry) {
.name = name,
.rg = (rbs_loc_range) { r.start.char_pos, r.end.char_pos },
};
}

void rbs_loc_add_required_child(rbs_location_t *loc, rbs_constant_id_t name, rbs_range_t r) {
Expand All @@ -31,7 +37,7 @@ void rbs_loc_add_required_child(rbs_location_t *loc, rbs_constant_id_t name, rbs
}

rbs_location_t *rbs_location_new(rbs_allocator_t *allocator, rbs_range_t rg) {
rbs_location_t *location = rbs_allocator_alloc(allocator, rbs_location_t);
rbs_location_t *location = rbs_alloc(allocator, rbs_location_t);
*location = (rbs_location_t) {
.rg = rg,
.children = NULL,
Expand All @@ -41,7 +47,7 @@ rbs_location_t *rbs_location_new(rbs_allocator_t *allocator, rbs_range_t rg) {
}

rbs_location_list_t *rbs_location_list_new(rbs_allocator_t *allocator) {
rbs_location_list_t *list = rbs_allocator_alloc(allocator, rbs_location_list_t);
rbs_location_list_t *list = rbs_alloc(allocator, rbs_location_list_t);
*list = (rbs_location_list_t) {
.allocator = allocator,
.head = NULL,
Expand All @@ -53,7 +59,7 @@ rbs_location_list_t *rbs_location_list_new(rbs_allocator_t *allocator) {
}

void rbs_location_list_append(rbs_location_list_t *list, rbs_location_t *loc) {
rbs_location_list_node_t *node = rbs_allocator_alloc(list->allocator, rbs_location_list_node_t);
rbs_location_list_node_t *node = rbs_alloc(list->allocator, rbs_location_list_node_t);
*node = (rbs_location_list_node_t) {
.loc = loc,
.next = NULL,
Expand Down
77 changes: 35 additions & 42 deletions src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -837,9 +837,12 @@ static bool parse_function(rbs_parser_t *parser, bool accept_type_binding, parse
);
}

(*result)->function = function;
(*result)->block = block;
(*result)->function_self_type = function_self_type;
**result = (parse_function_result) {
.function = function,
.block = block,
.function_self_type = function_self_type,
};

return true;
}

Expand All @@ -849,7 +852,7 @@ static bool parse_function(rbs_parser_t *parser, bool accept_type_binding, parse
NODISCARD
static bool parse_proc_type(rbs_parser_t *parser, rbs_types_proc_t **proc, bool self_allowed) {
rbs_position_t start = parser->current_token.range.start;
parse_function_result *result = rbs_allocator_alloc(ALLOCATOR(), parse_function_result);
parse_function_result *result = rbs_alloc(ALLOCATOR(), parse_function_result);
CHECK_PARSE(parse_function(parser, true, &result, self_allowed));

rbs_position_t end = parser->current_token.range.end;
Expand Down Expand Up @@ -1563,7 +1566,7 @@ bool rbs_parse_method_type(rbs_parser_t *parser, rbs_method_type_t **method_type
rbs_range_t type_range;
type_range.start = parser->next_token.range.start;

parse_function_result *result = rbs_allocator_alloc(ALLOCATOR(), parse_function_result);
parse_function_result *result = rbs_alloc(ALLOCATOR(), parse_function_result);
CHECK_PARSE(parse_function(parser, false, &result, true));

rg.end = parser->current_token.range.end;
Expand Down Expand Up @@ -1787,8 +1790,10 @@ static bool parse_method_name(rbs_parser_t *parser, rbs_range_t *range, rbs_ast_
case tULLIDENT:
KEYWORD_CASES
if (parser->next_token.type == pQUESTION && parser->current_token.range.end.byte_pos == parser->next_token.range.start.byte_pos) {
range->start = parser->current_token.range.start;
range->end = parser->next_token.range.end;
*range = (rbs_range_t) {
.start = parser->current_token.range.start,
.end = parser->next_token.range.end,
};
rbs_parser_advance(parser);

rbs_constant_id_t constant_id = rbs_constant_pool_insert_shared_with_encoding(
Expand Down Expand Up @@ -3208,7 +3213,7 @@ static rbs_ast_comment_t *parse_comment_lines(rbs_parser_t *parser, rbs_comment_
rbs_buffer_init(ALLOCATOR(), &rbs_buffer);

for (size_t i = 0; i < com->line_tokens_count; i++) {
rbs_token_t tok = com->line_tokens[i];
rbs_token_t tok = rbs_buffer_get(com->line_tokens, i, rbs_token_t);

const char *comment_start = parser->rbs_lexer_t->string.start + tok.range.start.byte_pos + hash_bytes;
size_t comment_bytes = RBS_RANGE_BYTES(tok.range) - hash_bytes;
Expand Down Expand Up @@ -3252,43 +3257,29 @@ static rbs_comment_t *comment_get_comment(rbs_comment_t *com, int line) {
}

static void comment_insert_new_line(rbs_allocator_t *allocator, rbs_comment_t *com, rbs_token_t comment_token) {
if (com->line_tokens_count == com->line_tokens_capacity) {
size_t old_size = com->line_tokens_capacity;
size_t new_size = old_size * 2;
com->line_tokens_capacity = new_size;

com->line_tokens = rbs_allocator_realloc(
allocator,
com->line_tokens,
sizeof(rbs_token_t) * old_size,
sizeof(rbs_token_t) * new_size,
rbs_token_t
);
}
rbs_buffer_append_value(allocator, &com->line_tokens, &comment_token, rbs_token_t);

com->line_tokens[com->line_tokens_count++] = comment_token;
com->line_tokens_count++;
com->end = comment_token.range.end;
}

static rbs_comment_t *alloc_comment(rbs_allocator_t *allocator, rbs_token_t comment_token, rbs_comment_t *last_comment) {
rbs_comment_t *new_comment = rbs_allocator_alloc(allocator, rbs_comment_t);

size_t initial_line_capacity = 10;

rbs_token_t *tokens = rbs_allocator_calloc(allocator, initial_line_capacity, rbs_token_t);
tokens[0] = comment_token;
rbs_comment_t *new_comment = rbs_alloc(allocator, rbs_comment_t);

*new_comment = (rbs_comment_t) {
.start = comment_token.range.start,
.end = comment_token.range.end,

.line_tokens_capacity = initial_line_capacity,
.line_tokens_count = 1,
.line_tokens = tokens,
.line_tokens_count = 0,
.line_tokens = { 0 },

.next_comment = last_comment,
};

size_t initial_line_capacity = 10;
rbs_buffer_init_with_capacity(allocator, &new_comment->line_tokens, initial_line_capacity * sizeof(rbs_token_t));
comment_insert_new_line(allocator, new_comment, comment_token);

return new_comment;
}

Expand Down Expand Up @@ -3357,20 +3348,20 @@ bool rbs_parse_type_params(rbs_parser_t *parser, bool module_type_params, rbs_no
}

id_table *alloc_empty_table(rbs_allocator_t *allocator) {
id_table *table = rbs_allocator_alloc(allocator, id_table);
id_table *table = rbs_alloc(allocator, id_table);

*table = (id_table) {
.size = 10,
.count = 0,
.ids = rbs_allocator_calloc(allocator, 10, rbs_constant_id_t),
.ids = rbs_calloc(allocator, 10, rbs_constant_id_t),
.next = NULL,
};

return table;
}

id_table *alloc_reset_table(rbs_allocator_t *allocator) {
id_table *table = rbs_allocator_alloc(allocator, id_table);
id_table *table = rbs_alloc(allocator, id_table);

*table = (id_table) {
.size = 0,
Expand Down Expand Up @@ -3407,7 +3398,7 @@ bool rbs_parser_insert_typevar(rbs_parser_t *parser, rbs_constant_id_t id) {
// expand
rbs_constant_id_t *ptr = table->ids;
table->size += 10;
table->ids = rbs_allocator_calloc(ALLOCATOR(), table->size, rbs_constant_id_t);
table->ids = rbs_calloc(ALLOCATOR(), table->size, rbs_constant_id_t);
memcpy(table->ids, ptr, sizeof(rbs_constant_id_t) * table->count);
}

Expand Down Expand Up @@ -3469,7 +3460,7 @@ rbs_ast_comment_t *rbs_parser_get_comment(rbs_parser_t *parser, int subject_line
}

rbs_lexer_t *rbs_lexer_new(rbs_allocator_t *allocator, rbs_string_t string, const rbs_encoding_t *encoding, int start_pos, int end_pos) {
rbs_lexer_t *lexer = rbs_allocator_alloc(allocator, rbs_lexer_t);
rbs_lexer_t *lexer = rbs_alloc(allocator, rbs_lexer_t);

rbs_position_t start_position = (rbs_position_t) {
.byte_pos = 0,
Expand Down Expand Up @@ -3500,7 +3491,7 @@ rbs_parser_t *rbs_parser_new(rbs_string_t string, const rbs_encoding_t *encoding
rbs_allocator_t *allocator = rbs_allocator_init();

rbs_lexer_t *lexer = rbs_lexer_new(allocator, string, encoding, start_pos, end_pos);
rbs_parser_t *parser = rbs_allocator_alloc(allocator, rbs_parser_t);
rbs_parser_t *parser = rbs_alloc(allocator, rbs_parser_t);

*parser = (rbs_parser_t) {
.rbs_lexer_t = lexer,
Expand Down Expand Up @@ -3561,16 +3552,18 @@ void rbs_parser_set_error(rbs_parser_t *parser, rbs_token_t tok, bool syntax_err
int length = vsnprintf(NULL, 0, fmt, args);
va_end(args);

char *message = rbs_allocator_alloc_many(ALLOCATOR(), length + 1, char);
char *message = rbs_alloc_many(ALLOCATOR(), length + 1, char);

va_start(args, fmt);
vsnprintf(message, length + 1, fmt, args);
va_end(args);

parser->error = rbs_allocator_alloc(ALLOCATOR(), rbs_error_t);
parser->error->token = tok;
parser->error->message = message;
parser->error->syntax_error = syntax_error;
parser->error = rbs_alloc(ALLOCATOR(), rbs_error_t);
*parser->error = (rbs_error_t) {
.message = message,
.token = tok,
.syntax_error = syntax_error,
};
}

/*
Expand Down
20 changes: 15 additions & 5 deletions src/util/rbs_buffer.c
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
#include "rbs/util/rbs_buffer.h"
#include "rbs/util/rbs_assert.h"

/**
* The default capacity of a rbs_buffer_t.
* If the buffer needs to grow beyond this capacity, it will be doubled.
*/
#define RBS_BUFFER_DEFAULT_CAPACITY 128

bool rbs_buffer_init(rbs_allocator_t *allocator, rbs_buffer_t *buffer) {
size_t capacity = RBS_BUFFER_DEFAULT_CAPACITY;
return rbs_buffer_init_with_capacity(allocator, buffer, RBS_BUFFER_DEFAULT_CAPACITY);
}

buffer->length = 0;
buffer->capacity = capacity;
bool rbs_buffer_init_with_capacity(rbs_allocator_t *allocator, rbs_buffer_t *buffer, size_t capacity) {
*buffer = (rbs_buffer_t) {
.length = 0,
.capacity = capacity,
.value = rbs_calloc(allocator, capacity, char),
};

buffer->value = rbs_allocator_calloc(allocator, capacity, char);
return buffer->value != NULL;
}

Expand All @@ -33,7 +43,7 @@ void rbs_buffer_append_string(rbs_allocator_t *allocator, rbs_buffer_t *buffer,
new_capacity *= 2;
}

char *new_value = rbs_allocator_realloc(allocator, buffer->value, old_capacity, new_capacity, char);
char *new_value = rbs_realloc(allocator, buffer->value, old_capacity, new_capacity, char);
rbs_assert(new_value != NULL, "Failed to append to buffer. Old capacity: %zu, new capacity: %zu", old_capacity, new_capacity);

buffer->value = new_value;
Expand Down
2 changes: 1 addition & 1 deletion src/util/rbs_unescape.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ rbs_string_t unescape_string(rbs_allocator_t *allocator, const rbs_string_t stri
size_t len = string.end - string.start;
const char *input = string.start;

char *output = rbs_allocator_alloc_many(allocator, len + 1, char);
char *output = rbs_alloc_many(allocator, len + 1, char);
if (!output) return RBS_STRING_NULL;

size_t i = 0, j = 0;
Expand Down
Loading
Loading