#ifndef BDL_PARSER_H #define BDL_PARSER_H #include "lexer.h" typedef struct Environment { struct Object **locals; struct Object **local_values; struct Object **params; struct Object **captured; 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, OBJ_TYPE_BUILTIN, } ObjectType; typedef enum Builtin { BUILTIN_ADD, BUILTIN_SUB, BUILTIN_MUL, BUILTIN_DIV, BUILTIN_MOD, BUILTIN_EQ, BUILTIN_LT, BUILTIN_GT, BUILTIN_LE, BUILTIN_GE, BUILTIN_NOT, BUILTIN_AND, BUILTIN_OR, BUILTIN_IS_NIL, BUILTIN_IS_ZERO, BUILTIN_IS_FIXNUM, BUILTIN_IS_BOOL, BUILTIN_PRINT, BUILTIN_CONS, BUILTIN_CAR, BUILTIN_CDR, } Builtin; 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; }; // OBJ_TYPE_BUILTIN struct { Builtin builtin; StringView builtin_text; }; }; bool visited; size_t line; size_t col; } Object; typedef struct Parser { Token *tokens; size_t current; } Parser; typedef Object* Root; typedef struct Program { Root *roots; Environment *env; } Program; // 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); Program 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) #define IS_BUILTIN(VAL) ((VAL)->type == OBJ_TYPE_BUILTIN) // Debug. #define OBJ_PRINT(OBJ) object_display(OBJ); printf("\n"); #endif // BDL_PARSER_H