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.
@@ -21,23 +21,21 @@ 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, :assert]
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
37
- LetBlock.for(
38
- lets: captures(:let_binding).map(&:value),
39
- body: capture(:expression).value
40
- )
34
+ captures(:let_binding).reverse.reduce(
35
+ capture(:expression).value
36
+ ) do |inside, let|
37
+ LetIn.new(let: let.value, body: inside)
38
+ end
41
39
  end
42
40
 
43
41
  def lambda
@@ -78,6 +76,21 @@ module Dhall
78
76
  type: capture(:application_expression)&.value
79
77
  )
80
78
  end
79
+
80
+ def list
81
+ EmptyList.new(type: capture(:application_expression).value)
82
+ end
83
+
84
+ def tomap
85
+ ToMap.new(
86
+ record: capture(:import_expression).value,
87
+ type: capture(:application_expression).value
88
+ )
89
+ end
90
+
91
+ def assert
92
+ Assertion.new(type: capture(:expression).value)
93
+ end
81
94
  end
82
95
 
83
96
  OPERATORS = {
@@ -92,7 +105,8 @@ module Dhall
92
105
  combine_types_expression: :RecursiveRecordTypeMerge,
93
106
  times_expression: :Times,
94
107
  equal_expression: :Equal,
95
- not_equal_expression: :NotEqual
108
+ not_equal_expression: :NotEqual,
109
+ equivalent_expression: :Equivalent
96
110
  }.freeze
97
111
 
98
112
  OPERATORS.to_a.zip(
@@ -109,22 +123,44 @@ module Dhall
109
123
 
110
124
  module ApplicationExpression
111
125
  def value
112
- some = capture(:some) ? [Variable["Some"]] : []
113
- els = some + captures(:import_expression).map(&:value)
126
+ first_expr = [capture(:first_application_expression).value]
127
+ els = first_expr + captures(:import_expression).map(&:value)
114
128
  els.reduce do |f, arg|
115
129
  Application.for(function: f, argument: arg)
116
130
  end
117
131
  end
118
132
  end
119
133
 
134
+ module FirstApplicationExpression
135
+ def value
136
+ if captures.key?(:merge)
137
+ merge
138
+ elsif captures.key?(:some)
139
+ Optional.new(value: capture(:import_expression).value)
140
+ elsif captures.key?(:tomap)
141
+ ToMap.new(record: capture(:import_expression).value)
142
+ else
143
+ super
144
+ end
145
+ end
146
+
147
+ def merge
148
+ Merge.new(
149
+ record: captures(:import_expression)[0].value,
150
+ input: captures(:import_expression)[1].value,
151
+ type: nil
152
+ )
153
+ end
154
+ end
155
+
120
156
  module SelectorExpression
121
157
  def value
122
158
  record = capture(:primitive_expression).value
123
- selectors = captures(:selector).map(&:value)
124
- selectors.reduce(record) do |rec, sels|
159
+ captures(:selector).map(&:value).reduce(record) do |rec, sels|
125
160
  if sels.is_a?(Array)
126
- return EmptyRecordProjection.new(record: rec) if sels.empty?
127
- RecordProjection.new(record: rec, selectors: sels)
161
+ RecordProjection.for(rec, sels)
162
+ elsif sels.is_a?(Dhall::Expression)
163
+ RecordProjectionByExpression.new(record: rec, selector: sels)
128
164
  else
129
165
  RecordSelection.new(record: rec, selector: sels)
130
166
  end
@@ -132,18 +168,36 @@ module Dhall
132
168
  end
133
169
  end
134
170
 
135
- module Labels
171
+ module Selector
136
172
  def value
137
- captures(:any_label).map(&:value)
173
+ if captures.key?(:type_selector)
174
+ capture(:expression).value
175
+ elsif captures.key?(:labels)
176
+ captures(:any_label).map(&:value)
177
+ else
178
+ super
179
+ end
138
180
  end
139
181
  end
140
182
 
141
183
  module Label
184
+ module Quoted
185
+ def quoted?
186
+ true
187
+ end
188
+ end
189
+
190
+ module Unquoted
191
+ def quoted?
192
+ false
193
+ end
194
+ end
195
+
142
196
  def value
143
197
  if first.string == "`"
144
- matches[1].string
198
+ matches[1].string.extend(Quoted)
145
199
  else
146
- string
200
+ string.extend(Unquoted)
147
201
  end
148
202
  end
149
203
  end
@@ -203,7 +257,7 @@ module Dhall
203
257
  .map(&:value)
204
258
  .chunk { |s| s.is_a?(String) }
205
259
  .flat_map do |(strs, group)|
206
- strs ? group.map { |s| s.encode("UTF-16BE") }.join : group
260
+ strs ? group.join : group
207
261
  end
208
262
  )
209
263
  end
@@ -232,24 +286,49 @@ module Dhall
232
286
  "t" => "\t"
233
287
  }.freeze
234
288
 
289
+ NON_CHARACTERS = [
290
+ (0xD800..0xDFFF),
291
+ (0xFFFE..0xFFFF),
292
+ (0x1FFFE..0x1FFFF),
293
+ (0x2FFFE..0x2FFFF),
294
+ (0x3FFFE..0x3FFFF),
295
+ (0x4FFFE..0x4FFFF),
296
+ (0x5FFFE..0x5FFFF),
297
+ (0x6FFFE..0x6FFFF),
298
+ (0x7FFFE..0x7FFFF),
299
+ (0x8FFFE..0x8FFFF),
300
+ (0x9FFFE..0x9FFFF),
301
+ (0xAFFFE..0xAFFFF),
302
+ (0xBFFFE..0xBFFFF),
303
+ (0xCFFFE..0xCFFFF),
304
+ (0xDFFFE..0xDFFFF),
305
+ (0xEFFFE..0xEFFFF),
306
+ (0xFFFFE..0xFFFFF),
307
+ (0x10FFFE..0x10FFFF)
308
+ ].freeze
309
+
235
310
  def value
236
311
  ESCAPES.fetch(string) do
237
- [string[1..-1]].pack("H*").force_encoding("UTF-16BE")
312
+ code = string.sub(/\Au\{?([A-F0-9]+)\}?/, "\\1").to_i(16)
313
+ NON_CHARACTERS.each do |range|
314
+ raise Citrus::ParseError, input if range.include?(code)
315
+ end
316
+ [code].pack("U*")
238
317
  end
239
318
  end
240
319
  end
241
320
 
242
321
  module SingleQuoteLiteral
243
322
  def value
244
- chunks = capture(:single_quote_continue).value
245
- indent = chunks.join.split(/\n/, -1).map { |line|
246
- line.match(/^( *|\t*)/).to_s.length
247
- }.min
323
+ chunks = capture(:single_quote_continue).value.flat_map do |chunk|
324
+ chunk.is_a?(String) ? chunk.gsub(/\r\n/, "\n").chars : chunk
325
+ end
326
+ indent = Util.indent_size(chunks.join)
248
327
 
249
328
  TextLiteral.for(
250
329
  *chunks
251
- .chunk { |c| c != "\n" }
252
- .flat_map { |(line, chunk)| line ? chunk[indent..-1] : chunk }
330
+ .chunk { |c| c != "\n" }
331
+ .flat_map { |(line, chunk)| line ? chunk[indent..-1] : chunk }
253
332
  )
254
333
  end
255
334
  end
@@ -260,6 +339,12 @@ module Dhall
260
339
  end
261
340
  end
262
341
 
342
+ module EndOfLine
343
+ def value
344
+ "\n"
345
+ end
346
+ end
347
+
263
348
  module Interpolation
264
349
  def value
265
350
  capture(:complete_expression).value
@@ -284,18 +369,21 @@ module Dhall
284
369
  end
285
370
  end
286
371
 
287
- module Identifier
372
+ module Variable
288
373
  def value
289
- name = capture(:any_label).value
374
+ Dhall::Variable.new(
375
+ name: capture(:nonreserved_label).value,
376
+ index: capture(:natural_literal)&.string.to_i
377
+ )
378
+ end
379
+ end
290
380
 
291
- return Dhall::Bool.new(value: true) if name == "True"
292
- return Dhall::Bool.new(value: false) if name == "False"
381
+ module Builtin
382
+ def value
383
+ return Dhall::Bool.new(value: true) if string == "True"
384
+ return Dhall::Bool.new(value: false) if string == "False"
293
385
 
294
- Dhall::Builtins::ALL[name]&.new ||
295
- Variable.new(
296
- name: name,
297
- index: capture(:natural_literal)&.string.to_i
298
- )
386
+ Dhall::Builtins[string.to_sym]
299
387
  end
300
388
  end
301
389
 
@@ -304,7 +392,7 @@ module Dhall
304
392
  key = [
305
393
  :complete_expression,
306
394
  :record_type_or_literal,
307
- :union_type_or_literal
395
+ :union_type
308
396
  ].find { |k| captures.key?(k) }
309
397
  key ? capture(key).value : super
310
398
  end
@@ -316,31 +404,6 @@ module Dhall
316
404
  end
317
405
  end
318
406
 
319
- module UnionTypeOrLiteralVariantType
320
- def value(label)
321
- rest = capture(:non_empty_union_type_or_literal)&.value
322
- type = UnionType.new(
323
- alternatives: { label => capture(:expression)&.value }
324
- )
325
- if rest.is_a?(Union)
326
- rest.with(alternatives: type.merge(rest.alternatives))
327
- else
328
- rest ? type.merge(rest) : type
329
- end
330
- end
331
- end
332
-
333
- module UnionLiteralVariantValue
334
- def value(label)
335
- Union.new(
336
- tag: label,
337
- value: capture(:expression).value,
338
- alternatives: captures(:union_type_entry).map(&:value)
339
- .reduce(UnionType.new(alternatives: {}), &:merge)
340
- )
341
- end
342
- end
343
-
344
407
  module UnionTypeEntry
345
408
  def value
346
409
  UnionType.new(
@@ -351,19 +414,9 @@ module Dhall
351
414
  end
352
415
  end
353
416
 
354
- module NonEmptyUnionTypeOrLiteral
417
+ module NonEmptyUnionType
355
418
  def value
356
- key = [
357
- :union_literal_variant_value,
358
- :union_type_or_literal_variant_type
359
- ].find { |k| captures.key?(k) }
360
-
361
- if key
362
- capture(key).value(capture(:any_label).value)
363
- else
364
- no_alts = UnionType.new(alternatives: {})
365
- Union.from(no_alts, capture(:any_label).value, nil)
366
- end
419
+ captures(:union_type_entry).map(&:value).reduce(&:merge)
367
420
  end
368
421
  end
369
422
 
@@ -421,25 +474,6 @@ module Dhall
421
474
 
422
475
  RecordTypeEntry = RecordLiteralEntry
423
476
 
424
- module EmptyCollection
425
- def value
426
- if captures.key?(:list)
427
- EmptyList.new(element_type: capture(:import_expression).value)
428
- else
429
- OptionalNone.new(value_type: capture(:import_expression).value)
430
- end
431
- end
432
- end
433
-
434
- module NonEmptyOptional
435
- def value
436
- Optional.new(
437
- value: capture(:expression).value,
438
- value_type: capture(:import_expression).value
439
- )
440
- end
441
- end
442
-
443
477
  module AnnotatedExpression
444
478
  def value
445
479
  if matches[1].string.empty?
@@ -468,6 +502,8 @@ module Dhall
468
502
  def value
469
503
  import_type = if captures.key?(:text)
470
504
  Dhall::Import::Text
505
+ elsif captures.key?(:location)
506
+ Dhall::Import::AsLocation
471
507
  else
472
508
  Dhall::Import::Expression
473
509
  end
@@ -487,7 +523,28 @@ module Dhall
487
523
  module Hash
488
524
  def value
489
525
  protocol, data = string.split(/:/, 2)
490
- Dhall::Import::IntegrityCheck.new(protocol, data)
526
+ Dhall::Import::IntegrityCheck.new(
527
+ code: Multihashes::TABLE.key(
528
+ protocol.sub(/\Asha(\d{3})/, "sha2-\\1")
529
+ ),
530
+ digest: [data].pack("H*")
531
+ )
532
+ end
533
+ end
534
+
535
+ module Scheme
536
+ def value
537
+ ::URI.scheme_list[string.upcase]
538
+ end
539
+ end
540
+
541
+ module Authority
542
+ def value
543
+ {
544
+ userinfo: capture(:userinfo)&.value,
545
+ host: capture(:host).value,
546
+ port: capture(:port)&.value
547
+ }
491
548
  end
492
549
  end
493
550
 
@@ -497,23 +554,24 @@ module Dhall
497
554
  "https" => Dhall::Import::Https
498
555
  }.freeze
499
556
 
557
+ def http(key)
558
+ @http ||= capture(:http_raw)
559
+ @http.capture(key)&.value
560
+ end
561
+
500
562
  def value
501
- http = capture(:http_raw)
502
- SCHEME.fetch(http.capture(:scheme).value).new(
503
- capture(:import_hashed)&.value(Dhall::Import::Expression),
504
- http.capture(:authority).value,
505
- *unescaped_components,
506
- http.capture(:query)&.value
563
+ uri = http(:scheme).build(
564
+ http(:authority).merge(
565
+ path: http(:url_path) || "/"
566
+ )
507
567
  )
508
- end
509
568
 
510
- def unescaped_components
511
- capture(:http_raw)
512
- .capture(:path)
513
- .captures(:path_component)
514
- .map do |pc|
515
- pc.value(URI.method(:unescape))
516
- end
569
+ uri.instance_variable_set(:@query, http(:query))
570
+
571
+ SCHEME.fetch(uri.scheme).new(
572
+ headers: capture(:import_expression)&.value,
573
+ uri: uri
574
+ )
517
575
  end
518
576
  end
519
577
 
@@ -521,9 +579,9 @@ module Dhall
521
579
  def value
522
580
  Dhall::Import::EnvironmentVariable.new(
523
581
  if captures.key?(:bash_environment_variable)
524
- capture(:bash_environment_variable).string
582
+ capture(:bash_environment_variable).value
525
583
  else
526
- capture(:posix_environment_variable).value.encode("utf-8")
584
+ capture(:posix_environment_variable).value
527
585
  end
528
586
  )
529
587
  end
@@ -531,12 +589,22 @@ module Dhall
531
589
 
532
590
  module PosixEnvironmentVariable
533
591
  def value
534
- matches.map(&:value).join
592
+ matches.map(&:value).join.encode(Encoding::UTF_8)
535
593
  end
536
594
  end
537
595
 
538
596
  module PosixEnvironmentVariableCharacter
539
- ESCAPES = Dhall::Import::EnvironmentVariable::ESCAPES
597
+ ESCAPES = {
598
+ "\"" => "\"",
599
+ "\\" => "\\",
600
+ "a" => "\a",
601
+ "b" => "\b",
602
+ "f" => "\f",
603
+ "n" => "\n",
604
+ "r" => "\r",
605
+ "t" => "\t",
606
+ "v" => "\v"
607
+ }.freeze
540
608
 
541
609
  def value
542
610
  if first&.string == "\\"
@@ -580,15 +648,28 @@ module Dhall
580
648
  end
581
649
 
582
650
  module PathComponent
583
- def value(unescaper=:itself.to_proc)
651
+ def value(escaper=:itself.to_proc)
584
652
  if captures.key?(:quoted_path_component)
585
- capture(:quoted_path_component).value
653
+ escaper.call(capture(:quoted_path_component).value)
586
654
  else
587
- unescaper.call(capture(:unquoted_path_component).value)
655
+ capture(:unquoted_path_component).value
588
656
  end
589
657
  end
590
658
  end
591
659
 
660
+ module UrlPath
661
+ def value
662
+ "/" + matches.map { |pc|
663
+ if pc.captures.key?(:path_component)
664
+ # We escape here because ruby stdlib URI just stores path unparsed
665
+ pc.value(Util.method(:uri_escape))
666
+ else
667
+ pc.string[1..-1]
668
+ end
669
+ }.join("/")
670
+ end
671
+ end
672
+
592
673
  module Missing
593
674
  def value
594
675
  Dhall::Import::MissingImport.new