Streamline op-assignments.
This commit is contained in:
@@ -17,6 +17,8 @@ use std::{
|
||||
|
||||
/// _(internals)_ An op-assignment operator.
|
||||
/// Exported under the `internals` feature only.
|
||||
///
|
||||
/// This type may hold a straight assignment (i.e. not an op-assignment).
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||
pub struct OpAssignment<'a> {
|
||||
/// Hash of the op-assignment call.
|
||||
@@ -27,9 +29,29 @@ pub struct OpAssignment<'a> {
|
||||
pub op_assign: &'a str,
|
||||
/// Underlying operator.
|
||||
pub op: &'a str,
|
||||
/// [Position] of the op-assignment operator.
|
||||
pub pos: Position,
|
||||
}
|
||||
|
||||
impl OpAssignment<'_> {
|
||||
/// Create a new [`OpAssignment`] that is only a straight assignment.
|
||||
#[must_use]
|
||||
#[inline(always)]
|
||||
pub const fn new_assignment(pos: Position) -> Self {
|
||||
Self {
|
||||
hash_op_assign: 0,
|
||||
hash_op: 0,
|
||||
op_assign: "=",
|
||||
op: "=",
|
||||
pos,
|
||||
}
|
||||
}
|
||||
/// Is this an op-assignment?
|
||||
#[must_use]
|
||||
#[inline(always)]
|
||||
pub const fn is_op_assignment(&self) -> bool {
|
||||
self.hash_op_assign != 0 || self.hash_op != 0
|
||||
}
|
||||
/// Create a new [`OpAssignment`].
|
||||
///
|
||||
/// # Panics
|
||||
@@ -37,8 +59,8 @@ impl OpAssignment<'_> {
|
||||
/// Panics if the name is not an op-assignment operator.
|
||||
#[must_use]
|
||||
#[inline(always)]
|
||||
pub fn new(name: &str) -> Self {
|
||||
Self::new_from_token(Token::lookup_from_syntax(name).expect("operator"))
|
||||
pub fn new_op_assignment(name: &str, pos: Position) -> Self {
|
||||
Self::new_op_assignment_from_token(Token::lookup_from_syntax(name).expect("operator"), pos)
|
||||
}
|
||||
/// Create a new [`OpAssignment`] from a [`Token`].
|
||||
///
|
||||
@@ -46,7 +68,7 @@ impl OpAssignment<'_> {
|
||||
///
|
||||
/// Panics if the token is not an op-assignment operator.
|
||||
#[must_use]
|
||||
pub fn new_from_token(op: Token) -> Self {
|
||||
pub fn new_op_assignment_from_token(op: Token, pos: Position) -> Self {
|
||||
let op_raw = op
|
||||
.get_base_op_from_assignment()
|
||||
.expect("op-assignment operator")
|
||||
@@ -56,6 +78,7 @@ impl OpAssignment<'_> {
|
||||
hash_op: calc_fn_hash(op_raw, 2),
|
||||
op_assign: op.literal_syntax(),
|
||||
op: op_raw,
|
||||
pos,
|
||||
}
|
||||
}
|
||||
/// Create a new [`OpAssignment`] from a base operator.
|
||||
@@ -65,8 +88,11 @@ impl OpAssignment<'_> {
|
||||
/// Panics if the name is not an operator that can be converted into an op-operator.
|
||||
#[must_use]
|
||||
#[inline(always)]
|
||||
pub fn new_from_base(name: &str) -> Self {
|
||||
Self::new_from_base_token(Token::lookup_from_syntax(name).expect("operator"))
|
||||
pub fn new_op_assignment_from_base(name: &str, pos: Position) -> Self {
|
||||
Self::new_op_assignment_from_base_token(
|
||||
Token::lookup_from_syntax(name).expect("operator"),
|
||||
pos,
|
||||
)
|
||||
}
|
||||
/// Convert a [`Token`] into a new [`OpAssignment`].
|
||||
///
|
||||
@@ -75,8 +101,8 @@ impl OpAssignment<'_> {
|
||||
/// Panics if the token is cannot be converted into an op-assignment operator.
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub fn new_from_base_token(op: Token) -> Self {
|
||||
Self::new_from_token(op.convert_to_op_assignment().expect("operator"))
|
||||
pub fn new_op_assignment_from_base_token(op: Token, pos: Position) -> Self {
|
||||
Self::new_op_assignment_from_token(op.convert_to_op_assignment().expect("operator"), pos)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -375,7 +401,7 @@ pub enum Stmt {
|
||||
/// * [`CONSTANT`][ASTFlags::CONSTANT] = `const`
|
||||
Var(Box<(Ident, Expr, Option<NonZeroUsize>)>, ASTFlags, Position),
|
||||
/// expr op`=` expr
|
||||
Assignment(Box<(Option<OpAssignment<'static>>, BinaryExpr)>, Position),
|
||||
Assignment(Box<(OpAssignment<'static>, BinaryExpr)>),
|
||||
/// func `(` expr `,` ... `)`
|
||||
///
|
||||
/// Note - this is a duplicate of [`Expr::FnCall`] to cover the very common pattern of a single
|
||||
@@ -464,7 +490,6 @@ impl Stmt {
|
||||
match self {
|
||||
Self::Noop(pos)
|
||||
| Self::BreakLoop(.., pos)
|
||||
| Self::Assignment(.., pos)
|
||||
| Self::FnCall(.., pos)
|
||||
| Self::If(.., pos)
|
||||
| Self::Switch(.., pos)
|
||||
@@ -475,6 +500,8 @@ impl Stmt {
|
||||
| Self::Var(.., pos)
|
||||
| Self::TryCatch(.., pos) => *pos,
|
||||
|
||||
Self::Assignment(x) => x.0.pos,
|
||||
|
||||
Self::Block(x) => x.position(),
|
||||
|
||||
Self::Expr(x) => x.start_position(),
|
||||
@@ -493,7 +520,6 @@ impl Stmt {
|
||||
match self {
|
||||
Self::Noop(pos)
|
||||
| Self::BreakLoop(.., pos)
|
||||
| Self::Assignment(.., pos)
|
||||
| Self::FnCall(.., pos)
|
||||
| Self::If(.., pos)
|
||||
| Self::Switch(.., pos)
|
||||
@@ -504,6 +530,8 @@ impl Stmt {
|
||||
| Self::Var(.., pos)
|
||||
| Self::TryCatch(.., pos) => *pos = new_pos,
|
||||
|
||||
Self::Assignment(x) => x.0.pos = new_pos,
|
||||
|
||||
Self::Block(x) => x.set_position(new_pos, x.end_position()),
|
||||
|
||||
Self::Expr(x) => {
|
||||
|
Reference in New Issue
Block a user