@@ -1001,7 +1001,7 @@ export const createParse = /* #__PURE__ */ factory(name, dependencies, ({
1001
1001
function parseAddSubtract ( state ) {
1002
1002
let node , name , fn , params
1003
1003
1004
- node = parseMultiplyDivideModulusPercentage ( state )
1004
+ node = parseMultiplyDivideModulus ( state )
1005
1005
1006
1006
const operators = {
1007
1007
'+' : 'add' ,
@@ -1012,7 +1012,7 @@ export const createParse = /* #__PURE__ */ factory(name, dependencies, ({
1012
1012
fn = operators [ name ]
1013
1013
1014
1014
getTokenSkipNewline ( state )
1015
- const rightNode = parseMultiplyDivideModulusPercentage ( state )
1015
+ const rightNode = parseMultiplyDivideModulus ( state )
1016
1016
if ( rightNode . isPercentage ) {
1017
1017
params = [ node , new OperatorNode ( '*' , 'multiply' , [ node , rightNode ] ) ]
1018
1018
} else {
@@ -1025,11 +1025,11 @@ export const createParse = /* #__PURE__ */ factory(name, dependencies, ({
1025
1025
}
1026
1026
1027
1027
/**
1028
- * multiply, divide, modulus, percentage
1028
+ * multiply, divide, modulus
1029
1029
* @return {Node } node
1030
1030
* @private
1031
1031
*/
1032
- function parseMultiplyDivideModulusPercentage ( state ) {
1032
+ function parseMultiplyDivideModulus ( state ) {
1033
1033
let node , last , name , fn
1034
1034
1035
1035
node = parseImplicitMultiplication ( state )
@@ -1053,17 +1053,8 @@ export const createParse = /* #__PURE__ */ factory(name, dependencies, ({
1053
1053
getTokenSkipNewline ( state )
1054
1054
1055
1055
if ( name === '%' && state . tokenType === TOKENTYPE . DELIMITER && state . token !== '(' ) {
1056
- // If the expression contains only %, then treat that as /100
1057
- if ( state . token !== '' && operators [ state . token ] ) {
1058
- const left = new OperatorNode ( '/' , 'divide' , [ node , new ConstantNode ( 100 ) ] , false , true )
1059
- name = state . token
1060
- fn = operators [ name ]
1061
- getTokenSkipNewline ( state )
1062
- last = parseImplicitMultiplication ( state )
1063
-
1064
- node = new OperatorNode ( name , fn , [ left , last ] )
1065
- } else { node = new OperatorNode ( '/' , 'divide' , [ node , new ConstantNode ( 100 ) ] , false , true ) }
1066
- // return node
1056
+ // This % cannot be interpreted as a modulus, and it wasn't handled by parseUnaryPostfix
1057
+ throw createSyntaxError ( state , 'Unexpected operator %' )
1067
1058
} else {
1068
1059
last = parseImplicitMultiplication ( state )
1069
1060
node = new OperatorNode ( name , fn , [ node , last ] )
@@ -1120,7 +1111,7 @@ export const createParse = /* #__PURE__ */ factory(name, dependencies, ({
1120
1111
* @private
1121
1112
*/
1122
1113
function parseRule2 ( state ) {
1123
- let node = parseUnary ( state )
1114
+ let node = parseUnaryPercentage ( state )
1124
1115
let last = node
1125
1116
const tokenStates = [ ]
1126
1117
@@ -1143,7 +1134,7 @@ export const createParse = /* #__PURE__ */ factory(name, dependencies, ({
1143
1134
// Rewind once and build the "number / number" node; the symbol will be consumed later
1144
1135
Object . assign ( state , tokenStates . pop ( ) )
1145
1136
tokenStates . pop ( )
1146
- last = parseUnary ( state )
1137
+ last = parseUnaryPercentage ( state )
1147
1138
node = new OperatorNode ( '/' , 'divide' , [ node , last ] )
1148
1139
} else {
1149
1140
// Not a match, so rewind
@@ -1164,6 +1155,30 @@ export const createParse = /* #__PURE__ */ factory(name, dependencies, ({
1164
1155
return node
1165
1156
}
1166
1157
1158
+ /**
1159
+ * Unary percentage operator (treated as `value / 100`)
1160
+ * @return {Node } node
1161
+ * @private
1162
+ */
1163
+ function parseUnaryPercentage ( state ) {
1164
+ let node = parseUnary ( state )
1165
+
1166
+ if ( state . token === '%' ) {
1167
+ const previousState = Object . assign ( { } , state )
1168
+ getTokenSkipNewline ( state )
1169
+
1170
+ if ( state . tokenType === TOKENTYPE . DELIMITER && state . token !== '(' ) {
1171
+ // This is unary postfix %, then treat that as /100
1172
+ node = new OperatorNode ( '/' , 'divide' , [ node , new ConstantNode ( 100 ) ] , false , true )
1173
+ } else {
1174
+ // Not a match, so rewind
1175
+ Object . assign ( state , previousState )
1176
+ }
1177
+ }
1178
+
1179
+ return node
1180
+ }
1181
+
1167
1182
/**
1168
1183
* Unary plus and minus, and logical and bitwise not
1169
1184
* @return {Node } node
0 commit comments