dhall 0.1.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|