Change precedence to own type.
This commit is contained in:
parent
008ef0a41b
commit
d9df6aabc8
@ -17,7 +17,7 @@ use crate::stdlib::{
|
||||
collections::{HashMap, HashSet},
|
||||
fmt, format,
|
||||
hash::{Hash, Hasher},
|
||||
num::{NonZeroU64, NonZeroU8, NonZeroUsize},
|
||||
num::{NonZeroU8, NonZeroUsize},
|
||||
ops::DerefMut,
|
||||
string::{String, ToString},
|
||||
vec::Vec,
|
||||
@ -41,6 +41,8 @@ use crate::Map;
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
pub const TYPICAL_MAP_SIZE: usize = 8; // Small maps are typical
|
||||
|
||||
pub type Precedence = NonZeroU8;
|
||||
|
||||
/// _(INTERNALS)_ A stack of imported [modules][Module].
|
||||
/// Exported under the `internals` feature only.
|
||||
///
|
||||
@ -590,7 +592,7 @@ pub struct Limits {
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
pub max_function_expr_depth: Option<NonZeroUsize>,
|
||||
/// Maximum number of operations allowed to run.
|
||||
pub max_operations: Option<NonZeroU64>,
|
||||
pub max_operations: Option<crate::stdlib::num::NonZeroU64>,
|
||||
/// Maximum number of [modules][Module] allowed to load.
|
||||
///
|
||||
/// Set to zero to effectively disable loading any [module][Module].
|
||||
@ -724,7 +726,7 @@ pub struct Engine {
|
||||
/// A hashset containing symbols to disable.
|
||||
pub(crate) disabled_symbols: HashSet<String>,
|
||||
/// A hashmap containing custom keywords and precedence to recognize.
|
||||
pub(crate) custom_keywords: HashMap<String, Option<NonZeroU8>>,
|
||||
pub(crate) custom_keywords: HashMap<String, Option<Precedence>>,
|
||||
/// Custom syntax.
|
||||
pub(crate) custom_syntax: HashMap<ImmutableString, CustomSyntax>,
|
||||
/// Callback closure for resolving variable access.
|
||||
|
@ -1,6 +1,7 @@
|
||||
//! Configuration settings for [`Engine`].
|
||||
|
||||
use crate::stdlib::{format, num::NonZeroU8, string::String};
|
||||
use crate::engine::Precedence;
|
||||
use crate::stdlib::{format, string::String};
|
||||
use crate::token::Token;
|
||||
use crate::Engine;
|
||||
|
||||
@ -272,7 +273,7 @@ impl Engine {
|
||||
keyword: &str,
|
||||
precedence: u8,
|
||||
) -> Result<&mut Self, String> {
|
||||
let precedence = NonZeroU8::new(precedence);
|
||||
let precedence = Precedence::new(precedence);
|
||||
|
||||
if precedence.is_none() {
|
||||
return Err("precedence cannot be zero".into());
|
||||
|
@ -5,7 +5,7 @@ use crate::ast::{
|
||||
Stmt, StmtBlock,
|
||||
};
|
||||
use crate::dynamic::{AccessMode, Union};
|
||||
use crate::engine::{KEYWORD_THIS, OP_CONTAINS};
|
||||
use crate::engine::{Precedence, KEYWORD_THIS, OP_CONTAINS};
|
||||
use crate::module::NamespaceRef;
|
||||
use crate::optimize::optimize_into_ast;
|
||||
use crate::optimize::OptimizationLevel;
|
||||
@ -1611,7 +1611,7 @@ fn parse_binary_op(
|
||||
input: &mut TokenStream,
|
||||
state: &mut ParseState,
|
||||
lib: &mut FunctionsLib,
|
||||
parent_precedence: u8,
|
||||
parent_precedence: Option<Precedence>,
|
||||
lhs: Expr,
|
||||
mut settings: ParseSettings,
|
||||
) -> Result<Expr, ParseError> {
|
||||
@ -1625,18 +1625,12 @@ fn parse_binary_op(
|
||||
loop {
|
||||
let (current_op, current_pos) = input.peek().unwrap();
|
||||
let precedence = match current_op {
|
||||
Token::Custom(c) => {
|
||||
if state
|
||||
Token::Custom(c) => state
|
||||
.engine
|
||||
.custom_keywords
|
||||
.get(c)
|
||||
.map_or(false, Option::is_some)
|
||||
{
|
||||
state.engine.custom_keywords.get(c).unwrap().unwrap().get()
|
||||
} else {
|
||||
return Err(PERR::Reserved(c.clone()).into_err(*current_pos));
|
||||
}
|
||||
}
|
||||
.cloned()
|
||||
.ok_or_else(|| PERR::Reserved(c.clone()).into_err(*current_pos))?,
|
||||
Token::Reserved(c) if !is_valid_identifier(c.chars()) => {
|
||||
return Err(PERR::UnknownOperator(c.into()).into_err(*current_pos))
|
||||
}
|
||||
@ -1656,18 +1650,12 @@ fn parse_binary_op(
|
||||
|
||||
let (next_op, next_pos) = input.peek().unwrap();
|
||||
let next_precedence = match next_op {
|
||||
Token::Custom(c) => {
|
||||
if state
|
||||
Token::Custom(c) => state
|
||||
.engine
|
||||
.custom_keywords
|
||||
.get(c)
|
||||
.map_or(false, Option::is_some)
|
||||
{
|
||||
state.engine.custom_keywords.get(c).unwrap().unwrap().get()
|
||||
} else {
|
||||
return Err(PERR::Reserved(c.clone()).into_err(*next_pos));
|
||||
}
|
||||
}
|
||||
.cloned()
|
||||
.ok_or_else(|| PERR::Reserved(c.clone()).into_err(*next_pos))?,
|
||||
Token::Reserved(c) if !is_valid_identifier(c.chars()) => {
|
||||
return Err(PERR::UnknownOperator(c.into()).into_err(*next_pos))
|
||||
}
|
||||
@ -1937,7 +1925,14 @@ fn parse_expr(
|
||||
|
||||
// Parse expression normally.
|
||||
let lhs = parse_unary(input, state, lib, settings.level_up())?;
|
||||
parse_binary_op(input, state, lib, 1, lhs, settings.level_up())
|
||||
parse_binary_op(
|
||||
input,
|
||||
state,
|
||||
lib,
|
||||
Precedence::new(1),
|
||||
lhs,
|
||||
settings.level_up(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Make sure that the expression is not a statement expression (i.e. wrapped in `{}`).
|
||||
|
10
src/token.rs
10
src/token.rs
@ -1,8 +1,8 @@
|
||||
//! Main module defining the lexer and parser.
|
||||
|
||||
use crate::engine::{
|
||||
KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_FN_PTR_CALL, KEYWORD_FN_PTR_CURRY,
|
||||
KEYWORD_IS_DEF_VAR, KEYWORD_PRINT, KEYWORD_THIS, KEYWORD_TYPE_OF,
|
||||
Precedence, KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_FN_PTR_CALL,
|
||||
KEYWORD_FN_PTR_CURRY, KEYWORD_IS_DEF_VAR, KEYWORD_PRINT, KEYWORD_THIS, KEYWORD_TYPE_OF,
|
||||
};
|
||||
use crate::stdlib::{
|
||||
borrow::Cow,
|
||||
@ -666,10 +666,10 @@ impl Token {
|
||||
}
|
||||
|
||||
/// Get the precedence number of the token.
|
||||
pub fn precedence(&self) -> u8 {
|
||||
pub fn precedence(&self) -> Option<Precedence> {
|
||||
use Token::*;
|
||||
|
||||
match self {
|
||||
Precedence::new(match self {
|
||||
// Assignments are not considered expressions - set to zero
|
||||
Equals | PlusAssign | MinusAssign | MultiplyAssign | DivideAssign | PowerOfAssign
|
||||
| LeftShiftAssign | RightShiftAssign | AndAssign | OrAssign | XOrAssign
|
||||
@ -696,7 +696,7 @@ impl Token {
|
||||
Period => 240,
|
||||
|
||||
_ => 0,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Does an expression bind to the right (instead of left)?
|
||||
|
Loading…
Reference in New Issue
Block a user