...

Source file src/cuelang.org/go/internal/core/adt/default.go

Documentation: cuelang.org/go/internal/core/adt

     1  // Copyright 2020 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  
    15  package adt
    16  
    17  // Default returns the default value or itself if there is no default.
    18  func Default(v Value) Value {
    19  	switch x := v.(type) {
    20  	case *Vertex:
    21  		return x.Default()
    22  	case *Disjunction:
    23  		return x.Default()
    24  	default:
    25  		return v
    26  	}
    27  }
    28  
    29  func (d *Disjunction) Default() Value {
    30  	switch d.NumDefaults {
    31  	case 0:
    32  		return d
    33  	case 1:
    34  		return d.Values[0]
    35  	default:
    36  		return &Disjunction{
    37  			Src:         d.Src,
    38  			Values:      d.Values[:d.NumDefaults],
    39  			NumDefaults: 0,
    40  		}
    41  	}
    42  }
    43  
    44  // Default returns the default value or itself if there is no default.
    45  //
    46  // It also closes a list, representing its default value.
    47  func (v *Vertex) Default() *Vertex {
    48  	switch d := v.BaseValue.(type) {
    49  	default:
    50  		return v
    51  
    52  	case *Disjunction:
    53  		var w *Vertex
    54  
    55  		switch d.NumDefaults {
    56  		case 0:
    57  			return v
    58  		case 1:
    59  			w = ToVertex(Default(d.Values[0]))
    60  		default:
    61  			x := *v
    62  			x.state = nil
    63  			x.BaseValue = &Disjunction{
    64  				Src:         d.Src,
    65  				Values:      d.Values[:d.NumDefaults],
    66  				NumDefaults: 0,
    67  			}
    68  			w = &x
    69  			w.Conjuncts = nil
    70  		}
    71  
    72  		if w.Conjuncts == nil {
    73  			for _, c := range v.Conjuncts {
    74  				// TODO: preserve field information.
    75  				expr, _ := stripNonDefaults(c.Elem())
    76  				w.Conjuncts = append(w.Conjuncts, MakeRootConjunct(c.Env, expr))
    77  			}
    78  		}
    79  		return w
    80  
    81  	case *ListMarker:
    82  		m := *d
    83  		m.IsOpen = false
    84  
    85  		w := *v
    86  		w.BaseValue = &m
    87  		w.state = nil
    88  		return &w
    89  	}
    90  }
    91  
    92  // TODO: this should go: record preexpanded disjunctions in Vertex.
    93  func stripNonDefaults(elem Elem) (r Elem, stripped bool) {
    94  	expr, ok := elem.(Expr)
    95  	if !ok {
    96  		return elem, false
    97  	}
    98  	switch x := expr.(type) {
    99  	case *DisjunctionExpr:
   100  		if !x.HasDefaults {
   101  			return x, false
   102  		}
   103  		d := *x
   104  		d.Values = []Disjunct{}
   105  		for _, v := range x.Values {
   106  			if v.Default {
   107  				d.Values = append(d.Values, v)
   108  			}
   109  		}
   110  		if len(d.Values) == 1 {
   111  			return d.Values[0].Val, true
   112  		}
   113  		return &d, true
   114  
   115  	case *BinaryExpr:
   116  		if x.Op != AndOp {
   117  			return x, false
   118  		}
   119  		a, sa := stripNonDefaults(x.X)
   120  		b, sb := stripNonDefaults(x.Y)
   121  		if sa || sb {
   122  			bin := *x
   123  			bin.X = a.(Expr)
   124  			bin.Y = b.(Expr)
   125  			return &bin, true
   126  		}
   127  		return x, false
   128  
   129  	default:
   130  		return x, false
   131  	}
   132  }
   133  

View as plain text