#ifndef LEX_H #define LEX_H #include "str.h" #define LEX_TOK_LIST\ X(EOF, "end-of-file")\ X(IDENT, "identifier")\ X(PROC, "proc")\ X(LET, "let")\ X(VAR, "var")\ X(CONST, "const")\ X(RETURN, "return")\ X(LBRACE, "{")\ X(RBRACE, "}")\ X(LPAREN, "(")\ X(RPAREN, ")")\ X(PLUS, "+")\ X(MINUS, "-")\ X(ASTERISK, "*")\ X(SLASH, "/")\ X(EQUALS, "=")\ X(COLON, ":")\ X(COMMA, ",")\ X(LIT_STR, "string literal")\ X(LIT_CHAR, "character literal")\ X(LIT_NUM, "numeric literal") #define LEX_TOK_CHAR_LIST\ X(TOK_LBRACE, '{')\ X(TOK_RBRACE, '}')\ X(TOK_LPAREN, '(')\ X(TOK_RPAREN, ')')\ X(TOK_PLUS, '+')\ X(TOK_MINUS, '-')\ X(TOK_ASTERISK, '*')\ X(TOK_SLASH, '/')\ X(TOK_EQUALS, '=')\ X(TOK_COLON, ':')\ X(TOK_COMMA, ',') typedef enum { #define X(n, s) TOK_##n, LEX_TOK_LIST #undef X TOK_MAX, } Token; static const char *lex_tok_str[TOK_MAX] = { #define X(n, s) s, LEX_TOK_LIST #undef X }; #define TMASK(t) (1L << t) typedef enum { #define X(n, s) TM_##n = TMASK(TOK_##n), LEX_TOK_LIST #undef X } TokMask; typedef struct { Token tok; Str ident; Str filename, buf; Arena arena; int ofs; } Lexer; typedef enum { LE_WARN, LE_ERROR } LexErr; void lex_start(Lexer *l, const char *path); void lex_free(Lexer *l); void lex_expected(Lexer *l, TokMask t); void lex_expected_not(Lexer *l, TokMask t); void lex_expect(Lexer *l, TokMask t); /* next -> expected */ void lex_expect_not(Lexer *l, TokMask t); /* next -> expected_not */ void lex_error(Lexer *l, LexErr e, Str msg); void lex_pos(Lexer *l, int *line, int *col); void lex_next(Lexer *l); #endif