@@ -1323,10 +1323,49 @@ nullCoalescion(lhs:Code,rhs:Code):Expr := (
13231323 else e);
13241324setup(QuestionQuestionS, nullify, nullCoalescion);
13251325
1326+ -- TODO: is there a better way to declare this?
1327+ augmentedAssignmentFun(c:augmentedAssignmentCode):Expr;
1328+ header "static parse_Expr augmentedAssignmentFun(parse_augmentedAssignmentCode c);";
1329+ augmentedParallelAssignmentFun(oper:Symbol, lhs:CodeSequence, rhs:Code):Expr:= (
1330+ n := length(lhs);
1331+ rexpr := eval(rhs);
1332+ when rexpr
1333+ is Error do return rexpr else nothing;
1334+ if n == 1 then rexpr = seq(rexpr);
1335+ when rexpr
1336+ is rvals:Sequence do (
1337+ if length(rvals) == n then (
1338+ pos := codePosition(rhs);
1339+ e := nullE;
1340+ result := new Sequence len n at i do provide (
1341+ when e is Error do nullE
1342+ else (
1343+ r := augmentedAssignmentFun(augmentedAssignmentCode(oper,
1344+ lhs.i, Code(evaluatedCode(rvals.i, pos)), pos));
1345+ when r is Error do (
1346+ e = r;
1347+ nullE)
1348+ else r));
1349+ when e
1350+ is Error do e
1351+ else if n == 1 then result.0 else Expr(result)))
1352+ else ParallelAssignmentError(n));
1353+
13261354augmentedAssignmentFun(x:augmentedAssignmentCode):Expr := (
13271355 when lookup(x.oper.word, augmentedAssignmentOperatorTable)
13281356 is null do buildErrorPacket("unknown augmented assignment operator")
13291357 is s:Symbol do (
1358+ -- parallel assignment?
1359+ when x.lhs
1360+ is y:sequenceCode do (
1361+ return augmentedParallelAssignmentFun(x.oper, y.x, x.rhs))
1362+ is y:listCode do (
1363+ return augmentedParallelAssignmentFun(x.oper, y.y, x.rhs))
1364+ is y:arrayCode do (
1365+ return augmentedParallelAssignmentFun(x.oper, y.z, x.rhs))
1366+ is y:angleBarListCode do (
1367+ return augmentedParallelAssignmentFun(x.oper, y.t, x.rhs))
1368+ else nothing;
13301369 -- evaluate the left-hand side first
13311370 lexpr := nullE;
13321371 if s.word.name === "??" -- x ??= y is treated like x ?? (x = y)
@@ -1349,33 +1388,32 @@ augmentedAssignmentFun(x:augmentedAssignmentCode):Expr := (
13491388 else return r)
13501389 else return r);
13511390 -- if not, use default behavior
1352- left := evaluatedCode(lexpr, codePosition(x.lhs));
1391+ c := Code(binaryCode(s, Code(evaluatedCode(lexpr, codePosition(x.lhs))),
1392+ x.rhs, x.position));
13531393 when x.lhs
13541394 is y:globalMemoryReferenceCode do (
1355- r := s.binary(Code(left), x.rhs );
1356- when r is e: Error do r
1395+ r := eval(c );
1396+ when r is Error do r
13571397 else globalAssignment(y.var.frameindex, y.var, r))
13581398 is y:localMemoryReferenceCode do (
1359- r := s.binary(Code(left), x.rhs );
1360- when r is e: Error do r
1399+ r := eval(c );
1400+ when r is Error do r
13611401 else localAssignment(y.nestingDepth, y.frameindex, r))
13621402 is y:threadMemoryReferenceCode do (
1363- r := s.binary(Code(left), x.rhs );
1364- when r is e: Error do r
1403+ r := eval(c );
1404+ when r is Error do r
13651405 else globalAssignment(y.var.frameindex, y.var, r))
13661406 is y:binaryCode do (
1367- r := Code(binaryCode(s, Code(left), x.rhs, x.position));
13681407 if y.oper == DotS.symbol || y.oper == SharpS.symbol
1369- then AssignElemFun(y.lhs, y.rhs, r )
1408+ then AssignElemFun(y.lhs, y.rhs, c )
13701409 else InstallValueFun(CodeSequence(
1371- convertGlobalOperator(y.oper), y.lhs, y.rhs, r )))
1410+ convertGlobalOperator(y.oper), y.lhs, y.rhs, c )))
13721411 is y:adjacentCode do (
1373- r := Code(binaryCode(s, Code(left), x.rhs, x.position));
13741412 InstallValueFun(CodeSequence(
1375- convertGlobalOperator(AdjacentS.symbol), y.lhs, y.rhs, r )))
1413+ convertGlobalOperator(AdjacentS.symbol), y.lhs, y.rhs, c )))
13761414 is y:unaryCode do (
1377- r := Code(binaryCode(s, Code(left ), x .rhs, x.position));
1378- UnaryInstallValueFun(convertGlobalOperator(y.oper), y.rhs, r))
1415+ UnaryInstallValueFun(convertGlobalOperator(y.oper ), y .rhs, c))
1416+ is nullCode do nullE -- for use w/ parallel assignment
13791417 else buildErrorPacket(
13801418 "augmented assignment not implemented for this code")));
13811419
0 commit comments