summaryrefslogtreecommitdiff
path: root/compiler/lexer/keywords.c
blob: 88c2e67ead7e52c39ba28c022cef5408609a7eb8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/*
 * Keyword hashmap.
 * Copyright (c) 2023-2024, Quinn Stephens and the OSMORA team.
 * Provided under the BSD 3-Clause license.
 */

#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include "hash.h"
#include "hashmap.h"
#include "debug.h"
#include "lexer/keywords.h"

#define HASHMAP_ROWS 8

struct keyword {
    struct hashmap_entry hashmap_entry;
    size_t len;
    token_kind_t value;
};

static bool initialized = false;
static struct list keywords_rows[HASHMAP_ROWS];
static struct hashmap keywords;

static void
add_keyword(char *name, token_kind_t value)
{
    size_t len;
    struct keyword *kwd;

    len = strlen(name);
    kwd = malloc(sizeof(struct keyword));
    kwd->hashmap_entry.hash = hash_data(name, len);
    kwd->len = len;
    kwd->value = value;

    hashmap_add(&keywords, &kwd->hashmap_entry);
}

token_kind_t
keywords_find(struct token *tok)
{
    struct keyword *kwd;

    kwd = (struct keyword*)hashmap_find(&keywords, tok->hash);
    if (kwd == NULL || kwd->len != tok->len) {
        return TK_UNKNOWN;
    }

    return kwd->value;
}

void
keywords_init(void)
{
    if (initialized) {
        return;
    }

    debug("Initializing keywords...\n");

    keywords.rows = keywords_rows;
    keywords.n_rows = HASHMAP_ROWS;
    hashmap_init(&keywords);

    add_keyword("proc", TK_PROC);
    add_keyword("type", TK_TYPE);
    add_keyword("enum", TK_ENUM);
    add_keyword("struct", TK_STRUCT);

    initialized = true;
}