ox

The Ox programming language, compiler and tools (WIP)
Log | Files | Refs | README | LICENSE

commit 92e1639b07afa8e67e225e020ddb157de0637c83
parent 177e774dc5134b62d28f960334abca595023af6d
Author: citbl <citbl@citbl.org>
Date:   Mon, 13 Oct 2025 20:45:06 +1000

reformatting

Diffstat:
Msrc/file.h | 7++++---
Msrc/gen.h | 2+-
Msrc/hmap.c | 55+++++++++++++++++++++++++++++--------------------------
Msrc/hmap.h | 18+++++++++---------
Msrc/hmap_test.c | 51++++++++++++++++++++++++++++-----------------------
Msrc/lexer.c | 105+++++++++++++++++++++++++++++++++----------------------------------------------
Msrc/parser.h | 2--
Msrc/parser/ast.c | 46+++++++++++++++++++++++-----------------------
Msrc/parser/decl.c | 22+++++++++++-----------
Msrc/parser/expr.c | 87+++++++++++++++++++++++++++++++++++--------------------------------------------
Msrc/parser/parser.c | 153+++++++++++++++++++++++++++++++++++--------------------------------------------
Msrc/parser/stmt.c | 64++++++++++++++++++++++++++++++++--------------------------------
Msrc/sem.h | 1-
13 files changed, 288 insertions(+), 325 deletions(-)

diff --git a/src/file.h b/src/file.h @@ -5,9 +5,10 @@ #include "utils.h" -char* readfile(const char* file_path) +char * +readfile(const char *file_path) { - FILE* fp = fopen(file_path, "rb"); + FILE *fp = fopen(file_path, "rb"); if (fp == NULL) { perror("Failed to read file"); return NULL; @@ -36,7 +37,7 @@ char* readfile(const char* file_path) return NULL; } - char* contents = (char*)calloc(1, (size_t)file_size + 1); + char *contents = (char *)calloc(1, (size_t)file_size + 1); if (contents == NULL) { panic("Failed to allocate memory to read file"); fclose(fp); diff --git a/src/gen.h b/src/gen.h @@ -18,5 +18,5 @@ typedef struct { const char *src; } Gen; -Gen gen_init(Scope *, const char *, Node*, bool); +Gen gen_init(Scope *, const char *, Node *, bool); void gen_next(Gen *, Node *); diff --git a/src/hmap.c b/src/hmap.c @@ -6,10 +6,11 @@ #define INITIAL_BUCKETS 8 #define LOAD_FACTOR 0.75 -static void hmap_grow(HashMap* map); +static void hmap_grow(HashMap *map); // Simple string hash function (djb2) -static unsigned long hash(const char* str) +static unsigned long +hash(const char *str) { unsigned long h = 5381; unsigned char c; @@ -18,16 +19,15 @@ static unsigned long hash(const char* str) return h; } -HashMap* hmap_create(size_t value_size) +HashMap * +hmap_create(size_t value_size) { - HashMap* map = calloc(1, sizeof(HashMap)); - if (map == NULL) { - fprintf(stderr, "hmap_create: map: could not alloc\n"); - } + HashMap *map = calloc(1, sizeof(HashMap)); + if (map == NULL) { fprintf(stderr, "hmap_create: map: could not alloc\n"); } map->bucket_count = INITIAL_BUCKETS; map->size = 0; map->value_size = value_size; - map->buckets = calloc(map->bucket_count, sizeof(HashNode*)); + map->buckets = calloc(map->bucket_count, sizeof(HashNode *)); if (map->buckets == NULL) { fprintf(stderr, "hmap_create: bucket: could not alloc\n"); exit(1); @@ -35,13 +35,12 @@ HashMap* hmap_create(size_t value_size) return map; } -void hmap_put(HashMap* map, const char* key, const void* value) +void +hmap_put(HashMap *map, const char *key, const void *value) { - if ((float)(map->size + 1) / map->bucket_count > LOAD_FACTOR) { - hmap_grow(map); - } + if ((float)(map->size + 1) / map->bucket_count > LOAD_FACTOR) { hmap_grow(map); } unsigned long h = hash(key) % map->bucket_count; - HashNode* node = map->buckets[h]; + HashNode *node = map->buckets[h]; while (node) { if (strcmp(node->key, key) == 0) { memcpy(node->value, value, map->value_size); @@ -49,7 +48,7 @@ void hmap_put(HashMap* map, const char* key, const void* value) } node = node->next; } - HashNode* new_node = calloc(1, sizeof(HashNode)); + HashNode *new_node = calloc(1, sizeof(HashNode)); if (new_node == NULL) { fprintf(stderr, "hmap_put: new_node: could not alloc\n"); exit(1); @@ -66,10 +65,11 @@ void hmap_put(HashMap* map, const char* key, const void* value) map->size++; } -bool hmap_get(HashMap* map, const char* key, void* out) +bool +hmap_get(HashMap *map, const char *key, void *out) { unsigned long h = hash(key) % map->bucket_count; - HashNode* node = map->buckets[h]; + HashNode *node = map->buckets[h]; while (node) { if (strcmp(node->key, key) == 0) { memcpy(out, node->value, map->value_size); @@ -80,11 +80,12 @@ bool hmap_get(HashMap* map, const char* key, void* out) return false; } -bool hmap_remove(HashMap* map, const char* key) +bool +hmap_remove(HashMap *map, const char *key) { unsigned long h = hash(key) % map->bucket_count; - HashNode* node = map->buckets[h]; - HashNode* prev = NULL; + HashNode *node = map->buckets[h]; + HashNode *prev = NULL; while (node) { if (strcmp(node->key, key) == 0) { if (prev) { @@ -104,18 +105,19 @@ bool hmap_remove(HashMap* map, const char* key) return false; } -static void hmap_grow(HashMap* map) +static void +hmap_grow(HashMap *map) { size_t new_bucket_count = map->bucket_count * 2; - HashNode** new_buckets = calloc(new_bucket_count, sizeof(HashNode*)); + HashNode **new_buckets = calloc(new_bucket_count, sizeof(HashNode *)); if (new_buckets == NULL) { fprintf(stderr, "hmap_grow: could not alloc\n"); exit(1); } for (size_t i = 0; i < map->bucket_count; i++) { - HashNode* node = map->buckets[i]; + HashNode *node = map->buckets[i]; while (node) { - HashNode* next = node->next; + HashNode *next = node->next; unsigned long h = hash(node->key) % new_bucket_count; node->next = new_buckets[h]; new_buckets[h] = node; @@ -127,12 +129,13 @@ static void hmap_grow(HashMap* map) map->bucket_count = new_bucket_count; } -void hmap_free(HashMap* map) +void +hmap_free(HashMap *map) { for (size_t i = 0; i < map->bucket_count; i++) { - HashNode* node = map->buckets[i]; + HashNode *node = map->buckets[i]; while (node) { - HashNode* next = node->next; + HashNode *next = node->next; free(node->key); free(node->value); free(node); diff --git a/src/hmap.h b/src/hmap.h @@ -4,20 +4,20 @@ #include <stdlib.h> typedef struct HashNode { - char* key; - void* value; - struct HashNode* next; + char *key; + void *value; + struct HashNode *next; } HashNode; typedef struct HashMap { size_t bucket_count; size_t size; size_t value_size; - struct HashNode** buckets; + struct HashNode **buckets; } HashMap; -HashMap* hmap_create(size_t); -void hmap_put(HashMap* map, const char* key, const void* value); -bool hmap_get(HashMap* map, const char* key, void* out); -bool hmap_remove(HashMap* map, const char* key); -void hmap_free(HashMap* map); +HashMap *hmap_create(size_t); +void hmap_put(HashMap *map, const char *key, const void *value); +bool hmap_get(HashMap *map, const char *key, void *out); +bool hmap_remove(HashMap *map, const char *key); +void hmap_free(HashMap *map); diff --git a/src/hmap_test.c b/src/hmap_test.c @@ -4,15 +4,16 @@ #include "hmap.h" -static void hmap_test_basic(void) +static void +hmap_test_basic(void) { int i; printf("Testing dict of integers...\n"); - HashMap* map = hmap_create(sizeof(int)); + HashMap *map = hmap_create(sizeof(int)); struct { - const char* key; + const char *key; int value; } items[] = { { "one", 1 }, @@ -36,11 +37,11 @@ static void hmap_test_basic(void) all_ok = 0; } } - if (all_ok) - printf("PASS: dict of integers test\n"); + if (all_ok) printf("PASS: dict of integers test\n"); } -static void hmap_test_T(void) +static void +hmap_test_T(void) { int i; printf("Testing struct T...\n"); @@ -53,7 +54,7 @@ static void hmap_test_T(void) float score; }; - HashMap* map = hmap_create(sizeof(struct T)); + HashMap *map = hmap_create(sizeof(struct T)); struct T items[] = { { 1, "alice", 30, "alice@example.com", 95.5f }, @@ -70,24 +71,29 @@ static void hmap_test_T(void) struct T v; int all_ok = 1; for (i = 0; i < 3; i++) { - if (hmap_get(map, items[i].name, &v) && v.id == items[i].id && strcmp(v.name, items[i].name) == 0 && v.age == items[i].age && strcmp(v.email, items[i].email) == 0 && v.score == items[i].score) { + if (hmap_get(map, items[i].name, &v) && v.id == items[i].id && strcmp(v.name, items[i].name) == 0 && v.age == items[i].age + && strcmp(v.email, items[i].email) == 0 && v.score == items[i].score) { printf("PASS: %s == {id:%d, age:%d, email:%s, score:%.1f}\n", - items[i].name, items[i].id, items[i].age, items[i].email, items[i].score); + items[i].name, + items[i].id, + items[i].age, + items[i].email, + items[i].score); } else { printf("FAIL: %s\n", items[i].name); all_ok = 0; } } - if (all_ok) - printf("PASS: struct T test\n"); + if (all_ok) printf("PASS: struct T test\n"); } -static void hmap_test_memory_bumping(void) +static void +hmap_test_memory_bumping(void) { int i; printf("Testing memory bumping...\n"); - HashMap* map = hmap_create(sizeof(int)); + HashMap *map = hmap_create(sizeof(int)); const int N = 1000; // Large enough to trigger resizing char key[32]; @@ -105,26 +111,25 @@ static void hmap_test_memory_bumping(void) int v = -1; if (hmap_get(map, key, &v) && v == i) { // Optionally print only a few - if (i < 3 || i > N - 3) - printf("PASS: %s == %d\n", key, v); + if (i < 3 || i > N - 3) printf("PASS: %s == %d\n", key, v); } else { printf("FAIL: %s\n", key); all_ok = 0; } } - if (all_ok) - printf("PASS: memory bumping test\n"); + if (all_ok) printf("PASS: memory bumping test\n"); } -static void hmap_test_removal(void) +static void +hmap_test_removal(void) { int i; printf("Testing removal...\n"); - HashMap* map = hmap_create(sizeof(int)); + HashMap *map = hmap_create(sizeof(int)); struct { - const char* key; + const char *key; int value; } items[] = { { "alpha", 10 }, @@ -161,11 +166,11 @@ static void hmap_test_removal(void) } } } - if (all_ok) - printf("PASS: removal test\n"); + if (all_ok) printf("PASS: removal test\n"); } -void hmap_tests(void) +void +hmap_tests(void) { hmap_test_basic(); hmap_test_T(); diff --git a/src/lexer.c b/src/lexer.c @@ -8,26 +8,27 @@ #include <ctype.h> #include <assert.h> -static char peek(Lexer* lex) +static char +peek(Lexer *lex) { char c = lex->src[lex->pos]; return c ? c : 0; } -static char peek2(Lexer* lex) +static char +peek2(Lexer *lex) { char c = lex->src[lex->pos]; - if (!c) - return 0; + if (!c) return 0; c = lex->src[lex->pos + 1]; return c ? c : 0; } -static char nudge(Lexer* lex) +static char +nudge(Lexer *lex) { const char c = peek(lex); - if (!c) - return 0; + if (!c) return 0; if (c == '\n') { lex->line++; lex->col = 1; @@ -38,7 +39,8 @@ static char nudge(Lexer* lex) return c; } -static void skip_space_and_comments(Lexer* lex) +static void +skip_space_and_comments(Lexer *lex) { for (;;) { for (;;) { @@ -59,7 +61,8 @@ static void skip_space_and_comments(Lexer* lex) } } -static Token make_ident(Lexer* lex, size_t pos, size_t line, size_t col) +static Token +make_ident(Lexer *lex, size_t pos, size_t line, size_t col) { for (;;) { char c = peek(lex); @@ -104,13 +107,10 @@ static Token make_ident(Lexer* lex, size_t pos, size_t line, size_t col) // } // } - return (Token) { .type = type, - .start = pos, - .line = line, - .col = col, - .end = lex->pos }; + return (Token) { .type = type, .start = pos, .line = line, .col = col, .end = lex->pos }; } -static Token make_number(Lexer* lex, size_t pos, size_t line, size_t col) +static Token +make_number(Lexer *lex, size_t pos, size_t line, size_t col) { bool is_float = false; while (isdigit(peek(lex))) @@ -121,32 +121,21 @@ static Token make_number(Lexer* lex, size_t pos, size_t line, size_t col) while (isdigit(peek(lex))) nudge(lex); } - return (Token) { - .type = is_float ? TOKEN_FLOAT_LITERAL : TOKEN_INT_LITERAL, - .start = pos, - .end = lex->pos, - .line = line, - .col = col - }; + return (Token) { .type = is_float ? TOKEN_FLOAT_LITERAL : TOKEN_INT_LITERAL, .start = pos, .end = lex->pos, .line = line, .col = col }; } -static Token make_string(Lexer* lex, size_t pos, size_t line, size_t col) +static Token +make_string(Lexer *lex, size_t pos, size_t line, size_t col) { nudge(lex); // " start while (peek(lex) != '"' && peek(lex) != 0) nudge(lex); - if (peek(lex) == '"') - nudge(lex); // " end - return (Token) { - .type = TOKEN_STRING_LITERAL, - .start = pos, - .end = lex->pos, - .line = line, - .col = col - }; + if (peek(lex) == '"') nudge(lex); // " end + return (Token) { .type = TOKEN_STRING_LITERAL, .start = pos, .end = lex->pos, .line = line, .col = col }; } -static Token next_token(Lexer* lex) +static Token +next_token(Lexer *lex) { skip_space_and_comments(lex); size_t start = lex->pos; @@ -154,17 +143,11 @@ static Token next_token(Lexer* lex) size_t col = lex->col; const char c = peek(lex); - if (c == 0) - return (Token) { - .type = TOKEN_EOF, .start = start, .end = lex->pos, .col = col, .line = line - }; + if (c == 0) return (Token) { .type = TOKEN_EOF, .start = start, .end = lex->pos, .col = col, .line = line }; - if (isalpha(c) || c == '_') - return make_ident(lex, start, line, col); - if (isdigit(c)) - return make_number(lex, start, line, col); - if (c == '"') - return make_string(lex, start, line, col); + if (isalpha(c) || c == '_') return make_ident(lex, start, line, col); + if (isdigit(c)) return make_number(lex, start, line, col); + if (c == '"') return make_string(lex, start, line, col); TokenType type = TOKEN_UNKNOWN; @@ -276,10 +259,10 @@ static Token next_token(Lexer* lex) return t; } -static void print_token(const Token* t, const char* contents) +static void +print_token(const Token *t, const char *contents) { - static const char* TYPES[] = { - [TOKEN_IDENT] = "ident/type", + static const char *TYPES[] = { [TOKEN_IDENT] = "ident/type", [TOKEN_LPAREN] = "open paren", [TOKEN_RPAREN] = "close paren", [TOKEN_LBRACE] = "open brace", @@ -311,54 +294,55 @@ static void print_token(const Token* t, const char* contents) [TOKEN_FOR] = "for", [TOKEN_RETURN] = "return", [TOKEN_UNKNOWN] = "< UNKNOWN >", - [TOKEN_EOF] = "~EOF~" - }; + [TOKEN_EOF] = "~EOF~" }; printf("L%zu:%zu \t%-14s '", t->line + 1, t->col + 1, TYPES[t->type]); fwrite(contents + t->start, 1, t->end - t->start, stdout); printf("'\n"); } -static void add_token(Lexer* lex, Token tok) +static void +add_token(Lexer *lex, Token tok) { if (lex->token_count >= lex->token_cap) { lex->token_cap *= 2; - lex->tokens = (Token*)realloc(lex->tokens, sizeof(Token) * lex->token_cap); + lex->tokens = (Token *)realloc(lex->tokens, sizeof(Token) * lex->token_cap); } lex->tokens[lex->token_count++] = tok; } -void lexer_print(Lexer* lex) +void +lexer_print(Lexer *lex) { for (size_t i = 0; i < lex->token_count; i++) { print_token(&lex->tokens[i], lex->src); } } -void lexer_lex(Lexer* lex, const char* filename, const char* contents) +void +lexer_lex(Lexer *lex, const char *filename, const char *contents) { lex->line = 1; lex->col = 1; lex->pos = 0; lex->token_cap = 128; lex->token_count = 0; - lex->tokens = (Token*)calloc(lex->token_cap, sizeof(Token)); - if(lex->tokens == NULL) panic("lexer_lex: could not alloc"); + lex->tokens = (Token *)calloc(lex->token_cap, sizeof(Token)); + if (lex->tokens == NULL) panic("lexer_lex: could not alloc"); lex->filename = filename; lex->src = contents; lex->src_len = strlen(contents); for (;;) { Token tok = next_token(lex); add_token(lex, tok); - if (tok.type == TOKEN_EOF) - break; + if (tok.type == TOKEN_EOF) break; } } -const char* token_type_str(TokenType t) +const char * +token_type_str(TokenType t) { - static const char* type_strings[] = { - [TOKEN_IDENT] = "TOKEN_IDENT", + static const char *type_strings[] = { [TOKEN_IDENT] = "TOKEN_IDENT", [TOKEN_LPAREN] = "TOKEN_LPAREN", [TOKEN_RPAREN] = "TOKEN_RPAREN", [TOKEN_LBRACE] = "TOKEN_LBRACE", @@ -393,8 +377,7 @@ const char* token_type_str(TokenType t) [TOKEN_BREAK] = "TOKEN_BREAK", [TOKEN_PERCENT] = "TOKEN_PERCENT", [TOKEN_UNKNOWN] = "TOKEN_UNKNOWN", - [TOKEN_EOF] = "TOKEN_EOF" - }; + [TOKEN_EOF] = "TOKEN_EOF" }; if (t >= TOKEN_IDENT && t <= TOKEN_EOF) { return type_strings[t]; } else { diff --git a/src/parser.h b/src/parser.h @@ -1,7 +1,5 @@ #pragma once -#include "lexer.h" -#include "sem.h" #include "types.h" #include <stdlib.h> diff --git a/src/parser/ast.c b/src/parser/ast.c @@ -6,10 +6,10 @@ #include <stdbool.h> #include <assert.h> -Node* -make_postfix_node(UnaryOp op, Node* operand) +Node * +make_postfix_node(UnaryOp op, Node *operand) { - Node* node = (Node*)calloc(1, sizeof(Node)); + Node *node = (Node *)calloc(1, sizeof(Node)); if (node == NULL) panic("make_postfix_node: could not alloc"); node->type = NODE_UNARY_EXPR; node->scope = NULL; @@ -20,10 +20,10 @@ make_postfix_node(UnaryOp op, Node* operand) return node; } -Node* -make_subscript_node(Node* array, Node* index) +Node * +make_subscript_node(Node *array, Node *index) { - Node* node = calloc(1, sizeof(Node)); + Node *node = calloc(1, sizeof(Node)); if (node == NULL) panic("make_subscript_node: could not alloc"); node->type = NODE_SUBSCRIPT_EXPR; node->scope = NULL; @@ -33,8 +33,8 @@ make_subscript_node(Node* array, Node* index) return node; } -Node* -make_number_node(Parser* par) +Node * +make_number_node(Parser *par) { Token tok = consume(par); assert(tok.type == TOKEN_INT_LITERAL || tok.type == TOKEN_FLOAT_LITERAL); @@ -44,7 +44,7 @@ make_number_node(Parser* par) buf[i] = par->src[tok.start + i]; buf[len] = '\0'; double value = strtod(buf, NULL); - Node* node = (Node*)calloc(1, sizeof(Node)); + Node *node = (Node *)calloc(1, sizeof(Node)); if (node == NULL) panic("make_number_node: could not alloc"); node->type = tok.type == TOKEN_INT_LITERAL ? NODE_INT_LITERAL : NODE_FLOAT_LITERAL; node->scope = NULL; @@ -52,10 +52,10 @@ make_number_node(Parser* par) return node; } -Node* -make_unary_node(UnaryOp op, Node* operand) +Node * +make_unary_node(UnaryOp op, Node *operand) { - Node* node = (Node*)calloc(1, sizeof(Node)); + Node *node = (Node *)calloc(1, sizeof(Node)); if (node == NULL) panic("make_unary_node: could not alloc"); node->type = NODE_UNARY_EXPR; node->scope = NULL; @@ -66,11 +66,11 @@ make_unary_node(UnaryOp op, Node* operand) return node; } -Node* -make_string_node(Parser* par) +Node * +make_string_node(Parser *par) { Token tok = consume(par); - Node* node = (Node*)calloc(1, sizeof(Node)); + Node *node = (Node *)calloc(1, sizeof(Node)); if (node == NULL) panic("make_string_node: could not alloc"); node->type = NODE_STRING_LITERAL; node->scope = NULL; @@ -79,10 +79,10 @@ make_string_node(Parser* par) return node; } -Node* -make_binary_node(OpType op, Node* lhs, Node* rhs) +Node * +make_binary_node(OpType op, Node *lhs, Node *rhs) { - Node* node = (Node*)calloc(1, sizeof(Node)); + Node *node = (Node *)calloc(1, sizeof(Node)); if (node == NULL) panic("make_binary_node: could not alloc"); node->type = NODE_BINARY_EXPR; node->scope = NULL; @@ -93,10 +93,10 @@ make_binary_node(OpType op, Node* lhs, Node* rhs) return node; } -Node* +Node * make_empty_statement(void) { - Node* node = (Node*)calloc(1, sizeof(Node)); + Node *node = (Node *)calloc(1, sizeof(Node)); if (node == NULL) panic("make_empty_statement: could not alloc"); assert(node != NULL); node->type = NODE_EMPTY_STATEMENT; @@ -104,10 +104,10 @@ make_empty_statement(void) return node; } -Node* -make_call_node(Node* callee, NodeVec args) +Node * +make_call_node(Node *callee, NodeVec args) { - Node* call = (Node*)calloc(1, sizeof(Node)); + Node *call = (Node *)calloc(1, sizeof(Node)); if (call == NULL) panic("make_call_node: could not alloc"); assert(call != NULL); call->type = NODE_CALL_EXPR; diff --git a/src/parser/decl.c b/src/parser/decl.c @@ -6,8 +6,8 @@ #include <stdbool.h> #include <assert.h> -Node* -parse_type(Parser* par) +Node * +parse_type(Parser *par) { Token tok = expect(par, TOKEN_IDENT); @@ -18,7 +18,7 @@ parse_type(Parser* par) // // assume this is a user type // } - Node* node = calloc(1, sizeof(Node)); + Node *node = calloc(1, sizeof(Node)); if (node == NULL) panic("parse_type: alloc failed"); node->type = NODE_TYPE; node->scope = NULL; @@ -27,13 +27,13 @@ parse_type(Parser* par) } // <TYPE> name:<IDENT> -Node* -make_param_decl(Parser* par) +Node * +make_param_decl(Parser *par) { - Node* type = parse_type(par); + Node *type = parse_type(par); Token param_name = expect(par, TOKEN_IDENT); Span ident_name = { .start = param_name.start, .end = param_name.end }; - Node* param = (Node*)calloc(1, sizeof(Node)); + Node *param = (Node *)calloc(1, sizeof(Node)); if (param == NULL) panic("make_param_decl alloc failed"); param->type = NODE_PARAM; param->scope = NULL; @@ -43,22 +43,22 @@ make_param_decl(Parser* par) } NodeVec -parse_param_list(Parser* par) +parse_param_list(Parser *par) { NodeVec v = { 0 }; if (peek(par).type == TOKEN_RPAREN) return v; // found `)` no parameters v.cap = 4; - v.items = (Node**)calloc(v.cap, sizeof(Node*)); + v.items = (Node **)calloc(v.cap, sizeof(Node *)); if (v.items == NULL) panic("parse_param_list: could not alloc"); for (;;) { - Node* param = make_param_decl(par); + Node *param = make_param_decl(par); if (v.len == v.cap) { v.cap *= 2; - v.items = (Node**)realloc(v.items, v.cap * sizeof(Node*)); + v.items = (Node **)realloc(v.items, v.cap * sizeof(Node *)); } v.items[v.len++] = param; diff --git a/src/parser/expr.c b/src/parser/expr.c @@ -6,37 +6,34 @@ #include <stdbool.h> #include <assert.h> -Node* -parse_func_call(Parser* par) +Node * +parse_func_call(Parser *par) { Token tok = expect(par, TOKEN_IDENT); Span callee = { .start = tok.start, .end = tok.end }; - Node* ident = make_ident_node(callee); + Node *ident = make_ident_node(callee); - const char* name = span_str(par->src, ident->data.ident.name, (char[IDENTSZ]) { 0 }); + const char *name = span_str(par->src, ident->data.ident.name, (char[IDENTSZ]) { 0 }); printf("parse_func_call: %s\n", name); expect(par, TOKEN_LPAREN); - Node* call = (Node*)calloc(1, sizeof(Node)); + Node *call = (Node *)calloc(1, sizeof(Node)); if (call == NULL) panic("parse_func_call: alloc failed"); // start parse arguments if (peek(par).type != TOKEN_RPAREN) { - call->data.call_expr.args = (Node**)calloc(4, sizeof(Node*)); - if (call->data.call_expr.args == NULL) - panic("parse_func_call: args: could not alloc"); + call->data.call_expr.args = (Node **)calloc(4, sizeof(Node *)); + if (call->data.call_expr.args == NULL) panic("parse_func_call: args: could not alloc"); call->data.call_expr.cap = 4; call->data.call_expr.len = 0; for (;;) { - Node* arg = parse_expression(par); + Node *arg = parse_expression(par); if (call->data.call_expr.len == call->data.call_expr.cap) { call->data.call_expr.cap *= 2; - call->data.call_expr.args - = (Node**)realloc(call->data.call_expr.args, - call->data.call_expr.cap * sizeof(Node*)); + call->data.call_expr.args = (Node **)realloc(call->data.call_expr.args, call->data.call_expr.cap * sizeof(Node *)); } call->data.call_expr.args[call->data.call_expr.len++] = arg; @@ -53,8 +50,8 @@ parse_func_call(Parser* par) return call; } -Node* -parse_number(Parser* par) +Node * +parse_number(Parser *par) { Token tok = consume(par); assert(tok.type == TOKEN_INT_LITERAL || tok.type == TOKEN_FLOAT_LITERAL); @@ -66,7 +63,7 @@ parse_number(Parser* par) buf[len] = '\0'; double value = strtod(buf, NULL); - Node* num_node = (Node*)calloc(1, sizeof(Node)); + Node *num_node = (Node *)calloc(1, sizeof(Node)); if (num_node == NULL) panic("parse_number: alloc failed"); num_node->type = tok.type == TOKEN_INT_LITERAL ? NODE_INT_LITERAL : NODE_FLOAT_LITERAL; num_node->scope = NULL; @@ -74,12 +71,12 @@ parse_number(Parser* par) return num_node; } -Node* -parse_ident(Parser* par) +Node * +parse_ident(Parser *par) { Token tok = consume(par); assert(tok.type == TOKEN_IDENT); - Node* ident_node = (Node*)calloc(1, sizeof(Node)); + Node *ident_node = (Node *)calloc(1, sizeof(Node)); if (ident_node == NULL) panic("parse_ident: alloc failed"); ident_node->type = NODE_IDENT; ident_node->scope = NULL; @@ -93,21 +90,21 @@ parse_ident(Parser* par) } NodeVec -parse_func_arguments(Parser* par) +parse_func_arguments(Parser *par) { NodeVec v = { 0 }; if (peek(par).type == TOKEN_RPAREN) return v; // found `)` no arguments v.cap = 4; - v.items = (Node**)calloc(v.cap, sizeof(Node*)); + v.items = (Node **)calloc(v.cap, sizeof(Node *)); if (v.items == NULL) panic("parse_func_arguments: could not alloc"); for (;;) { - Node* arg = parse_expression(par); + Node *arg = parse_expression(par); if (v.len == v.cap) { v.cap *= 2; - v.items = (Node**)realloc(v.items, v.cap * sizeof(Node*)); + v.items = (Node **)realloc(v.items, v.cap * sizeof(Node *)); } v.items[v.len++] = arg; @@ -117,10 +114,10 @@ parse_func_arguments(Parser* par) return v; } -Node* -parse_postfix(Parser* par) +Node * +parse_postfix(Parser *par) { - Node* node = parse_primary(par); + Node *node = parse_primary(par); for (;;) { if (match(par, TOKEN_PLUSPLUS)) { @@ -128,7 +125,7 @@ parse_postfix(Parser* par) } else if (match(par, TOKEN_MINUSMINUS)) { node = make_postfix_node(OPER_POSTDEC, node); } else if (match(par, TOKEN_LBRACKET)) { - Node* index = parse_expression(par); // parse inside brackets + Node *index = parse_expression(par); // parse inside brackets expect(par, TOKEN_RBRACKET); node = make_subscript_node(node, index); // } else if (match(par, TOKEN_DOT)) { // TODO dot members and arrows @@ -150,10 +147,10 @@ parse_postfix(Parser* par) #define STARTING_ROOT_NODES 32 -Node* -make_program_node(Parser* par) +Node * +make_program_node(Parser *par) { - Node* node = (Node*)calloc(1, sizeof(Node)); + Node *node = (Node *)calloc(1, sizeof(Node)); if (node == NULL) panic("make_program_node: alloc failed"); node->type = NODE_PROGRAM; node->filename = par->filename; @@ -161,15 +158,15 @@ make_program_node(Parser* par) node->next = NULL; node->data.program.cap = STARTING_ROOT_NODES; node->data.program.len = 0; - node->data.program.decl = (Node**)calloc(STARTING_ROOT_NODES, sizeof(Node)); + node->data.program.decl = (Node **)calloc(STARTING_ROOT_NODES, sizeof(Node)); if (node->data.program.decl == NULL) panic("make_program_node: decls: alloc failed"); return node; } -Node* +Node * make_ident_node(Span name) { - Node* node = (Node*)calloc(1, sizeof(Node)); + Node *node = (Node *)calloc(1, sizeof(Node)); if (node == NULL) panic("make_ident_node: alloc failed"); node->type = NODE_IDENT; node->scope = NULL; @@ -178,8 +175,8 @@ make_ident_node(Span name) return node; } -Node* -parse_primary(Parser* par) +Node * +parse_primary(Parser *par) { Token tok = peek(par); if (tok.type == TOKEN_STRING_LITERAL) { return make_string_node(par); } @@ -187,27 +184,21 @@ parse_primary(Parser* par) if (tok.type == TOKEN_IDENT) { return parse_ident(par); } if (tok.type == TOKEN_LPAREN) { consume(par); // consume '(' - Node* node = parse_expression(par); + Node *node = parse_expression(par); expect(par, TOKEN_RPAREN); return node; } - const char* name = span_str( - par->src, (Span) { .start = tok.start, .end = tok.end }, (char[IDENTSZ]) { 0 }); - panic("Expected Primary Expr, but found '%s' (%s at %s:%zu:%zu", - name, - token_type_str(tok.type), - par->filename, - tok.line, - tok.col); + const char *name = span_str(par->src, (Span) { .start = tok.start, .end = tok.end }, (char[IDENTSZ]) { 0 }); + panic("Expected Primary Expr, but found '%s' (%s at %s:%zu:%zu", name, token_type_str(tok.type), par->filename, tok.line, tok.col); return NULL; } -Node* -parse_unary(Parser* par) +Node * +parse_unary(Parser *par) { - Node* inner = NULL; + Node *inner = NULL; switch (peek(par).type) { case TOKEN_MINUS: consume(par); @@ -235,8 +226,8 @@ parse_unary(Parser* par) } // called by parse_multiplicative -Node* -parse_term(Parser* par) +Node * +parse_term(Parser *par) { return parse_unary(par); } diff --git a/src/parser/parser.c b/src/parser/parser.c @@ -9,25 +9,22 @@ // TODO make sure ALL callocs have been successful Parser -parser_init(Lexer* lex) +parser_init(Lexer *lex) { - return (Parser) { .pos = 0, - .tokens = lex->tokens, - .token_count = lex->token_count, - .src = lex->src, - .src_len = lex->src_len, - .filename = lex->filename }; + return (Parser) { + .pos = 0, .tokens = lex->tokens, .token_count = lex->token_count, .src = lex->src, .src_len = lex->src_len, .filename = lex->filename + }; } Token -peek(Parser* par) +peek(Parser *par) { Token t = par->tokens[par->pos]; return t.type ? t : (Token) { .type = TOKEN_EOF }; } Token -peek2(Parser* par) +peek2(Parser *par) { if (par->pos + 1 >= par->token_count) return (Token) { .type = TOKEN_EOF }; Token t = par->tokens[par->pos + 1]; @@ -35,7 +32,7 @@ peek2(Parser* par) } Token -consume(Parser* par) +consume(Parser *par) { Token t = par->tokens[par->pos]; if (!t.type) return (Token) { .type = TOKEN_EOF }; @@ -44,31 +41,25 @@ consume(Parser* par) } bool -check(Parser* p, TokenType type) +check(Parser *p, TokenType type) { return (peek(p).type == type); } Token -expect(Parser* par, TokenType type) +expect(Parser *par, TokenType type) { Token tok = peek(par); if (tok.type != type) { - const char* name = range_str(par->src, tok.start, tok.end, (char[IDENTSZ]) { 0 }); - panic("Expected %d got '%s' (%d) at %s:%zu:%zu", - token_type_str(type), - name, - tok.type, - par->filename, - tok.line, - tok.col); + const char *name = range_str(par->src, tok.start, tok.end, (char[IDENTSZ]) { 0 }); + panic("Expected %d got '%s' (%d) at %s:%zu:%zu", token_type_str(type), name, tok.type, par->filename, tok.line, tok.col); assert(tok.type == type); } return consume(par); } bool -match(Parser* p, TokenType type) +match(Parser *p, TokenType type) { // printf("matching type %d\n", type); if (peek(p).type == type) { @@ -78,20 +69,20 @@ match(Parser* p, TokenType type) return false; } -static Node* -parse_multiplicative(Parser* par) +static Node * +parse_multiplicative(Parser *par) { - Node* node = parse_term(par); + Node *node = parse_term(par); for (;;) { if (match(par, TOKEN_STAR)) { - Node* rhs = parse_unary(par); + Node *rhs = parse_unary(par); node = make_binary_node(OP_MUL, node, rhs); } else if (match(par, TOKEN_SLASH)) { - Node* rhs = parse_unary(par); + Node *rhs = parse_unary(par); node = make_binary_node(OP_DIV, node, rhs); } else if (match(par, TOKEN_PERCENT)) { - Node* rhs = parse_unary(par); + Node *rhs = parse_unary(par); node = make_binary_node(OP_MOD, node, rhs); } else break; @@ -100,16 +91,16 @@ parse_multiplicative(Parser* par) return node; } // additive: +, - -static Node* -parse_additive(Parser* par) +static Node * +parse_additive(Parser *par) { - Node* node = parse_multiplicative(par); + Node *node = parse_multiplicative(par); for (;;) { if (match(par, TOKEN_PLUS)) { - Node* rhs = parse_multiplicative(par); + Node *rhs = parse_multiplicative(par); node = make_binary_node(OP_PLUS, node, rhs); } else if (match(par, TOKEN_MINUS)) { - Node* rhs = parse_multiplicative(par); + Node *rhs = parse_multiplicative(par); node = make_binary_node(OP_MINUS, node, rhs); } else break; @@ -117,22 +108,22 @@ parse_additive(Parser* par) return node; } -static Node* -parse_relational(Parser* par) +static Node * +parse_relational(Parser *par) { - Node* node = parse_additive(par); + Node *node = parse_additive(par); for (;;) { if (match(par, TOKEN_LT)) { - Node* rhs = parse_additive(par); + Node *rhs = parse_additive(par); node = make_binary_node('<', node, rhs); } else if (match(par, TOKEN_LT_EQ)) { - Node* rhs = parse_additive(par); + Node *rhs = parse_additive(par); node = make_binary_node(OP_LT_EQ, node, rhs); } else if (match(par, TOKEN_GT)) { - Node* rhs = parse_additive(par); + Node *rhs = parse_additive(par); node = make_binary_node('>', node, rhs); } else if (match(par, TOKEN_GT_EQ)) { - Node* rhs = parse_additive(par); + Node *rhs = parse_additive(par); node = make_binary_node(OP_GT_EQ, node, rhs); } else break; @@ -140,16 +131,16 @@ parse_relational(Parser* par) return node; } -static Node* -parse_equality(Parser* par) +static Node * +parse_equality(Parser *par) { - Node* node = parse_relational(par); + Node *node = parse_relational(par); for (;;) { if (match(par, TOKEN_EQUALITY)) { // "==" - Node* rhs = parse_relational(par); + Node *rhs = parse_relational(par); node = make_binary_node(OP_EQUALITY, node, rhs); } else if (match(par, TOKEN_INEQUALITY)) { // "!=" - Node* rhs = parse_relational(par); + Node *rhs = parse_relational(par); node = make_binary_node(OP_INEQUALITY, node, rhs); } else break; @@ -157,19 +148,19 @@ parse_equality(Parser* par) return node; } -Node* -parse_expression(Parser* par) +Node * +parse_expression(Parser *par) { return parse_equality(par); } -Node* -parse_expression_statement(Parser* par) +Node * +parse_expression_statement(Parser *par) { - Node* expr = parse_expression(par); + Node *expr = parse_expression(par); expect(par, TOKEN_SEMICOLON); - Node* node = (Node*)calloc(1, sizeof(Node)); + Node *node = (Node *)calloc(1, sizeof(Node)); if (node == NULL) panic("parse_expression_statement: could not alloc"); node->type = NODE_EXPR_STATEMENT; node->scope = NULL; @@ -181,8 +172,8 @@ parse_expression_statement(Parser* par) // // parse_statement // -Node* -parse_statement(Parser* par) +Node * +parse_statement(Parser *par) { Token tok = peek(par), tok2 = peek2(par); @@ -191,8 +182,7 @@ parse_statement(Parser* par) return parse_block(par); } - if (tok.type == TOKEN_IDENT && tok2.type == TOKEN_IDENT) - return parse_decl_or_func_decl(par); + if (tok.type == TOKEN_IDENT && tok2.type == TOKEN_IDENT) return parse_decl_or_func_decl(par); switch (tok.type) { case TOKEN_RETURN: @@ -220,11 +210,11 @@ parse_statement(Parser* par) } } -Node* -parse_block(Parser* par) +Node * +parse_block(Parser *par) { - Node* stmt; - Node* block = (Node*)calloc(1, sizeof(Node)); + Node *stmt; + Node *block = (Node *)calloc(1, sizeof(Node)); if (block == NULL) panic("parse_block: could not alloc"); block->type = NODE_BLOCK; block->scope = NULL; @@ -232,13 +222,9 @@ parse_block(Parser* par) stmt = parse_statement(par); if (block->data.block.cap == block->data.block.len) { - block->data.block.cap - = block->data.block.cap == 0 ? 4 : block->data.block.cap * 2; - block->data.block.stmts = realloc( - block->data.block.stmts, block->data.block.cap * sizeof(Node*)); - if (block->data.block.stmts == NULL) { - panic("realloc failed in parse_block"); - } + block->data.block.cap = block->data.block.cap == 0 ? 4 : block->data.block.cap * 2; + block->data.block.stmts = realloc(block->data.block.stmts, block->data.block.cap * sizeof(Node *)); + if (block->data.block.stmts == NULL) { panic("realloc failed in parse_block"); } } block->data.block.stmts[block->data.block.len++] = stmt; @@ -249,16 +235,14 @@ parse_block(Parser* par) return block; } -Node* -parse_declaration_statement(Parser* par) +Node * +parse_declaration_statement(Parser *par) { - Node* type = parse_type(par); // consumes the type (e.g., "float") + Node *type = parse_type(par); // consumes the type (e.g., "float") Token ident = expect(par, TOKEN_IDENT); // variable or function name - if (match(par, TOKEN_LPAREN)) { - perror("called a var decl but this looks to be a func decl"); - } + if (match(par, TOKEN_LPAREN)) { perror("called a var decl but this looks to be a func decl"); } - Node* var = calloc(1, sizeof(Node)); + Node *var = calloc(1, sizeof(Node)); if (var == NULL) panic("parse_declaration_statement: could not alloc"); var->type = NODE_VAR_DECL; var->scope = NULL; @@ -276,14 +260,14 @@ parse_declaration_statement(Parser* par) return var; } -Node* -parse_decl_or_func_decl(Parser* par) +Node * +parse_decl_or_func_decl(Parser *par) { - Node* type = parse_type(par); // consumes the type (e.g., "float") + Node *type = parse_type(par); // consumes the type (e.g., "float") Token ident = expect(par, TOKEN_IDENT); // variable or function name if (match(par, TOKEN_LPAREN)) { // function - Node* fn = calloc(1, sizeof(Node)); + Node *fn = calloc(1, sizeof(Node)); if (fn == NULL) panic("parse_decl_or_func_decl: func: could not alloc"); fn->type = NODE_FUNCTION_DECL; @@ -297,7 +281,7 @@ parse_decl_or_func_decl(Parser* par) expect(par, TOKEN_RPAREN); expect(par, TOKEN_LBRACE); - Node* body = parse_block(par); + Node *body = parse_block(par); fn->data.function_decl.body = body; fn->data.function_decl.name = (Span) { ident.start, ident.end }; @@ -308,7 +292,7 @@ parse_decl_or_func_decl(Parser* par) return fn; } else { // variable - Node* var = calloc(1, sizeof(Node)); + Node *var = calloc(1, sizeof(Node)); if (var == NULL) panic("parse_decl_or_func_decl: var: could not alloc"); var->type = NODE_VAR_DECL; var->scope = NULL; @@ -329,8 +313,8 @@ parse_decl_or_func_decl(Parser* par) } } -Node* -parse_declarations(Parser* par) +Node * +parse_declarations(Parser *par) { Token tok = peek(par); if (tok.type == TOKEN_EOF) return NULL; @@ -347,18 +331,17 @@ parse_declarations(Parser* par) } void -parser_parse(Ast* ast, Parser* par) +parser_parse(Ast *ast, Parser *par) { assert(par->token_count > 0 && "no tokens to parse"); - Node* node; - Node* program = make_program_node(par); + Node *node; + Node *program = make_program_node(par); for (;;) { node = parse_declarations(par); if (node == NULL) break; if (program->data.program.len == program->data.program.cap) { program->data.program.cap *= 2; - program->data.program.decl = (Node**)realloc(program->data.program.decl, - program->data.program.cap * sizeof(Node*)); + program->data.program.decl = (Node **)realloc(program->data.program.decl, program->data.program.cap * sizeof(Node *)); assert(program->data.program.decl != NULL && "realloc failed"); } program->data.program.decl[program->data.program.len++] = node; diff --git a/src/parser/stmt.c b/src/parser/stmt.c @@ -6,20 +6,20 @@ #include <stdbool.h> #include <assert.h> -Node* -parse_if(Parser* par) +Node * +parse_if(Parser *par) { expect(par, TOKEN_IF); expect(par, TOKEN_LPAREN); // @later remove necessity for parens - Node* cond = parse_expression(par); + Node *cond = parse_expression(par); expect(par, TOKEN_RPAREN); - Node* then_body = parse_statement(par); + Node *then_body = parse_statement(par); - Node* else_body = NULL; + Node *else_body = NULL; if (match(par, TOKEN_ELSE)) else_body = parse_statement(par); - Node* node = (Node*)calloc(1, sizeof(Node)); + Node *node = (Node *)calloc(1, sizeof(Node)); if (node == NULL) panic("parse_if: could not alloc"); node->type = NODE_IF; node->scope = NULL; @@ -29,17 +29,17 @@ parse_if(Parser* par) return node; } -Node* -parse_while(Parser* par) +Node * +parse_while(Parser *par) { expect(par, TOKEN_WHILE); expect(par, TOKEN_LPAREN); - Node* cond = parse_expression(par); + Node *cond = parse_expression(par); expect(par, TOKEN_RPAREN); - Node* body = parse_statement(par); + Node *body = parse_statement(par); - Node* node = (Node*)calloc(1, sizeof(Node)); + Node *node = (Node *)calloc(1, sizeof(Node)); if (node == NULL) panic("parse_while: could not alloc"); node->type = NODE_WHILE; node->scope = NULL; @@ -48,14 +48,14 @@ parse_while(Parser* par) return node; } -Node* -parse_for(Parser* par) +Node * +parse_for(Parser *par) { expect(par, TOKEN_FOR); expect(par, TOKEN_LPAREN); // init can be empty, a decl, or a expr statement - Node* init = NULL; // int i = 0 ... conditional expression stment + Node *init = NULL; // int i = 0 ... conditional expression stment if (!check(par, TOKEN_SEMICOLON)) { Token tok2 = peek2(par); if (tok2.type == TOKEN_IDENT) { @@ -66,17 +66,17 @@ parse_for(Parser* par) } else expect(par, TOKEN_SEMICOLON); - Node* cond = NULL; // i < len ... optional expression + Node *cond = NULL; // i < len ... optional expression if (!check(par, TOKEN_SEMICOLON)) cond = parse_expression(par); expect(par, TOKEN_SEMICOLON); - Node* inc = NULL; // i++ ... optional expression + Node *inc = NULL; // i++ ... optional expression if (!check(par, TOKEN_RPAREN)) { inc = parse_expression(par); } expect(par, TOKEN_RPAREN); - Node* body = parse_statement(par); + Node *body = parse_statement(par); - Node* node = (Node*)calloc(1, sizeof(Node)); + Node *node = (Node *)calloc(1, sizeof(Node)); node->type = NODE_FOR; node->scope = NULL; node->data.for_statement.init = init; @@ -88,20 +88,20 @@ parse_for(Parser* par) return node; } -Node* -parse_assignment(Parser* par) +Node * +parse_assignment(Parser *par) { Token ident = expect(par, TOKEN_IDENT); Span name = { .start = ident.start, .end = ident.end }; expect(par, TOKEN_EQUAL); - Node* expr = parse_expression(par); + Node *expr = parse_expression(par); - Node* assign = (Node*)calloc(1, sizeof(Node)); + Node *assign = (Node *)calloc(1, sizeof(Node)); if (assign == NULL) panic("parse_assignment: could not alloc"); assign->type = NODE_VAR_ASSIGN; assign->scope = NULL; - assign->data.var_assign.lhs = (Node*)calloc(1, sizeof(Node)); + assign->data.var_assign.lhs = (Node *)calloc(1, sizeof(Node)); if (assign->data.var_assign.lhs == NULL) panic("parse_for: lhs: could not alloc"); /* identifier @@ -125,25 +125,25 @@ parse_assignment(Parser* par) return assign; } -Node* -parse_break(Parser* par) +Node * +parse_break(Parser *par) { expect(par, TOKEN_BREAK); expect(par, TOKEN_SEMICOLON); - Node* node = (Node*)calloc(1, sizeof(Node)); + Node *node = (Node *)calloc(1, sizeof(Node)); if (node == NULL) panic("parse_break: could not alloc"); node->type = NODE_BREAK; node->scope = NULL; return node; } -Node* -parse_continue_statement(Parser* par) +Node * +parse_continue_statement(Parser *par) { expect(par, TOKEN_CONTINUE); // consume 'continue' - Node* node = (Node*)calloc(1, sizeof(Node)); + Node *node = (Node *)calloc(1, sizeof(Node)); if (node == NULL) panic("parse_continue_statemenet: could not alloc"); node->type = NODE_CONTINUE; node->scope = NULL; @@ -159,11 +159,11 @@ parse_continue_statement(Parser* par) return node; } -Node* -parse_return_statement(Parser* par) +Node * +parse_return_statement(Parser *par) { expect(par, TOKEN_RETURN); // consume 'return' - Node* ret = (Node*)calloc(1, sizeof(Node)); + Node *ret = (Node *)calloc(1, sizeof(Node)); if (ret == NULL) panic("parse_return_statemenet: could not alloc"); ret->type = NODE_RETURN; ret->scope = NULL; diff --git a/src/sem.h b/src/sem.h @@ -4,7 +4,6 @@ #include <stdlib.h> #include "types.h" -#include "parser.h" // Symbol table functions void symbol_add(const char *name, TypeInfo *type);