Skip to content

Commit

Permalink
Merge pull request #169 from wechat-miniprogram/fix-template-ops
Browse files Browse the repository at this point in the history
Fix template ops
  • Loading branch information
LastLeaf authored Jun 25, 2024
2 parents 2ec37e3 + 57b440f commit 1d04878
Show file tree
Hide file tree
Showing 4 changed files with 228 additions and 40 deletions.
125 changes: 107 additions & 18 deletions glass-easel-template-compiler/src/parse/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,22 @@ pub enum Expression {
location: Range<Position>,
},

LeftShift {
left: Box<Expression>,
right: Box<Expression>,
location: Range<Position>,
},
RightShift {
left: Box<Expression>,
right: Box<Expression>,
location: Range<Position>,
},
UnsignedRightShift {
left: Box<Expression>,
right: Box<Expression>,
location: Range<Position>,
},

Lt {
left: Box<Expression>,
right: Box<Expression>,
Expand Down Expand Up @@ -267,6 +283,9 @@ impl TemplateStructure for Expression {
Self::Remainer { left, .. } => left.location_start(),
Self::Plus { left, .. } => left.location_start(),
Self::Minus { left, .. } => left.location_start(),
Self::LeftShift { left, .. } => left.location_start(),
Self::RightShift { left, .. } => left.location_start(),
Self::UnsignedRightShift { left, .. } => left.location_start(),
Self::Lt { left, .. } => left.location_start(),
Self::Gt { left, .. } => left.location_start(),
Self::Lte { left, .. } => left.location_start(),
Expand Down Expand Up @@ -315,6 +334,9 @@ impl TemplateStructure for Expression {
Self::Remainer { right, .. } => right.location_end(),
Self::Plus { right, .. } => right.location_end(),
Self::Minus { right, .. } => right.location_end(),
Self::LeftShift { right, .. } => right.location_end(),
Self::RightShift { right, .. } => right.location_end(),
Self::UnsignedRightShift { right, .. } => right.location_end(),
Self::Lt { right, .. } => right.location_end(),
Self::Gt { right, .. } => right.location_end(),
Self::Lte { right, .. } => right.location_end(),
Expand Down Expand Up @@ -1036,7 +1058,8 @@ macro_rules! parse_left_to_right {

parse_left_to_right!(parse_multiply, parse_reverse, multiply => Multiply, divide => Divide, remainer => Remainer);
parse_left_to_right!(parse_plus, parse_multiply, plus => Plus, minus => Minus);
parse_left_to_right!(parse_cmp, parse_plus, lt => Lt, gt => Gt, lte => Lte, gte => Gte, instanceof => InstanceOf);
parse_left_to_right!(parse_shift, parse_plus, left_shift => LeftShift, right_shift => RightShift, unsigned_right_shift => UnsignedRightShift);
parse_left_to_right!(parse_cmp, parse_shift, lt => Lt, gt => Gt, lte => Lte, gte => Gte, instanceof => InstanceOf);
parse_left_to_right!(parse_eq, parse_cmp, eq => Eq, ne => Ne, eq_full => EqFull, ne_full => NeFull);
parse_left_to_right!(parse_bit_and, parse_eq, bit_and => BitAnd);
parse_left_to_right!(parse_bit_xor, parse_bit_and, bit_xor => BitXor);
Expand Down Expand Up @@ -1090,7 +1113,9 @@ define_operator!(remainer, "%", ["="]);
define_operator!(plus, "+", ["+", "="]);
define_operator!(minus, "-", ["-", "="]);

// `<<` `>>` `>>>` are not supported
define_operator!(left_shift, "<<", ["="]);
define_operator!(right_shift, ">>", [">", "="]);
define_operator!(unsigned_right_shift, ">>>", ["="]);

define_operator!(lt, "<", ["<", "="]);
define_operator!(lte, "<=", []);
Expand All @@ -1115,9 +1140,24 @@ define_operator!(logic_and, "&&", ["="]);
define_operator!(logic_or, "||", ["="]);
define_operator!(nullish_coalescing, "??", ["="]);

define_operator!(condition, "?", ["?", "."]);
define_operator!(condition_end, ":", []);

impl ParseOperator {
fn condition(ps: &mut ParseState) -> Option<Range<Position>> {
ps
.consume_str_except_followed("?", ["?", "."])
.or_else(|| {
let [p0, p1, p2] = ps.peek_n::<3>()?;
if p0 == '?' && p1 == '.' && ('0'..='9').contains(&p2) {
// `?.1` should be treated as `?` and `.1`
ps.consume_str("?")
} else {
None
}
})
}
}

// `=` `+=` `-=` `**=` `*=` `/=` `%=` `<<=` `>>=` `>>>=` `&=` `^=` `|=` `&&=` `||=` `??=` are not allowed

fn is_ident_char(ch: char) -> bool {
Expand Down Expand Up @@ -1309,6 +1349,9 @@ macro_rules! iter_sub_expr {
| Expression::Remainer { left, right, .. }
| Expression::Plus { left, right, .. }
| Expression::Minus { left, right, .. }
| Expression::LeftShift { left, right, .. }
| Expression::RightShift { left, right, .. }
| Expression::UnsignedRightShift { left, right, .. }
| Expression::Lt { left, right, .. }
| Expression::Gt { left, right, .. }
| Expression::Lte { left, right, .. }
Expand Down Expand Up @@ -1716,48 +1759,87 @@ mod test {
}

#[test]
fn lt() {
fn left_shift() {
case!(
"{{ a < }}",
"{{ a << }}",
"",
ParseErrorKind::UnexpectedExpressionCharacter,
7..7
8..8
);
case!(
"{{ a << b }}",
"{{ a <<= b }}",
"",
ParseErrorKind::UnexpectedExpressionCharacter,
5..5
);
case!("{{ a < b + c }}", "{{a<b+c}}");
case!("{{ a << b + c }}", "{{a<<b+c}}");
}

#[test]
fn lte() {
fn right_shift() {
case!(
"{{ a <= }}",
"{{ a >> }}",
"",
ParseErrorKind::UnexpectedExpressionCharacter,
8..8
);
case!("{{ a <= b + c }}", "{{a<=b+c}}");
case!(
"{{ a >>= b }}",
"",
ParseErrorKind::UnexpectedExpressionCharacter,
5..5
);
case!("{{ a >> b + c }}", "{{a>>b+c}}");
}

#[test]
fn gt() {
fn unsigned_right_shift() {
case!(
"{{ a > }}",
"{{ a >>> }}",
"",
ParseErrorKind::UnexpectedExpressionCharacter,
7..7
9..9
);
case!(
"{{ a >> b }}",
"{{ a >>>= b }}",
"",
ParseErrorKind::UnexpectedExpressionCharacter,
5..5
);
case!("{{ a > b + c }}", "{{a>b+c}}");
case!("{{ a >>> b + c }}", "{{a>>>b+c}}");
}

#[test]
fn lt() {
case!(
"{{ a < }}",
"",
ParseErrorKind::UnexpectedExpressionCharacter,
7..7
);
case!("{{ a < b << c }}", "{{a<b<<c}}");
}

#[test]
fn lte() {
case!(
"{{ a <= }}",
"",
ParseErrorKind::UnexpectedExpressionCharacter,
8..8
);
case!("{{ a <= b << c }}", "{{a<=b<<c}}");
}

#[test]
fn gt() {
case!(
"{{ a > }}",
"",
ParseErrorKind::UnexpectedExpressionCharacter,
7..7
);
case!("{{ a > b << c }}", "{{a>b<<c}}");
}

#[test]
Expand All @@ -1768,7 +1850,7 @@ mod test {
ParseErrorKind::UnexpectedExpressionCharacter,
8..8
);
case!("{{ a >= b + c }}", "{{a>=b+c}}");
case!("{{ a >= b << c }}", "{{a>=b<<c}}");
}

#[test]
Expand All @@ -1786,7 +1868,7 @@ mod test {
ParseErrorKind::UnexpectedExpressionCharacter,
5..5
);
case!("{{ a instanceof b + c }}", "{{a instanceof b+c}}");
case!("{{ a instanceof b >> c }}", "{{a instanceof b>>c}}");
}

#[test]
Expand Down Expand Up @@ -1955,6 +2037,13 @@ mod test {
ParseErrorKind::UnexpectedExpressionCharacter,
5..5
);
case!(
"{{ a ?. 1 : 2 }}",
"",
ParseErrorKind::UnexpectedExpressionCharacter,
5..5
);
case!("{{ a ?.1 : 2 }}", "{{a?0.1:2}}");
case!("{{ a ? b : c }}", "{{a?b:c}}");
}

Expand Down
56 changes: 51 additions & 5 deletions glass-easel-template-compiler/src/proc_gen/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,49 @@ impl Expression {
PathAnalysisState::NotInPath
}

Expression::LeftShift {
left: x, right: y, ..
} => {
x.to_proc_gen_rec_and_end_path(w, scopes, ExpressionLevel::Shift, path_calc, value)?;
write!(value, "<<")?;
y.to_proc_gen_rec_and_end_path(
w,
scopes,
ExpressionLevel::Plus,
path_calc,
value,
)?;
PathAnalysisState::NotInPath
}
Expression::RightShift {
left: x, right: y, ..
} => {
x.to_proc_gen_rec_and_end_path(w, scopes, ExpressionLevel::Shift, path_calc, value)?;
write!(value, ">>")?;
y.to_proc_gen_rec_and_end_path(
w,
scopes,
ExpressionLevel::Plus,
path_calc,
value,
)?;
PathAnalysisState::NotInPath
}
Expression::UnsignedRightShift {
left: x, right: y, ..
} => {
x.to_proc_gen_rec_and_end_path(w, scopes, ExpressionLevel::Shift, path_calc, value)?;
write!(value, ">>>")?;
y.to_proc_gen_rec_and_end_path(
w,
scopes,
ExpressionLevel::Plus,
path_calc,
value,
)?;
PathAnalysisState::NotInPath
}

Expression::Lt {
left: x, right: y, ..
} => {
Expand All @@ -812,7 +855,7 @@ impl Expression {
value,
)?;
write!(value, "<")?;
y.to_proc_gen_rec_and_end_path(w, scopes, ExpressionLevel::Plus, path_calc, value)?;
y.to_proc_gen_rec_and_end_path(w, scopes, ExpressionLevel::Shift, path_calc, value)?;
PathAnalysisState::NotInPath
}
Expression::Gt {
Expand All @@ -826,7 +869,7 @@ impl Expression {
value,
)?;
write!(value, ">")?;
y.to_proc_gen_rec_and_end_path(w, scopes, ExpressionLevel::Plus, path_calc, value)?;
y.to_proc_gen_rec_and_end_path(w, scopes, ExpressionLevel::Shift, path_calc, value)?;
PathAnalysisState::NotInPath
}
Expression::Lte {
Expand All @@ -840,7 +883,7 @@ impl Expression {
value,
)?;
write!(value, "<=")?;
y.to_proc_gen_rec_and_end_path(w, scopes, ExpressionLevel::Plus, path_calc, value)?;
y.to_proc_gen_rec_and_end_path(w, scopes, ExpressionLevel::Shift, path_calc, value)?;
PathAnalysisState::NotInPath
}
Expression::Gte {
Expand All @@ -854,7 +897,7 @@ impl Expression {
value,
)?;
write!(value, ">=")?;
y.to_proc_gen_rec_and_end_path(w, scopes, ExpressionLevel::Plus, path_calc, value)?;
y.to_proc_gen_rec_and_end_path(w, scopes, ExpressionLevel::Shift, path_calc, value)?;
PathAnalysisState::NotInPath
}
Expression::InstanceOf {
Expand All @@ -868,7 +911,7 @@ impl Expression {
value,
)?;
write!(value, " instanceof ")?;
y.to_proc_gen_rec_and_end_path(w, scopes, ExpressionLevel::Plus, path_calc, value)?;
y.to_proc_gen_rec_and_end_path(w, scopes, ExpressionLevel::Shift, path_calc, value)?;
PathAnalysisState::NotInPath
}
Expression::Eq {
Expand Down Expand Up @@ -1202,6 +1245,9 @@ fn proc_gen_expression_level(expr: &Expression) -> ExpressionLevel {
Expression::Remainer { .. } => ExpressionLevel::Multiply,
Expression::Plus { .. } => ExpressionLevel::Plus,
Expression::Minus { .. } => ExpressionLevel::Plus,
Expression::LeftShift { .. } => ExpressionLevel::Shift,
Expression::RightShift { .. } => ExpressionLevel::Shift,
Expression::UnsignedRightShift { .. } => ExpressionLevel::Shift,
Expression::Lt { .. } => ExpressionLevel::Comparison,
Expression::Gt { .. } => ExpressionLevel::Comparison,
Expression::Lte { .. } => ExpressionLevel::Comparison,
Expand Down
Loading

0 comments on commit 1d04878

Please sign in to comment.