Skip to content

Commit

Permalink
Refactor augmented assignment so we don't evaluate things twice
Browse files Browse the repository at this point in the history
Evaluate everything immediately but store it as evaluatedCode for
later.
  • Loading branch information
d-torrance committed Jan 20, 2024
1 parent c7b1140 commit d55cc5e
Showing 1 changed file with 23 additions and 21 deletions.
44 changes: 23 additions & 21 deletions M2/Macaulay2/d/evaluate.d
Original file line number Diff line number Diff line change
Expand Up @@ -1213,50 +1213,52 @@ augmentedAssignmentFun(x:augmentedAssignmentCode):Expr := (
when lookup(x.oper.word, augmentedAssignmentOperatorTable)
is null do buildErrorPacket("unknown augmented assignment operator")
is s:Symbol do (
-- first check if user-defined method
-- TODO: when there isn't a user-defined method, we end up evaluating
-- the left-hand side twice. is there any way to avoid this?
left := eval(x.lhs);
when left is e:Error do return Expr(e) else nothing;
meth := lookup(Class(left), Expr(SymbolClosure(globalFrame, x.oper)));
-- evaluate both sides first
left := evaluatedCode(eval(x.lhs), dummyPosition);
when left.expr is e:Error do return Expr(e) else nothing;
right := evaluatedCode(eval(x.rhs), dummyPosition);
when right.expr is e:Error do return Expr(e) else nothing;
-- check if user-defined method exists
meth := lookup(Class(left.expr),
Expr(SymbolClosure(globalFrame, x.oper)));
if meth != nullE then (
right := eval(x.rhs);
when right is e:Error do return Expr(e)
else (
r := applyEEE(meth, left, right);
when r
is s:SymbolClosure do (
if s.symbol.word.name === "Default" then nothing
else return r)
else return r));
r := applyEEE(meth, left.expr, right.expr);
when r
is s:SymbolClosure do (
if s.symbol.word.name === "Default" then nothing
else return r)
else return r);
-- if not, use default behavior
when x.lhs
is y:globalMemoryReferenceCode do (
r := s.binary(x.lhs, x.rhs);
r := s.binary(Code(left), Code(right));
when r is e:Error do Expr(e)
else globalAssignment(y.frameindex, x.info, r))
is y:localMemoryReferenceCode do (
r := s.binary(x.lhs, x.rhs);
r := s.binary(Code(left), Code(right));
when r is e:Error do Expr(e)
else localAssignment(y.nestingDepth, y.frameindex, r))
is y:threadMemoryReferenceCode do (
r := s.binary(x.lhs, x.rhs);
r := s.binary(Code(left), Code(right));
when r is e:Error do Expr(e)
else globalAssignment(y.frameindex, x.info, r))
is y:binaryCode do (
r := Code(binaryCode(s.binary, y, x.rhs, dummyPosition));
r := Code(binaryCode(s.binary, Code(left), Code(right),
dummyPosition));
if y.f == DotS.symbol.binary || y.f == SharpS.symbol.binary
then AssignElemFun(y.lhs, y.rhs, r)
else InstallValueFun(CodeSequence(Code(
globalSymbolClosureCode(x.info, dummyPosition)),
y.lhs, y.rhs, r)))
is y:adjacentCode do (
r := Code(binaryCode(s.binary, y, x.rhs, dummyPosition));
r := Code(binaryCode(s.binary, Code(left), Code(right),
dummyPosition));
InstallValueFun(CodeSequence(Code(globalSymbolClosureCode(
AdjacentS.symbol, dummyPosition)),
y.lhs, y.rhs, r)))
is y:unaryCode do (
r := Code(binaryCode(s.binary, y, x.rhs, dummyPosition));
r := Code(binaryCode(s.binary, Code(left), Code(right),
dummyPosition));
UnaryInstallValueFun(
Code(globalSymbolClosureCode(x.info, dummyPosition)),
y.rhs, r))
Expand Down

0 comments on commit d55cc5e

Please sign in to comment.