aboutsummaryrefslogtreecommitdiffstats
path: root/src/parser.h
blob: 17bd6d6de578dfa29af1508a014a8b9ee5cc548f (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
#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,
    OBJ_TYPE_LAMBDA,
} 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 *head;
            struct Object *tail;
        };

        // OBJ_TYPE_LAMBDA
         struct {
             struct Object **params;
             struct Object **body;
         };
    };

    size_t line;
    size_t col;
} Object;

typedef struct Parser {
    Token *tokens;
    size_t current;
} Parser;

typedef Object* Root;

// 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(Token tok);
Object * parse_string(Token tok);
Object * parse_bool(Token tok);
Object * parse_fixnum(Token tok);
Object * parse_list(Parser *parser, Errors *errors);
Object * parse_lambda(Parser *parser, Errors *errors);
Root * parse(Token *tokens, Errors *errors);

// Object operations.
void object_display(Object *obj);

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

//
// 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)
#define IS_LAMBDA(VAL) ((VAL)->type == OBJ_TYPE_LAMBDA)

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

#endif // BDL_PARSER_H