1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
#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
|