#ifndef LEX_H #define LEX_H #include "str.h" #define LEX_TOK_LIST\ X(TOK_EOF, "end-of-file")\ X(TOK_IDENT, "identifier")\ X(TOK_PROC, "proc")\ X(TOK_LET, "let")\ X(TOK_VAR, "var")\ X(TOK_CONST, "const")\ X(TOK_RETURN, "return")\ 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, ",")\ X(TOK_LIT_STR, "string literal")\ X(TOK_LIT_CHAR, "character literal")\ X(TOK_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) 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 unsigned long 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