| L2_TOK_CLOSE_BRACKET, | L2_TOK_CLOSE_BRACKET, | ||||
| L2_TOK_COMMA, | L2_TOK_COMMA, | ||||
| L2_TOK_PERIOD, | L2_TOK_PERIOD, | ||||
| L2_TOK_NUMBER, | |||||
| L2_TOK_EOF, | L2_TOK_EOF, | ||||
| L2_TOK_NUMBER, | |||||
| L2_TOK_STRING, | L2_TOK_STRING, | ||||
| L2_TOK_ERROR, | L2_TOK_ERROR, | ||||
| }; | }; | ||||
| const char *l2_token_kind_name(enum l2_token_kind kind); | |||||
| struct l2_token { | struct l2_token { | ||||
| enum l2_token_kind kind; | enum l2_token_kind kind; | ||||
| int line; | int line; | ||||
| void l2_token_free(struct l2_token *tok); | void l2_token_free(struct l2_token *tok); | ||||
| struct l2_token l2_token_move(struct l2_token *tok); | struct l2_token l2_token_move(struct l2_token *tok); | ||||
| void l2_token_print(struct l2_token *tok, struct l2_io_writer *w); | |||||
| struct l2_lexer { | struct l2_lexer { | ||||
| struct l2_token currtok; | struct l2_token currtok; |
| #include "io.h" | #include "io.h" | ||||
| #include "parse/lex.h" | |||||
| int main() { | int main() { | ||||
| struct l2_io_mem_reader r = { l2_io_mem_read }; | struct l2_io_mem_reader r = { l2_io_mem_read }; | ||||
| r.mem = "Hello World"; | |||||
| r.mem = " \"Hello\", [], {}."; | |||||
| r.len = strlen(r.mem); | r.len = strlen(r.mem); | ||||
| struct l2_bufio_reader rb; | |||||
| l2_bufio_reader_init(&rb, &r.r); | |||||
| struct l2_lexer lexer; | |||||
| l2_lexer_init(&lexer, &r.r); | |||||
| while (1) { | while (1) { | ||||
| int ch = l2_bufio_get(&rb); | |||||
| if (ch == EOF) break; | |||||
| printf("%c", (char)ch); | |||||
| struct l2_token *tok = l2_lexer_get(&lexer); | |||||
| printf("%s\n", l2_token_kind_name(tok->kind)); | |||||
| if (tok->kind == L2_TOK_EOF) { | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| printf("\n"); | |||||
| } | } |
| #include <stdlib.h> | #include <stdlib.h> | ||||
| const char *l2_token_kind_name(enum l2_token_kind kind) { | |||||
| switch (kind) { | |||||
| case L2_TOK_OPEN_PAREN: | |||||
| return "open-paren"; | |||||
| case L2_TOK_CLOSE_PAREN: | |||||
| return "close-paren"; | |||||
| case L2_TOK_OPEN_BRACE: | |||||
| return "open-brace"; | |||||
| case L2_TOK_CLOSE_BRACE: | |||||
| return "close-brace"; | |||||
| case L2_TOK_OPEN_BRACKET: | |||||
| return "open-bracket"; | |||||
| case L2_TOK_CLOSE_BRACKET: | |||||
| return "close-bracket"; | |||||
| case L2_TOK_COMMA: | |||||
| return "comma"; | |||||
| case L2_TOK_PERIOD: | |||||
| return "period"; | |||||
| case L2_TOK_EOF: | |||||
| return "end-of-file"; | |||||
| case L2_TOK_NUMBER: | |||||
| return "number"; | |||||
| case L2_TOK_STRING: | |||||
| return "string"; | |||||
| case L2_TOK_ERROR: | |||||
| return "error"; | |||||
| } | |||||
| } | |||||
| void l2_token_free(struct l2_token *tok) { | void l2_token_free(struct l2_token *tok) { | ||||
| if (tok->kind == L2_TOK_STRING) { | if (tok->kind == L2_TOK_STRING) { | ||||
| free(tok->v.str); | free(tok->v.str); |