diff --git a/src/defs.h b/src/defs.h index 6ddedd51..3b6f4438 100644 --- a/src/defs.h +++ b/src/defs.h @@ -79,6 +79,7 @@ typedef struct arena_block { typedef struct { arena_block_t *head; int total_bytes; /* Track total allocation for profiling */ + int block_size; /* Default block size for new blocks */ } arena_t; /* string-based hash map definitions */ diff --git a/src/globals.c b/src/globals.c index 195de542..4d4df304 100644 --- a/src/globals.c +++ b/src/globals.c @@ -144,6 +144,8 @@ arena_t *arena_init(int initial_capacity) } arena->head = arena_block_create(initial_capacity); arena->total_bytes = initial_capacity; + /* Use the initial capacity as the default block size for future growth. */ + arena->block_size = initial_capacity; return arena; } @@ -166,9 +168,12 @@ void *arena_alloc(arena_t *arena, int size) size = (size + PTR_SIZE - 1) & ~(PTR_SIZE - 1); if (!arena->head || arena->head->offset + size > arena->head->capacity) { - /* Need a new block: choose capacity = max(DEFAULT_ARENA_SIZE, size) */ - int new_capacity = - (size > DEFAULT_ARENA_SIZE ? size : DEFAULT_ARENA_SIZE); + /* Need a new block: choose capacity = max(DEFAULT_ARENA_SIZE, + * arena->block_size, size) */ + int base = + (arena->block_size > DEFAULT_ARENA_SIZE ? arena->block_size + : DEFAULT_ARENA_SIZE); + int new_capacity = (size > base ? size : base); arena_block_t *new_block = arena_block_create(new_capacity); new_block->next = arena->head; arena->head = new_block; diff --git a/src/lexer.c b/src/lexer.c index 948425c8..ec940a8c 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -235,20 +235,23 @@ bool is_numeric(char buffer[]) void skip_whitespace(void) { + int pos = SOURCE->size; while (true) { - if (is_linebreak(next_char)) { - SOURCE->size += 2; - next_char = SOURCE->elements[SOURCE->size]; + /* Handle backslash-newline (line continuation) using local pos */ + if (next_char == '\\' && SOURCE->elements[pos + 1] == '\n') { + pos += 2; + next_char = SOURCE->elements[pos]; continue; } if (is_whitespace(next_char) || (skip_newline && is_newline(next_char))) { - SOURCE->size++; - next_char = SOURCE->elements[SOURCE->size]; + pos++; + next_char = SOURCE->elements[pos]; continue; } break; } + SOURCE->size = pos; } char read_char(bool is_skip_space) @@ -296,17 +299,29 @@ token_t lex_token_internal(bool aliasing) /* C-style comments */ if (next_char == '*') { /* in a comment, skip until end */ + int pos = SOURCE->size; do { - read_char(false); + /* advance one char */ + pos++; + next_char = SOURCE->elements[pos]; if (next_char == '*') { - read_char(false); + /* look ahead */ + pos++; + next_char = SOURCE->elements[pos]; if (next_char == '/') { - read_char(true); + /* consume closing '/', then commit and skip trailing + * whitespaces + */ + pos++; + next_char = SOURCE->elements[pos]; + SOURCE->size = pos; + skip_whitespace(); return lex_token_internal(aliasing); } } } while (next_char); + SOURCE->size = pos; if (!next_char) error("Unenclosed C-style comment"); return lex_token_internal(aliasing); @@ -314,9 +329,12 @@ token_t lex_token_internal(bool aliasing) /* C++-style comments */ if (next_char == '/') { + int pos = SOURCE->size; do { - read_char(false); + pos++; + next_char = SOURCE->elements[pos]; } while (next_char && !is_newline(next_char)); + SOURCE->size = pos; return lex_token_internal(aliasing); }