dhall 0.3.0 → 0.4.0

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.
@@ -105,7 +105,12 @@ module Dhall
105
105
 
106
106
  refine List do
107
107
  def to_ruby(&decode)
108
- to_a.map(&decode)
108
+ arr = to_a.map(&decode)
109
+ unless element_type.is_a?(RecordType) &&
110
+ element_type.keys == ["mapKey", "mapValue"]
111
+ return arr
112
+ end
113
+ Hash[arr.map { |h| h.values_at("mapKey", "mapValue") }]
109
114
  end
110
115
  end
111
116
 
@@ -51,7 +51,7 @@ module Dhall
51
51
  normalized = super
52
52
  return normalized.fuse if normalized.fuse
53
53
 
54
- if normalized.function.is_a?(Builtin) ||
54
+ if normalized.function.is_a?(BuiltinFunction) ||
55
55
  normalized.function.is_a?(Function) ||
56
56
  normalized.function.is_a?(RecordSelection)
57
57
  return normalized.function.call(normalized.argument)
@@ -120,7 +120,7 @@ module Dhall
120
120
  end
121
121
  end
122
122
 
123
- class FunctionProxy
123
+ class FunctionProxyRaw
124
124
  def shift(*)
125
125
  self
126
126
  end
@@ -245,7 +245,7 @@ module Dhall
245
245
 
246
246
  class EmptyList
247
247
  def normalize
248
- super.with(element_type: element_type.normalize)
248
+ super.with(type: type.normalize)
249
249
  end
250
250
  end
251
251
 
@@ -265,6 +265,20 @@ module Dhall
265
265
  end
266
266
  end
267
267
 
268
+ class ToMap
269
+ def normalize
270
+ normalized = super
271
+ unless [Record, EmptyRecord].include?(normalized.record.class)
272
+ return normalized
273
+ end
274
+
275
+ List.of(*normalized.record.to_h.to_a.map do |(k, v)|
276
+ k = Text.new(value: k)
277
+ Record.new(record: { "mapKey" => k, "mapValue" => v })
278
+ end, type: normalized.type&.argument)
279
+ end
280
+ end
281
+
268
282
  class Merge
269
283
  def normalize
270
284
  normalized = super
@@ -316,7 +330,19 @@ module Dhall
316
330
 
317
331
  class RecordProjection
318
332
  def normalize
319
- record.normalize.slice(*selectors)
333
+ record.normalize.slice(*selectors.sort)
334
+ end
335
+ end
336
+
337
+ class RecordProjectionByExpression
338
+ def normalize
339
+ sel = selector.normalize
340
+
341
+ if sel.is_a?(RecordType)
342
+ RecordProjection.for(record, sel.keys).normalize
343
+ else
344
+ with(record: record.normalize, selector: sel)
345
+ end
320
346
  end
321
347
  end
322
348
 
@@ -1,7 +1,10 @@
1
1
  grammar Dhall::Parser::CitrusParser
2
2
  root complete_expression
3
3
  rule end_of_line
4
- (/\n/i | (/(?:\r)(?:\n)/i))
4
+ (/\n/i | (/(?:\r)(?:\n)/i)) <Dhall::Parser::EndOfLine>
5
+ end
6
+ rule valid_non_ascii
7
+ (/[\u{80}-\u{d7ff}\u{e000}-\u{fffd}\u{10000}-\u{1fffd}\u{20000}-\u{2fffd}\u{30000}-\u{3fffd}\u{40000}-\u{4fffd}\u{50000}-\u{5fffd}\u{60000}-\u{6fffd}\u{70000}-\u{7fffd}\u{80000}-\u{8fffd}\u{90000}-\u{9fffd}\u{a0000}-\u{afffd}\u{b0000}-\u{bfffd}\u{c0000}-\u{cfffd}\u{d0000}-\u{dfffd}\u{e0000}-\u{efffd}\u{f0000}-\u{ffffd}\u{100000}-\u{10fffd}]/i)
5
8
  end
6
9
  rule tab
7
10
  (/\t/i)
@@ -10,13 +13,13 @@ rule block_comment
10
13
  (/(?:\u{7b})(?:\u{2d})/i (block_comment_continue))
11
14
  end
12
15
  rule block_comment_char
13
- !("{-" | "-}") (/[\u{20}-@\u{5b}-\u{10ffff}]/i | (tab) | (end_of_line))
16
+ !("{-" | "-}") (/[\u{20}-@\u{5b}-\u{7f}]/i | (valid_non_ascii) | (tab) | (end_of_line))
14
17
  end
15
18
  rule block_comment_continue
16
19
  ("-}" | block_comment_char+ block_comment_continue | (block_comment block_comment_continue))
17
20
  end
18
21
  rule not_end_of_line
19
- (/[\u{20}-@\u{5b}-\u{10ffff}]/i | (tab))
22
+ (/[\u{20}-@\u{5b}-\u{7f}]/i | (valid_non_ascii) | (tab))
20
23
  end
21
24
  rule line_comment
22
25
  (/(?:\u{2d})(?:\u{2d})/i ((not_end_of_line)*) (end_of_line))
@@ -36,6 +39,9 @@ end
36
39
  rule digit
37
40
  (/\d/i)
38
41
  end
42
+ rule alphanum
43
+ ((alpha) | (digit))
44
+ end
39
45
  rule hexdig
40
46
  ((digit) | /[a-f]/i | (digit) | /[a-f]/i)
41
47
  end
@@ -43,7 +49,7 @@ rule simple_label_first_char
43
49
  ((alpha) | `_`)
44
50
  end
45
51
  rule simple_label_next_char
46
- ((alpha) | (digit) | /[\u{2d}\/_]/i)
52
+ ((alphanum) | /[\u{2d}\/_]/i)
47
53
  end
48
54
  rule simple_label
49
55
  (keyword simple_label_next_char+ | !keyword (simple_label_first_char simple_label_next_char*))
@@ -67,10 +73,13 @@ rule double_quote_chunk
67
73
  ((interpolation) | (/\u{5c}/i (double_quote_escaped)) | (double_quote_char)) <Dhall::Parser::DoubleQuoteChunk>
68
74
  end
69
75
  rule double_quote_escaped
70
- (/["\u{24}\/\u{5c}bfnrt]/ | ("u" ((hexdig) 4*4))) <Dhall::Parser::DoubleQuoteEscaped>
76
+ (/["\u{24}\/\u{5c}bfnrt]/ | ("u" (unicode_escape))) <Dhall::Parser::DoubleQuoteEscaped>
77
+ end
78
+ rule unicode_escape
79
+ (((hexdig) 4*4) | (/\u{7b}/i ((hexdig)+) /\u{7d}/i))
71
80
  end
72
81
  rule double_quote_char
73
- (/[\u{20}!\u{23}-@\u{5b}\u{5d}-\u{10ffff}]/i)
82
+ (/[\u{20}!\u{23}-@\u{5b}\u{5d}-\u{7f}]/i | (valid_non_ascii))
74
83
  end
75
84
  rule double_quote_literal
76
85
  (/"/i ((double_quote_chunk)*) /"/i) <Dhall::Parser::DoubleQuoteLiteral>
@@ -85,7 +94,7 @@ rule escaped_interpolation
85
94
  (/(?:''(?:\u{24}))(?:\u{7b})/i) <Dhall::Parser::EscapedInterpolation>
86
95
  end
87
96
  rule single_quote_char
88
- (/[\u{20}-@\u{5b}-\u{10ffff}]/i | (tab) | (end_of_line))
97
+ (/[\u{20}-@\u{5b}-\u{7f}]/i | (valid_non_ascii) | (tab) | (end_of_line))
89
98
  end
90
99
  rule single_quote_literal
91
100
  (`''` (end_of_line) (single_quote_continue)) <Dhall::Parser::SingleQuoteLiteral>
@@ -132,8 +141,11 @@ end
132
141
  rule some
133
142
  ("Some")
134
143
  end
144
+ rule tomap
145
+ ("toMap")
146
+ end
135
147
  rule keyword
136
- ((if) | (then) | (else) | (let) | (in) | (using) | (missing) | (as) | (infinity) | (nan) | (merge) | (some))
148
+ ((if) | (then) | (else) | (let) | (in) | (using) | (missing) | (as) | (infinity) | (nan) | (merge) | (some) | (tomap))
137
149
  end
138
150
  rule builtin
139
151
  ((natural_fold) | (natural_build) | (natural_iszero) | (natural_even) | (natural_odd) | (natural_tointeger) | (natural_show) | (integer_todouble) | (integer_show) | (double_show) | (list_build) | (list_fold) | (list_length) | (list_head) | (list_last) | (list_indexed) | (list_reverse) | (optional_fold) | (optional_build) | (text_show) | (bool) | (true) | (false) | (optional) | (none) | (natural) | (integer) | (double) | (text) | (list) | (type) | (kind) | (sort)) <Dhall::Parser::Builtin>
@@ -147,6 +159,9 @@ end
147
159
  rule list
148
160
  ("List")
149
161
  end
162
+ rule location
163
+ ("Location")
164
+ end
150
165
  rule bool
151
166
  ("Bool")
152
167
  end
@@ -286,7 +301,7 @@ rule path_character
286
301
  (/[!\u{24}-'\u{2a}\u{2b}\u{2d}\u{2e}0-;=@\u{5e}-z\u{7c}~]/i)
287
302
  end
288
303
  rule quoted_path_character
289
- (/[\u{20}!\u{23}-\u{2e}0-@\u{5b}-\u{10ffff}]/i)
304
+ (/[\u{20}!\u{23}-\u{2e}0-@\u{5b}-\u{7f}]/i | (valid_non_ascii))
290
305
  end
291
306
  rule unquoted_path_component
292
307
  ((path_character)+)
@@ -316,19 +331,22 @@ rule absolute_path
316
331
  (path) <Dhall::Parser::AbsolutePath>
317
332
  end
318
333
  rule scheme
319
- ("http" ("s"?))
334
+ ("http" ("s"?)) <Dhall::Parser::Scheme>
320
335
  end
321
336
  rule http_raw
322
- ((scheme) /(?::(?:\/))(?:\/)/i (authority) (path) ((/\u{3f}/i (query))?))
337
+ ((scheme) /(?::(?:\/))(?:\/)/i (authority) (url_path) ((/\u{3f}/i (query))?))
338
+ end
339
+ rule url_path
340
+ (((path_component) | (/\//i (segment)))*) <Dhall::Parser::UrlPath>
323
341
  end
324
342
  rule authority
325
- ((((userinfo) /@/i)?) (host) ((`:` (port))?))
343
+ ((((userinfo) /@/i)?) (host) ((`:` (port))?)) <Dhall::Parser::Authority>
326
344
  end
327
345
  rule userinfo
328
346
  (((unreserved) | (pct_encoded) | (sub_delims) | `:`)*)
329
347
  end
330
348
  rule host
331
- ((ip_literal) | (ipv4address) | (reg_name))
349
+ ((ip_literal) | (ipv4address) | (domain))
332
350
  end
333
351
  rule port
334
352
  ((digit)*)
@@ -354,8 +372,14 @@ end
354
372
  rule dec_octet
355
373
  ((/25(?:[0-5])/i) | (/2(?:[0-4])/i (digit)) | (`1` ((digit) 2*2)) | (/[1-9]/i (digit)) | (digit))
356
374
  end
357
- rule reg_name
358
- (((unreserved) | (pct_encoded) | (sub_delims))*)
375
+ rule domain
376
+ ((domainlabel) ((/\u{2e}/i (domainlabel))*) (/\u{2e}/i?))
377
+ end
378
+ rule domainlabel
379
+ (((alphanum)+) (((/\u{2d}/i+) ((alphanum)+))*))
380
+ end
381
+ rule segment
382
+ ((pchar)*)
359
383
  end
360
384
  rule pchar
361
385
  ((unreserved) | (pct_encoded) | (sub_delims) | /[:@]/i)
@@ -367,19 +391,19 @@ rule pct_encoded
367
391
  (/%/i (hexdig) (hexdig))
368
392
  end
369
393
  rule unreserved
370
- ((alpha) | (digit) | /[\u{2d}\u{2e}_~]/i)
394
+ ((alphanum) | /[\u{2d}\u{2e}_~]/i)
371
395
  end
372
396
  rule sub_delims
373
- (/[!\u{24}&-,;=]/i)
397
+ (/[!\u{24}&'\u{2a}\u{2b};=]/i)
374
398
  end
375
399
  rule http
376
- ((http_raw) (((whsp) (using) (whsp1) ((import_hashed) | (/\u{28}/i (whsp) (import_hashed) (whsp) /\u{29}/i)))?)) <Dhall::Parser::Http>
400
+ ((http_raw) (((whsp) (using) (whsp1) (import_expression))?)) <Dhall::Parser::Http>
377
401
  end
378
402
  rule env
379
403
  (`env:` ((bash_environment_variable) | (/"/i (posix_environment_variable) /"/i))) <Dhall::Parser::Env>
380
404
  end
381
405
  rule bash_environment_variable
382
- (((alpha) | `_`) (((alpha) | (digit) | `_`)*))
406
+ (((alpha) | `_`) (((alphanum) | `_`)*))
383
407
  end
384
408
  rule posix_environment_variable
385
409
  ((posix_environment_variable_character)+) <Dhall::Parser::PosixEnvironmentVariable>
@@ -397,10 +421,10 @@ rule import_hashed
397
421
  ((import_type) (((whsp1) (hash))?)) <Dhall::Parser::ImportHashed>
398
422
  end
399
423
  rule import
400
- ((import_hashed) (((whsp) (as) (whsp1) (text))?)) <Dhall::Parser::Import>
424
+ ((import_hashed) (((whsp) (as) (whsp1) ((text) | (location)))?)) <Dhall::Parser::Import>
401
425
  end
402
426
  rule expression
403
- (((lambda) (whsp) /\u{28}/i (whsp) (nonreserved_label) (whsp) `:` (whsp1) (expression) (whsp) /\u{29}/i (whsp) (arrow) (whsp) (expression)) | ((if) (whsp1) (expression) (whsp) (then) (whsp1) (expression) (whsp) (else) (whsp1) (expression)) | (((let_binding)+) (in) (whsp1) (expression)) | ((forall) (whsp) /\u{28}/i (whsp) (nonreserved_label) (whsp) `:` (whsp1) (expression) (whsp) /\u{29}/i (whsp) (arrow) (whsp) (expression)) | ((operator_expression) (whsp) (arrow) (whsp) (expression)) | ((merge) (whsp1) (import_expression) (whsp1) (import_expression) (whsp) `:` (whsp1) (application_expression)) | (/\u{5b}/i (whsp) ((empty_collection) | (non_empty_optional))) | (annotated_expression)) <Dhall::Parser::Expression>
427
+ (((lambda) (whsp) /\u{28}/i (whsp) (nonreserved_label) (whsp) `:` (whsp1) (expression) (whsp) /\u{29}/i (whsp) (arrow) (whsp) (expression)) | ((if) (whsp1) (expression) (whsp) (then) (whsp1) (expression) (whsp) (else) (whsp1) (expression)) | (((let_binding)+) (in) (whsp1) (expression)) | ((forall) (whsp) /\u{28}/i (whsp) (nonreserved_label) (whsp) `:` (whsp1) (expression) (whsp) /\u{29}/i (whsp) (arrow) (whsp) (expression)) | ((operator_expression) (whsp) (arrow) (whsp) (expression)) | ((merge) (whsp1) (import_expression) (whsp1) (import_expression) (whsp) `:` (whsp1) (application_expression)) | (/\u{5b}/i (whsp) /\u{5d}/i (whsp) `:` (whsp1) (application_expression)) | ((tomap) (whsp1) (import_expression) (whsp) `:` (whsp1) (application_expression)) | (annotated_expression)) <Dhall::Parser::Expression>
404
428
  end
405
429
  rule annotated_expression
406
430
  ((operator_expression) (((whsp) `:` (whsp1) (expression))?)) <Dhall::Parser::AnnotatedExpression>
@@ -408,12 +432,6 @@ end
408
432
  rule let_binding
409
433
  ((let) (whsp1) (nonreserved_label) (whsp) ((`:` (whsp1) (expression) (whsp))?) /=/i (whsp) (expression) (whsp)) <Dhall::Parser::LetBinding>
410
434
  end
411
- rule empty_collection
412
- (/\u{5d}/i (whsp) `:` (whsp1) ((list) | (optional)) (whsp) (import_expression)) <Dhall::Parser::EmptyCollection>
413
- end
414
- rule non_empty_optional
415
- ((expression) (whsp) /\u{5d}/i (whsp) `:` (whsp1) (optional) (whsp) (import_expression)) <Dhall::Parser::NonEmptyOptional>
416
- end
417
435
  rule operator_expression
418
436
  (import_alt_expression)
419
437
  end
@@ -457,7 +475,7 @@ rule application_expression
457
475
  ((first_application_expression) (((whsp1) (import_expression))*)) <Dhall::Parser::ApplicationExpression>
458
476
  end
459
477
  rule first_application_expression
460
- (((merge) (whsp1) (import_expression) (whsp1) (import_expression)) | ((some) (whsp1) (import_expression)) | (import_expression)) <Dhall::Parser::FirstApplicationExpression>
478
+ (((merge) (whsp1) (import_expression) (whsp1) (import_expression)) | ((some) (whsp1) (import_expression)) | ((tomap) (whsp1) (import_expression)) | (import_expression)) <Dhall::Parser::FirstApplicationExpression>
461
479
  end
462
480
  rule import_expression
463
481
  ((import) | (selector_expression))
@@ -466,10 +484,13 @@ rule selector_expression
466
484
  ((primitive_expression) (((whsp) /\u{2e}/i (whsp) (selector))*)) <Dhall::Parser::SelectorExpression>
467
485
  end
468
486
  rule selector
469
- ((any_label) | (labels))
487
+ ((any_label) | (labels) | (type_selector)) <Dhall::Parser::Selector>
470
488
  end
471
489
  rule labels
472
- (/\u{7b}/i (whsp) (((any_label) (whsp) ((/,/i (whsp) (any_label) (whsp))*))?) /\u{7d}/i) <Dhall::Parser::Labels>
490
+ (/\u{7b}/i (whsp) (((any_label) (whsp) ((/,/i (whsp) (any_label) (whsp))*))?) /\u{7d}/i)
491
+ end
492
+ rule type_selector
493
+ (/\u{28}/i (whsp) (expression) (whsp) /\u{29}/i)
473
494
  end
474
495
  rule primitive_expression
475
496
  ((double_literal) | (natural_literal) | (integer_literal) | (text_literal) | (/\u{7b}/i (whsp) (record_type_or_literal) (whsp) /\u{7d}/i) | (/</i (whsp) (union_type_or_literal) (whsp) />/i) | (non_empty_list_literal) | (identifier) | (/\u{28}/i (complete_expression) /\u{29}/i)) <Dhall::Parser::PrimitiveExpression>
@@ -21,16 +21,13 @@ module Dhall
21
21
 
22
22
  module Expression
23
23
  def value
24
- key =
25
- [:let_binding, :lambda, :forall, :arrow, :if, :merge]
26
- .find { |k| captures.key?(k) }
27
-
28
- return public_send(key) if key
24
+ return list if string =~ /\A\[\s*\]/
29
25
 
30
26
  key =
31
- [:empty_collection, :non_empty_optional]
27
+ [:let_binding, :lambda, :forall, :arrow, :if, :merge, :tomap]
32
28
  .find { |k| captures.key?(k) }
33
- key ? capture(key).value : super
29
+
30
+ key ? public_send(key) : super
34
31
  end
35
32
 
36
33
  def let_binding
@@ -78,6 +75,17 @@ module Dhall
78
75
  type: capture(:application_expression)&.value
79
76
  )
80
77
  end
78
+
79
+ def list
80
+ EmptyList.new(type: capture(:application_expression).value)
81
+ end
82
+
83
+ def tomap
84
+ ToMap.new(
85
+ record: capture(:import_expression).value,
86
+ type: capture(:application_expression).value
87
+ )
88
+ end
81
89
  end
82
90
 
83
91
  OPERATORS = {
@@ -122,9 +130,9 @@ module Dhall
122
130
  if captures.key?(:merge)
123
131
  merge
124
132
  elsif captures.key?(:some)
125
- Optional.new(
126
- value: capture(:import_expression).value
127
- )
133
+ Optional.new(value: capture(:import_expression).value)
134
+ elsif captures.key?(:tomap)
135
+ ToMap.new(record: capture(:import_expression).value)
128
136
  else
129
137
  super
130
138
  end
@@ -142,11 +150,11 @@ module Dhall
142
150
  module SelectorExpression
143
151
  def value
144
152
  record = capture(:primitive_expression).value
145
- selectors = captures(:selector).map(&:value)
146
- selectors.reduce(record) do |rec, sels|
153
+ captures(:selector).map(&:value).reduce(record) do |rec, sels|
147
154
  if sels.is_a?(Array)
148
- return EmptyRecordProjection.new(record: rec) if sels.empty?
149
- RecordProjection.new(record: rec, selectors: sels)
155
+ RecordProjection.for(rec, sels)
156
+ elsif sels.is_a?(Dhall::Expression)
157
+ RecordProjectionByExpression.new(record: rec, selector: sels)
150
158
  else
151
159
  RecordSelection.new(record: rec, selector: sels)
152
160
  end
@@ -154,9 +162,15 @@ module Dhall
154
162
  end
155
163
  end
156
164
 
157
- module Labels
165
+ module Selector
158
166
  def value
159
- captures(:any_label).map(&:value)
167
+ if captures.key?(:type_selector)
168
+ capture(:expression).value
169
+ elsif captures.key?(:labels)
170
+ captures(:any_label).map(&:value)
171
+ else
172
+ string
173
+ end
160
174
  end
161
175
  end
162
176
 
@@ -237,7 +251,7 @@ module Dhall
237
251
  .map(&:value)
238
252
  .chunk { |s| s.is_a?(String) }
239
253
  .flat_map do |(strs, group)|
240
- strs ? group.map { |s| s.encode("UTF-16BE") }.join : group
254
+ strs ? group.join : group
241
255
  end
242
256
  )
243
257
  end
@@ -266,9 +280,34 @@ module Dhall
266
280
  "t" => "\t"
267
281
  }.freeze
268
282
 
283
+ NON_CHARACTERS = [
284
+ (0xD800..0xDFFF),
285
+ (0xFFFE..0xFFFF),
286
+ (0x1FFFE..0x1FFFF),
287
+ (0x2FFFE..0x2FFFF),
288
+ (0x3FFFE..0x3FFFF),
289
+ (0x4FFFE..0x4FFFF),
290
+ (0x5FFFE..0x5FFFF),
291
+ (0x6FFFE..0x6FFFF),
292
+ (0x7FFFE..0x7FFFF),
293
+ (0x8FFFE..0x8FFFF),
294
+ (0x9FFFE..0x9FFFF),
295
+ (0xAFFFE..0xAFFFF),
296
+ (0xBFFFE..0xBFFFF),
297
+ (0xCFFFE..0xCFFFF),
298
+ (0xDFFFE..0xDFFFF),
299
+ (0xEFFFE..0xEFFFF),
300
+ (0xFFFFE..0xFFFFF),
301
+ (0x10FFFE..0x10FFFF)
302
+ ].freeze
303
+
269
304
  def value
270
305
  ESCAPES.fetch(string) do
271
- [string[1..-1]].pack("H*").force_encoding("UTF-16BE")
306
+ code = string.sub(/\Au\{?([A-F0-9]+)\}?/, "\\1").to_i(16)
307
+ NON_CHARACTERS.each do |range|
308
+ raise Citrus::ParseError, input if range.include?(code)
309
+ end
310
+ [code].pack("U*")
272
311
  end
273
312
  end
274
313
  end
@@ -276,10 +315,7 @@ module Dhall
276
315
  module SingleQuoteLiteral
277
316
  def value
278
317
  chunks = capture(:single_quote_continue).value
279
- raw = chunks.join
280
- indent = raw.scan(/^[ \t]*(?=[^ \t\r\n])/).map(&:chars)
281
- .reduce(&Util.method(:longest_common_prefix)).length
282
- indent = 0 if raw.end_with?("\n")
318
+ indent = Util.indent_size(chunks.join)
283
319
 
284
320
  TextLiteral.for(
285
321
  *chunks
@@ -295,6 +331,12 @@ module Dhall
295
331
  end
296
332
  end
297
333
 
334
+ module EndOfLine
335
+ def value
336
+ "\n"
337
+ end
338
+ end
339
+
298
340
  module Interpolation
299
341
  def value
300
342
  capture(:complete_expression).value
@@ -459,25 +501,6 @@ module Dhall
459
501
 
460
502
  RecordTypeEntry = RecordLiteralEntry
461
503
 
462
- module EmptyCollection
463
- def value
464
- if captures.key?(:list)
465
- EmptyList.new(element_type: capture(:import_expression).value)
466
- else
467
- OptionalNone.new(value_type: capture(:import_expression).value)
468
- end
469
- end
470
- end
471
-
472
- module NonEmptyOptional
473
- def value
474
- Optional.new(
475
- value: capture(:expression).value,
476
- value_type: capture(:import_expression).value
477
- )
478
- end
479
- end
480
-
481
504
  module AnnotatedExpression
482
505
  def value
483
506
  if matches[1].string.empty?
@@ -506,6 +529,8 @@ module Dhall
506
529
  def value
507
530
  import_type = if captures.key?(:text)
508
531
  Dhall::Import::Text
532
+ elsif captures.key?(:location)
533
+ Dhall::Import::AsLocation
509
534
  else
510
535
  Dhall::Import::Expression
511
536
  end
@@ -525,7 +550,28 @@ module Dhall
525
550
  module Hash
526
551
  def value
527
552
  protocol, data = string.split(/:/, 2)
528
- Dhall::Import::IntegrityCheck.new(protocol, data)
553
+ Dhall::Import::IntegrityCheck.new(
554
+ code: Multihashes::TABLE.key(
555
+ protocol.sub(/\Asha(\d{3})/, "sha2-\\1")
556
+ ),
557
+ digest: [data].pack("H*")
558
+ )
559
+ end
560
+ end
561
+
562
+ module Scheme
563
+ def value
564
+ ::URI.scheme_list[string.upcase]
565
+ end
566
+ end
567
+
568
+ module Authority
569
+ def value
570
+ {
571
+ userinfo: capture(:userinfo)&.value,
572
+ host: capture(:host).value,
573
+ port: capture(:port)&.value
574
+ }
529
575
  end
530
576
  end
531
577
 
@@ -535,23 +581,24 @@ module Dhall
535
581
  "https" => Dhall::Import::Https
536
582
  }.freeze
537
583
 
584
+ def http(key)
585
+ @http ||= capture(:http_raw)
586
+ @http.capture(key)&.value
587
+ end
588
+
538
589
  def value
539
- http = capture(:http_raw)
540
- SCHEME.fetch(http.capture(:scheme).value).new(
541
- capture(:import_hashed)&.value(Dhall::Import::Expression),
542
- http.capture(:authority).value,
543
- *unescaped_components,
544
- http.capture(:query)&.value
590
+ uri = http(:scheme).build(
591
+ http(:authority).merge(
592
+ path: http(:url_path) || "/"
593
+ )
545
594
  )
546
- end
547
595
 
548
- def unescaped_components
549
- capture(:http_raw)
550
- .capture(:path)
551
- .captures(:path_component)
552
- .map do |pc|
553
- pc.value(URI.method(:unescape))
554
- end
596
+ uri.instance_variable_set(:@query, http(:query))
597
+
598
+ SCHEME.fetch(uri.scheme).new(
599
+ headers: capture(:import_expression)&.value,
600
+ uri: uri
601
+ )
555
602
  end
556
603
  end
557
604
 
@@ -628,15 +675,28 @@ module Dhall
628
675
  end
629
676
 
630
677
  module PathComponent
631
- def value(unescaper=:itself.to_proc)
678
+ def value(escaper=:itself.to_proc)
632
679
  if captures.key?(:quoted_path_component)
633
- capture(:quoted_path_component).value
680
+ escaper.call(capture(:quoted_path_component).value)
634
681
  else
635
- unescaper.call(capture(:unquoted_path_component).value)
682
+ capture(:unquoted_path_component).value
636
683
  end
637
684
  end
638
685
  end
639
686
 
687
+ module UrlPath
688
+ def value
689
+ "/" + matches.map { |pc|
690
+ if pc.captures.key?(:path_component)
691
+ # We escape here because ruby stdlib URI just stores path unparsed
692
+ pc.value(Util.method(:uri_escape))
693
+ else
694
+ pc.string[1..-1]
695
+ end
696
+ }.join("/")
697
+ end
698
+ end
699
+
640
700
  module Missing
641
701
  def value
642
702
  Dhall::Import::MissingImport.new