dhall 0.1.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,199 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "psych"
4
+
5
+ module Dhall
6
+ class Coder
7
+ JSON_LIKE = [
8
+ ::Array, ::Hash,
9
+ ::TrueClass, ::FalseClass, ::NilClass,
10
+ ::Integer, ::Float, ::String
11
+ ].freeze
12
+
13
+ class Verifier
14
+ def initialize(*classes)
15
+ @classes = classes
16
+ @matcher = ValueSemantics::Either.new(classes)
17
+ end
18
+
19
+ def verify_class(klass, op)
20
+ if @classes.any? { |safe| klass <= safe }
21
+ klass
22
+ else
23
+ raise ArgumentError, "#{op} does not match "\
24
+ "#{@classes.inspect}: #{klass}"
25
+ end
26
+ end
27
+
28
+ def verify(obj, op)
29
+ if @matcher === obj
30
+ obj
31
+ else
32
+ raise ArgumentError, "#{op} does not match "\
33
+ "#{@classes.inspect}: #{obj.inspect}"
34
+ end
35
+ end
36
+ end
37
+
38
+ def self.load(source, transform_keys: :to_s)
39
+ new.load(source, transform_keys: transform_keys)
40
+ end
41
+
42
+ def self.dump(obj)
43
+ new.dump(obj)
44
+ end
45
+
46
+ def initialize(default: nil, safe: JSON_LIKE)
47
+ @default = default
48
+ @verifier = Verifier.new(*Array(safe))
49
+ @verifier.verify(default, "default value")
50
+ end
51
+
52
+ def load_async(source, op="load_async", transform_keys: :to_s)
53
+ return Promise.resolve(@default) if source.nil?
54
+ return Promise.resolve(source) unless source.is_a?(String)
55
+
56
+ Dhall.load(source).then do |expr|
57
+ decode(expr, op, transform_keys: transform_keys)
58
+ end
59
+ end
60
+
61
+ def load(source, transform_keys: :to_s)
62
+ load_async(source, "load", transform_keys: transform_keys).sync
63
+ end
64
+
65
+ module ToRuby
66
+ refine Expression do
67
+ def to_ruby
68
+ self
69
+ end
70
+ end
71
+
72
+ refine Natural do
73
+ alias_method :to_ruby, :to_i
74
+ end
75
+
76
+ refine Integer do
77
+ alias_method :to_ruby, :to_i
78
+ end
79
+
80
+ refine Double do
81
+ alias_method :to_ruby, :to_f
82
+ end
83
+
84
+ refine Text do
85
+ alias_method :to_ruby, :to_s
86
+ end
87
+
88
+ refine Bool do
89
+ def to_ruby
90
+ self === true
91
+ end
92
+ end
93
+
94
+ refine Record do
95
+ def to_ruby(&decode)
96
+ Hash[to_h.map { |k, v| [k, decode[v]] }]
97
+ end
98
+ end
99
+
100
+ refine EmptyRecord do
101
+ def to_ruby
102
+ {}
103
+ end
104
+ end
105
+
106
+ refine List do
107
+ def to_ruby(&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") }]
114
+ end
115
+ end
116
+
117
+ refine Optional do
118
+ def to_ruby(&decode)
119
+ reduce(nil, &decode)
120
+ end
121
+ end
122
+
123
+ refine Function do
124
+ def to_ruby(&decode)
125
+ ->(*args) { decode[call(*args)] }
126
+ end
127
+ end
128
+
129
+ refine Enum do
130
+ def to_ruby
131
+ extract == :None ? nil : extract
132
+ end
133
+ end
134
+
135
+ refine Union do
136
+ def to_ruby
137
+ rtag = tag.sub(/_[0-9a-f]{64}\Z/, "")
138
+ if tag.match(/\A\p{Upper}/) &&
139
+ Object.const_defined?(rtag) && !Dhall.const_defined?(rtag, false)
140
+ yield extract, Object.const_get(rtag)
141
+ else
142
+ yield extract
143
+ end
144
+ end
145
+ end
146
+
147
+ refine TypeAnnotation do
148
+ def to_ruby
149
+ yield value
150
+ end
151
+ end
152
+ end
153
+
154
+ using ToRuby
155
+
156
+ module InitWith
157
+ refine Object do
158
+ def init_with(coder)
159
+ coder.map.each do |k, v|
160
+ instance_variable_set(:"@#{k}", v)
161
+ end
162
+ end
163
+ end
164
+ end
165
+
166
+ using InitWith
167
+
168
+ def revive(klass, expr, op="revive", transform_keys: :to_s)
169
+ @verifier.verify_class(klass, op)
170
+ return klass.from_dhall(expr) if klass.respond_to?(:from_dhall)
171
+
172
+ klass.allocate.tap do |o|
173
+ o.init_with(Util.psych_coder_for(
174
+ klass.name,
175
+ decode(expr, op, transform_keys: transform_keys)
176
+ ))
177
+ end
178
+ end
179
+
180
+ def decode(expr, op="decode", klass: nil, transform_keys: :to_s)
181
+ return revive(klass, expr, op, transform_keys: transform_keys) if klass
182
+ @verifier.verify(
183
+ Util.transform_keys(
184
+ expr.to_ruby { |dexpr, dklass|
185
+ decode(dexpr, op, klass: dklass, transform_keys: transform_keys)
186
+ },
187
+ &transform_keys
188
+ ),
189
+ op
190
+ )
191
+ end
192
+
193
+ def dump(obj)
194
+ return if obj.nil?
195
+
196
+ Dhall.dump(@verifier.verify(obj, "dump"))
197
+ end
198
+ end
199
+ end
@@ -1,26 +1,37 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "dhall/builtins"
4
- require "dhall/visitor"
5
4
  require "dhall/util"
6
5
 
7
6
  module Dhall
8
- module ExpressionVisitor
7
+ class ExpressionVisitor
9
8
  ExpressionHash = Util::HashOf.new(
10
9
  ValueSemantics::Anything,
11
10
  ValueSemantics::Either.new([Expression, nil])
12
11
  )
13
12
 
14
- def self.new(&block)
15
- Visitor.new(
16
- Expression => block,
17
- Util::ArrayOf.new(Expression) => lambda do |x|
18
- x.map(&block)
19
- end,
20
- ExpressionHash => lambda do |x|
21
- Hash[x.map { |k, v| [k, v.nil? ? v : block[v]] }.sort]
22
- end
23
- )
13
+ ExpressionArray = Util::ArrayOf.new(Expression)
14
+
15
+ def initialize(&block)
16
+ @block = block
17
+ end
18
+
19
+ def visit(expr)
20
+ expr.to_h.each_with_object({}) do |(attr, value), h|
21
+ result = one_visit(value)
22
+ h[attr] = result if result
23
+ end
24
+ end
25
+
26
+ def one_visit(value)
27
+ case value
28
+ when Expression
29
+ @block[value]
30
+ when ExpressionArray
31
+ value.map(&@block)
32
+ when ExpressionHash
33
+ Hash[value.map { |k, v| [k, v.nil? ? v : @block[v]] }.sort]
34
+ end
24
35
  end
25
36
  end
26
37
 
@@ -51,7 +62,7 @@ module Dhall
51
62
  normalized = super
52
63
  return normalized.fuse if normalized.fuse
53
64
 
54
- if normalized.function.is_a?(Builtin) ||
65
+ if normalized.function.is_a?(BuiltinFunction) ||
55
66
  normalized.function.is_a?(Function) ||
56
67
  normalized.function.is_a?(RecordSelection)
57
68
  return normalized.function.call(normalized.argument)
@@ -120,15 +131,26 @@ module Dhall
120
131
  end
121
132
  end
122
133
 
123
- class Forall; end
134
+ class FunctionProxyRaw
135
+ def shift(*)
136
+ self
137
+ end
138
+
139
+ def substitute(*)
140
+ raise "Cannot substitute #{self}"
141
+ end
124
142
 
125
- class Bool
143
+ def normalize
144
+ self
145
+ end
126
146
  end
127
147
 
128
148
  class Variable
129
149
  def shift(amount, name, min_index)
130
150
  return self if self.name != name || min_index > index
131
151
 
152
+ raise TypeError, "free variable" if (index + amount).negative?
153
+
132
154
  with(index: index + amount)
133
155
  end
134
156
 
@@ -199,14 +221,7 @@ module Dhall
199
221
 
200
222
  class TextConcatenate
201
223
  def normalize
202
- normalized = super
203
- if normalized.lhs == Text.new(value: "")
204
- normalized.rhs
205
- elsif normalized.rhs == Text.new(value: "")
206
- normalized.lhs
207
- else
208
- normalized.lhs << normalized.rhs
209
- end
224
+ TextLiteral.for(lhs, rhs).normalize
210
225
  end
211
226
  end
212
227
 
@@ -230,7 +245,10 @@ module Dhall
230
245
 
231
246
  class RightBiasedRecordMerge
232
247
  def normalize
233
- lhs.normalize.merge(rhs.normalize)
248
+ n_lhs = lhs.normalize
249
+ n_rhs = rhs.normalize
250
+ return n_lhs if n_lhs == n_rhs
251
+ n_lhs.merge(n_rhs)
234
252
  end
235
253
  end
236
254
 
@@ -243,7 +261,7 @@ module Dhall
243
261
 
244
262
  class EmptyList
245
263
  def normalize
246
- super.with(element_type: element_type.normalize)
264
+ super.with(type: type.normalize)
247
265
  end
248
266
  end
249
267
 
@@ -263,6 +281,20 @@ module Dhall
263
281
  end
264
282
  end
265
283
 
284
+ class ToMap
285
+ def normalize
286
+ normalized = super
287
+ unless [Record, EmptyRecord].include?(normalized.record.class)
288
+ return normalized
289
+ end
290
+
291
+ List.of(*normalized.record.to_h.to_a.map do |(k, v)|
292
+ k = Text.new(value: k)
293
+ Record.new(record: { "mapKey" => k, "mapValue" => v })
294
+ end, type: normalized.type&.argument)
295
+ end
296
+ end
297
+
266
298
  class Merge
267
299
  def normalize
268
300
  normalized = super
@@ -314,7 +346,19 @@ module Dhall
314
346
 
315
347
  class RecordProjection
316
348
  def normalize
317
- record.normalize.slice(*selectors)
349
+ record.normalize.slice(*selectors.sort)
350
+ end
351
+ end
352
+
353
+ class RecordProjectionByExpression
354
+ def normalize
355
+ sel = selector.normalize
356
+
357
+ if sel.is_a?(RecordType)
358
+ RecordProjection.for(record, sel.keys).normalize
359
+ else
360
+ with(record: record.normalize, selector: sel)
361
+ end
318
362
  end
319
363
  end
320
364
 
@@ -342,6 +386,12 @@ module Dhall
342
386
  end
343
387
  end
344
388
 
389
+ class Enum
390
+ def normalize
391
+ with(alternatives: alternatives.normalize)
392
+ end
393
+ end
394
+
345
395
  class If
346
396
  def normalize
347
397
  normalized = super
@@ -362,19 +412,16 @@ module Dhall
362
412
  end
363
413
  end
364
414
 
365
- class Number
366
- end
367
-
368
- class Natural; end
369
- class Integer; end
370
- class Double; end
371
-
372
- class Text
373
- end
374
-
375
415
  class TextLiteral
376
416
  def normalize
377
- TextLiteral.for(*super.flatten.chunks)
417
+ lit = TextLiteral.for(*super.flatten.chunks)
418
+
419
+ if lit.is_a?(TextLiteral) && lit.chunks.length == 3 &&
420
+ lit.start_empty? && lit.end_empty?
421
+ lit.chunks[1]
422
+ else
423
+ lit
424
+ end
378
425
  end
379
426
 
380
427
  def flatten
@@ -384,9 +431,6 @@ module Dhall
384
431
  end
385
432
  end
386
433
 
387
- class Import
388
- end
389
-
390
434
  class LetIn
391
435
  def normalize
392
436
  desugar.normalize
@@ -400,15 +444,16 @@ module Dhall
400
444
  body: body.shift(amount, name, min_index + 1)
401
445
  )
402
446
  end
403
- end
404
-
405
- class LetBlock
406
- def normalize
407
- desugar.normalize
408
- end
409
447
 
410
- def shift(amount, name, min_index)
411
- unflatten.shift(amount, name, min_index)
448
+ def substitute(svar, with_expr)
449
+ var = let.var
450
+ with(
451
+ let: let.substitute(svar, with_expr),
452
+ body: body.substitute(
453
+ var == svar.name ? svar.with(index: svar.index + 1) : svar,
454
+ with_expr.shift(1, var, 0)
455
+ )
456
+ )
412
457
  end
413
458
  end
414
459
 
@@ -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)
@@ -9,14 +12,14 @@ end
9
12
  rule block_comment
10
13
  (/(?:\u{7b})(?:\u{2d})/i (block_comment_continue))
11
14
  end
12
- rule block_comment_chunk
13
- ((block_comment) | /[\u{20}-@\u{5b}-\u{10ffff}]/i | (tab) | (end_of_line))
15
+ rule block_comment_char
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
- ((/(?:\u{2d})(?:\u{7d})/i) | ((block_comment_chunk) (block_comment_continue)))
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*))
@@ -58,7 +64,7 @@ rule label
58
64
  ((/`/i (quoted_label) /`/i) | (simple_label)) <Dhall::Parser::Label>
59
65
  end
60
66
  rule nonreserved_label
61
- (reserved_identifier simple_label_next_char+ | !reserved_identifier label) <Dhall::Parser::NonreservedLabel>
67
+ (builtin simple_label_next_char+ | !builtin label) <Dhall::Parser::NonreservedLabel>
62
68
  end
63
69
  rule any_label
64
70
  (label)
@@ -67,16 +73,19 @@ 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>
77
86
  end
78
87
  rule single_quote_continue
79
- (((interpolation) (single_quote_continue)) | ((escaped_quote_pair) (single_quote_continue)) | ((escaped_interpolation) (single_quote_continue)) | ((single_quote_char) (single_quote_continue)) | (`''`)) <Dhall::Parser::SingleQuoteContinue>
88
+ (single_quote_char+ single_quote_continue | interpolation single_quote_continue | escaped_quote_pair single_quote_continue | escaped_interpolation single_quote_continue | "''") <Dhall::Parser::SingleQuoteContinue>
80
89
  end
81
90
  rule escaped_quote_pair
82
91
  (`'''`) <Dhall::Parser::EscapedQuotePair>
@@ -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,17 @@ end
132
141
  rule some
133
142
  ("Some")
134
143
  end
144
+ rule tomap
145
+ ("toMap")
146
+ end
147
+ rule assert
148
+ ("assert")
149
+ end
135
150
  rule keyword
136
- ((if) | (then) | (else) | (let) | (in) | (using) | (missing) | (as) | (infinity) | (nan) | (merge) | (some))
151
+ ((if) | (then) | (else) | (let) | (in) | (using) | (missing) | (as) | (infinity) | (nan) | (merge) | (some) | (tomap))
152
+ end
153
+ rule builtin
154
+ ((natural_fold) | (natural_build) | (natural_iszero) | (natural_even) | (natural_odd) | (natural_tointeger) | (natural_show) | (integer_todouble) | (integer_show) | (natural_subtract) | (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>
137
155
  end
138
156
  rule optional
139
157
  ("Optional")
@@ -144,12 +162,111 @@ end
144
162
  rule list
145
163
  ("List")
146
164
  end
165
+ rule location
166
+ ("Location")
167
+ end
168
+ rule bool
169
+ ("Bool")
170
+ end
171
+ rule true
172
+ ("True")
173
+ end
174
+ rule false
175
+ ("False")
176
+ end
177
+ rule none
178
+ ("None")
179
+ end
180
+ rule natural
181
+ ("Natural")
182
+ end
183
+ rule integer
184
+ ("Integer")
185
+ end
186
+ rule double
187
+ ("Double")
188
+ end
189
+ rule type
190
+ ("Type")
191
+ end
192
+ rule kind
193
+ ("Kind")
194
+ end
195
+ rule sort
196
+ ("Sort")
197
+ end
198
+ rule natural_fold
199
+ ("Natural" /\//i "f" "o" "l" "d")
200
+ end
201
+ rule natural_build
202
+ ("Natural" /\//i "b" "u" "i" "l" "d")
203
+ end
204
+ rule natural_iszero
205
+ ("Natural" /\//i "i" "s" "Z" "e" "r" "o")
206
+ end
207
+ rule natural_even
208
+ ("Natural" /\//i "e" "v" "e" "n")
209
+ end
210
+ rule natural_odd
211
+ ("Natural" /\//i "o" "d" "d")
212
+ end
213
+ rule natural_tointeger
214
+ ("Natural" /\//i "t" "o" "I" "n" "t" "e" "g" "e" "r")
215
+ end
216
+ rule natural_show
217
+ ("Natural" /\//i "s" "h" "o" "w")
218
+ end
219
+ rule natural_subtract
220
+ ("Natural" /\//i "s" "u" "b" "t" "r" "a" "c" "t")
221
+ end
222
+ rule integer_todouble
223
+ ("Integer" /\//i "t" "o" "D" "o" "u" "b" "l" "e")
224
+ end
225
+ rule integer_show
226
+ ("Integer" /\//i "s" "h" "o" "w")
227
+ end
228
+ rule double_show
229
+ ("Double" /\//i "s" "h" "o" "w")
230
+ end
231
+ rule list_build
232
+ ("List" /\//i "b" "u" "i" "l" "d")
233
+ end
234
+ rule list_fold
235
+ ("List" /\//i "f" "o" "l" "d")
236
+ end
237
+ rule list_length
238
+ ("List" /\//i "l" "e" "n" "g" "t" "h")
239
+ end
240
+ rule list_head
241
+ ("List" /\//i "h" "e" "a" "d")
242
+ end
243
+ rule list_last
244
+ ("List" /\//i "l" "a" "s" "t")
245
+ end
246
+ rule list_indexed
247
+ ("List" /\//i "i" "n" "d" "e" "x" "e" "d")
248
+ end
249
+ rule list_reverse
250
+ ("List" /\//i "r" "e" "v" "e" "r" "s" "e")
251
+ end
252
+ rule optional_fold
253
+ ("Optional" /\//i "f" "o" "l" "d")
254
+ end
255
+ rule optional_build
256
+ ("Optional" /\//i "b" "u" "i" "l" "d")
257
+ end
258
+ rule text_show
259
+ ("Text" /\//i "s" "h" "o" "w")
260
+ end
147
261
  rule combine
148
262
  (/\u{2227}/i | (/(?:\/)(?:\u{5c})/i))
149
263
  end
150
264
  rule combine_types
151
265
  (/\u{2a53}/i | (/(?:(?:(?:\/)(?:\/))(?:\u{5c}))(?:\u{5c})/i))
152
266
  end
267
+ rule equivalent
268
+ (/\u{2261}/i | (/(?:(?:=)(?:=))(?:=)/i))
269
+ end
153
270
  rule prefer
154
271
  (/\u{2afd}/i | (/(?:\/)(?:\/)/i))
155
272
  end
@@ -184,13 +301,16 @@ rule integer_literal
184
301
  (/[\u{2b}\u{2d}]/i (natural_literal)) <Dhall::Parser::IntegerLiteral>
185
302
  end
186
303
  rule identifier
187
- ((any_label) (((whsp) /@/i (whsp) (natural_literal))?)) <Dhall::Parser::Identifier>
304
+ ((variable) | (builtin))
305
+ end
306
+ rule variable
307
+ ((nonreserved_label) (((whsp) /@/i (whsp) (natural_literal))?)) <Dhall::Parser::Variable>
188
308
  end
189
309
  rule path_character
190
310
  (/[!\u{24}-'\u{2a}\u{2b}\u{2d}\u{2e}0-;=@\u{5e}-z\u{7c}~]/i)
191
311
  end
192
312
  rule quoted_path_character
193
- (/[\u{20}!\u{23}-\u{2e}0-@\u{5b}-\u{10ffff}]/i)
313
+ (/[\u{20}!\u{23}-\u{2e}0-@\u{5b}-\u{7f}]/i | (valid_non_ascii))
194
314
  end
195
315
  rule unquoted_path_component
196
316
  ((path_character)+)
@@ -220,19 +340,22 @@ rule absolute_path
220
340
  (path) <Dhall::Parser::AbsolutePath>
221
341
  end
222
342
  rule scheme
223
- ("http" ("s"?))
343
+ ("http" ("s"?)) <Dhall::Parser::Scheme>
224
344
  end
225
345
  rule http_raw
226
- ((scheme) /(?::(?:\/))(?:\/)/i (authority) (path) ((/\u{3f}/i (query))?))
346
+ ((scheme) /(?::(?:\/))(?:\/)/i (authority) (url_path) ((/\u{3f}/i (query))?))
347
+ end
348
+ rule url_path
349
+ (((path_component) | (/\//i (segment)))*) <Dhall::Parser::UrlPath>
227
350
  end
228
351
  rule authority
229
- ((((userinfo) /@/i)?) (host) ((`:` (port))?))
352
+ ((((userinfo) /@/i)?) (host) ((`:` (port))?)) <Dhall::Parser::Authority>
230
353
  end
231
354
  rule userinfo
232
355
  (((unreserved) | (pct_encoded) | (sub_delims) | `:`)*)
233
356
  end
234
357
  rule host
235
- ((ip_literal) | (ipv4address) | (reg_name))
358
+ ((ip_literal) | (ipv4address) | (domain))
236
359
  end
237
360
  rule port
238
361
  ((digit)*)
@@ -244,7 +367,7 @@ rule ipvfuture
244
367
  (`v` ((hexdig)+) /\u{2e}/i (((unreserved) | (sub_delims) | `:`)+))
245
368
  end
246
369
  rule ipv6address
247
- (((((h16) `:`) 6*6) (ls32)) | (`::` (((h16) `:`) 5*5) (ls32)) | (((h16)?) `::` (((h16) `:`) 4*4) (ls32)) | ((((((h16) `:`)?) (h16))?) `::` (((h16) `:`) 3*3) (ls32)) | ((((((h16) `:`) 0*2) (h16))?) `::` (((h16) `:`) 2*2) (ls32)) | ((((((h16) `:`) 0*3) (h16))?) `::` (h16) `:` (ls32)) | ((((((h16) `:`) 0*4) (h16))?) `::` (ls32)) | ((((((h16) `:`) 0*5) (h16))?) `::` (h16)) | ((((((h16) `:`) 0*6) (h16))?) `::`))
370
+ (((((h16) `:`) 6*6) (ls32)) | (`::` (((h16) `:`) 5*5) (ls32)) | (((h16)?) `::` (((h16) `:`) 4*4) (ls32)) | ((((h16) ((`:` (h16))?))?) `::` (((h16) `:`) 3*3) (ls32)) | ((((h16) ((`:` (h16)) 0*2))?) `::` (((h16) `:`) 2*2) (ls32)) | ((((h16) ((`:` (h16)) 0*3))?) `::` (h16) `:` (ls32)) | ((((h16) ((`:` (h16)) 0*4))?) `::` (ls32)) | ((((h16) ((`:` (h16)) 0*5))?) `::` (h16)) | ((((h16) ((`:` (h16)) 0*6))?) `::`))
248
371
  end
249
372
  rule h16
250
373
  ((hexdig) 1*4)
@@ -256,10 +379,16 @@ rule ipv4address
256
379
  ((dec_octet) /\u{2e}/i (dec_octet) /\u{2e}/i (dec_octet) /\u{2e}/i (dec_octet))
257
380
  end
258
381
  rule dec_octet
259
- ((digit) | (/[1-9]/i (digit)) | (`1` ((digit) 2*2)) | (/2(?:[0-4])/i (digit)) | (/25(?:[0-5])/i))
382
+ ((/25(?:[0-5])/i) | (/2(?:[0-4])/i (digit)) | (`1` ((digit) 2*2)) | (/[1-9]/i (digit)) | (digit))
260
383
  end
261
- rule reg_name
262
- (((unreserved) | (pct_encoded) | (sub_delims))*)
384
+ rule domain
385
+ ((domainlabel) ((/\u{2e}/i (domainlabel))*) (/\u{2e}/i?))
386
+ end
387
+ rule domainlabel
388
+ (((alphanum)+) (((/\u{2d}/i+) ((alphanum)+))*))
389
+ end
390
+ rule segment
391
+ ((pchar)*)
263
392
  end
264
393
  rule pchar
265
394
  ((unreserved) | (pct_encoded) | (sub_delims) | /[:@]/i)
@@ -271,19 +400,19 @@ rule pct_encoded
271
400
  (/%/i (hexdig) (hexdig))
272
401
  end
273
402
  rule unreserved
274
- ((alpha) | (digit) | /[\u{2d}\u{2e}_~]/i)
403
+ ((alphanum) | /[\u{2d}\u{2e}_~]/i)
275
404
  end
276
405
  rule sub_delims
277
- (/[!\u{24}&-,;=]/i)
406
+ (/[!\u{24}&'\u{2a}\u{2b};=]/i)
278
407
  end
279
408
  rule http
280
- ((http_raw) (((whsp) (using) (whsp1) ((import_hashed) | (/\u{28}/i (whsp) (import_hashed) (whsp) /\u{29}/i)))?)) <Dhall::Parser::Http>
409
+ ((http_raw) (((whsp) (using) (whsp1) (import_expression))?)) <Dhall::Parser::Http>
281
410
  end
282
411
  rule env
283
412
  (`env:` ((bash_environment_variable) | (/"/i (posix_environment_variable) /"/i))) <Dhall::Parser::Env>
284
413
  end
285
414
  rule bash_environment_variable
286
- (((alpha) | `_`) (((alpha) | (digit) | `_`)*))
415
+ (((alpha) | `_`) (((alphanum) | `_`)*))
287
416
  end
288
417
  rule posix_environment_variable
289
418
  ((posix_environment_variable_character)+) <Dhall::Parser::PosixEnvironmentVariable>
@@ -301,10 +430,10 @@ rule import_hashed
301
430
  ((import_type) (((whsp1) (hash))?)) <Dhall::Parser::ImportHashed>
302
431
  end
303
432
  rule import
304
- ((import_hashed) (((whsp) (as) (whsp1) (text))?)) <Dhall::Parser::Import>
433
+ ((import_hashed) (((whsp) (as) (whsp1) ((text) | (location)))?)) <Dhall::Parser::Import>
305
434
  end
306
435
  rule expression
307
- (((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) (whsp) (import_expression) (((whsp) `:` (whsp1) (application_expression))?)) | (/\u{5b}/i (whsp) ((empty_collection) | (non_empty_optional))) | (annotated_expression)) <Dhall::Parser::Expression>
436
+ (((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)) | (empty_list_literal) | ((tomap) (whsp1) (import_expression) (whsp) `:` (whsp1) (application_expression)) | ((assert) (whsp) `:` (whsp1) (expression)) | (annotated_expression)) <Dhall::Parser::Expression>
308
437
  end
309
438
  rule annotated_expression
310
439
  ((operator_expression) (((whsp) `:` (whsp1) (expression))?)) <Dhall::Parser::AnnotatedExpression>
@@ -312,11 +441,8 @@ end
312
441
  rule let_binding
313
442
  ((let) (whsp1) (nonreserved_label) (whsp) ((`:` (whsp1) (expression) (whsp))?) /=/i (whsp) (expression) (whsp)) <Dhall::Parser::LetBinding>
314
443
  end
315
- rule empty_collection
316
- (/\u{5d}/i (whsp) `:` (whsp1) ((list) | (optional)) (whsp) (import_expression)) <Dhall::Parser::EmptyCollection>
317
- end
318
- rule non_empty_optional
319
- ((expression) (whsp) /\u{5d}/i (whsp) `:` (whsp1) (optional) (whsp) (import_expression)) <Dhall::Parser::NonEmptyOptional>
444
+ rule empty_list_literal
445
+ (/\u{5b}/i (whsp) /\u{5d}/i (whsp) `:` (whsp1) (application_expression))
320
446
  end
321
447
  rule operator_expression
322
448
  (import_alt_expression)
@@ -355,10 +481,16 @@ rule equal_expression
355
481
  ((not_equal_expression) (((whsp) /(?:=)(?:=)/i (whsp) (not_equal_expression))*)) <Dhall::Parser::EqualExpression>
356
482
  end
357
483
  rule not_equal_expression
358
- ((application_expression) (((whsp) /(?:!)(?:=)/i (whsp) (application_expression))*)) <Dhall::Parser::NotEqualExpression>
484
+ ((equivalent_expression) (((whsp) /(?:!)(?:=)/i (whsp) (equivalent_expression))*)) <Dhall::Parser::NotEqualExpression>
485
+ end
486
+ rule equivalent_expression
487
+ ((application_expression) (((whsp) (equivalent) (whsp) (application_expression))*)) <Dhall::Parser::EquivalentExpression>
359
488
  end
360
489
  rule application_expression
361
- ((((some) (whsp1))?) (import_expression) (((whsp1) (import_expression))*)) <Dhall::Parser::ApplicationExpression>
490
+ ((first_application_expression) (((whsp1) (import_expression))*)) <Dhall::Parser::ApplicationExpression>
491
+ end
492
+ rule first_application_expression
493
+ (((merge) (whsp1) (import_expression) (whsp1) (import_expression)) | ((some) (whsp1) (import_expression)) | ((tomap) (whsp1) (import_expression)) | (import_expression)) <Dhall::Parser::FirstApplicationExpression>
362
494
  end
363
495
  rule import_expression
364
496
  ((import) | (selector_expression))
@@ -367,13 +499,16 @@ rule selector_expression
367
499
  ((primitive_expression) (((whsp) /\u{2e}/i (whsp) (selector))*)) <Dhall::Parser::SelectorExpression>
368
500
  end
369
501
  rule selector
370
- ((any_label) | (labels))
502
+ ((any_label) | (labels) | (type_selector)) <Dhall::Parser::Selector>
371
503
  end
372
504
  rule labels
373
- (/\u{7b}/i (whsp) (((any_label) (whsp) ((/,/i (whsp) (any_label) (whsp))*))?) /\u{7d}/i) <Dhall::Parser::Labels>
505
+ (/\u{7b}/i (whsp) (((any_label) (whsp) ((/,/i (whsp) (any_label) (whsp))*))?) /\u{7d}/i)
506
+ end
507
+ rule type_selector
508
+ (/\u{28}/i (whsp) (expression) (whsp) /\u{29}/i)
374
509
  end
375
510
  rule primitive_expression
376
- ((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>
511
+ ((double_literal) | (natural_literal) | (integer_literal) | (text_literal) | (/\u{7b}/i (whsp) (record_type_or_literal) (whsp) /\u{7d}/i) | (/</i (whsp) (union_type) (whsp) />/i) | (non_empty_list_literal) | (identifier) | (/\u{28}/i (complete_expression) /\u{29}/i)) <Dhall::Parser::PrimitiveExpression>
377
512
  end
378
513
  rule record_type_or_literal
379
514
  ((empty_record_literal) | (non_empty_record_type_or_literal) | (empty_record_type))
@@ -399,24 +534,18 @@ end
399
534
  rule record_literal_entry
400
535
  ((any_label) (whsp) /=/i (whsp) (expression)) <Dhall::Parser::RecordLiteralEntry>
401
536
  end
402
- rule union_type_or_literal
403
- ((non_empty_union_type_or_literal) | (empty_union_type))
537
+ rule union_type
538
+ ((non_empty_union_type) | (empty_union_type))
404
539
  end
405
540
  rule empty_union_type
406
541
  ("") <Dhall::Parser::EmptyUnionType>
407
542
  end
408
- rule non_empty_union_type_or_literal
409
- ((any_label) (((whsp) ((union_literal_variant_value) | (union_type_or_literal_variant_type)))?)) <Dhall::Parser::NonEmptyUnionTypeOrLiteral>
410
- end
411
- rule union_literal_variant_value
412
- (/=/i (whsp) (expression) (((whsp) /\u{7c}/i (whsp) (union_type_entry))*)) <Dhall::Parser::UnionLiteralVariantValue>
543
+ rule non_empty_union_type
544
+ ((union_type_entry) (((whsp) /\u{7c}/i (whsp) (union_type_entry))*)) <Dhall::Parser::NonEmptyUnionType>
413
545
  end
414
546
  rule union_type_entry
415
547
  ((any_label) (((whsp) `:` (whsp1) (expression))?)) <Dhall::Parser::UnionTypeEntry>
416
548
  end
417
- rule union_type_or_literal_variant_type
418
- (((`:` (whsp1) (expression))?) (((whsp) /\u{7c}/i (whsp) (non_empty_union_type_or_literal))?)) <Dhall::Parser::UnionTypeOrLiteralVariantType>
419
- end
420
549
  rule non_empty_list_literal
421
550
  (/\u{5b}/i (whsp) (expression) (whsp) ((/,/i (whsp) (expression) (whsp))*) /\u{5d}/i) <Dhall::Parser::NonEmptyListLiteral>
422
551
  end
@@ -462,39 +591,4 @@ end
462
591
  rule wsp
463
592
  ((sp) | (htab))
464
593
  end
465
- rule reserved_identifier
466
- "Natural/build" |
467
- "Natural/fold" |
468
- "Natural/isZero" |
469
- "Natural/even" |
470
- "Natural/odd" |
471
- "Natural/toInteger" |
472
- "Natural/show" |
473
- "Integer/toDouble" |
474
- "Integer/show" |
475
- "Double/show" |
476
- "List/build" |
477
- "List/fold" |
478
- "List/length" |
479
- "List/head" |
480
- "List/last" |
481
- "List/indexed" |
482
- "List/reverse" |
483
- "Optional/fold" |
484
- "Optional/build" |
485
- "Text/show" |
486
- "Bool" |
487
- "Optional" |
488
- "Natural" |
489
- "Integer" |
490
- "Double" |
491
- "Text" |
492
- "List" |
493
- "True" |
494
- "False" |
495
- "None" |
496
- "Type" |
497
- "Kind" |
498
- "Sort"
499
- end
500
594
  end