Fix unary parsing.
This commit is contained in:
parent
42bef4c28c
commit
a227963f7a
@ -9,6 +9,7 @@ Bug fixes
|
|||||||
|
|
||||||
* Printing of integral floating-point numbers is fixed (used to only prints `0.0`).
|
* Printing of integral floating-point numbers is fixed (used to only prints `0.0`).
|
||||||
* `func!()` calls now work properly under `no_closure`.
|
* `func!()` calls now work properly under `no_closure`.
|
||||||
|
* Fixed parsing of unary negation such that expressions like `if foo { ... } -x` parses correctly.
|
||||||
|
|
||||||
|
|
||||||
Version 1.1.2
|
Version 1.1.2
|
||||||
|
@ -28,7 +28,7 @@ impl Engine {
|
|||||||
pub(crate) fn global_namespace(&self) -> &Module {
|
pub(crate) fn global_namespace(&self) -> &Module {
|
||||||
self.global_modules
|
self.global_modules
|
||||||
.first()
|
.first()
|
||||||
.expect("global_modules contains at least one module")
|
.expect("global_modules not empty")
|
||||||
}
|
}
|
||||||
/// Get a mutable reference to the global namespace module
|
/// Get a mutable reference to the global namespace module
|
||||||
/// (which is the first module in `global_modules`).
|
/// (which is the first module in `global_modules`).
|
||||||
@ -37,9 +37,9 @@ impl Engine {
|
|||||||
Shared::get_mut(
|
Shared::get_mut(
|
||||||
self.global_modules
|
self.global_modules
|
||||||
.first_mut()
|
.first_mut()
|
||||||
.expect("global_modules contains at least one module"),
|
.expect("global_modules not empty"),
|
||||||
)
|
)
|
||||||
.expect("global namespace module is never shared")
|
.expect("global namespace never shared")
|
||||||
}
|
}
|
||||||
/// Register a custom function with the [`Engine`].
|
/// Register a custom function with the [`Engine`].
|
||||||
///
|
///
|
||||||
|
32
src/parse.rs
32
src/parse.rs
@ -347,14 +347,18 @@ fn ensure_not_assignment(input: &mut TokenStream) -> Result<(), ParseError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Consume a particular [token][Token], checking that it is the expected one.
|
/// Consume a particular [token][Token], checking that it is the expected one.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the next token is not the expected one.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn eat_token(input: &mut TokenStream, token: Token) -> Position {
|
fn eat_token(input: &mut TokenStream, expected_token: Token) -> Position {
|
||||||
let (t, pos) = input.next().expect(NEVER_ENDS);
|
let (t, pos) = input.next().expect(NEVER_ENDS);
|
||||||
|
|
||||||
if t != token {
|
if t != expected_token {
|
||||||
unreachable!(
|
unreachable!(
|
||||||
"expecting {} (found {}) at {}",
|
"expecting {} (found {}) at {}",
|
||||||
token.syntax(),
|
expected_token.syntax(),
|
||||||
t.syntax(),
|
t.syntax(),
|
||||||
pos
|
pos
|
||||||
);
|
);
|
||||||
@ -1479,8 +1483,9 @@ fn parse_unary(
|
|||||||
|
|
||||||
match token {
|
match token {
|
||||||
// -expr
|
// -expr
|
||||||
Token::UnaryMinus => {
|
Token::Minus | Token::UnaryMinus => {
|
||||||
let pos = eat_token(input, Token::UnaryMinus);
|
let token = token.clone();
|
||||||
|
let pos = eat_token(input, token);
|
||||||
|
|
||||||
match parse_unary(input, state, lib, settings.level_up())? {
|
match parse_unary(input, state, lib, settings.level_up())? {
|
||||||
// Negative integer
|
// Negative integer
|
||||||
@ -1516,8 +1521,9 @@ fn parse_unary(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// +expr
|
// +expr
|
||||||
Token::UnaryPlus => {
|
Token::Plus | Token::UnaryPlus => {
|
||||||
let pos = eat_token(input, Token::UnaryPlus);
|
let token = token.clone();
|
||||||
|
let pos = eat_token(input, token);
|
||||||
|
|
||||||
match parse_unary(input, state, lib, settings.level_up())? {
|
match parse_unary(input, state, lib, settings.level_up())? {
|
||||||
expr @ Expr::IntegerConstant(_, _) => Ok(expr),
|
expr @ Expr::IntegerConstant(_, _) => Ok(expr),
|
||||||
@ -2753,9 +2759,9 @@ fn parse_stmt(
|
|||||||
|
|
||||||
let (token, token_pos) = match input.peek().expect(NEVER_ENDS) {
|
let (token, token_pos) = match input.peek().expect(NEVER_ENDS) {
|
||||||
(Token::EOF, pos) => return Ok(Stmt::Noop(*pos)),
|
(Token::EOF, pos) => return Ok(Stmt::Noop(*pos)),
|
||||||
x => x,
|
(x, pos) => (x, *pos),
|
||||||
};
|
};
|
||||||
settings.pos = *token_pos;
|
settings.pos = token_pos;
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
settings.ensure_level_within_max_limit(state.max_expr_depth)?;
|
settings.ensure_level_within_max_limit(state.max_expr_depth)?;
|
||||||
@ -2764,7 +2770,7 @@ fn parse_stmt(
|
|||||||
// ; - empty statement
|
// ; - empty statement
|
||||||
Token::SemiColon => {
|
Token::SemiColon => {
|
||||||
eat_token(input, Token::SemiColon);
|
eat_token(input, Token::SemiColon);
|
||||||
Ok(Stmt::Noop(settings.pos))
|
Ok(Stmt::Noop(token_pos))
|
||||||
}
|
}
|
||||||
|
|
||||||
// { - statements block
|
// { - statements block
|
||||||
@ -2772,7 +2778,7 @@ fn parse_stmt(
|
|||||||
|
|
||||||
// fn ...
|
// fn ...
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
Token::Fn if !settings.is_global => Err(PERR::WrongFnDefinition.into_err(settings.pos)),
|
Token::Fn if !settings.is_global => Err(PERR::WrongFnDefinition.into_err(token_pos)),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
Token::Fn | Token::Private => {
|
Token::Fn | Token::Private => {
|
||||||
@ -2853,7 +2859,7 @@ fn parse_stmt(
|
|||||||
let pos = eat_token(input, Token::Break);
|
let pos = eat_token(input, Token::Break);
|
||||||
Ok(Stmt::BreakLoop(AST_OPTION_BREAK_OUT, pos))
|
Ok(Stmt::BreakLoop(AST_OPTION_BREAK_OUT, pos))
|
||||||
}
|
}
|
||||||
Token::Continue | Token::Break => Err(PERR::LoopBreak.into_err(settings.pos)),
|
Token::Continue | Token::Break => Err(PERR::LoopBreak.into_err(token_pos)),
|
||||||
|
|
||||||
Token::Return | Token::Throw => {
|
Token::Return | Token::Throw => {
|
||||||
let (return_type, token_pos) = input
|
let (return_type, token_pos) = input
|
||||||
@ -2896,7 +2902,7 @@ fn parse_stmt(
|
|||||||
Token::Import => parse_import(input, state, lib, settings.level_up()),
|
Token::Import => parse_import(input, state, lib, settings.level_up()),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
Token::Export if !settings.is_global => Err(PERR::WrongExport.into_err(settings.pos)),
|
Token::Export if !settings.is_global => Err(PERR::WrongExport.into_err(token_pos)),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
Token::Export => parse_export(input, state, lib, settings.level_up()),
|
Token::Export => parse_export(input, state, lib, settings.level_up()),
|
||||||
|
@ -806,6 +806,7 @@ impl Token {
|
|||||||
match self {
|
match self {
|
||||||
LexError(_) |
|
LexError(_) |
|
||||||
SemiColon | // ; - is unary
|
SemiColon | // ; - is unary
|
||||||
|
Colon | // #{ foo: - is unary
|
||||||
Comma | // ( ... , -expr ) - is unary
|
Comma | // ( ... , -expr ) - is unary
|
||||||
//Period |
|
//Period |
|
||||||
LeftBrace | // { -expr } - is unary
|
LeftBrace | // { -expr } - is unary
|
||||||
|
Loading…
Reference in New Issue
Block a user