@@ -1285,6 +1285,55 @@ maybeUnlock(x:HashTableOrNull):void := (
12851285 if !y.beingInitialized then unlock(y.mutex))
12861286 else nothing);
12871287
1288+ --what about mutable lists?
1289+ --assumes that the table has been locked on
1290+ hashTableAugmentedAssignmentFun(lhs:binaryCode, oper1: Symbol, oper:Symbol, rexpr:Expr, rpos:Position):Expr := (
1291+ lexpr := nullE;
1292+ key := nullE;
1293+ table := eval(lhs.lhs);
1294+ when table
1295+ is Error do return table
1296+ is hashTable:HashTable do (
1297+ if lhs.f == DotS.symbol.binary then (
1298+ --this replicates dotfun from actors5.d but using the non-locking variation of lookup1force
1299+ when lhs.rhs
1300+ is r:globalSymbolClosureCode do (
1301+ key = Expr(SymbolClosure(globalFrame,r.symbol));
1302+ lexpr = lookup1forceNoLock(hashTable, key))
1303+ else nothing) --TODO correct error message printErrorMessageE(rhs,"expected a symbol"))
1304+ else if lhs.f == SharpS.symbol.binary then (
1305+ --TODO
1306+ key = eval(lhs.rhs);
1307+ lexpr = lookup1forceNoLock(hashTable, key)
1308+ )
1309+ else (
1310+ --this case should be impossible
1311+ return nullE;
1312+ );
1313+ meth := lookup(Class(lexpr), Expr(SymbolClosure(globalFrame, oper1)));
1314+ if meth != nullE then (
1315+ r := applyEEE(meth,lexpr,rexpr);--TODO what if meth tries to assign to the same hash table
1316+ --check if the returned value is the symbol "Default"
1317+ when r
1318+ is s:SymbolClosure do (
1319+ if (s.symbol.word.name === "Default") then nothing
1320+ else (
1321+ return r
1322+ )
1323+ )
1324+ else (
1325+ return r;
1326+ )
1327+ );
1328+ left := evaluatedCode(lexpr, codePosition(Code(lhs)));
1329+ right := evaluatedCode(rexpr, rpos);
1330+ r := eval(Code(binaryCode(oper.binary, Code(left), right, rpos)));
1331+ --r := oper.binary(Code(left),Code(right));
1332+ storeInHashTableNoLock(hashTable,key,hash(key),r);
1333+ r)
1334+ else WrongArgHashTable(1)
1335+ );
1336+
12881337augmentedAssignmentFun(x:augmentedAssignmentCode):Expr := (
12891338 when lookup(x.oper.word, augmentedAssignmentOperatorTable)
12901339 is null do buildErrorPacket("unknown augmented assignment operator")
@@ -1293,17 +1342,58 @@ augmentedAssignmentFun(x:augmentedAssignmentCode):Expr := (
12931342 table := maybeLock(x.lhs);
12941343 -- evaluate the left- hand side first
12951344 lexpr := nullE;
1345+ -- this will eventually hold the value to assign
12961346 if s.word.name == = " ??" -- x ??= y is treated like x ?? (x = y)
12971347 then (
1348+ maybeUnlock(table);
12981349 e := nullify(x.lhs);
12991350 when e
1300- is Nothing do nothing
1351+ is Nothing do (
1352+ return when x.lhs
1353+ is y:globalMemoryReferenceCode do (
1354+ r := eval(x.rhs);
1355+ when r is e:Error do r
1356+ else globalAssignment(y.frameindex, x.info, r))
1357+ is y:localMemoryReferenceCode do (
1358+ r := eval(x.rhs);
1359+ when r is e:Error do r
1360+ else localAssignment(y.nestingDepth, y.frameindex, r))
1361+ is y:threadMemoryReferenceCode do (
1362+ r := eval(x.rhs);
1363+ when r is e:Error do r
1364+ else globalAssignment(y.frameindex, x.info, r))
1365+ is y:binaryCode do (
1366+ r := x.rhs;
1367+ if y.f == DotS.symbol.binary || y.f == SharpS.symbol.binary
1368+ then (
1369+ z := AssignElemFun(y.lhs, y.rhs, r);
1370+ z)
1371+ else InstallValueFun(CodeSequence(
1372+ convertGlobalOperator(x.info), y.lhs, y.rhs, r)))
1373+ is y:adjacentCode do (
1374+ r := x.rhs;
1375+ InstallValueFun(CodeSequence(
1376+ convertGlobalOperator(AdjacentS.symbol), y.lhs, y.rhs, r)))
1377+ is y:unaryCode do (
1378+ r := x.rhs;
1379+ UnaryInstallValueFun(convertGlobalOperator(x.info), y.rhs, r))
1380+ else buildErrorPacket(
1381+ " augmented assignment not implemented for this code" )
1382+ )
13011383 else (
1302- maybeUnlock(table);
13031384 return e))
1304- else lexpr = eval(x.lhs);
1385+ else (
1386+ when table is hashTable:HashTable do (
1387+ when x.lhs is y:binaryCode do (
1388+ r := hashTableAugmentedAssignmentFun(y, x.oper, s, eval(x.rhs), codePosition(x.rhs));
1389+ unlock(hashTable.mutex);
1390+ return r)
1391+ else nothing; -- this case should be impossible
1392+ )
1393+ else nothing;
1394+ lexpr = eval(x.lhs)
1395+ );
13051396 when lexpr is e:Error do (
1306- maybeUnlock(table);
13071397 return lexpr)
13081398 else nothing;
13091399 -- check if user- defined method exists
@@ -1319,10 +1409,8 @@ augmentedAssignmentFun(x:augmentedAssignmentCode):Expr := (
13191409 is s:SymbolClosure do (
13201410 if s.symbol.word.name == = " Default" then nothing
13211411 else (
1322- maybeUnlock(table);
13231412 return r))
13241413 else (
1325- maybeUnlock(table);
13261414 return r));
13271415 -- if not, use default behavior
13281416 left := evaluatedCode(lexpr, codePosition(x.lhs));
@@ -1344,7 +1432,6 @@ augmentedAssignmentFun(x:augmentedAssignmentCode):Expr := (
13441432 if y.f == DotS.symbol.binary || y.f == SharpS.symbol.binary
13451433 then (
13461434 z := AssignElemFun(y.lhs, y.rhs, r);
1347- maybeUnlock(table);
13481435 z)
13491436 else InstallValueFun(CodeSequence(
13501437 convertGlobalOperator(x.info), y.lhs, y.rhs, r)))
0 commit comments