#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