From 4ca3a665aece4f72dbc9bbed012d7bcc158d7c18 Mon Sep 17 00:00:00 2001 From: cmwslw Date: Sun, 16 Jul 2017 17:21:57 -0700 Subject: [PATCH] Immutable append/prepend. --- expreduce/builtin_list.go | 11 +++++++---- expreduce/ex_expression.go | 8 ++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/expreduce/builtin_list.go b/expreduce/builtin_list.go index 578f4bf..3f4f20f 100644 --- a/expreduce/builtin_list.go +++ b/expreduce/builtin_list.go @@ -549,8 +549,9 @@ func GetListDefinitions() (defs []Definition) { if !isExpr { return this } - expr.Parts = append(expr.Parts, this.Parts[2]) - return expr + res := NewExpression(append([]Ex{}, expr.Parts...)) + res.Parts = append(res.Parts, this.Parts[2]) + return res }, SimpleExamples: []TestInstruction{ &SameTest{"{a,b,c}", "Append[{a,b},c]"}, @@ -575,8 +576,10 @@ func GetListDefinitions() (defs []Definition) { if !isExpr { return this } - expr.Parts = append(append([]Ex{expr.Parts[0]}, this.Parts[2]), expr.Parts[1:]...) - return expr + res := NewExpression([]Ex{expr.Parts[0]}) + res.Parts = append(res.Parts, this.Parts[2]) + res.Parts = append(res.Parts, expr.Parts[1:]...) + return res }, SimpleExamples: []TestInstruction{ &SameTest{"{c,a,b}", "Prepend[{a,b},c]"}, diff --git a/expreduce/ex_expression.go b/expreduce/ex_expression.go index a5c741b..1a9a53a 100644 --- a/expreduce/ex_expression.go +++ b/expreduce/ex_expression.go @@ -9,6 +9,7 @@ import "flag" import "hash" var printevals = flag.Bool("printevals", false, "") +var checkhashes = flag.Bool("checkhashes", false, "") type Expression struct { Parts []Ex @@ -104,6 +105,7 @@ func (this *Expression) mergeSequences(es *EvalState, headStr string, shouldEval func (this *Expression) Eval(es *EvalState) Ex { lastExHash := uint64(0) + var lastEx Ex = this currExHash := hashEx(this) if currExHash == this.cachedHash { return this @@ -113,6 +115,12 @@ func (this *Expression) Eval(es *EvalState) Ex { for currExHash != lastExHash { lastExHash = currExHash curr, isExpr := currEx.(*Expression) + if *checkhashes { + if isExpr && curr.cachedHash != 0 && currExHash != curr.cachedHash { + fmt.Printf("invalid cache: %v. Used to be %v\n", curr, lastEx) + } + lastEx = currEx + } if isExpr && insideDefinition { retVal, isReturn := tryReturnValue(curr)