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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
#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(FUNC, "func")\
X(LET, "let")\
X(VAR, "var")\
X(CONST, "const")\
X(RETURN, "return")\
X(TRUE, "true")\
X(FALSE, "false")\
X(IF, "if")\
X(ELSE, "else")\
X(LBRACE, "{")\
X(RBRACE, "}")\
X(LPAREN, "(")\
X(RPAREN, ")")\
X(PLUS, "+")\
X(MINUS, "-")\
X(ASTERISK, "*")\
X(SLASH, "/")\
X(COLON, ":")\
X(COMMA, ",")\
X(NOT, "~")\
X(AND, "&")\
X(OR, "|")\
X(XOR, "xor")\
X(SHL, "<<")\
X(SHR, ">>")\
X(ASSIGN, ":=")\
X(EQL, "=")\
X(NEQ, "<>")\
X(LES, "<")\
X(GTR, ">")\
X(LTE, "<=")\
X(GTE, ">=")\
X(DEREF, "^")\
X(LIT_STR, "string")\
X(LIT_CHAR, "character")\
X(LIT_NUM, "number")
#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_EQL, '=')\
X(TOK_COMMA, ',')\
X(TOK_NOT, '~')\
X(TOK_AND, '&')\
X(TOK_OR, '|')\
X(TOK_DEREF, '^')
typedef enum {
#define X(n, s) TOK_##n,
LEX_TOK_LIST
#undef X
TOK_MAX,
} Token;
#define TMASK(t) (1L << t)
typedef enum {
#define X(n, s) TM_##n = TMASK(TOK_##n),
LEX_TOK_LIST
#undef X
} TokMask;
typedef struct {
int ofs, n;
} LexSpan;
typedef struct {
Token tok;
Str ident;
LexSpan pos;
Str filename, buf;
Arena arena;
int ofs;
} Lexer;
typedef enum {
LE_NONE,
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_at(Lexer *l, LexSpan pos, LexErr e, Str msg);
void lex_error(Lexer *l, LexErr e, Str msg);
void lex_pos(Lexer *l, int ofs, int *line, int *col);
void lex_next(Lexer *l);
#endif
|