aboutsummaryrefslogtreecommitdiffstats
path: root/src/parser.h
blob: f4388636fb5153641a6dae2bdf8bc21961bbcef6 (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
89
90
91
92
93
94
95
96
97
98
99
100
#ifndef BDL_PARSER_H
#define BDL_PARSER_H

#include "lexer.h"

typedef enum ObjectType {
    OBJ_TYPE_NIL,
    OBJ_TYPE_TRUE,
    OBJ_TYPE_FALSE,
    OBJ_TYPE_FIXNUM,
    OBJ_TYPE_SYMBOL,
    OBJ_TYPE_STRING,
    OBJ_TYPE_PAIR,
} ObjectType;

typedef struct Object {
    ObjectType type;
    union {
        // OBJ_TYPE_FIXNUM
        ssize_t fixnum;

        // OBJ_TYPE_STRING
        // OBJ_TYPE_SYMBOL
        char *text;

        // OBJ_TYPE_PAIR
        struct {
            struct Object *car;
            struct Object *cdr;
        };
    };

    size_t line;
    size_t col;
} Object;

typedef struct Parser {
    Token *tokens;
    size_t current;

    // Unique symbols and strings.
    Object **symbols;
    Object **strings;
} Parser;

typedef Object* Root;

typedef struct ParserResults {
    // All root statements.
    Root *roots;

    // Unique symbols (tracking only first occurence).
    Object **symbols;

    // Unique strings (tracking only first occurence).
    Object **strings;
} ParserResults;

// Mimics the functionality in the Scanner functions, but for tokens.
Token next_token(Parser *parser);
Token previous_token(Parser *parser);
Token rewind_token(Parser *parser);
Token peek_token(const Parser *parser);
bool has_next_token(const Parser *parser);

// Parsing operations.
Object * parse_tree(Parser *parser, Errors *errors);
Object * parse_symbol(Parser *parser, Token tok);
Object * parse_string(Parser *parser, Token tok);
Object * parse_bool(Token tok);
Object * parse_fixnum(Token tok);
Object * parse_list(Parser *parser, Errors *errors);
ParserResults parse(Token *tokens, Errors *errors);

// Object operations.
void object_display(Object *obj);
bool object_equal(Object *a, Object *b);

// Manage resources.
Object * object_alloc(Token tok, ObjectType type);
void object_free(Object *node);
void free_parser_results(ParserResults *pr);

//
// Helper macros.
//

// Type checking.
#define IS_NIL(VAL)    ((VAL)->type == OBJ_TYPE_NIL)
#define IS_TRUE(VAL)   ((VAL)->type != OBJ_TYPE_FALSE)
#define IS_FALSE(VAL)  ((VAL)->type == OBJ_TYPE_FALSE)
#define IS_FIXNUM(VAL) ((VAL)->type == OBJ_TYPE_FIXNUM)
#define IS_STRING(VAL) ((VAL)->type == OBJ_TYPE_STRING)
#define IS_SYMBOL(VAL) ((VAL)->type == OBJ_TYPE_SYMBOL)
#define IS_PAIR(VAL)   ((VAL)->type == OBJ_TYPE_PAIR)

// Debug.
#define OBJ_PRINT(OBJ) object_display(OBJ); printf("\n");

#endif // BDL_PARSER_H