blob: 75011c3058e7d284cd44f02625621004c4b2edfa [file] [log] [blame]
Marcel van Lohuizen17157ea2018-12-11 10:41:10 +01001// Copyright 2018 The CUE Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package cue
16
17func (c *context) copy(v value) value {
18 // return v.copy(c)
19 return rewrite(c, v, rewriteCopy)
20}
21
22func rewriteCopy(ctx *context, v value) (value, bool) {
23 switch x := v.(type) {
24 case *nodeRef:
25 node := ctx.deref(x.node)
26 if node == x.node {
27 return x, false
28 }
29 return &nodeRef{x.baseValue, node}, false
30
31 case *structLit:
32 arcs := make(arcs, len(x.arcs))
Marcel van Lohuizen66db9202018-12-17 19:02:08 +010033
Marcel van Lohuizen7f48df72019-02-01 17:24:59 +010034 obj := &structLit{x.baseValue, nil, nil, nil, arcs, nil}
Marcel van Lohuizen66db9202018-12-17 19:02:08 +010035
36 defer ctx.pushForwards(x, obj).popForwards()
37
Marcel van Lohuizen17157ea2018-12-11 10:41:10 +010038 emit := x.emit
39 if emit != nil {
40 emit = ctx.copy(x.emit)
41 }
Marcel van Lohuizen66db9202018-12-17 19:02:08 +010042 obj.emit = x.emit
43
Marcel van Lohuizen17157ea2018-12-11 10:41:10 +010044 t := x.template
45 if t != nil {
46 v := ctx.copy(t)
47 if isBottom(v) {
48 return t, false
49 }
Marcel van Lohuizen66db9202018-12-17 19:02:08 +010050 t = v
Marcel van Lohuizen17157ea2018-12-11 10:41:10 +010051 }
Marcel van Lohuizen66db9202018-12-17 19:02:08 +010052 obj.template = t
Marcel van Lohuizen17157ea2018-12-11 10:41:10 +010053
Marcel van Lohuizen17157ea2018-12-11 10:41:10 +010054 for i, a := range x.arcs {
Marcel van Lohuizen08a0ef22019-03-28 09:12:19 +010055 a.setValue(ctx.copy(a.v))
56 arcs[i] = a
Marcel van Lohuizen17157ea2018-12-11 10:41:10 +010057 }
Marcel van Lohuizen66db9202018-12-17 19:02:08 +010058
59 comp := make([]*fieldComprehension, len(x.comprehensions))
60 for i, c := range x.comprehensions {
61 comp[i] = ctx.copy(c).(*fieldComprehension)
62 }
63 obj.comprehensions = comp
Marcel van Lohuizen17157ea2018-12-11 10:41:10 +010064 return obj, false
65
66 case *lambdaExpr:
67 arcs := make([]arc, len(x.arcs))
68 for i, a := range x.arcs {
69 arcs[i] = arc{feature: a.feature, v: ctx.copy(a.v)}
70 }
71 lambda := &lambdaExpr{x.baseValue, &params{arcs}, nil}
72 defer ctx.pushForwards(x, lambda).popForwards()
73
74 lambda.value = ctx.copy(x.value)
75 return lambda, false
76 }
77 return v, true
78}