@@ -1154,6 +1154,79 @@ func (p *Parser) evaluateVarDefinition(ctx context) (Statement, error) {
11541154 return variable , nil
11551155}
11561156
1157+ func (p * Parser ) evaluateCompoundAssignment (ctx context ) (Statement , error ) {
1158+ nameTokens , err := p .evaluateVarNames ()
1159+
1160+ if err != nil {
1161+ return nil , err
1162+ }
1163+ nameToken := nameTokens [0 ]
1164+ namesLen := len (nameTokens )
1165+
1166+ if namesLen > 1 {
1167+ return nil , p .expectedError ("a single variable on the left side" , nameToken )
1168+ }
1169+ assignToken := p .eat ()
1170+
1171+ // Check assign token.
1172+ if assignToken .Type () != lexer .COMPOUND_ASSIGN_OPERATOR {
1173+ return nil , p .expectedError (`"+=", "-=", "*=", "/=" or "%="` , assignToken )
1174+ }
1175+ valuesToken := p .peek ()
1176+ evaluatedVals , err := p .evaluateValues (ctx )
1177+
1178+ if err != nil {
1179+ return nil , err
1180+ }
1181+ isMultiReturnFuncCall , call := evaluatedVals .isMultiReturnFuncCall ()
1182+ values := evaluatedVals .values
1183+ valuesTypes := []ValueType {}
1184+
1185+ // If it's a multi return function call evaluate how many values are returned by the function.
1186+ if isMultiReturnFuncCall {
1187+ valuesTypes = call .ReturnTypes ()
1188+ } else {
1189+ for _ , value := range values {
1190+ valuesTypes = append (valuesTypes , value .ValueType ())
1191+ }
1192+ }
1193+ valuesTypesLen := len (valuesTypes )
1194+
1195+ if valuesTypesLen > 1 {
1196+ return nil , p .expectedError ("a single value on the right side" , valuesToken )
1197+ }
1198+ name := nameToken .Value ()
1199+
1200+ // Make sure variable has been defined.
1201+ definedVariable , exists := ctx .findVariable (name , p .prefix , ctx .global ())
1202+
1203+ if ! exists {
1204+ return nil , p .atError (fmt .Sprintf ("variable %s has not been defined" , name ), nameToken )
1205+ }
1206+ valueType := valuesTypes [0 ]
1207+ expectedValueType := definedVariable .ValueType ()
1208+
1209+ if valueType != expectedValueType {
1210+ return nil , p .expectedError (fmt .Sprintf ("%s but got %s" , expectedValueType .ToString (), valueType .ToString ()), valuesToken )
1211+ }
1212+ assignOperator := assignToken .Value ()
1213+ binaryOperator := string (assignOperator [0 ])
1214+
1215+ if ! slices .Contains ([]BinaryOperator {BINARY_OPERATOR_ADDITION , BINARY_OPERATOR_SUBTRACTION , BINARY_OPERATOR_MULTIPLICATION , BINARY_OPERATOR_DIVISION , BINARY_OPERATOR_MODULO }, binaryOperator ) {
1216+ return nil , p .expectedError (fmt .Sprintf (`valid compound assignment operator but got "%s"` , assignOperator ), assignToken )
1217+ }
1218+ return VariableAssignment {
1219+ variables : []Variable {definedVariable },
1220+ values : []Expression {
1221+ BinaryOperation {
1222+ left : VariableEvaluation {definedVariable },
1223+ operator : binaryOperator ,
1224+ right : values [0 ],
1225+ },
1226+ },
1227+ }, nil
1228+ }
1229+
11571230func (p * Parser ) evaluateVarAssignment (ctx context ) (Statement , error ) {
11581231 nameTokens , err := p .evaluateVarNames ()
11591232
@@ -1948,6 +2021,8 @@ func (p *Parser) evaluateStatement(ctx context) (Statement, error) {
19482021 switch p .peekAt (1 ).Type () {
19492022 case lexer .INCREMENT_OPERATOR , lexer .DECREMENT_OPERATOR :
19502023 stmt , err = p .evaluateIncrementDecrement (ctx )
2024+ case lexer .COMPOUND_ASSIGN_OPERATOR :
2025+ stmt , err = p .evaluateCompoundAssignment (ctx )
19512026 case lexer .ASSIGN_OPERATOR , lexer .COMMA :
19522027 stmt , err = p .evaluateVarAssignment (ctx )
19532028 default :
@@ -2067,7 +2142,7 @@ func (p *Parser) evaluateLogicalOperation(ctx context, operator LogicalOperator,
20672142 if operatorToken .Type () != lexer .LOGICAL_OPERATOR || operatorToken .Value () != operator {
20682143 break
20692144 }
2070-
2145+
20712146 if ! leftExpression .ValueType ().IsBool () {
20722147 return nil , p .expectedError ("boolean value" , conditionToken )
20732148 }
0 commit comments