summaryrefslogtreecommitdiff
path: root/compiler/parser/parser.c
blob: 261385b846b0038371127edb6df5b8774a6009de (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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*
 * Quark parser.
 * Turns tokens into an AST (Abstract Syntax Tree).
 * Copyright (c) 2023-2024, Quinn Stephens and the OSMORA team.
 * Provided under the BSD 3-Clause license.
 */

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "debug.h"
#include "hashmap.h"
#include "parser/type.h"
#include "parser.h"

static void
add_builtin(struct hashmap *map, char *name, size_t size, int n_ptrs)
{
    struct type *type;
    size_t name_len;

    name_len = strlen(name);

    type = malloc(sizeof(struct type));
    type->hashmap_entry.hash = hash_data(name, name_len);
    type->name = name;
    type->name_len = name_len;
    type->size = size;
    type->n_ptrs = n_ptrs;

    hashmap_add(map, &type->hashmap_entry);
}

void
tok_error(struct token *tok, const char *fmt, ...)
{
    va_list ap;

    fprintf(stderr, "\033[1m%s:%d:%d: \033[31merror:\033[0m ", tok->fname, tok->line, tok->col);
    va_start(ap, fmt);
    vfprintf(stderr, fmt, ap);
    va_end(ap);
}

void
tok_warn(struct token *tok, const char *fmt, ...)
{
    va_list ap;

    printf("\033[1m%s:%d:%d: \033[33mwarning:\033[0m ", tok->fname, tok->line, tok->col);
    va_start(ap, fmt);
    vprintf(fmt, ap);
    va_end(ap);
}

void
parser_parse(struct parser *ctx)
{
    debug("Parsing...\n");

    next_token(ctx);
    while (ctx->tok.kind != TK_EOF) {
        switch (ctx->tok.kind) {
        case TK_TYPE:
            parse_type(ctx);
            break;
        default:
            tok_error(&ctx->tok, "unexpected \"%.*s\"\n", (int)ctx->tok.len, ctx->tok.pos);
            next_token(ctx);
            break;
        }
    }
}

void
parser_init(struct parser *ctx, char *source)
{
    debug("Initializing parser...\n");
    lexer_init(&ctx->lexer, source);

    add_builtin(ctx->types, "any", 0, 0);
    add_builtin(ctx->types, "uint", sizeof(void*), 0);
    add_builtin(ctx->types, "uint64", 8, 0);
    add_builtin(ctx->types, "uint32", 4, 0);
    add_builtin(ctx->types, "uint16", 2, 0);
    add_builtin(ctx->types, "uint8", 1, 0);
}