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
|