lang: replace stack-based parser with a recursive parser
This commit is contained in:
+40
-4
@@ -1,11 +1,11 @@
|
||||
#include "lex.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <fx/core/hash.h>
|
||||
#include <fx/core/queue.h>
|
||||
#include <fx/ds/dict.h>
|
||||
#include <fx/ds/number.h>
|
||||
#include <fx/ds/string.h>
|
||||
#include <ctype.h>
|
||||
#include <ivy/diag.h>
|
||||
#include <ivy/lang/diag.h>
|
||||
#include <ivy/lang/lex.h>
|
||||
@@ -132,6 +132,7 @@ static void report_unrecognised_char(struct ivy_lexer *lex, int c)
|
||||
diag, lex->lex_cursor_row, lex->lex_cursor_row, NULL, 0, hl, nr_hl);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void report_missing_whitespace(struct ivy_lexer *lex, int msg)
|
||||
{
|
||||
struct ivy_diag *diag = ivy_diag_ctx_create_diag(
|
||||
@@ -150,6 +151,7 @@ static void report_missing_whitespace(struct ivy_lexer *lex, int msg)
|
||||
ivy_diag_push_snippet(
|
||||
diag, lex->lex_cursor_row, lex->lex_cursor_row, NULL, 0, hl, nr_hl);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct lexer_state *push_lexer_state(
|
||||
struct ivy_lexer *lex, enum lexer_state_type state_type)
|
||||
@@ -490,7 +492,7 @@ static int advance(struct ivy_lexer *lex)
|
||||
lex->lex_cur_char = lex->lex_linebuf[lex->lex_linebuf_ptr];
|
||||
|
||||
lex->lex_cursor_col++;
|
||||
if (lex->lex_cur_char == '\n') {
|
||||
if (lex->lex_prev_char == '\n') {
|
||||
lex->lex_cursor_col = 1;
|
||||
lex->lex_cursor_row++;
|
||||
}
|
||||
@@ -1014,12 +1016,14 @@ static enum ivy_status read_symbol(struct ivy_lexer *lex)
|
||||
return read_number(lex, true);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if ((node->s_def->flags & LEX_TOK_REQUIRES_WHITESPACE)
|
||||
&& (!isspace(prev) || !isspace(prefix))) {
|
||||
report_missing_whitespace(
|
||||
lex, IVY_LANG_MSG_WHITESPACE_REQUIRED_AROUND_BINARY_OP);
|
||||
return IVY_ERR_BAD_SYNTAX;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (node->s_def->id) {
|
||||
case IVY_SYM_SQUOTE:
|
||||
@@ -1080,8 +1084,11 @@ static enum ivy_status read_ident(struct ivy_lexer *lex)
|
||||
break;
|
||||
}
|
||||
|
||||
if (c == '-' && prev == '-') {
|
||||
return IVY_ERR_BAD_SYNTAX;
|
||||
if (c == '-') {
|
||||
char next = peek_next(lex);
|
||||
if (!isalnum(next)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char s[2] = {c, 0};
|
||||
@@ -1245,6 +1252,21 @@ struct ivy_token *ivy_token_create_ident(const char *s)
|
||||
return tok;
|
||||
}
|
||||
|
||||
struct ivy_token *ivy_token_create_discard(void)
|
||||
{
|
||||
struct ivy_token *tok = malloc(sizeof *tok);
|
||||
|
||||
if (!tok) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(tok, 0x0, sizeof *tok);
|
||||
|
||||
tok->t_type = IVY_TOK_NONE;
|
||||
|
||||
return tok;
|
||||
}
|
||||
|
||||
void ivy_token_destroy(struct ivy_token *tok)
|
||||
{
|
||||
switch (tok->t_type) {
|
||||
@@ -1382,3 +1404,17 @@ const char *ivy_symbol_to_string(enum ivy_symbol sym)
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
const char *ivy_token_to_string(const struct ivy_token *tok)
|
||||
{
|
||||
switch (tok->t_type) {
|
||||
case IVY_TOK_SYMBOL:
|
||||
return ivy_symbol_to_string(tok->t_symbol);
|
||||
case IVY_TOK_IDENT:
|
||||
return tok->t_str;
|
||||
case IVY_TOK_KEYWORD:
|
||||
return ivy_keyword_to_string(tok->t_keyword);
|
||||
default:
|
||||
return ivy_lex_token_type_to_string(tok->t_type);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user