1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package compile
16
17 import (
18 "strconv"
19
20 "cuelang.org/go/cue/ast"
21 "cuelang.org/go/cue/token"
22 "cuelang.org/go/internal/core/adt"
23 )
24
25 func predeclared(n *ast.Ident) adt.Expr {
26
27
28
29 switch n.Name {
30 case "string", "__string":
31 return &adt.BasicType{Src: n, K: adt.StringKind}
32 case "bytes", "__bytes":
33 return &adt.BasicType{Src: n, K: adt.BytesKind}
34 case "bool", "__bool":
35 return &adt.BasicType{Src: n, K: adt.BoolKind}
36 case "int", "__int":
37 return &adt.BasicType{Src: n, K: adt.IntKind}
38 case "float", "__float":
39 return &adt.BasicType{Src: n, K: adt.FloatKind}
40 case "number", "__number":
41 return &adt.BasicType{Src: n, K: adt.NumKind}
42
43 case "len", "__len":
44 return lenBuiltin
45 case "close", "__close":
46 return closeBuiltin
47 case "and", "__and":
48 return andBuiltin
49 case "or", "__or":
50 return orBuiltin
51 case "div", "__div":
52 return divBuiltin
53 case "mod", "__mod":
54 return modBuiltin
55 case "quo", "__quo":
56 return quoBuiltin
57 case "rem", "__rem":
58 return remBuiltin
59 }
60
61 if r, ok := predefinedRanges[n.Name]; ok {
62 return r
63 }
64
65 return nil
66 }
67
68
69
70 func LookupRange(name string) adt.Expr {
71 return predefinedRanges[name]
72 }
73
74 var predefinedRanges = map[string]adt.Expr{
75 "rune": mkIntRange("0", strconv.Itoa(0x10FFFF)),
76 "int8": mkIntRange("-128", "127"),
77 "int16": mkIntRange("-32768", "32767"),
78 "int32": mkIntRange("-2147483648", "2147483647"),
79 "int64": mkIntRange("-9223372036854775808", "9223372036854775807"),
80 "int128": mkIntRange(
81 "-170141183460469231731687303715884105728",
82 "170141183460469231731687303715884105727"),
83
84
85
86 "uint": mkUint(),
87 "uint8": mkIntRange("0", "255"),
88 "uint16": mkIntRange("0", "65535"),
89 "uint32": mkIntRange("0", "4294967295"),
90 "uint64": mkIntRange("0", "18446744073709551615"),
91 "uint128": mkIntRange("0", "340282366920938463463374607431768211455"),
92
93
94 "float32": mkFloatRange(
95 "-3.40282346638528859811704183484516925440e+38",
96 "3.40282346638528859811704183484516925440e+38",
97 ),
98
99 "float64": mkFloatRange(
100 "-1.797693134862315708145274237317043567981e+308",
101 "1.797693134862315708145274237317043567981e+308",
102 ),
103 }
104
105 func init() {
106 for k, v := range predefinedRanges {
107 predefinedRanges["__"+k] = v
108 }
109 }
110
111
112
113 func mkUint() adt.Expr {
114 from := newBound(adt.GreaterEqualOp, adt.IntKind, parseInt("0"))
115 ident := ast.NewIdent("__int")
116 src := ast.NewBinExpr(token.AND, ident, from.Src)
117 return &adt.Conjunction{
118 Src: src,
119 Values: []adt.Value{
120 &adt.BasicType{Src: ident, K: adt.IntKind}, from,
121 },
122 }
123 }
124
125 func mkIntRange(a, b string) adt.Expr {
126 from := newBound(adt.GreaterEqualOp, adt.IntKind, parseInt(a))
127 to := newBound(adt.LessEqualOp, adt.IntKind, parseInt(b))
128 ident := ast.NewIdent("__int")
129 src := ast.NewBinExpr(token.AND, ident, from.Src, to.Src)
130 return &adt.Conjunction{
131 Src: src,
132 Values: []adt.Value{
133 &adt.BasicType{Src: ident, K: adt.IntKind}, from, to,
134 },
135 }
136 }
137
138 func mkFloatRange(a, b string) adt.Expr {
139 from := newBound(adt.GreaterEqualOp, adt.NumKind, parseFloat(a))
140 to := newBound(adt.LessEqualOp, adt.NumKind, parseFloat(b))
141 src := ast.NewBinExpr(token.AND, from.Src, to.Src)
142 return &adt.Conjunction{Src: src, Values: []adt.Value{from, to}}
143 }
144
145 func newBound(op adt.Op, k adt.Kind, v adt.Value) *adt.BoundValue {
146 src := &ast.UnaryExpr{Op: op.Token(), X: v.Source().(ast.Expr)}
147 return &adt.BoundValue{Src: src, Op: op, Value: v}
148 }
149
150 func parseInt(s string) *adt.Num {
151 n := parseNum(adt.IntKind, s)
152 n.Src = &ast.BasicLit{Kind: token.INT, Value: s}
153 return n
154 }
155
156 func parseFloat(s string) *adt.Num {
157 n := parseNum(adt.FloatKind, s)
158 n.Src = &ast.BasicLit{Kind: token.FLOAT, Value: s}
159 return n
160 }
161
162 func parseNum(k adt.Kind, s string) *adt.Num {
163 num := &adt.Num{K: k}
164 _, _, err := num.X.SetString(s)
165 if err != nil {
166 panic(err)
167 }
168 return num
169 }
170
View as plain text