143 lines
5.7 KiB
C
143 lines
5.7 KiB
C
/* spl_lexer.h — 独立词法分析器 */
|
|
#ifndef __SPL_LEXER_H__
|
|
#define __SPL_LEXER_H__
|
|
|
|
#include "../stage0/spl_ir.h"
|
|
|
|
/* clang-format off */
|
|
#define KEYWORD_TABLE \
|
|
X(as , KW_AS , SPL_V0) \
|
|
X(asm , KW_ASM , SPL_V0) \
|
|
X(bool , KW_BOOL , SPL_V0) \
|
|
X(break , KW_BREAK , SPL_V0) \
|
|
X(catch , KW_CATCH , SPL_V0) \
|
|
X(comptime , KW_COMPTIME , SPL_V0) \
|
|
X(const , KW_CONST , SPL_V0) \
|
|
X(continue , KW_CONTINUE , SPL_V0) \
|
|
X(defer , KW_DEFER , SPL_V0) \
|
|
X(else , KW_ELSE , SPL_V0) \
|
|
X(enum , KW_ENUM , SPL_V0) \
|
|
X(errdefer , KW_ERRDEFER , SPL_V0) \
|
|
X(false , KW_FALSE , SPL_V0) \
|
|
X(fn , KW_FN , SPL_V0) \
|
|
X(for , KW_FOR , SPL_V0) \
|
|
X(if , KW_IF , SPL_V0) \
|
|
X(loop , KW_LOOP , SPL_V0) \
|
|
X(match , KW_MATCH , SPL_V0) \
|
|
X(null , KW_NULL , SPL_V0) \
|
|
X(pub , KW_PUB , SPL_V0) \
|
|
X(ret , KW_RET , SPL_V0) \
|
|
X(struct , KW_STRUCT , SPL_V0) \
|
|
X(test , KW_TEST , SPL_V0) \
|
|
X(true , KW_TRUE , SPL_V0) \
|
|
X(try , KW_TRY , SPL_V0) \
|
|
X(type , KW_TYPE , SPL_V0) \
|
|
X(union , KW_UNION , SPL_V0) \
|
|
X(var , KW_VAR , SPL_V0) \
|
|
X(void , KW_VOID , SPL_V0) \
|
|
X(while , KW_WHILE , SPL_V0) \
|
|
X(_ , KW_ANY , SPL_V0) \
|
|
// KEYWORD_TABLE
|
|
|
|
#define TOKEN_TABLE \
|
|
X(unknown , TOK_UNKNOWN , SPL_V0 ) \
|
|
X(EOF , TOK_EOF , SPL_V0 ) \
|
|
X(blank , TOK_BLANK , SPL_V0 ) \
|
|
X(endline , TOK_ENDLINE , SPL_V0 ) \
|
|
X("#" , TOK_SHARP , SPL_V0 ) \
|
|
X("@" , TOK_AT , SPL_V0 ) \
|
|
X("==" , TOK_EQ , SPL_V0 ) \
|
|
X("=" , TOK_ASSIGN , SPL_V0 ) \
|
|
X("+=" , TOK_ASSIGN_ADD , SPL_V0 ) \
|
|
X("+" , TOK_ADD , SPL_V0 ) \
|
|
X("-=" , TOK_ASSIGN_SUB , SPL_V0 ) \
|
|
X("->" , TOK_RIGHT_ARRAY , SPL_V0 ) \
|
|
X("<-" , TOK_LEFT_ARRAY , SPL_V0 ) \
|
|
X("-" , TOK_SUB , SPL_V0 ) \
|
|
X("*=" , TOK_ASSIGN_MUL , SPL_V0 ) \
|
|
X("*" , TOK_MUL , SPL_V0 ) \
|
|
X("/=" , TOK_ASSIGN_DIV , SPL_V0 ) \
|
|
X("/" , TOK_DIV , SPL_V0 ) \
|
|
X("//" , TOK_LINE_COMMENT , SPL_V0 ) \
|
|
X("/* */" , TOK_BLOCK_COMMENT , SPL_V0 ) \
|
|
X("%=" , TOK_ASSIGN_MOD , SPL_V0 ) \
|
|
X("%" , TOK_MOD , SPL_V0 ) \
|
|
X("&&" , TOK_AND_AND , SPL_V0 ) \
|
|
X("&=" , TOK_ASSIGN_AND , SPL_V0 ) \
|
|
X("&" , TOK_AND , SPL_V0 ) \
|
|
X("||" , TOK_OR_OR , SPL_V0 ) \
|
|
X("|=" , TOK_ASSIGN_OR , SPL_V0 ) \
|
|
X("|" , TOK_OR , SPL_V0 ) \
|
|
X("^=" , TOK_ASSIGN_XOR , SPL_V0 ) \
|
|
X("^" , TOK_XOR , SPL_V0 ) \
|
|
X("<<=" , TOK_ASSIGN_L_SH , SPL_V0 ) \
|
|
X("<<" , TOK_L_SH , SPL_V0 ) \
|
|
X("<=" , TOK_LE , SPL_V0 ) \
|
|
X("<" , TOK_LT , SPL_V0 ) \
|
|
X(">>=" , TOK_ASSIGN_R_SH , SPL_V0 ) \
|
|
X(">>" , TOK_R_SH , SPL_V0 ) \
|
|
X(">=" , TOK_GE , SPL_V0 ) \
|
|
X(">" , TOK_GT , SPL_V0 ) \
|
|
X("!" , TOK_NOT , SPL_V0 ) \
|
|
X("!=" , TOK_NEQ , SPL_V0 ) \
|
|
X("~" , TOK_BIT_NOT , SPL_V0 ) \
|
|
X("[" , TOK_L_BRACKET , SPL_V0 ) \
|
|
X("]" , TOK_R_BRACKET , SPL_V0 ) \
|
|
X("(" , TOK_L_PAREN , SPL_V0 ) \
|
|
X(")" , TOK_R_PAREN , SPL_V0 ) \
|
|
X("{" , TOK_L_BRACE , SPL_V0 ) \
|
|
X("}" , TOK_R_BRACE , SPL_V0 ) \
|
|
X(";" , TOK_SEMICOLON , SPL_V0 ) \
|
|
X("," , TOK_COMMA , SPL_V0 ) \
|
|
X(":" , TOK_COLON , SPL_V0 ) \
|
|
X(":=" , TOK_COLON_ASSIGN , SPL_V0 ) \
|
|
X("." , TOK_DOT , SPL_V0 ) \
|
|
X(".." , TOK_RANGE , SPL_V0 ) \
|
|
X("..." , TOK_ELLIPSIS , SPL_V0 ) \
|
|
X("?" , TOK_COND , SPL_V0 ) \
|
|
X(ident , TOK_IDENT , SPL_V0 ) \
|
|
X(int , TOK_INT_LITERAL , SPL_V0 ) \
|
|
X(float , TOK_FLOAT_LITERAL , SPL_V0 ) \
|
|
X(char , TOK_CHAR_LITERAL , SPL_V0 ) \
|
|
X(string , TOK_STRING_LITERAL , SPL_V0 ) \
|
|
// TOKEN_TABLE
|
|
/* clang-format on */
|
|
|
|
/* spl_tok_type_t — KEYWORD_TABLE + TOKEN_TABLE 展开 */
|
|
/* clang-format off */
|
|
typedef enum {
|
|
#define X(name, enum_name, dummy) enum_name,
|
|
KEYWORD_TABLE
|
|
#undef X
|
|
#define X(name, enum_name, dummy) enum_name,
|
|
TOKEN_TABLE
|
|
#undef X
|
|
} spl_tok_type_t;
|
|
/* clang-format on */
|
|
|
|
typedef struct {
|
|
spl_tok_type_t type;
|
|
const char *lexeme;
|
|
usize len; /* token length in bytes */
|
|
const char *fname;
|
|
usize offset;
|
|
usize line;
|
|
usize col;
|
|
} spl_tok_t;
|
|
|
|
typedef VEC(spl_tok_t) spl_tok_vec_t;
|
|
|
|
/* Lexer entry point */
|
|
spl_tok_vec_t spl_lex(const char *source, const char *fname);
|
|
|
|
/* Utility functions */
|
|
const char *spl_tok_type_name(spl_tok_type_t type);
|
|
void spl_tok_dump(spl_tok_t *tok);
|
|
void spl_tok_vec_dump(spl_tok_vec_t *toks);
|
|
void spl_tok_vec_drop(spl_tok_vec_t *toks);
|
|
|
|
/* Decode escape sequence, advance *s past it. Returns 0 on success. */
|
|
int spl_decode_escape(const char **s, char *out);
|
|
|
|
#endif /* __SPL_LEXER_H__ */
|