math: Add error length
Like we now do for syntax errors, this marks the extent of the error. Currently for unknown functions only, would be cool for division too
This commit is contained in:
parent
5edba044a3
commit
52e065e479
@ -258,7 +258,12 @@ static int evaluate_expression(const wchar_t *cmd, const parser_t &parser, io_st
|
||||
} else {
|
||||
streams.err.append_format(L"%ls: Error: %ls\n", cmd, math_describe_error(error));
|
||||
streams.err.append_format(L"'%ls'\n", expression.c_str());
|
||||
streams.err.append_format(L"%*ls%ls\n", error.position - 1, L" ", L"^");
|
||||
if (error.len >= 2) {
|
||||
wcstring tildes(error.len - 2, L'~');
|
||||
streams.err.append_format(L"%*ls%ls%ls%ls\n", error.position - 1, L" ", L"^", tildes.c_str(), L"^");
|
||||
} else {
|
||||
streams.err.append_format(L"%*ls%ls\n", error.position - 1, L" ", L"^");
|
||||
}
|
||||
retval = STATUS_CMD_ERROR;
|
||||
}
|
||||
return retval;
|
||||
|
@ -113,11 +113,11 @@ struct state {
|
||||
double eval() { return expr(); }
|
||||
|
||||
[[nodiscard]] te_error_t error() const {
|
||||
if (type_ == TOK_END) return {TE_ERROR_NONE, 0};
|
||||
if (type_ == TOK_END) return {TE_ERROR_NONE, 0, 0};
|
||||
// If we have an error position set, use that,
|
||||
// otherwise the current position.
|
||||
const wchar_t *tok = errpos_ ? errpos_ : next_;
|
||||
te_error_t err{error_, static_cast<int>(tok - start_) + 1};
|
||||
te_error_t err{error_, static_cast<int>(tok - start_) + 1, errlen_};
|
||||
if (error_ == TE_ERROR_NONE) {
|
||||
// If we're not at the end but there's no error, then that means we have a
|
||||
// superfluous token that we have no idea what to do with.
|
||||
@ -133,6 +133,7 @@ struct state {
|
||||
const wchar_t *start_;
|
||||
const wchar_t *next_;
|
||||
const wchar_t *errpos_{nullptr};
|
||||
int errlen_{0};
|
||||
|
||||
te_fun_t current_{NAN};
|
||||
void next_token();
|
||||
@ -312,6 +313,9 @@ void state::next_token() {
|
||||
// Our error is more specific, so it takes precedence.
|
||||
type_ = TOK_ERROR;
|
||||
error_ = TE_ERROR_UNKNOWN_FUNCTION;
|
||||
errpos_ = start + 1;
|
||||
errlen_ = next_ - start;
|
||||
|
||||
}
|
||||
} else {
|
||||
/* Look for an operator or special character. */
|
||||
@ -533,6 +537,7 @@ double state::term() {
|
||||
error_ = TE_ERROR_DIV_BY_ZERO;
|
||||
// Error position is the "/" or "%" sign for now
|
||||
errpos_ = tok;
|
||||
errlen_ = 1;
|
||||
}
|
||||
ret = fn(ret, ret2);
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ typedef enum {
|
||||
typedef struct te_error_t {
|
||||
te_error_type_t type;
|
||||
int position;
|
||||
int len;
|
||||
} te_error_t;
|
||||
|
||||
/* Parses the input expression, evaluates it, and frees it. */
|
||||
|
@ -113,7 +113,7 @@ not math 'ncr(1)'
|
||||
not math 'blah()'
|
||||
# CHECKERR: math: Error: Unknown function
|
||||
# CHECKERR: 'blah()'
|
||||
# CHECKERR: ^
|
||||
# CHECKERR: ^~~^
|
||||
|
||||
math n + 4
|
||||
# CHECKERR: math: Error: Unknown function
|
||||
@ -167,7 +167,7 @@ math 2x 4
|
||||
math 2 x4 # ERROR
|
||||
# CHECKERR: math: Error: Unknown function
|
||||
# CHECKERR: '2 x4'
|
||||
# CHECKERR: ^
|
||||
# CHECKERR: ^^
|
||||
math 0x 3
|
||||
# CHECK: 2
|
||||
# CHECK: 20
|
||||
|
Loading…
x
Reference in New Issue
Block a user