dhall 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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