summaryrefslogtreecommitdiff
path: root/scope.c
diff options
context:
space:
mode:
authorCarson Fleming <cflems@cflems.net>2026-07-26 19:20:30 -0700
committerCarson Fleming <cflems@cflems.net>2026-07-26 19:20:30 -0700
commit4f9d0247549b06ddb25b76bb425541190105cb48 (patch)
tree56f191c3611fc7509e6350138ce03c20956b656f /scope.c
parent6a169de321b131e73b86967a1a8564365217275a (diff)
downloadccc-4f9d0247549b06ddb25b76bb425541190105cb48.tar.gz
functioning type system perhaps?
Diffstat (limited to 'scope.c')
-rw-r--r--scope.c139
1 files changed, 16 insertions, 123 deletions
diff --git a/scope.c b/scope.c
index d725c2f..3f3dc44 100644
--- a/scope.c
+++ b/scope.c
@@ -1,14 +1,13 @@
#include "scope.h"
-#include "ast.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define DEFAULT_SIZE 16
static void scope_init(struct scope* scope) {
- scope->types = calloc(DEFAULT_SIZE, sizeof(struct type_def*));
+ scope->types = ccc_alloc(DEFAULT_SIZE * sizeof(struct type_def*));
scope->type_cap = DEFAULT_SIZE;
- scope->vars = calloc(DEFAULT_SIZE, sizeof(struct var_def*));
+ scope->vars = ccc_alloc(DEFAULT_SIZE * sizeof(struct var_def*));
scope->var_cap = DEFAULT_SIZE;
}
@@ -47,41 +46,23 @@ static integral_t hash_name(const char* name, integral_t cap) {
return hash;
}
-integral_t hash_type_key(const struct type_key* key, integral_t cap) {
- integral_t hash = hash_name(key->name, cap);
- hash = advance_hash(hash, key->how_long, cap);
- hash = advance_hash(hash, key->marked_signed, cap);
- hash = advance_hash(hash, key->marked_unsigned, cap);
- return hash;
-}
-
-static bool type_keys_equal(
- const struct type_key* a,
- const struct type_key* b
-) {
- return a->how_long == b->how_long
- && a->marked_signed == b->marked_signed
- && a->marked_unsigned == b->marked_unsigned
- && strcmp(a->name, b->name) == 0;
-}
-
-static struct type_def** type_cell(
+static struct type_alias** type_cell(
const struct scope* scope,
- const struct type_key* key
+ const char* name
) {
- integral_t orig_idx = hash_type_key(key, scope->type_cap);
+ integral_t orig_idx = hash_name(name, scope->type_cap);
integral_t idx = orig_idx;
do {
if (scope->types[idx] == NULL
- || type_keys_equal(key, &scope->types[idx]->key))
+ || strcmp(name, scope->types[idx]->name) == 0)
return &scope->types[idx];
} while ((idx = (idx + 1) % scope->type_cap) != orig_idx);
return NULL;
}
static void rehash_types(struct scope* scope) {
- struct type_def** old_types = scope->types;
+ struct type_alias** old_types = scope->types;
integral_t old_cap = scope->type_cap;
scope->type_cap *= 2;
scope->types = calloc(scope->type_cap, sizeof(struct type_def*));
@@ -93,7 +74,7 @@ static void rehash_types(struct scope* scope) {
for (integral_t i = 0; i < old_cap; i++) {
if (old_types[i] == NULL) continue;
- struct type_def** cell = type_cell(scope, &old_types[i]->key);
+ struct type_alias** cell = type_cell(scope, old_types[i]->name);
if (cell == NULL) {
fprintf(stderr, "ccc: types rehash failed, likely a bug\n");
exit(1);
@@ -152,101 +133,13 @@ void scope_pop(struct scope** p_scope) {
*p_scope = (*p_scope)->next_out;
}
-void scope_install_default_types(struct ast* ast) {
- /* TODO: don't let people make void variables */
- ast->void_type = scope_define_type(ast->root_scope, (struct type_def) {
- .key = {
- .name = "void",
- .how_long = 0,
- .marked_signed = false,
- .marked_unsigned = false,
- },
- .is_signed = false,
- .is_floating = false,
- .sz = 0,
- });
-
- ast->char_type = scope_define_type(ast->root_scope, (struct type_def) {
- .key = {
- .name = "char",
- .how_long = 0,
- .marked_signed = false,
- .marked_unsigned = false,
- },
- .sz = 1,
- .is_signed = true, /* implementation defined babyyyyyy */
- .is_floating = false,
- });
-
- scope_define_type(ast->root_scope, (struct type_def) {
- .key = {
- .name = "short",
- .how_long = 0,
- .marked_signed = false,
- .marked_unsigned = false,
- },
- .sz = 2,
- .is_signed = true,
- .is_floating = false,
- });
-
- scope_define_type(ast->root_scope, (struct type_def) {
- .key = {
- .name = "int",
- .how_long = 0,
- .marked_signed = false,
- .marked_unsigned = false,
- },
- .sz = 4,
- .is_signed = true,
- .is_floating = false,
- });
-
- ast->integral_type = scope_define_type(ast->root_scope, (struct type_def) {
- .key = {
- .name = "int",
- .how_long = 1,
- .marked_signed = false,
- .marked_unsigned = false,
- },
- .sz = 8,
- .is_signed = true,
- .is_floating = false,
- });
- ast->pointer_type = ast->integral_type; /* TODO: support pointers */
-
- scope_define_type(ast->root_scope, (struct type_def) {
- .key = {
- .name = "float",
- .how_long = 0,
- .marked_signed = false,
- .marked_unsigned = false,
- },
- .sz = 4,
- .is_signed = true,
- .is_floating = true,
- });
-
- ast->decimal_type = scope_define_type(ast->root_scope, (struct type_def) {
- .key = {
- .name = "double",
- .how_long = 0,
- .marked_signed = false,
- .marked_unsigned = false,
- },
- .sz = 8,
- .is_signed = true,
- .is_floating = true,
- });
-}
-
bool scope_get_type(
const struct scope* scope,
- const struct type_def** p_entry,
- const struct type_key* key
+ const struct type_alias** p_entry,
+ const char* name
) {
for (; scope != NULL; scope = scope->next_out) {
- struct type_def** cell = type_cell(scope, key);
+ struct type_alias** cell = type_cell(scope, name);
if (cell == NULL || *cell == NULL) continue;
if (p_entry != NULL) *p_entry = *cell;
return true;
@@ -254,20 +147,20 @@ bool scope_get_type(
return false;
}
-const struct type_def* scope_define_type(
+const struct type_alias* scope_define_type(
struct scope* scope,
- struct type_def type
+ struct type_alias type
) {
- struct type_def** cell = type_cell(scope, &type.key);
+ struct type_alias** cell = type_cell(scope, type.name);
while (cell == NULL) {
rehash_types(scope);
- cell = type_cell(scope, &type.key);
+ cell = type_cell(scope, type.name);
}
/* redefinition leaks memory, so refuse */
if (*cell != NULL) return NULL;
- *cell = calloc(1, sizeof(struct type_def));
+ *cell = calloc(1, sizeof(struct type_alias));
if (*cell == NULL) {
fprintf(stderr, "ccc: out of memory\n");
exit(1);