dhall 0.1.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +31 -4
- data/bin/dhall-compile +111 -0
- data/bin/json-to-dhall +1 -1
- data/bin/yaml-to-dhall +1 -1
- data/dhall.gemspec +5 -1
- data/lib/dhall.rb +25 -11
- data/lib/dhall/as_dhall.rb +132 -33
- data/lib/dhall/ast.rb +512 -210
- data/lib/dhall/binary.rb +102 -24
- data/lib/dhall/builtins.rb +227 -247
- data/lib/dhall/coder.rb +199 -0
- data/lib/dhall/normalize.rb +93 -48
- data/lib/dhall/parser.citrus +177 -83
- data/lib/dhall/parser.rb +199 -118
- data/lib/dhall/resolve.rb +200 -48
- data/lib/dhall/typecheck.rb +292 -129
- data/lib/dhall/types.rb +19 -0
- data/lib/dhall/util.rb +142 -38
- metadata +63 -4
- data/lib/dhall/visitor.rb +0 -23
data/lib/dhall/binary.rb
CHANGED
@@ -2,9 +2,11 @@
|
|
2
2
|
|
3
3
|
require "cbor"
|
4
4
|
require "digest/sha2"
|
5
|
+
require "multihashes"
|
5
6
|
|
6
7
|
require "dhall/ast"
|
7
8
|
require "dhall/builtins"
|
9
|
+
require "dhall/parser"
|
8
10
|
|
9
11
|
module Dhall
|
10
12
|
def self.from_binary(cbor_binary)
|
@@ -34,10 +36,13 @@ module Dhall
|
|
34
36
|
CBOR.encode(as_json)
|
35
37
|
end
|
36
38
|
end
|
37
|
-
|
39
|
+
|
40
|
+
def to_binary
|
41
|
+
CBOR.encode(::CBOR::Tagged.new(55799, self))
|
42
|
+
end
|
38
43
|
|
39
44
|
def digest(digest: Digest::SHA2.new(256))
|
40
|
-
(digest << normalize.
|
45
|
+
(digest << normalize.to_cbor).freeze
|
41
46
|
end
|
42
47
|
|
43
48
|
def cache_key
|
@@ -80,15 +85,21 @@ module Dhall
|
|
80
85
|
|
81
86
|
class List
|
82
87
|
def self.decode(type, *els)
|
83
|
-
type = type.nil? ? nil : Dhall.decode(type)
|
88
|
+
type = type.nil? ? nil : Builtins[:List].call(Dhall.decode(type))
|
84
89
|
if els.empty?
|
85
|
-
EmptyList.new(
|
90
|
+
EmptyList.new(type: type)
|
86
91
|
else
|
87
|
-
List.new(elements: els.map(&Dhall.method(:decode)),
|
92
|
+
List.new(elements: els.map(&Dhall.method(:decode)), type: type)
|
88
93
|
end
|
89
94
|
end
|
90
95
|
end
|
91
96
|
|
97
|
+
class EmptyList
|
98
|
+
def self.decode(type)
|
99
|
+
EmptyList.new(type: Dhall.decode(type))
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
92
103
|
class Optional
|
93
104
|
def self.decode(type, value=nil)
|
94
105
|
if value.nil?
|
@@ -102,6 +113,15 @@ module Dhall
|
|
102
113
|
end
|
103
114
|
end
|
104
115
|
|
116
|
+
class ToMap
|
117
|
+
def self.decode(record, type=nil)
|
118
|
+
new(
|
119
|
+
record: Dhall.decode(record),
|
120
|
+
type: type.nil? ? nil : Dhall.decode(type)
|
121
|
+
)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
105
125
|
class Merge
|
106
126
|
def self.decode(record, input, type=nil)
|
107
127
|
new(
|
@@ -140,10 +160,14 @@ module Dhall
|
|
140
160
|
|
141
161
|
class RecordProjection
|
142
162
|
def self.decode(record, *selectors)
|
143
|
-
|
144
|
-
|
163
|
+
record = Dhall.decode(record)
|
164
|
+
if selectors.length == 1 && selectors[0].is_a?(Array)
|
165
|
+
RecordProjectionByExpression.new(
|
166
|
+
record: record,
|
167
|
+
selector: Dhall.decode(selectors[0][0])
|
168
|
+
)
|
145
169
|
else
|
146
|
-
|
170
|
+
self.for(record, selectors)
|
147
171
|
end
|
148
172
|
end
|
149
173
|
end
|
@@ -189,31 +213,79 @@ module Dhall
|
|
189
213
|
end
|
190
214
|
end
|
191
215
|
|
216
|
+
class Assertion
|
217
|
+
def self.decode(type)
|
218
|
+
new(type: Dhall.decode(type))
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
192
222
|
class Import
|
223
|
+
class IntegrityCheck
|
224
|
+
def self.decode(integrity_check)
|
225
|
+
return unless integrity_check
|
226
|
+
|
227
|
+
IntegrityCheck.new(
|
228
|
+
Multihashes.decode(integrity_check).select { |k, _|
|
229
|
+
[:code, :digest].include?(k)
|
230
|
+
}
|
231
|
+
)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
class URI
|
236
|
+
def self.decode(headers, authority, *path, query)
|
237
|
+
uri = ::URI.scheme_list[name.split(/::/).last.upcase].build(
|
238
|
+
Parser.parse(authority, root: :authority).value.merge(
|
239
|
+
path: "/#{path.join("/")}"
|
240
|
+
)
|
241
|
+
)
|
242
|
+
uri.instance_variable_set(:@query, query)
|
243
|
+
new(headers: headers, uri: uri)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
class Path
|
248
|
+
def self.decode(*args)
|
249
|
+
new(*args)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
class EnvironmentVariable
|
254
|
+
def self.decode(*args)
|
255
|
+
new(*args)
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
class MissingImport
|
260
|
+
def self.decode(*args)
|
261
|
+
new(*args)
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
193
265
|
def self.decode(integrity_check, import_type, path_type, *parts)
|
194
266
|
parts[0] = Dhall.decode(parts[0]) if path_type < 2 && !parts[0].nil?
|
195
|
-
|
267
|
+
path_type = PATH_TYPES.fetch(path_type)
|
196
268
|
|
197
269
|
new(
|
198
|
-
IntegrityCheck.
|
270
|
+
IntegrityCheck.decode(integrity_check),
|
199
271
|
IMPORT_TYPES[import_type],
|
200
|
-
|
272
|
+
path_type.decode(*parts)
|
201
273
|
)
|
202
274
|
end
|
203
275
|
end
|
204
276
|
|
205
|
-
class
|
277
|
+
class LetIn
|
206
278
|
def self.decode(*parts)
|
207
279
|
body = Dhall.decode(parts.pop)
|
208
|
-
|
280
|
+
parts.each_slice(3).map { |(var, type, assign)|
|
209
281
|
Let.new(
|
210
282
|
var: var,
|
211
283
|
assign: Dhall.decode(assign),
|
212
284
|
type: type.nil? ? nil : Dhall.decode(type)
|
213
285
|
)
|
286
|
+
}.reverse.reduce(body) do |inside, let|
|
287
|
+
LetIn.new(let: let, body: inside)
|
214
288
|
end
|
215
|
-
|
216
|
-
self.for(lets: lets, body: body)
|
217
289
|
end
|
218
290
|
end
|
219
291
|
|
@@ -223,13 +295,21 @@ module Dhall
|
|
223
295
|
end
|
224
296
|
end
|
225
297
|
|
298
|
+
def self.handle_tag(e)
|
299
|
+
return e unless e.is_a?(::CBOR::Tagged)
|
300
|
+
return e.value if e.tag == 55799
|
301
|
+
|
302
|
+
raise "Unknown tag: #{e.inspect}"
|
303
|
+
end
|
304
|
+
|
226
305
|
BINARY = {
|
227
306
|
::TrueClass => ->(e) { Bool.new(value: e) },
|
228
307
|
::FalseClass => ->(e) { Bool.new(value: e) },
|
229
308
|
::Float => ->(e) { Double.new(value: e) },
|
230
|
-
::String => ->(e) { Builtins
|
309
|
+
::String => ->(e) { Builtins[e.to_sym] || (raise "Unknown builtin") },
|
231
310
|
::Integer => ->(e) { Variable.new(index: e) },
|
232
311
|
::Array => lambda { |e|
|
312
|
+
e = e.map(&method(:handle_tag))
|
233
313
|
if e.length == 2 && e.first.is_a?(::String)
|
234
314
|
Variable.new(name: e[0], index: e[1])
|
235
315
|
else
|
@@ -238,11 +318,7 @@ module Dhall
|
|
238
318
|
(raise "Unknown expression: #{e.inspect}")
|
239
319
|
end
|
240
320
|
},
|
241
|
-
::CBOR::Tagged =>
|
242
|
-
return Dhall.decode(e.value) if e.tag == 55799
|
243
|
-
|
244
|
-
raise "Unknown tag: #{e.inspect}"
|
245
|
-
}
|
321
|
+
::CBOR::Tagged => ->(e) { Dhall.decode(handle_tag(e)) }
|
246
322
|
}.freeze
|
247
323
|
|
248
324
|
BINARY_TAGS = [
|
@@ -265,13 +341,15 @@ module Dhall
|
|
265
341
|
Integer,
|
266
342
|
nil,
|
267
343
|
TextLiteral,
|
268
|
-
|
344
|
+
Assertion,
|
269
345
|
nil,
|
270
346
|
nil,
|
271
347
|
nil,
|
272
348
|
nil,
|
273
349
|
Import,
|
274
|
-
|
275
|
-
TypeAnnotation
|
350
|
+
LetIn,
|
351
|
+
TypeAnnotation,
|
352
|
+
ToMap,
|
353
|
+
EmptyList
|
276
354
|
].freeze
|
277
355
|
end
|
data/lib/dhall/builtins.rb
CHANGED
@@ -6,93 +6,74 @@ module Dhall
|
|
6
6
|
class Builtin < Expression
|
7
7
|
include(ValueSemantics.for_attributes {})
|
8
8
|
|
9
|
-
def
|
10
|
-
|
11
|
-
|
9
|
+
def as_json
|
10
|
+
self.class.name&.split(/::/)&.last&.tr("_", "/").to_s
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class BuiltinFunction < Builtin
|
15
|
+
include(ValueSemantics.for_attributes do
|
16
|
+
partial_application ArrayOf(Expression), default: []
|
17
|
+
end)
|
18
|
+
|
19
|
+
def unfill(*args)
|
20
|
+
(args.empty? ? partial_application : args).reduce(self.class.new) do |f, arg|
|
12
21
|
Application.new(function: f, argument: arg)
|
13
22
|
end
|
14
23
|
end
|
15
24
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
25
|
+
def call(*new_args)
|
26
|
+
args = partial_application + new_args
|
27
|
+
if args.length == method(:uncurried_call).arity
|
28
|
+
uncurried_call(*args)
|
29
|
+
else
|
30
|
+
with(partial_application: args)
|
23
31
|
end
|
24
32
|
end
|
25
33
|
|
26
34
|
def as_json
|
27
|
-
if (unfilled = unfill)
|
35
|
+
if (unfilled = unfill) != self
|
28
36
|
unfilled.as_json
|
29
37
|
else
|
30
|
-
|
38
|
+
super
|
31
39
|
end
|
32
40
|
end
|
41
|
+
end
|
33
42
|
|
34
|
-
|
43
|
+
module Builtins
|
44
|
+
# rubocop:disable Style/ClassAndModuleCamelCase
|
35
45
|
|
36
|
-
|
37
|
-
|
38
|
-
end
|
46
|
+
class Double_show < BuiltinFunction
|
47
|
+
protected
|
39
48
|
|
40
|
-
|
41
|
-
|
42
|
-
if !send(attr.name).nil?
|
43
|
-
h[attr.name] = send(attr.name)
|
44
|
-
elsif attr.validate?(value)
|
45
|
-
h[attr.name] = value
|
46
|
-
value = nil
|
47
|
-
else
|
48
|
-
return nil
|
49
|
-
end
|
50
|
-
end)
|
51
|
-
end
|
49
|
+
def uncurried_call(arg)
|
50
|
+
return unfill(arg) unless arg.is_a?(Dhall::Double)
|
52
51
|
|
53
|
-
|
54
|
-
|
52
|
+
Dhall::Text.new(value: arg.to_s)
|
53
|
+
end
|
55
54
|
end
|
56
55
|
|
57
|
-
|
58
|
-
|
59
|
-
end
|
60
|
-
end
|
56
|
+
class Integer_show < BuiltinFunction
|
57
|
+
protected
|
61
58
|
|
62
|
-
|
63
|
-
|
59
|
+
def uncurried_call(arg)
|
60
|
+
return unfill(arg) unless arg.is_a?(Dhall::Integer)
|
64
61
|
|
65
|
-
|
66
|
-
def call(arg)
|
67
|
-
if arg.is_a?(Double)
|
68
|
-
Text.new(value: arg.to_s)
|
69
|
-
else
|
70
|
-
super
|
71
|
-
end
|
62
|
+
Dhall::Text.new(value: arg.to_s)
|
72
63
|
end
|
73
64
|
end
|
74
65
|
|
75
|
-
class
|
76
|
-
|
77
|
-
if arg.is_a?(Integer)
|
78
|
-
Text.new(value: arg.to_s)
|
79
|
-
else
|
80
|
-
super
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
66
|
+
class Integer_toDouble < BuiltinFunction
|
67
|
+
protected
|
84
68
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
else
|
90
|
-
super
|
91
|
-
end
|
69
|
+
def uncurried_call(arg)
|
70
|
+
return unfill(arg) unless arg.is_a?(Dhall::Integer)
|
71
|
+
|
72
|
+
Dhall::Double.new(value: arg.value.to_f)
|
92
73
|
end
|
93
74
|
end
|
94
75
|
|
95
|
-
class Natural_build <
|
76
|
+
class Natural_build < BuiltinFunction
|
96
77
|
def fusion(arg, *bogus)
|
97
78
|
if bogus.empty? &&
|
98
79
|
arg.is_a?(Application) &&
|
@@ -103,91 +84,105 @@ module Dhall
|
|
103
84
|
end
|
104
85
|
end
|
105
86
|
|
106
|
-
|
87
|
+
protected
|
88
|
+
|
89
|
+
def uncurried_call(arg)
|
107
90
|
arg.call(
|
108
|
-
|
91
|
+
Natural.new,
|
109
92
|
Function.of_arguments(
|
110
|
-
|
111
|
-
body: Variable["_"] + Natural.new(value: 1)
|
93
|
+
Natural.new,
|
94
|
+
body: Variable["_"] + Dhall::Natural.new(value: 1)
|
112
95
|
),
|
113
|
-
Natural.new(value: 0)
|
96
|
+
Dhall::Natural.new(value: 0)
|
114
97
|
)
|
115
98
|
end
|
116
99
|
end
|
117
100
|
|
118
|
-
class
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
101
|
+
class Natural_subtract < BuiltinFunction
|
102
|
+
protected
|
103
|
+
|
104
|
+
def uncurried_call(x, y)
|
105
|
+
return y if zero?(x) || zero?(y)
|
106
|
+
|
107
|
+
return Dhall::Natural.new(value: 0) if x == y
|
108
|
+
|
109
|
+
unless x.is_a?(Dhall::Natural) && y.is_a?(Dhall::Natural)
|
110
|
+
return unfill(x, y)
|
124
111
|
end
|
112
|
+
|
113
|
+
Dhall::Natural.new(value: [y.to_i - x.to_i, 0].max)
|
114
|
+
end
|
115
|
+
|
116
|
+
def zero?(x)
|
117
|
+
Natural_isZero.new.call(x) === true
|
125
118
|
end
|
126
119
|
end
|
127
120
|
|
128
|
-
class
|
129
|
-
|
130
|
-
nat Either(nil, Natural), default: nil
|
131
|
-
type Either(nil, Expression), default: nil
|
132
|
-
f Either(nil, Expression), default: nil
|
133
|
-
end)
|
121
|
+
class Natural_even < BuiltinFunction
|
122
|
+
protected
|
134
123
|
|
135
|
-
def
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
else
|
140
|
-
@f.call(with(nat: nat.pred).call(arg))
|
141
|
-
end
|
142
|
-
end || super
|
124
|
+
def uncurried_call(nat)
|
125
|
+
return unfill(nat) unless nat.is_a?(Dhall::Natural)
|
126
|
+
|
127
|
+
Dhall::Bool.new(value: nat.even?)
|
143
128
|
end
|
144
129
|
end
|
145
130
|
|
146
|
-
class
|
147
|
-
|
148
|
-
|
149
|
-
|
131
|
+
class Natural_fold < BuiltinFunction
|
132
|
+
protected
|
133
|
+
|
134
|
+
def uncurried_call(nat, type, f, z)
|
135
|
+
return unfill(nat, type, f, z) unless nat.is_a?(Dhall::Natural)
|
136
|
+
|
137
|
+
if nat.zero?
|
138
|
+
z.normalize
|
150
139
|
else
|
151
|
-
|
140
|
+
f.call(Natural_fold.new.call(nat.pred, type, f, z))
|
152
141
|
end
|
153
142
|
end
|
154
143
|
end
|
155
144
|
|
156
|
-
class
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
145
|
+
class Natural_isZero < BuiltinFunction
|
146
|
+
protected
|
147
|
+
|
148
|
+
def uncurried_call(nat)
|
149
|
+
return unfill(nat) unless nat.is_a?(Dhall::Natural)
|
150
|
+
|
151
|
+
Dhall::Bool.new(value: nat.zero?)
|
163
152
|
end
|
164
153
|
end
|
165
154
|
|
166
|
-
class
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
155
|
+
class Natural_odd < BuiltinFunction
|
156
|
+
protected
|
157
|
+
|
158
|
+
def uncurried_call(nat)
|
159
|
+
return unfill(nat) unless nat.is_a?(Dhall::Natural)
|
160
|
+
|
161
|
+
Dhall::Bool.new(value: nat.odd?)
|
173
162
|
end
|
174
163
|
end
|
175
164
|
|
176
|
-
class
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
165
|
+
class Natural_show < BuiltinFunction
|
166
|
+
protected
|
167
|
+
|
168
|
+
def uncurried_call(nat)
|
169
|
+
return unfill(nat) unless nat.is_a?(Dhall::Natural)
|
170
|
+
|
171
|
+
Dhall::Text.new(value: nat.to_s)
|
183
172
|
end
|
184
173
|
end
|
185
174
|
|
186
|
-
class
|
187
|
-
|
188
|
-
|
189
|
-
|
175
|
+
class Natural_toInteger < BuiltinFunction
|
176
|
+
protected
|
177
|
+
|
178
|
+
def uncurried_call(nat)
|
179
|
+
return unfill(nat) unless nat.is_a?(Dhall::Natural)
|
190
180
|
|
181
|
+
Dhall::Integer.new(value: nat.value)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
class List_build < BuiltinFunction
|
191
186
|
def fusion(*args)
|
192
187
|
_, arg, = args
|
193
188
|
if arg.is_a?(Application) &&
|
@@ -199,80 +194,55 @@ module Dhall
|
|
199
194
|
end
|
200
195
|
end
|
201
196
|
|
202
|
-
def call(arg)
|
203
|
-
fill_or_call(arg) do
|
204
|
-
arg.call(
|
205
|
-
Variable["List"].call(type),
|
206
|
-
cons,
|
207
|
-
EmptyList.new(element_type: type)
|
208
|
-
)
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
197
|
protected
|
213
198
|
|
214
|
-
def
|
199
|
+
def uncurried_call(type, arg)
|
200
|
+
arg.call(
|
201
|
+
List.new.call(type),
|
202
|
+
cons(type),
|
203
|
+
EmptyList.new(element_type: type)
|
204
|
+
)
|
205
|
+
end
|
206
|
+
|
207
|
+
def cons(type)
|
215
208
|
Function.of_arguments(
|
216
209
|
type,
|
217
|
-
|
218
|
-
body: List.of(Variable["_", 1]).concat(Variable["_"])
|
210
|
+
List.new.call(type.shift(1, "_", 0)),
|
211
|
+
body: Dhall::List.of(Variable["_", 1]).concat(Variable["_"])
|
219
212
|
)
|
220
213
|
end
|
221
214
|
end
|
222
215
|
|
223
|
-
class List_fold <
|
224
|
-
|
225
|
-
ltype Either(nil, Expression), default: nil
|
226
|
-
list Either(nil, List), default: nil
|
227
|
-
ztype Either(nil, Expression), default: nil
|
228
|
-
f Either(nil, Expression), default: nil
|
229
|
-
end)
|
230
|
-
|
231
|
-
def call(arg)
|
232
|
-
fill_or_call(arg) do
|
233
|
-
list.reduce(arg, &f).normalize
|
234
|
-
end || super
|
235
|
-
end
|
236
|
-
end
|
216
|
+
class List_fold < BuiltinFunction
|
217
|
+
protected
|
237
218
|
|
238
|
-
|
239
|
-
|
240
|
-
type Either(nil, Expression), default: nil
|
241
|
-
end)
|
219
|
+
def uncurried_call(ltype, list, ztype, f, z)
|
220
|
+
return unfill(ltype, list, ztype, f, z) unless list.is_a?(Dhall::List)
|
242
221
|
|
243
|
-
|
244
|
-
fill_or_call(arg) do
|
245
|
-
if arg.is_a?(List)
|
246
|
-
arg.first
|
247
|
-
else
|
248
|
-
super
|
249
|
-
end
|
250
|
-
end
|
222
|
+
list.reduce(z, &f).normalize
|
251
223
|
end
|
252
224
|
end
|
253
225
|
|
254
|
-
class
|
255
|
-
|
256
|
-
type Either(nil, Expression), default: nil
|
257
|
-
end)
|
226
|
+
class List_head < BuiltinFunction
|
227
|
+
protected
|
258
228
|
|
259
|
-
def
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
else
|
264
|
-
super
|
265
|
-
end
|
266
|
-
end
|
229
|
+
def uncurried_call(type, list)
|
230
|
+
return unfill(type, list) unless list.is_a?(Dhall::List)
|
231
|
+
|
232
|
+
list.first
|
267
233
|
end
|
234
|
+
end
|
268
235
|
|
236
|
+
class List_indexed < BuiltinFunction
|
269
237
|
protected
|
270
238
|
|
271
|
-
def
|
272
|
-
|
239
|
+
def uncurried_call(type, list)
|
240
|
+
return unfill(type, list) unless list.is_a?(Dhall::List)
|
241
|
+
|
242
|
+
list.map(type: indexed_type(type)) { |x, idx|
|
273
243
|
Record.new(
|
274
244
|
record: {
|
275
|
-
"index" => Natural.new(value: idx),
|
245
|
+
"index" => Dhall::Natural.new(value: idx),
|
276
246
|
"value" => x
|
277
247
|
}
|
278
248
|
)
|
@@ -282,66 +252,44 @@ module Dhall
|
|
282
252
|
def indexed_type(value_type)
|
283
253
|
RecordType.new(
|
284
254
|
record: {
|
285
|
-
"index" =>
|
255
|
+
"index" => Natural.new,
|
286
256
|
"value" => value_type
|
287
257
|
}
|
288
258
|
)
|
289
259
|
end
|
290
260
|
end
|
291
261
|
|
292
|
-
class List_last <
|
293
|
-
|
294
|
-
type Either(nil, Expression), default: nil
|
295
|
-
end)
|
262
|
+
class List_last < BuiltinFunction
|
263
|
+
protected
|
296
264
|
|
297
|
-
def
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
else
|
302
|
-
super
|
303
|
-
end
|
304
|
-
end
|
265
|
+
def uncurried_call(type, list)
|
266
|
+
return unfill(type, list) unless list.is_a?(Dhall::List)
|
267
|
+
|
268
|
+
list.last
|
305
269
|
end
|
306
270
|
end
|
307
271
|
|
308
|
-
class List_length <
|
309
|
-
|
310
|
-
type Either(nil, Expression), default: nil
|
311
|
-
end)
|
272
|
+
class List_length < BuiltinFunction
|
273
|
+
protected
|
312
274
|
|
313
|
-
def
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
else
|
318
|
-
super
|
319
|
-
end
|
320
|
-
end
|
275
|
+
def uncurried_call(type, list)
|
276
|
+
return unfill(type, list) unless list.is_a?(Dhall::List)
|
277
|
+
|
278
|
+
Dhall::Natural.new(value: list.length)
|
321
279
|
end
|
322
280
|
end
|
323
281
|
|
324
|
-
class List_reverse <
|
325
|
-
|
326
|
-
type Either(nil, Expression), default: nil
|
327
|
-
end)
|
282
|
+
class List_reverse < BuiltinFunction
|
283
|
+
protected
|
328
284
|
|
329
|
-
def
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
else
|
334
|
-
super
|
335
|
-
end
|
336
|
-
end
|
285
|
+
def uncurried_call(type, list)
|
286
|
+
return unfill(type, list) unless list.is_a?(Dhall::List)
|
287
|
+
|
288
|
+
list.reverse
|
337
289
|
end
|
338
290
|
end
|
339
291
|
|
340
|
-
class Optional_build <
|
341
|
-
include(ValueSemantics.for_attributes do
|
342
|
-
type Either(nil, Expression), default: nil
|
343
|
-
end)
|
344
|
-
|
292
|
+
class Optional_build < BuiltinFunction
|
345
293
|
def fusion(*args)
|
346
294
|
_, arg, = args
|
347
295
|
if arg.is_a?(Application) &&
|
@@ -353,22 +301,20 @@ module Dhall
|
|
353
301
|
end
|
354
302
|
end
|
355
303
|
|
356
|
-
def call(arg)
|
357
|
-
fill_or_call(arg) do
|
358
|
-
arg.call(
|
359
|
-
Variable["Optional"].call(type),
|
360
|
-
some,
|
361
|
-
OptionalNone.new(value_type: type)
|
362
|
-
)
|
363
|
-
end
|
364
|
-
end
|
365
|
-
|
366
304
|
protected
|
367
305
|
|
368
|
-
def
|
306
|
+
def uncurried_call(type, f)
|
307
|
+
f.call(
|
308
|
+
Optional.new.call(type),
|
309
|
+
some(type),
|
310
|
+
OptionalNone.new(value_type: type)
|
311
|
+
)
|
312
|
+
end
|
313
|
+
|
314
|
+
def some(type)
|
369
315
|
Function.of_arguments(
|
370
316
|
type,
|
371
|
-
body: Optional.new(
|
317
|
+
body: Dhall::Optional.new(
|
372
318
|
value: Variable["_"],
|
373
319
|
value_type: type
|
374
320
|
)
|
@@ -376,24 +322,19 @@ module Dhall
|
|
376
322
|
end
|
377
323
|
end
|
378
324
|
|
379
|
-
class Optional_fold <
|
380
|
-
|
381
|
-
type Either(nil, Expression), default: nil
|
382
|
-
optional Either(nil, Optional), default: nil
|
383
|
-
ztype Either(nil, Expression), default: nil
|
384
|
-
f Either(nil, Expression), default: nil
|
385
|
-
end)
|
325
|
+
class Optional_fold < BuiltinFunction
|
326
|
+
protected
|
386
327
|
|
387
|
-
def
|
388
|
-
|
389
|
-
|
390
|
-
fold.optional.reduce(arg, &fold.f)
|
391
|
-
end || super
|
328
|
+
def uncurried_call(type, optional, ztype, f, z)
|
329
|
+
unless optional.is_a?(Dhall::Optional)
|
330
|
+
return unfill(type, optional, ztype, f, z)
|
392
331
|
end
|
332
|
+
|
333
|
+
optional.reduce(z, &f)
|
393
334
|
end
|
394
335
|
end
|
395
336
|
|
396
|
-
class Text_show <
|
337
|
+
class Text_show < BuiltinFunction
|
397
338
|
ENCODE = (Hash.new { |_, x| "\\u%04x" % x.ord }).merge(
|
398
339
|
"\"" => "\\\"",
|
399
340
|
"\\" => "\\\\",
|
@@ -404,22 +345,61 @@ module Dhall
|
|
404
345
|
"\t" => "\\t"
|
405
346
|
)
|
406
347
|
|
348
|
+
protected
|
349
|
+
|
350
|
+
def uncurried_call(text)
|
351
|
+
return unfill(text) unless text.is_a?(Dhall::Text)
|
352
|
+
|
353
|
+
Dhall::Text.new(
|
354
|
+
value: "\"#{text.to_s.gsub(
|
355
|
+
/["\$\\\b\f\n\r\t\u0000-\u001F]/,
|
356
|
+
&ENCODE
|
357
|
+
)}\""
|
358
|
+
)
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
class Bool < Builtin
|
363
|
+
end
|
364
|
+
|
365
|
+
class Optional < Builtin
|
366
|
+
end
|
367
|
+
|
368
|
+
class Natural < Builtin
|
369
|
+
end
|
370
|
+
|
371
|
+
class Integer < Builtin
|
372
|
+
end
|
373
|
+
|
374
|
+
class Double < Builtin
|
375
|
+
end
|
376
|
+
|
377
|
+
class Text < Builtin
|
378
|
+
end
|
379
|
+
|
380
|
+
class List < Builtin
|
381
|
+
end
|
382
|
+
|
383
|
+
class None < Builtin
|
407
384
|
def call(arg)
|
408
|
-
|
409
|
-
Text.new(
|
410
|
-
value: "\"#{arg.value.gsub(
|
411
|
-
/["\$\\\b\f\n\r\t\u0000-\u001F]/,
|
412
|
-
&ENCODE
|
413
|
-
)}\""
|
414
|
-
)
|
415
|
-
else
|
416
|
-
super
|
417
|
-
end
|
385
|
+
OptionalNone.new(value_type: arg)
|
418
386
|
end
|
419
387
|
end
|
420
388
|
|
389
|
+
class Type < Builtin
|
390
|
+
end
|
391
|
+
|
392
|
+
class Kind < Builtin
|
393
|
+
end
|
394
|
+
|
395
|
+
class Sort < Builtin
|
396
|
+
end
|
397
|
+
|
421
398
|
# rubocop:enable Style/ClassAndModuleCamelCase
|
422
399
|
|
423
|
-
|
400
|
+
def self.[](k)
|
401
|
+
const = constants.find { |c| c.to_s.tr("_", "/").to_sym == k }
|
402
|
+
const && const_get(const).new
|
403
|
+
end
|
424
404
|
end
|
425
405
|
end
|