aboutsummaryrefslogtreecommitdiffstats
path: root/src/parser.h
blob: 9414a247b6a0baab83b0487301df0f9ddc05722f (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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#ifndef BDL_PARSER_H
#define BDL_PARSER_H

#include "lexer.h"
#include "hashtable.h"

typedef struct Environment {
    HashTable *table;
    struct Environment *parent;
} Environment;

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,
    OBJ_TYPE_IF,
    OBJ_TYPE_DEF,
    OBJ_TYPE_SET,
} ObjectType;

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

        // OBJ_TYPE_STRING
        // OBJ_TYPE_SYMBOL
        StringView text;

        // OBJ_TYPE_PAIR
        struct {
            struct Object *head;
            struct Object *tail;
            size_t n_elems;
        };

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

         // OBJ_TYPE_IF
         struct {
             struct Object *condition;
             struct Object *expr_true;
             struct Object *expr_false;
         };

         // OBJ_TYPE_DEF
         // OBJ_TYPE_SET
         struct {
             struct Object *var_name;
             struct Object *var_expr;
         };
    };

    bool visited;
    size_t line;
    size_t col;
} Object;

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

typedef Object* Root;

// Token scanner.
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);
Object * parse_if(Parser *parser, Errors *errors);
Object * parse_var(Parser *parser, Errors *errors);
Root * parse(Token *tokens, Errors *errors);

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

// Manage resources.
Environment * env_alloc(Environment *parent);
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_BOOL(VAL)   \
    (((VAL)->type == OBJ_TYPE_FALSE) || ((VAL)->type == OBJ_TYPE_TRUE))
#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