aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-19 17:21:28 +0200
committerBad Diode <bd@badd10de.dev>2021-10-19 17:21:28 +0200
commitf7b5da260fc7b6b73b5ed6c87d3593de372db6ad (patch)
treec13531ae52cbe0fb6fb5ed5f45d6f718dfcc9619
parentc0202d26b94434253fb99450734152b7cb1ae388 (diff)
downloadbdl-f7b5da260fc7b6b73b5ed6c87d3593de372db6ad.tar.gz
bdl-f7b5da260fc7b6b73b5ed6c87d3593de372db6ad.zip
Add generic dynamic array and change tokens to use it
-rw-r--r--src/bootstrap/darray.h55
-rw-r--r--src/bootstrap/lexer.c32
-rw-r--r--src/bootstrap/lexer.h11
-rwxr-xr-xsrc/bootstrap/main.c12
-rw-r--r--src/bootstrap/parser.c6
-rw-r--r--src/bootstrap/parser.h2
6 files changed, 77 insertions, 41 deletions
diff --git a/src/bootstrap/darray.h b/src/bootstrap/darray.h
new file mode 100644
index 0000000..bb49cdd
--- /dev/null
+++ b/src/bootstrap/darray.h
@@ -0,0 +1,55 @@
1#ifndef BDL_DARRAY_H
2#define BDL_DARRAY_H
3
4#include <string.h>
5
6typedef struct ArrayHeader {
7 size_t size;
8 size_t cap;
9} ArrayHeader;
10
11// Header/Size/capacity accessors.
12#define array_head(ARR) ((ArrayHeader *)((char *)(ARR) - sizeof(ArrayHeader)))
13#define array_size(ARR) ((ARR) ? array_head(ARR)->size : 0)
14#define array_cap(ARR) ((ARR) ? array_head(ARR)->cap : 0)
15
16// Initialize a dynamic array ARR with N elements. The initialization doesn't
17// zero out the data, so thread carefully..
18#define array_init(ARR,N) ((ARR) = _array_reserve(N, sizeof(*(ARR))))
19
20// Push a given element T to the dynamic array ARR.
21#define array_push(ARR, T) \
22 ((ARR) = _array_maybe_grow(ARR, sizeof(T)), \
23 (ARR)[array_head(ARR)->size++] = (T))
24
25// Return the last element of the array. Can be used to build stacks.
26#define array_pop(ARR) (ARR)[--array_head(ARR)->size]
27
28// Free the memory from the original allocated position.
29#define array_free(ARR) ((ARR) ? free(array_head(ARR)), (ARR) = NULL : 0)
30
31static inline void *
32_array_reserve(size_t num_elem, size_t type_size) {
33 char *p = malloc(num_elem * type_size + sizeof(ArrayHeader));
34 p += sizeof(ArrayHeader);
35 array_head(p)->size = 0;
36 array_head(p)->cap = num_elem;
37 return p;
38}
39
40static inline void *
41_array_maybe_grow(void *arr, size_t type_size) {
42 ArrayHeader *head = array_head(arr);
43 if (head->cap == head->size) {
44 if (head->cap == 0) {
45 head->cap++;
46 } else {
47 head->cap *= 2;
48 }
49 head = realloc(head, head->cap * type_size + sizeof(ArrayHeader));
50 }
51 arr = (char *)head + sizeof(ArrayHeader);
52 return arr;
53}
54
55#endif // BDL_DARRAY_H
diff --git a/src/bootstrap/lexer.c b/src/bootstrap/lexer.c
index 05324eb..38ca37c 100644
--- a/src/bootstrap/lexer.c
+++ b/src/bootstrap/lexer.c
@@ -44,19 +44,6 @@ print_token(Token tok) {
44 printf("\n"); 44 printf("\n");
45} 45}
46 46
47void
48push_token(Tokens *tokens, Token tok) {
49 if (tokens->buf == NULL) {
50 tokens->size = 0;
51 tokens->cap = TOK_BUF_CAP;
52 tokens->buf = malloc(tokens->cap * sizeof(Token));
53 } else if (tokens->size == tokens->cap) {
54 tokens->cap *= 2;
55 tokens->buf = realloc(tokens->buf, tokens->cap * sizeof(Token));
56 }
57 tokens->buf[tokens->size++] = tok;
58}
59
60char 47char
61scan_next(Scanner *scanner) { 48scan_next(Scanner *scanner) {
62 char c = sv_next(&scanner->current); 49 char c = sv_next(&scanner->current);
@@ -147,9 +134,10 @@ find_primitive_type(const StringView value) {
147 return TOKEN_SYMBOL; 134 return TOKEN_SYMBOL;
148} 135}
149 136
150Tokens 137Token *
151tokenize(const StringView *sv) { 138tokenize(const StringView *sv) {
152 Tokens tokens = (Tokens){0}; 139 Token *tokens = NULL;
140 array_init(tokens, 1);
153 Scanner scanner = (Scanner){ 141 Scanner scanner = (Scanner){
154 .current = *sv, 142 .current = *sv,
155 .line_number = 1, 143 .line_number = 1,
@@ -197,7 +185,7 @@ tokenize(const StringView *sv) {
197 .line = line, 185 .line = line,
198 .column = col, 186 .column = col,
199 }; 187 };
200 push_token(&tokens, token); 188 array_push(tokens, token);
201 } break; 189 } break;
202 case '\'': { 190 case '\'': {
203 Token token = (Token){ 191 Token token = (Token){
@@ -205,7 +193,7 @@ tokenize(const StringView *sv) {
205 .line = line, 193 .line = line,
206 .column = col, 194 .column = col,
207 }; 195 };
208 push_token(&tokens, token); 196 array_push(tokens, token);
209 } break; 197 } break;
210 case '(': { 198 case '(': {
211 if (scan_peek(&scanner) == ')') { 199 if (scan_peek(&scanner) == ')') {
@@ -215,14 +203,14 @@ tokenize(const StringView *sv) {
215 .line = line, 203 .line = line,
216 .column = col, 204 .column = col,
217 }; 205 };
218 push_token(&tokens, token); 206 array_push(tokens, token);
219 } else { 207 } else {
220 Token token = (Token){ 208 Token token = (Token){
221 .type = TOKEN_LPAREN, 209 .type = TOKEN_LPAREN,
222 .line = line, 210 .line = line,
223 .column = col, 211 .column = col,
224 }; 212 };
225 push_token(&tokens, token); 213 array_push(tokens, token);
226 } 214 }
227 } break; 215 } break;
228 case ')': { 216 case ')': {
@@ -231,7 +219,7 @@ tokenize(const StringView *sv) {
231 .line = line, 219 .line = line,
232 .column = col, 220 .column = col,
233 }; 221 };
234 push_token(&tokens, token); 222 array_push(tokens, token);
235 } break; 223 } break;
236 default: { 224 default: {
237 size_t n = 1; 225 size_t n = 1;
@@ -252,7 +240,7 @@ tokenize(const StringView *sv) {
252 .column = col, 240 .column = col,
253 }; 241 };
254 token.type = find_primitive_type(token.value); 242 token.type = find_primitive_type(token.value);
255 push_token(&tokens, token); 243 array_push(tokens, token);
256 } break; 244 } break;
257 } 245 }
258 } 246 }
@@ -263,7 +251,7 @@ tokenize(const StringView *sv) {
263 .line = scanner.line_number, 251 .line = scanner.line_number,
264 .column = 1, 252 .column = 1,
265 }; 253 };
266 push_token(&tokens, token); 254 array_push(tokens, token);
267 255
268 return tokens; 256 return tokens;
269} 257}
diff --git a/src/bootstrap/lexer.h b/src/bootstrap/lexer.h
index 129fd9a..2b2789f 100644
--- a/src/bootstrap/lexer.h
+++ b/src/bootstrap/lexer.h
@@ -22,12 +22,6 @@ typedef struct Token {
22 size_t column; 22 size_t column;
23} Token; 23} Token;
24 24
25typedef struct Tokens {
26 Token *buf;
27 size_t size;
28 size_t cap;
29} Tokens;
30
31typedef struct Scanner { 25typedef struct Scanner {
32 StringView current; 26 StringView current;
33 size_t line_number; 27 size_t line_number;
@@ -38,9 +32,6 @@ typedef struct Scanner {
38// Print a token to standard output for debugging purposes. 32// Print a token to standard output for debugging purposes.
39void print_token(Token tok); 33void print_token(Token tok);
40 34
41// Push a token to the token list.
42void push_token(Tokens *tokens, Token tok);
43
44// Same functionality as the ScanView pairs, but keeping track of line and 35// Same functionality as the ScanView pairs, but keeping track of line and
45// column numbers. 36// column numbers.
46char scan_next(Scanner *scanner); 37char scan_next(Scanner *scanner);
@@ -59,7 +50,7 @@ bool is_delimiter(char c);
59TokenType find_primitive_type(const StringView value); 50TokenType find_primitive_type(const StringView value);
60 51
61// Generate a list of tokens from the given string. 52// Generate a list of tokens from the given string.
62Tokens tokenize(const StringView *sv); 53Token * tokenize(const StringView *sv);
63 54
64#define TOK_BUF_CAP 256 55#define TOK_BUF_CAP 256
65 56
diff --git a/src/bootstrap/main.c b/src/bootstrap/main.c
index cfad9f1..22332af 100755
--- a/src/bootstrap/main.c
+++ b/src/bootstrap/main.c
@@ -6,6 +6,8 @@
6#include <stdlib.h> 6#include <stdlib.h>
7#include <string.h> 7#include <string.h>
8 8
9#include "darray.h"
10
9#include "singletons.c" 11#include "singletons.c"
10 12
11#include "environment.c" 13#include "environment.c"
@@ -92,10 +94,10 @@ init(void) {
92 94
93void 95void
94process_source(const StringView *source) { 96process_source(const StringView *source) {
95 Tokens tokens = tokenize(source); 97 Token *tokens = tokenize(source);
96 if (errors_n != 0) { 98 if (errors_n != 0) {
97 if (tokens.buf != NULL) { 99 if (tokens != NULL) {
98 free(tokens.buf); 100 array_free(tokens);
99 } 101 }
100 return; 102 return;
101 } 103 }
@@ -122,8 +124,8 @@ process_source(const StringView *source) {
122 pop_root(); 124 pop_root();
123 } 125 }
124 126
125 if (tokens.buf != NULL) { 127 if (tokens != NULL) {
126 free(tokens.buf); 128 array_free(tokens);
127 } 129 }
128} 130}
129 131
diff --git a/src/bootstrap/parser.c b/src/bootstrap/parser.c
index 5b0033a..a2f0f71 100644
--- a/src/bootstrap/parser.c
+++ b/src/bootstrap/parser.c
@@ -2,17 +2,17 @@
2 2
3Token 3Token
4peek_token(const Visitor *visitor) { 4peek_token(const Visitor *visitor) {
5 return visitor->tokens.buf[visitor->current]; 5 return visitor->tokens[visitor->current];
6} 6}
7 7
8Token 8Token
9next_token(Visitor *visitor) { 9next_token(Visitor *visitor) {
10 return visitor->tokens.buf[visitor->current++]; 10 return visitor->tokens[visitor->current++];
11} 11}
12 12
13bool 13bool
14has_next_token(const Visitor *visitor) { 14has_next_token(const Visitor *visitor) {
15 return visitor->current < visitor->tokens.size; 15 return visitor->current < array_size(visitor->tokens);
16} 16}
17 17
18Object * 18Object *
diff --git a/src/bootstrap/parser.h b/src/bootstrap/parser.h
index 3bd17ef..3834c75 100644
--- a/src/bootstrap/parser.h
+++ b/src/bootstrap/parser.h
@@ -2,7 +2,7 @@
2#define BDL_PARSER_H 2#define BDL_PARSER_H
3 3
4typedef struct Visitor { 4typedef struct Visitor {
5 Tokens tokens; 5 Token *tokens;
6 size_t current; 6 size_t current;
7} Visitor; 7} Visitor;
8 8