summaryrefslogtreecommitdiff
path: root/lex.h
blob: 66de6d5d21bfdf2315cd1bbcb7ac5f88d887db01 (plain)
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
#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(NOT, "~")\
	X(AND, "&")\
	X(OR, "|")\
	X(XOR, "^")\
	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, ',')\
	X(TOK_NOT, '~')\
	X(TOK_AND, '&')\
	X(TOK_OR, '|')\
	X(TOK_XOR, '^')


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 {
	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