Reduce memory footprint of Target.
This commit is contained in:
parent
619b627d54
commit
f5c7d7cd0d
@ -83,7 +83,7 @@ enum Target<'a> {
|
|||||||
/// The target is a variable stored in the current `Scope`.
|
/// The target is a variable stored in the current `Scope`.
|
||||||
Scope(&'a RefCell<Dynamic>),
|
Scope(&'a RefCell<Dynamic>),
|
||||||
/// The target is a temporary `Dynamic` value (i.e. the mutation can cause no side effects).
|
/// The target is a temporary `Dynamic` value (i.e. the mutation can cause no side effects).
|
||||||
Value(Dynamic),
|
Value(Box<Dynamic>),
|
||||||
/// The target is a character inside a String.
|
/// The target is a character inside a String.
|
||||||
StringChar(Box<(&'a mut Dynamic, usize, Dynamic)>),
|
StringChar(Box<(&'a mut Dynamic, usize, Dynamic)>),
|
||||||
}
|
}
|
||||||
@ -94,7 +94,7 @@ impl Target<'_> {
|
|||||||
match self {
|
match self {
|
||||||
Target::Ref(r) => r.clone(),
|
Target::Ref(r) => r.clone(),
|
||||||
Target::Scope(r) => r.borrow().clone(),
|
Target::Scope(r) => r.borrow().clone(),
|
||||||
Target::Value(v) => v,
|
Target::Value(v) => *v,
|
||||||
Target::StringChar(s) => s.2,
|
Target::StringChar(s) => s.2,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -144,7 +144,7 @@ impl<'a> From<&'a mut Dynamic> for Target<'a> {
|
|||||||
}
|
}
|
||||||
impl<T: Into<Dynamic>> From<T> for Target<'_> {
|
impl<T: Into<Dynamic>> From<T> for Target<'_> {
|
||||||
fn from(value: T) -> Self {
|
fn from(value: T) -> Self {
|
||||||
Self::Value(value.into())
|
Self::Value(Box::new(value.into()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -724,7 +724,7 @@ impl Engine {
|
|||||||
let obj = match target {
|
let obj = match target {
|
||||||
Target::Scope(_) => scope_base.as_mut().unwrap().deref_mut(),
|
Target::Scope(_) => scope_base.as_mut().unwrap().deref_mut(),
|
||||||
Target::Ref(r) => r,
|
Target::Ref(r) => r,
|
||||||
Target::Value(ref mut r) => r,
|
Target::Value(ref mut r) => r.as_mut(),
|
||||||
Target::StringChar(ref mut x) => &mut x.2,
|
Target::StringChar(ref mut x) => &mut x.2,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -777,6 +777,7 @@ impl Engine {
|
|||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let def_val = def_val.as_ref();
|
let def_val = def_val.as_ref();
|
||||||
// A function call is assumed to have side effects, so the value is changed
|
// A function call is assumed to have side effects, so the value is changed
|
||||||
|
// TODO - Remove assumption of side effects by checking whether the first parameter is &mut
|
||||||
self.exec_fn_call(fn_lib, fn_name, &mut args, def_val, *pos, 0).map(|v| (v, true))
|
self.exec_fn_call(fn_lib, fn_name, &mut args, def_val, *pos, 0).map(|v| (v, true))
|
||||||
}
|
}
|
||||||
// {xxx:map}.id
|
// {xxx:map}.id
|
||||||
|
@ -505,6 +505,7 @@ impl Expr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert a `Variable` into a `Property`. All other variants are untouched.
|
||||||
pub(crate) fn into_property(self) -> Self {
|
pub(crate) fn into_property(self) -> Self {
|
||||||
match self {
|
match self {
|
||||||
Self::Variable(id, pos) => Self::Property(id, pos),
|
Self::Variable(id, pos) => Self::Property(id, pos),
|
||||||
@ -626,9 +627,10 @@ fn parse_call_expr<'a, S: Into<Cow<'static, str>> + Display>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse an indexing expression.
|
/// Parse an indexing chain.
|
||||||
fn parse_index_expr<'a>(
|
/// Indexing binds to the right, so this call parses all possible levels of indexing following in the input.
|
||||||
lhs: Box<Expr>,
|
fn parse_index_chain<'a>(
|
||||||
|
lhs: Expr,
|
||||||
input: &mut Peekable<TokenIterator<'a>>,
|
input: &mut Peekable<TokenIterator<'a>>,
|
||||||
pos: Position,
|
pos: Position,
|
||||||
allow_stmt_expr: bool,
|
allow_stmt_expr: bool,
|
||||||
@ -645,7 +647,7 @@ fn parse_index_expr<'a>(
|
|||||||
))
|
))
|
||||||
.into_err(*pos))
|
.into_err(*pos))
|
||||||
}
|
}
|
||||||
Expr::IntegerConstant(_, pos) => match *lhs {
|
Expr::IntegerConstant(_, pos) => match lhs {
|
||||||
Expr::Array(_, _) | Expr::StringConstant(_, _) => (),
|
Expr::Array(_, _) | Expr::StringConstant(_, _) => (),
|
||||||
|
|
||||||
Expr::Map(_, _) => {
|
Expr::Map(_, _) => {
|
||||||
@ -674,7 +676,7 @@ fn parse_index_expr<'a>(
|
|||||||
},
|
},
|
||||||
|
|
||||||
// lhs[string]
|
// lhs[string]
|
||||||
Expr::StringConstant(_, pos) => match *lhs {
|
Expr::StringConstant(_, pos) => match lhs {
|
||||||
Expr::Map(_, _) => (),
|
Expr::Map(_, _) => (),
|
||||||
|
|
||||||
Expr::Array(_, _) | Expr::StringConstant(_, _) => {
|
Expr::Array(_, _) | Expr::StringConstant(_, _) => {
|
||||||
@ -742,15 +744,18 @@ fn parse_index_expr<'a>(
|
|||||||
(Token::RightBracket, _) => {
|
(Token::RightBracket, _) => {
|
||||||
eat_token(input, Token::RightBracket);
|
eat_token(input, Token::RightBracket);
|
||||||
|
|
||||||
let idx_expr = Box::new(idx_expr);
|
// Any more indexing following?
|
||||||
|
|
||||||
match input.peek().unwrap() {
|
match input.peek().unwrap() {
|
||||||
|
// If another indexing level, right-bind it
|
||||||
(Token::LeftBracket, _) => {
|
(Token::LeftBracket, _) => {
|
||||||
let follow_pos = eat_token(input, Token::LeftBracket);
|
let follow_pos = eat_token(input, Token::LeftBracket);
|
||||||
let follow = parse_index_expr(idx_expr, input, follow_pos, allow_stmt_expr)?;
|
// Recursively parse the indexing chain, right-binding each
|
||||||
Ok(Expr::Index(lhs, Box::new(follow), pos))
|
let follow = parse_index_chain(idx_expr, input, follow_pos, allow_stmt_expr)?;
|
||||||
|
// Indexing binds to right
|
||||||
|
Ok(Expr::Index(Box::new(lhs), Box::new(follow), pos))
|
||||||
}
|
}
|
||||||
_ => Ok(Expr::Index(lhs, idx_expr, pos)),
|
// Otherwise terminate the indexing chain
|
||||||
|
_ => Ok(Expr::Index(Box::new(lhs), Box::new(idx_expr), pos)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Token::LexError(err), pos) => return Err(PERR::BadInput(err.to_string()).into_err(*pos)),
|
(Token::LexError(err), pos) => return Err(PERR::BadInput(err.to_string()).into_err(*pos)),
|
||||||
@ -943,9 +948,7 @@ fn parse_primary<'a>(
|
|||||||
parse_call_expr(id, input, pos, allow_stmt_expr)?
|
parse_call_expr(id, input, pos, allow_stmt_expr)?
|
||||||
}
|
}
|
||||||
// Indexing
|
// Indexing
|
||||||
(expr, Token::LeftBracket) => {
|
(expr, Token::LeftBracket) => parse_index_chain(expr, input, pos, allow_stmt_expr)?,
|
||||||
parse_index_expr(Box::new(expr), input, pos, allow_stmt_expr)?
|
|
||||||
}
|
|
||||||
// Unknown postfix operator
|
// Unknown postfix operator
|
||||||
(expr, token) => panic!("unknown postfix operator {:?} for {:?}", token, expr),
|
(expr, token) => panic!("unknown postfix operator {:?} for {:?}", token, expr),
|
||||||
}
|
}
|
||||||
@ -1068,6 +1071,7 @@ fn parse_op_assignment_stmt<'a>(
|
|||||||
fn make_dot_expr(lhs: Expr, rhs: Expr, op_pos: Position, is_index: bool) -> Expr {
|
fn make_dot_expr(lhs: Expr, rhs: Expr, op_pos: Position, is_index: bool) -> Expr {
|
||||||
match (lhs, rhs) {
|
match (lhs, rhs) {
|
||||||
// idx_lhs[idx_rhs].rhs
|
// idx_lhs[idx_rhs].rhs
|
||||||
|
// Attach dot chain to the bottom level of indexing chain
|
||||||
(Expr::Index(idx_lhs, idx_rhs, idx_pos), rhs) => Expr::Index(
|
(Expr::Index(idx_lhs, idx_rhs, idx_pos), rhs) => Expr::Index(
|
||||||
idx_lhs,
|
idx_lhs,
|
||||||
Box::new(make_dot_expr(*idx_rhs, rhs, op_pos, true)),
|
Box::new(make_dot_expr(*idx_rhs, rhs, op_pos, true)),
|
||||||
|
Loading…
Reference in New Issue
Block a user