forked from enlightenment/efl
eolian: fix error cursor positioning
Previously, multi-char tokens (such as strings, docs etc) always put the error cursor to the end of the token. That was confusing, so now the cursor always appears at the beginning of the token instead (for multiline tokens, currently only docs, the line number is also adjusted to point to the first line of the doc token). @fix
This commit is contained in:
parent
4fd1c4f25b
commit
922e4e9181
|
@ -154,8 +154,9 @@ static void next_line(Eo_Lexer *ls)
|
||||||
next_char(ls);
|
next_char(ls);
|
||||||
ls->stream_line = ls->stream;
|
ls->stream_line = ls->stream;
|
||||||
}
|
}
|
||||||
if (++ls->line_number >= INT_MAX)
|
if (++ls->iline_number >= INT_MAX)
|
||||||
eo_lexer_syntax_error(ls, "chunk has too many lines");
|
eo_lexer_syntax_error(ls, "chunk has too many lines");
|
||||||
|
ls->line_number = ls->iline_number;
|
||||||
ls->icolumn = ls->column = 0;
|
ls->icolumn = ls->column = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -833,10 +834,15 @@ lex(Eo_Lexer *ls, Eo_Token *tok)
|
||||||
case '[':
|
case '[':
|
||||||
{
|
{
|
||||||
int dline = ls->line_number, dcol = ls->column;
|
int dline = ls->line_number, dcol = ls->column;
|
||||||
|
const char *sline = ls->stream_line;
|
||||||
next_char(ls);
|
next_char(ls);
|
||||||
if (ls->current != '[') return '[';
|
if (ls->current != '[') return '[';
|
||||||
next_char(ls);
|
next_char(ls);
|
||||||
read_doc(ls, tok, dline, dcol);
|
read_doc(ls, tok, dline, dcol);
|
||||||
|
ls->column = dcol + 1;
|
||||||
|
/* doc is the only potentially multiline token */
|
||||||
|
ls->line_number = dline;
|
||||||
|
ls->stream_line = sline;
|
||||||
return TOK_DOC;
|
return TOK_DOC;
|
||||||
}
|
}
|
||||||
case '\0':
|
case '\0':
|
||||||
|
@ -845,11 +851,13 @@ lex(Eo_Lexer *ls, Eo_Token *tok)
|
||||||
next_char(ls);
|
next_char(ls);
|
||||||
if (!ls->expr_mode || (ls->current != '=')) return '=';
|
if (!ls->expr_mode || (ls->current != '=')) return '=';
|
||||||
next_char(ls);
|
next_char(ls);
|
||||||
|
--ls->column;
|
||||||
return TOK_EQ;
|
return TOK_EQ;
|
||||||
case '!':
|
case '!':
|
||||||
next_char(ls);
|
next_char(ls);
|
||||||
if (!ls->expr_mode || (ls->current != '=')) return '!';
|
if (!ls->expr_mode || (ls->current != '=')) return '!';
|
||||||
next_char(ls);
|
next_char(ls);
|
||||||
|
--ls->column;
|
||||||
return TOK_NQ;
|
return TOK_NQ;
|
||||||
case '>':
|
case '>':
|
||||||
next_char(ls);
|
next_char(ls);
|
||||||
|
@ -857,11 +865,13 @@ lex(Eo_Lexer *ls, Eo_Token *tok)
|
||||||
if (ls->current == '=')
|
if (ls->current == '=')
|
||||||
{
|
{
|
||||||
next_char(ls);
|
next_char(ls);
|
||||||
|
--ls->column;
|
||||||
return TOK_GE;
|
return TOK_GE;
|
||||||
}
|
}
|
||||||
else if (ls->current == '>')
|
else if (ls->current == '>')
|
||||||
{
|
{
|
||||||
next_char(ls);
|
next_char(ls);
|
||||||
|
--ls->column;
|
||||||
return TOK_RSH;
|
return TOK_RSH;
|
||||||
}
|
}
|
||||||
return '>';
|
return '>';
|
||||||
|
@ -871,11 +881,13 @@ lex(Eo_Lexer *ls, Eo_Token *tok)
|
||||||
if (ls->current == '=')
|
if (ls->current == '=')
|
||||||
{
|
{
|
||||||
next_char(ls);
|
next_char(ls);
|
||||||
|
--ls->column;
|
||||||
return TOK_LE;
|
return TOK_LE;
|
||||||
}
|
}
|
||||||
else if (ls->current == '<')
|
else if (ls->current == '<')
|
||||||
{
|
{
|
||||||
next_char(ls);
|
next_char(ls);
|
||||||
|
--ls->column;
|
||||||
return TOK_LSH;
|
return TOK_LSH;
|
||||||
}
|
}
|
||||||
return '<';
|
return '<';
|
||||||
|
@ -883,47 +895,62 @@ lex(Eo_Lexer *ls, Eo_Token *tok)
|
||||||
next_char(ls);
|
next_char(ls);
|
||||||
if (!ls->expr_mode || (ls->current != '&')) return '&';
|
if (!ls->expr_mode || (ls->current != '&')) return '&';
|
||||||
next_char(ls);
|
next_char(ls);
|
||||||
|
--ls->column;
|
||||||
return TOK_AND;
|
return TOK_AND;
|
||||||
case '|':
|
case '|':
|
||||||
next_char(ls);
|
next_char(ls);
|
||||||
if (!ls->expr_mode || (ls->current != '|')) return '|';
|
if (!ls->expr_mode || (ls->current != '|')) return '|';
|
||||||
next_char(ls);
|
next_char(ls);
|
||||||
|
--ls->column;
|
||||||
return TOK_OR;
|
return TOK_OR;
|
||||||
case '"':
|
case '"':
|
||||||
if (!ls->expr_mode)
|
{
|
||||||
{
|
int dcol = ls->column;
|
||||||
next_char(ls);
|
if (!ls->expr_mode)
|
||||||
return '"';
|
{
|
||||||
}
|
next_char(ls);
|
||||||
read_string(ls, tok);
|
return '"';
|
||||||
return TOK_STRING;
|
}
|
||||||
|
/* strings are not multiline for now at least */
|
||||||
|
read_string(ls, tok);
|
||||||
|
ls->column = dcol + 1;
|
||||||
|
return TOK_STRING;
|
||||||
|
}
|
||||||
case '\'':
|
case '\'':
|
||||||
next_char(ls);
|
{
|
||||||
if (!ls->expr_mode) return '\'';
|
int dcol = ls->column;
|
||||||
if (ls->current == '\\')
|
next_char(ls);
|
||||||
{
|
if (!ls->expr_mode) return '\'';
|
||||||
next_char(ls);
|
if (ls->current == '\\')
|
||||||
eina_strbuf_reset(ls->buff);
|
{
|
||||||
read_escape(ls);
|
next_char(ls);
|
||||||
tok->value.c = (char)*eina_strbuf_string_get(ls->buff);
|
eina_strbuf_reset(ls->buff);
|
||||||
}
|
read_escape(ls);
|
||||||
else
|
tok->value.c = (char)*eina_strbuf_string_get(ls->buff);
|
||||||
{
|
}
|
||||||
tok->value.c = ls->current;
|
else
|
||||||
next_char(ls);
|
{
|
||||||
}
|
tok->value.c = ls->current;
|
||||||
if (ls->current != '\'')
|
next_char(ls);
|
||||||
eo_lexer_lex_error(ls, "unfinished character", TOK_CHAR);
|
}
|
||||||
next_char(ls);
|
if (ls->current != '\'')
|
||||||
return TOK_CHAR;
|
eo_lexer_lex_error(ls, "unfinished character", TOK_CHAR);
|
||||||
|
next_char(ls);
|
||||||
|
ls->column = dcol + 1;
|
||||||
|
return TOK_CHAR;
|
||||||
|
}
|
||||||
case '.':
|
case '.':
|
||||||
next_char(ls);
|
{
|
||||||
if (!ls->expr_mode) return '.';
|
int dcol = ls->column;
|
||||||
if (!isdigit(ls->current)) return '.';
|
next_char(ls);
|
||||||
eina_strbuf_reset(ls->buff);
|
if (!ls->expr_mode) return '.';
|
||||||
eina_strbuf_append_char(ls->buff, '.');
|
if (!isdigit(ls->current)) return '.';
|
||||||
read_number(ls, tok);
|
eina_strbuf_reset(ls->buff);
|
||||||
return TOK_NUMBER;
|
eina_strbuf_append_char(ls->buff, '.');
|
||||||
|
read_number(ls, tok);
|
||||||
|
ls->column = dcol + 1;
|
||||||
|
return TOK_NUMBER;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
if (isspace(ls->current))
|
if (isspace(ls->current))
|
||||||
|
@ -934,8 +961,10 @@ lex(Eo_Lexer *ls, Eo_Token *tok)
|
||||||
}
|
}
|
||||||
else if (ls->expr_mode && isdigit(ls->current))
|
else if (ls->expr_mode && isdigit(ls->current))
|
||||||
{
|
{
|
||||||
|
int col = ls->column;
|
||||||
eina_strbuf_reset(ls->buff);
|
eina_strbuf_reset(ls->buff);
|
||||||
read_number(ls, tok);
|
read_number(ls, tok);
|
||||||
|
ls->column = col + 1;
|
||||||
return TOK_NUMBER;
|
return TOK_NUMBER;
|
||||||
}
|
}
|
||||||
if (ls->current && (isalnum(ls->current)
|
if (ls->current && (isalnum(ls->current)
|
||||||
|
@ -998,7 +1027,7 @@ eo_lexer_set_input(Eo_Lexer *ls, const char *source)
|
||||||
ls->stream_line = ls->stream;
|
ls->stream_line = ls->stream;
|
||||||
ls->source = eina_stringshare_add(source);
|
ls->source = eina_stringshare_add(source);
|
||||||
ls->filename = get_filename(ls);
|
ls->filename = get_filename(ls);
|
||||||
ls->line_number = 1;
|
ls->iline_number = ls->line_number = 1;
|
||||||
ls->icolumn = ls->column = -1;
|
ls->icolumn = ls->column = -1;
|
||||||
ls->decpoint = '.';
|
ls->decpoint = '.';
|
||||||
next_char(ls);
|
next_char(ls);
|
||||||
|
|
|
@ -136,8 +136,8 @@ typedef struct _Eo_Lexer
|
||||||
* it points to the beginning of it after the lexing is done, icolumn is
|
* it points to the beginning of it after the lexing is done, icolumn is
|
||||||
* token unaware, always pointing to current column */
|
* token unaware, always pointing to current column */
|
||||||
int column, icolumn;
|
int column, icolumn;
|
||||||
/* the current line number */
|
/* the current line number, token aware and unaware */
|
||||||
int line_number;
|
int line_number, iline_number;
|
||||||
/* t: "normal" - token to lex into, "lookahead" - a lookahead token, used
|
/* t: "normal" - token to lex into, "lookahead" - a lookahead token, used
|
||||||
* to look one token past "t", when we need to check for a token after the
|
* to look one token past "t", when we need to check for a token after the
|
||||||
* current one and use it in a conditional without consuming the current
|
* current one and use it in a conditional without consuming the current
|
||||||
|
|
Loading…
Reference in New Issue