#ifndef PARSE_H #define PARSE_H #include "collection.h" #include // phases: // https://en.cppreference.com/c/language/translation_phases // phase 1 - source chars typedef struct { char ch; int line; int col; } Char; typedef struct { const char* text; size_t i; int line; int col; } SourceIter; void source_iter_init(SourceIter* r, const char* text); Char source_iter_next(SourceIter* r); // phase 2 - logical source lines typedef struct { SourceIter* source_char_iter; Char curr; } LslIter; void lsl_iter_init(LslIter* r, SourceIter* source_iter); Char lsl_iter_next(LslIter* r); // phase 3 - preprocessor tokens typedef enum { Tok_Eof, Tok_Ident, Tok_Int, Tok_Str, Tok_Char, Tok_Whitespace, Tok_HeaderName, Tok_Eol = '\n', // NOTE: has value 10 Tok_Semicolon = ';', Tok_LParen = '(', Tok_RParen = ')', Tok_LBrace = '{', Tok_RBrace = '}', Tok_Comma = ',', Tok_Asterisk = '*', Tok_Hashtag = '#', } TokTy; const char* tokty_str(TokTy ty); typedef struct { TokTy ty; char* text; int line; int col; } Tok; typedef struct { LslIter* lsl_iter; Arena* arena; Char curr; bool lex_whitespace; bool lex_headername; } Lexer; void lexer_init(Lexer* r, LslIter* lsl_iter, Arena* arena); Tok lexer_next(Lexer* l); // phase 4 - preprocessor typedef struct MacroDef MacroDef; typedef struct MacroInv MacroInv; typedef struct { Lexer* lexer; Tok curr; MacroDef* defs; size_t defs_cap; size_t defs_size; Hashmap def_map; Arena arg_arena; MacroInv* macro_invs; size_t macro_invs_cap; size_t macro_invs_size; } Preproc; void preproc_init(Preproc* p, Lexer* lexer); void preproc_deinit(Preproc* p); Tok preproc_next_with_newline(Preproc* p); Tok preproc_next(Preproc* p); #endif