blob: c36ea9c9a909027c55af67a4a08b12cef71de073 [file] [log] [blame]
// Copyright 2020 CUE Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package adt
import (
"regexp"
"github.com/cockroachdb/apd/v2"
"cuelang.org/go/cue/ast"
"cuelang.org/go/cue/errors"
"cuelang.org/go/cue/token"
)
// A StructLit represents an unevaluated struct literal or file body.
type StructLit struct {
Src ast.Node // ast.File or ast.StructLit
Decls []Decl
// administrative fields like hasreferences.
// hasReferences bool
}
func (x *StructLit) Source() ast.Node { return x.Src }
// FIELDS
//
// Fields can also be used as expressions whereby the value field is the
// expression this allows retaining more context.
// Field represents a field with a fixed label. It can be a regular field,
// definition or hidden field.
//
// foo: bar
// #foo: bar
// _foo: bar
//
// Legacy:
//
// Foo :: bar
//
type Field struct {
Src *ast.Field
Label Feature
Value Expr
}
func (x *Field) Source() ast.Node { return x.Src }
// An OptionalField represents an optional regular field.
//
// foo?: expr
//
type OptionalField struct {
Src *ast.Field
Label Feature
Value Expr
}
func (x *OptionalField) Source() ast.Node { return x.Src }
// A BulkOptionalField represents a set of optional field.
//
// [expr]: expr
//
type BulkOptionalField struct {
Src *ast.Field // Elipsis or Field
Filter Expr
Value Expr
Label Feature // for reference and formatting
}
func (x *BulkOptionalField) Source() ast.Node { return x.Src }
// A Ellipsis represents a set of optional fields of a given type.
//
// ...T
//
type Ellipsis struct {
Src *ast.Ellipsis
Value Expr
}
func (x *Ellipsis) Source() ast.Node { return x.Src }
// A DynamicField represents a regular field for which the key is computed.
//
// "\(expr)": expr
// (expr): expr
//
type DynamicField struct {
Src *ast.Field
Key Expr
Value Expr
}
func (x *DynamicField) IsOptional() bool {
return x.Src.Optional != token.NoPos
}
func (x *DynamicField) Source() ast.Node { return x.Src }
// Expressions
// A ListLit represents an unevaluated list literal.
//
// [a, for x in src { ... }, b, ...T]
//
type ListLit struct {
Src *ast.ListLit
// scalars, comprehensions, ...T
Elems []Elem
}
func (x *ListLit) Source() ast.Node { return x.Src }
// -- Literals
// Bottom represents an error or bottom symbol.
type Bottom struct {
Src ast.Node
Err errors.Error
}
func (x *Bottom) Source() ast.Node { return x.Src }
func (x *Bottom) Kind() Kind { return BottomKind }
// Null represents null. It can be used as a Value and Expr.
type Null struct {
Src ast.Node
}
func (x *Null) Source() ast.Node { return x.Src }
func (x *Null) Kind() Kind { return NullKind }
// Bool is a boolean value. It can be used as a Value and Expr.
type Bool struct {
Src ast.Node
B bool
}
func (x *Bool) Source() ast.Node { return x.Src }
func (x *Bool) Kind() Kind { return BoolKind }
// Num is a numeric value. It can be used as a Value and Expr.
type Num struct {
Src ast.Node
K Kind // needed?
X apd.Decimal // Is integer if the apd.Decimal is an integer.
}
func (x *Num) Source() ast.Node { return x.Src }
func (x *Num) Kind() Kind { return x.K }
// String is a string value. It can be used as a Value and Expr.
type String struct {
Src ast.Node
Str string
RE *regexp.Regexp // only set if needed
}
func (x *String) Source() ast.Node { return x.Src }
func (x *String) Kind() Kind { return StringKind }
// Bytes is a bytes value. It can be used as a Value and Expr.
type Bytes struct {
Src ast.Node
B []byte
RE *regexp.Regexp // only set if needed
}
func (x *Bytes) Source() ast.Node { return x.Src }
func (x *Bytes) Kind() Kind { return BytesKind }
// -- composites: the evaluated fields of a composite are recorded in the arc
// vertices.
type ListMarker struct {
Src ast.Node
}
func (x *ListMarker) Source() ast.Node { return x.Src }
func (x *ListMarker) Kind() Kind { return ListKind }
func (x *ListMarker) node() {}
type StructMarker struct {
Closed bool
}
func (x *StructMarker) Source() ast.Node { return nil }
func (x *StructMarker) Kind() Kind { return StructKind }
func (x *StructMarker) node() {}
// -- top types
// Top represents all possible values. It can be used as a Value and Expr.
type Top struct{ Src *ast.Ident }
func (x *Top) Source() ast.Node { return x.Src }
func (x *Top) Kind() Kind { return TopKind }
// BasicType represents all values of a certain Kind. It can be used as a Value
// and Expr.
//
// string
// int
// num
// bool
//
type BasicType struct {
Src *ast.Ident
K Kind
}
func (x *BasicType) Source() ast.Node { return x.Src }
func (x *BasicType) Kind() Kind { return x.K }
// TODO: should we use UnaryExpr for Bound now we have BoundValue?
// BoundExpr represents an unresolved unary comparator.
//
// <a
// =~MyPattern
//
type BoundExpr struct {
Src *ast.UnaryExpr
Op Op
Expr Expr
}
func (x *BoundExpr) Source() ast.Node { return x.Src }
// A BoundValue is a fully evaluated unary comparator that can be used to
// validate other values.
//
// <5
// =~"Name$"
//
type BoundValue struct {
Src ast.Node
Op Op
Value Value
K Kind
}
func (x *BoundValue) Source() ast.Node { return x.Src }
func (x *BoundValue) Kind() Kind { return x.K }
// -- References
// A FieldReference represents a lexical reference to a field.
//
// a
//
type FieldReference struct {
Src *ast.Ident
UpCount int32
Label Feature
}
func (x *FieldReference) Source() ast.Node { return x.Src }
// A LabelReference refers to the string or integer value of a label.
//
// [X=Pattern]: b: X
//
type LabelReference struct {
Src *ast.Ident
UpCount int32
}
// TODO: should this implement resolver at all?
func (x *LabelReference) Source() ast.Node { return x.Src }
// A DynamicReference is like a LabelReference, but with a computed label.
//
// X=(x): X
// X="\(x)": X
//
type DynamicReference struct {
Src *ast.Ident
UpCount int32
Label Expr
// TODO: only use aliases and store the actual expression only in the scope.
// The feature is unique for every instance. This will also allow dynamic
// fields to be ordered among normal fields.
//
// This could also be used to assign labels to embedded values, if they
// don't match a label.
Alias Feature
}
func (x *DynamicReference) Source() ast.Node { return x.Src }
// An ImportReference refers to an imported package.
//
// import "strings"
//
// strings.ToLower("Upper")
//
type ImportReference struct {
Src *ast.Ident
ImportPath Feature
Label Feature // for informative purposes
}
func (x *ImportReference) Source() ast.Node { return x.Src }
// A LetReference evaluates a let expression in its original environment.
//
// let X = x
//
type LetReference struct {
Src *ast.Ident
UpCount int32
Label Feature // for informative purposes
X Expr
}
func (x *LetReference) Source() ast.Node { return x.Src }
// A SelectorExpr looks up a fixed field in an expression.
//
// X.Sel
//
type SelectorExpr struct {
Src *ast.SelectorExpr
X Expr
Sel Feature
}
func (x *SelectorExpr) Source() ast.Node { return x.Src }
// IndexExpr is like a selector, but selects an index.
//
// X[Index]
//
type IndexExpr struct {
Src *ast.IndexExpr
X Expr
Index Expr
}
func (x *IndexExpr) Source() ast.Node { return x.Src }
// A SliceExpr represents a slice operation. (Not currently in spec.)
//
// X[Lo:Hi:Stride]
//
type SliceExpr struct {
Src *ast.SliceExpr
X Expr
Lo Expr
Hi Expr
Stride Expr
}
func (x *SliceExpr) Source() ast.Node { return x.Src }
// An Interpolation is a string interpolation.
//
// "a \(b) c"
//
type Interpolation struct {
Src *ast.Interpolation
K Kind // string or bytes
Parts []Expr // odd: strings, even sources
}
func (x *Interpolation) Source() ast.Node { return x.Src }
// UnaryExpr is a unary expression.
//
// Op X
// -X !X +X
//
type UnaryExpr struct {
Src *ast.UnaryExpr
Op Op
X Expr
}
func (x *UnaryExpr) Source() ast.Node { return x.Src }
// BinaryExpr is a binary expression.
//
// X + Y
// X & Y
//
type BinaryExpr struct {
Src *ast.BinaryExpr
Op Op
X Expr
Y Expr
}
func (x *BinaryExpr) Source() ast.Node { return x.Src }
// -- builtins
// A CallExpr represents a call to a builtin.
//
// len(x)
// strings.ToLower(x)
//
type CallExpr struct {
Src *ast.CallExpr
Fun Expr
Args []Expr
}
func (x *CallExpr) Source() ast.Node { return x.Src }
// A BuiltinValidator is a Value that results from evaluation a partial call
// to a builtin (using CallExpr).
//
// strings.MinRunes(4)
//
type BuiltinValidator struct {
Src *ast.CallExpr
Fun Expr // TODO: should probably be builtin.
Args []Value // any but the first value
// call *builtin // function must return a bool
}
func (x *BuiltinValidator) Source() ast.Node { return x.Src }
func (x *BuiltinValidator) Kind() Kind { return TopKind }
// A Disjunction represents a disjunction, where each disjunct may or may not
// be marked as a default.
type DisjunctionExpr struct {
Src *ast.BinaryExpr
Values []Disjunct
HasDefaults bool
}
// A Disjunct is used in Disjunction.
type Disjunct struct {
Val Expr
Default bool
}
func (x *DisjunctionExpr) Source() ast.Node {
if x.Src == nil {
return nil
}
return x.Src
}
// A Conjunction is a conjunction of values that cannot be represented as a
// single value. It is the result of unification.
type Conjunction struct {
Values []Value
}
func (x *Conjunction) Source() ast.Node { return nil }
func (x *Conjunction) Kind() Kind { return TopKind }
// A disjunction is a disjunction of values. It is the result of expanding
// a DisjunctionExpr if the expression cannot be represented as a single value.
type Disjunction struct {
Src ast.Expr
// Values are the non-error disjuncts of this expression. The first
// NumDefault values are default values.
Values []*Vertex
Errors *Bottom // []bottom
// NumDefaults indicates the number of default values.
NumDefaults int
}
func (x *Disjunction) Source() ast.Node { return x.Src }
func (x *Disjunction) Kind() Kind {
k := BottomKind
for _, v := range x.Values {
k |= v.Kind()
}
return k
}
// A ForClause represents a for clause of a comprehension. It can be used
// as a struct or list element.
//
// for k, v in src {}
//
type ForClause struct {
Syntax *ast.ForClause
Key Feature
Value Feature
Src Expr
Dst Yielder
}
func (x *ForClause) Source() ast.Node { return x.Syntax }
// An IfClause represents an if clause of a comprehension. It can be used
// as a struct or list element.
//
// if cond {}
//
type IfClause struct {
Src *ast.IfClause
Condition Expr
Dst Yielder
}
func (x *IfClause) Source() ast.Node { return x.Src }
// An LetClause represents a let clause in a comprehension.
//
// for k, v in src {}
//
type LetClause struct {
Src *ast.LetClause
Label Feature
Expr Expr
Dst Yielder
}
func (x *LetClause) Source() ast.Node { return x.Src }
// A ValueClause represents the value part of a comprehension.
type ValueClause struct {
*StructLit
}
func (x *ValueClause) Source() ast.Node { return x.Src }