dhall 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -199,14 +199,7 @@ module Dhall
199
199
 
200
200
  class TextConcatenate
201
201
  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
202
+ TextLiteral.for(lhs, rhs).normalize
210
203
  end
211
204
  end
212
205
 
@@ -362,16 +355,6 @@ module Dhall
362
355
  end
363
356
  end
364
357
 
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
358
  class TextLiteral
376
359
  def normalize
377
360
  TextLiteral.for(*super.flatten.chunks)
@@ -384,9 +367,6 @@ module Dhall
384
367
  end
385
368
  end
386
369
 
387
- class Import
388
- end
389
-
390
370
  class LetIn
391
371
  def normalize
392
372
  desugar.normalize
@@ -9,11 +9,11 @@ end
9
9
  rule block_comment
10
10
  (/(?:\u{7b})(?:\u{2d})/i (block_comment_continue))
11
11
  end
12
- rule block_comment_chunk
13
- ((block_comment) | /[\u{20}-@\u{5b}-\u{10ffff}]/i | (tab) | (end_of_line))
12
+ rule block_comment_char
13
+ (/[\u{20}-@\u{5b}-\u{10ffff}]/i | (tab) | (end_of_line))
14
14
  end
15
15
  rule block_comment_continue
16
- ((/(?:\u{2d})(?:\u{7d})/i) | ((block_comment_chunk) (block_comment_continue)))
16
+ ((/(?:\u{2d})(?:\u{7d})/i) | ((block_comment) (block_comment_continue)) | ((block_comment_char) (block_comment_continue)))
17
17
  end
18
18
  rule not_end_of_line
19
19
  (/[\u{20}-@\u{5b}-\u{10ffff}]/i | (tab))
@@ -58,7 +58,7 @@ rule label
58
58
  ((/`/i (quoted_label) /`/i) | (simple_label)) <Dhall::Parser::Label>
59
59
  end
60
60
  rule nonreserved_label
61
- (reserved_identifier simple_label_next_char+ | !reserved_identifier label) <Dhall::Parser::NonreservedLabel>
61
+ (builtin simple_label_next_char+ | !builtin label) <Dhall::Parser::NonreservedLabel>
62
62
  end
63
63
  rule any_label
64
64
  (label)
@@ -135,6 +135,9 @@ end
135
135
  rule keyword
136
136
  ((if) | (then) | (else) | (let) | (in) | (using) | (missing) | (as) | (infinity) | (nan) | (merge) | (some))
137
137
  end
138
+ rule builtin
139
+ ((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>
140
+ end
138
141
  rule optional
139
142
  ("Optional")
140
143
  end
@@ -144,6 +147,96 @@ end
144
147
  rule list
145
148
  ("List")
146
149
  end
150
+ rule bool
151
+ ("Bool")
152
+ end
153
+ rule true
154
+ ("True")
155
+ end
156
+ rule false
157
+ ("False")
158
+ end
159
+ rule none
160
+ ("None")
161
+ end
162
+ rule natural
163
+ ("Natural")
164
+ end
165
+ rule integer
166
+ ("Integer")
167
+ end
168
+ rule double
169
+ ("Double")
170
+ end
171
+ rule type
172
+ ("Type")
173
+ end
174
+ rule kind
175
+ ("Kind")
176
+ end
177
+ rule sort
178
+ ("Sort")
179
+ end
180
+ rule natural_fold
181
+ ("Natural" /\//i "f" "o" "l" "d")
182
+ end
183
+ rule natural_build
184
+ ("Natural" /\//i "b" "u" "i" "l" "d")
185
+ end
186
+ rule natural_iszero
187
+ ("Natural" /\//i "i" "s" "Z" "e" "r" "o")
188
+ end
189
+ rule natural_even
190
+ ("Natural" /\//i "e" "v" "e" "n")
191
+ end
192
+ rule natural_odd
193
+ ("Natural" /\//i "o" "d" "d")
194
+ end
195
+ rule natural_tointeger
196
+ ("Natural" /\//i "t" "o" "I" "n" "t" "e" "g" "e" "r")
197
+ end
198
+ rule natural_show
199
+ ("Natural" /\//i "s" "h" "o" "w")
200
+ end
201
+ rule integer_todouble
202
+ ("Integer" /\//i "t" "o" "D" "o" "u" "b" "l" "e")
203
+ end
204
+ rule integer_show
205
+ ("Integer" /\//i "s" "h" "o" "w")
206
+ end
207
+ rule double_show
208
+ ("Double" /\//i "s" "h" "o" "w")
209
+ end
210
+ rule list_build
211
+ ("List" /\//i "b" "u" "i" "l" "d")
212
+ end
213
+ rule list_fold
214
+ ("List" /\//i "f" "o" "l" "d")
215
+ end
216
+ rule list_length
217
+ ("List" /\//i "l" "e" "n" "g" "t" "h")
218
+ end
219
+ rule list_head
220
+ ("List" /\//i "h" "e" "a" "d")
221
+ end
222
+ rule list_last
223
+ ("List" /\//i "l" "a" "s" "t")
224
+ end
225
+ rule list_indexed
226
+ ("List" /\//i "i" "n" "d" "e" "x" "e" "d")
227
+ end
228
+ rule list_reverse
229
+ ("List" /\//i "r" "e" "v" "e" "r" "s" "e")
230
+ end
231
+ rule optional_fold
232
+ ("Optional" /\//i "f" "o" "l" "d")
233
+ end
234
+ rule optional_build
235
+ ("Optional" /\//i "b" "u" "i" "l" "d")
236
+ end
237
+ rule text_show
238
+ ("Text" /\//i "s" "h" "o" "w")
239
+ end
147
240
  rule combine
148
241
  (/\u{2227}/i | (/(?:\/)(?:\u{5c})/i))
149
242
  end
@@ -184,7 +277,10 @@ rule integer_literal
184
277
  (/[\u{2b}\u{2d}]/i (natural_literal)) <Dhall::Parser::IntegerLiteral>
185
278
  end
186
279
  rule identifier
187
- ((any_label) (((whsp) /@/i (whsp) (natural_literal))?)) <Dhall::Parser::Identifier>
280
+ ((variable) | (builtin))
281
+ end
282
+ rule variable
283
+ ((nonreserved_label) (((whsp) /@/i (whsp) (natural_literal))?)) <Dhall::Parser::Variable>
188
284
  end
189
285
  rule path_character
190
286
  (/[!\u{24}-'\u{2a}\u{2b}\u{2d}\u{2e}0-;=@\u{5e}-z\u{7c}~]/i)
@@ -304,7 +400,7 @@ rule import
304
400
  ((import_hashed) (((whsp) (as) (whsp1) (text))?)) <Dhall::Parser::Import>
305
401
  end
306
402
  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>
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>
308
404
  end
309
405
  rule annotated_expression
310
406
  ((operator_expression) (((whsp) `:` (whsp1) (expression))?)) <Dhall::Parser::AnnotatedExpression>
@@ -358,7 +454,10 @@ rule not_equal_expression
358
454
  ((application_expression) (((whsp) /(?:!)(?:=)/i (whsp) (application_expression))*)) <Dhall::Parser::NotEqualExpression>
359
455
  end
360
456
  rule application_expression
361
- ((((some) (whsp1))?) (import_expression) (((whsp1) (import_expression))*)) <Dhall::Parser::ApplicationExpression>
457
+ ((first_application_expression) (((whsp1) (import_expression))*)) <Dhall::Parser::ApplicationExpression>
458
+ end
459
+ rule first_application_expression
460
+ (((merge) (whsp1) (import_expression) (whsp1) (import_expression)) | ((some) (whsp1) (import_expression)) | (import_expression)) <Dhall::Parser::FirstApplicationExpression>
362
461
  end
363
462
  rule import_expression
364
463
  ((import) | (selector_expression))
@@ -462,39 +561,4 @@ end
462
561
  rule wsp
463
562
  ((sp) | (htab))
464
563
  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
564
  end
data/lib/dhall/parser.rb CHANGED
@@ -109,14 +109,36 @@ module Dhall
109
109
 
110
110
  module ApplicationExpression
111
111
  def value
112
- some = capture(:some) ? [Variable["Some"]] : []
113
- els = some + captures(:import_expression).map(&:value)
112
+ first_expr = [capture(:first_application_expression).value]
113
+ els = first_expr + captures(:import_expression).map(&:value)
114
114
  els.reduce do |f, arg|
115
115
  Application.for(function: f, argument: arg)
116
116
  end
117
117
  end
118
118
  end
119
119
 
120
+ module FirstApplicationExpression
121
+ def value
122
+ if captures.key?(:merge)
123
+ merge
124
+ elsif captures.key?(:some)
125
+ Optional.new(
126
+ value: capture(:import_expression).value
127
+ )
128
+ else
129
+ super
130
+ end
131
+ end
132
+
133
+ def merge
134
+ Merge.new(
135
+ record: captures(:import_expression)[0].value,
136
+ input: captures(:import_expression)[1].value,
137
+ type: nil
138
+ )
139
+ end
140
+ end
141
+
120
142
  module SelectorExpression
121
143
  def value
122
144
  record = capture(:primitive_expression).value
@@ -139,11 +161,23 @@ module Dhall
139
161
  end
140
162
 
141
163
  module Label
164
+ module Quoted
165
+ def quoted?
166
+ true
167
+ end
168
+ end
169
+
170
+ module Unquoted
171
+ def quoted?
172
+ false
173
+ end
174
+ end
175
+
142
176
  def value
143
177
  if first.string == "`"
144
- matches[1].string
178
+ matches[1].string.extend(Quoted)
145
179
  else
146
- string
180
+ string.extend(Unquoted)
147
181
  end
148
182
  end
149
183
  end
@@ -284,18 +318,21 @@ module Dhall
284
318
  end
285
319
  end
286
320
 
287
- module Identifier
321
+ module Variable
288
322
  def value
289
- name = capture(:any_label).value
323
+ Dhall::Variable.new(
324
+ name: capture(:nonreserved_label).value,
325
+ index: capture(:natural_literal)&.string.to_i
326
+ )
327
+ end
328
+ end
290
329
 
291
- return Dhall::Bool.new(value: true) if name == "True"
292
- return Dhall::Bool.new(value: false) if name == "False"
330
+ module Builtin
331
+ def value
332
+ return Dhall::Bool.new(value: true) if string == "True"
333
+ return Dhall::Bool.new(value: false) if string == "False"
293
334
 
294
- Dhall::Builtins::ALL[name]&.new ||
295
- Variable.new(
296
- name: name,
297
- index: capture(:natural_literal)&.string.to_i
298
- )
335
+ Dhall::Builtins[string.to_sym]
299
336
  end
300
337
  end
301
338
 
data/lib/dhall/resolve.rb CHANGED
@@ -20,7 +20,18 @@ module Dhall
20
20
  end
21
21
  end
22
22
 
23
+ ReadEnvironmentSources = lambda do |sources|
24
+ sources.map do |source|
25
+ Promise.resolve(nil).then do
26
+ ENV.fetch(source.var) do
27
+ raise ImportFailedException, "No #{source}"
28
+ end
29
+ end
30
+ end
31
+ end
32
+
23
33
  PreflightCORS = lambda do |source, parent_origin|
34
+ timeout = source.deadline.timeout
24
35
  uri = source.uri
25
36
  if parent_origin != "localhost" && parent_origin != source.origin
26
37
  req = Net::HTTP::Options.new(uri)
@@ -31,7 +42,11 @@ module Dhall
31
42
  r = Net::HTTP.start(
32
43
  uri.hostname,
33
44
  uri.port,
34
- use_ssl: uri.scheme == "https"
45
+ use_ssl: uri.scheme == "https",
46
+ open_timeout: timeout,
47
+ ssl_timeout: timeout,
48
+ read_timeout: timeout,
49
+ write_timeout: timeout
35
50
  ) { |http| http.request(req) }
36
51
 
37
52
  raise ImportFailedException, source if r.code != "200"
@@ -46,6 +61,7 @@ module Dhall
46
61
  sources.map do |source|
47
62
  Promise.resolve(nil).then do
48
63
  PreflightCORS.call(source, parent_origin)
64
+ timeout = source.deadline.timeout
49
65
  uri = source.uri
50
66
  req = Net::HTTP::Get.new(uri)
51
67
  source.headers.each do |header|
@@ -54,7 +70,11 @@ module Dhall
54
70
  r = Net::HTTP.start(
55
71
  uri.hostname,
56
72
  uri.port,
57
- use_ssl: uri.scheme == "https"
73
+ use_ssl: uri.scheme == "https",
74
+ open_timeout: timeout,
75
+ ssl_timeout: timeout,
76
+ read_timeout: timeout,
77
+ write_timeout: timeout
58
78
  ) { |http| http.request(req) }
59
79
 
60
80
  raise ImportFailedException, source if r.code != "200"
@@ -63,6 +83,18 @@ module Dhall
63
83
  end
64
84
  end
65
85
 
86
+ StandardReadHttpSources = lambda do |sources, parent_origin|
87
+ ReadHttpSources.call(sources, parent_origin).map do |source_promise|
88
+ source_promise.then do |s|
89
+ s = s.force_encoding("UTF-8")
90
+ unless s.valid_encoding?
91
+ raise ImportFailedException, "#{s.inspect} is not valid UTF-8"
92
+ end
93
+ s
94
+ end
95
+ end
96
+ end
97
+
66
98
  RejectSources = lambda do |sources|
67
99
  sources.map do |source|
68
100
  Promise.new.reject(ImportBannedException.new(source))
@@ -89,7 +121,7 @@ module Dhall
89
121
  def call(sources)
90
122
  @path_reader.call(sources).map.with_index do |promise, idx|
91
123
  source = sources[idx]
92
- if source.is_a?(Import::AbsolutePath) &&
124
+ if source.canonical.is_a?(Import::AbsolutePath) &&
93
125
  ["ipfs", "ipns"].include?(source.path.first)
94
126
  gateway_fallback(source, promise)
95
127
  else
@@ -117,17 +149,67 @@ module Dhall
117
149
  end
118
150
  end
119
151
 
152
+ module NoCache
153
+ def self.fetch(*)
154
+ yield
155
+ end
156
+ end
157
+
158
+ class RamCache
159
+ def initialize
160
+ @cache = {}
161
+ end
162
+
163
+ def fetch(key, &block)
164
+ return @cache[key] if @cache.key?(key)
165
+
166
+ Promise.resolve(nil).then(&block).then do |result|
167
+ @cache[key] = result
168
+ end
169
+ end
170
+ end
171
+
172
+ class StandardFileCache
173
+ def initialize(
174
+ dir=Pathname.new(ENV.fetch(
175
+ "XDG_CACHE_HOME", ENV.fetch("HOME") + "/.cache/"
176
+ )) + "dhall/"
177
+ )
178
+ dir.mkpath
179
+ @dir = dir
180
+ @ram = RamCache.new
181
+ end
182
+
183
+ def fetch(key, &block)
184
+ if key.is_a?(String) && key.start_with?("sha256:")
185
+ file = @dir + key.sub(/^sha256:/, "")
186
+ return Dhall.from_binary(file.binread) if file.exist?
187
+
188
+ Promise.resolve(nil).then(&block).then do |result|
189
+ file.open("wb") { |fh| fh.write(result.to_binary) }
190
+ result
191
+ end
192
+ else
193
+ @ram.fetch(key, &block)
194
+ end
195
+ end
196
+ end
197
+
120
198
  class ResolutionSet
121
- def initialize(reader)
199
+ def initialize(reader, max_depth:)
122
200
  @reader = reader
201
+ @max_depth = max_depth
123
202
  @parents = []
124
203
  @set = Hash.new { |h, k| h[k] = [] }
125
204
  end
126
205
 
127
206
  def register(source)
128
207
  p = Promise.new
129
- if @parents.include?(source)
208
+ if @parents.include?(source.canonical)
130
209
  p.reject(ImportLoopException.new(source))
210
+ elsif @parents.length + 1 > @max_depth
211
+ msg = "Max import depth of #{@max_depth} exceeded"
212
+ p.reject(ImportFailedException.new(msg))
131
213
  else
132
214
  @set[source] << p
133
215
  end
@@ -141,6 +223,8 @@ module Dhall
141
223
 
142
224
  def reader
143
225
  lambda do |sources|
226
+ raise TimeoutException if sources.any? { |s| s.deadline.exceeded? }
227
+
144
228
  if @reader.arity == 2
145
229
  @reader.call(sources, @parents.last&.origin || "localhost")
146
230
  else
@@ -159,28 +243,66 @@ module Dhall
159
243
  end
160
244
  end
161
245
 
246
+ class SourceWithDeadline < SimpleDelegator
247
+ attr_reader :deadline
248
+
249
+ def initialize(source, deadline)
250
+ @source = source
251
+ @deadline = deadline
252
+
253
+ super(source)
254
+ end
255
+
256
+ def to_uri(*args)
257
+ self.class.new(super, deadline)
258
+ end
259
+ end
260
+
162
261
  class Standard
262
+ attr_reader :deadline
263
+
163
264
  def initialize(
164
265
  path_reader: ReadPathSources,
165
- http_reader: ReadHttpSources,
166
- https_reader: http_reader
266
+ http_reader: StandardReadHttpSources,
267
+ https_reader: http_reader,
268
+ environment_reader: ReadEnvironmentSources,
269
+ cache: StandardFileCache.new,
270
+ max_depth: Float::INFINITY
167
271
  )
168
- @path_resolutions = ResolutionSet.new(path_reader)
169
- @http_resolutions = ResolutionSet.new(http_reader)
170
- @https_resolutions = ResolutionSet.new(https_reader)
171
- @cache = {}
272
+ @path_resolutions = ResolutionSet.new(path_reader, max_depth: max_depth)
273
+ @http_resolutions = ResolutionSet.new(http_reader, max_depth: max_depth)
274
+ @https_resolutions = ResolutionSet.new(https_reader, max_depth: max_depth)
275
+ @env_resolutions = ResolutionSet.new(
276
+ environment_reader, max_depth: max_depth
277
+ )
278
+ @deadline = Util::NoDeadline.new
279
+ @cache = cache
280
+ end
281
+
282
+ def with_deadline(deadline)
283
+ dup.tap do |c|
284
+ c.instance_eval do
285
+ @deadline = deadline
286
+ end
287
+ end
172
288
  end
173
289
 
174
290
  def cache_fetch(key, &fallback)
175
291
  @cache.fetch(key) do
176
- Promise.resolve(nil).then(&fallback).then do |result|
177
- @cache[key] = result
178
- end
292
+ Promise.resolve(nil).then(&fallback)
179
293
  end
180
294
  end
181
295
 
182
296
  def resolve_path(path_source)
183
- @path_resolutions.register(path_source)
297
+ @path_resolutions.register(
298
+ SourceWithDeadline.new(path_source, @deadline)
299
+ )
300
+ end
301
+
302
+ def resolve_environment(env_source)
303
+ @env_resolutions.register(
304
+ SourceWithDeadline.new(env_source, @deadline)
305
+ )
184
306
  end
185
307
 
186
308
  def resolve_http(http_source)
@@ -188,8 +310,9 @@ module Dhall
188
310
  resolver: self,
189
311
  relative_to: Dhall::Import::RelativePath.new
190
312
  ).then do |headers|
313
+ source = http_source.with(headers: headers.normalize)
191
314
  @http_resolutions.register(
192
- http_source.with(headers: headers.normalize)
315
+ SourceWithDeadline.new(source, @deadline)
193
316
  )
194
317
  end
195
318
  end
@@ -199,8 +322,9 @@ module Dhall
199
322
  resolver: self,
200
323
  relative_to: Dhall::Import::RelativePath.new
201
324
  ).then do |headers|
325
+ source = https_source.with(headers: headers.normalize)
202
326
  @https_resolutions.register(
203
- https_source.with(headers: headers.normalize)
327
+ SourceWithDeadline.new(source, @deadline)
204
328
  )
205
329
  end
206
330
  end
@@ -208,6 +332,7 @@ module Dhall
208
332
  def finish!
209
333
  [
210
334
  @path_resolutions,
335
+ @env_resolutions,
211
336
  @http_resolutions,
212
337
  @https_resolutions
213
338
  ].each do |rset|
@@ -220,6 +345,7 @@ module Dhall
220
345
  dup.tap do |c|
221
346
  c.instance_eval do
222
347
  @path_resolutions = @path_resolutions.child(parent_source)
348
+ @env_resolutions = @env_resolutions.child(parent_source)
223
349
  @http_resolutions = @http_resolutions.child(parent_source)
224
350
  @https_resolutions = @https_resolutions.child(parent_source)
225
351
  end
@@ -232,27 +358,36 @@ module Dhall
232
358
  path_reader: ReadPathSources,
233
359
  http_reader: ReadHttpSources,
234
360
  https_reader: http_reader,
235
- ipfs_public_gateway: "cloudflare-ipfs.com"
361
+ environment_reader: ReadEnvironmentSources,
362
+ ipfs_public_gateway: "cloudflare-ipfs.com",
363
+ cache: RamCache.new,
364
+ max_depth: 50
236
365
  )
237
366
  super(
238
- path_reader: ReadPathAndIPFSSources.new(
367
+ path_reader: ReadPathAndIPFSSources.new(
239
368
  path_reader: path_reader,
240
369
  http_reader: http_reader,
241
370
  https_reader: https_reader,
242
371
  public_gateway: ipfs_public_gateway
243
372
  ),
244
- http_reader: http_reader,
245
- https_reader: https_reader
373
+ http_reader: http_reader, https_reader: https_reader, cache: cache,
374
+ environment_reader: environment_reader, max_depth: max_depth
246
375
  )
247
376
  end
248
377
  end
249
378
 
250
379
  class LocalOnly < Standard
251
- def initialize(path_reader: ReadPathSources)
380
+ def initialize(
381
+ path_reader: ReadPathSources,
382
+ environment_reader: ReadEnvironmentSources,
383
+ max_depth: 50
384
+ )
252
385
  super(
253
- path_reader: path_reader,
254
- http_reader: RejectSources,
255
- https_reader: RejectSources
386
+ path_reader: path_reader,
387
+ environment_reader: environment_reader,
388
+ http_reader: RejectSources,
389
+ https_reader: RejectSources,
390
+ max_depth: max_depth
256
391
  )
257
392
  end
258
393
  end
@@ -260,9 +395,10 @@ module Dhall
260
395
  class None < Default
261
396
  def initialize
262
397
  super(
263
- path_reader: RejectSources,
264
- http_reader: RejectSources,
265
- https_reader: RejectSources
398
+ path_reader: RejectSources,
399
+ environment_reader: RejectSources,
400
+ http_reader: RejectSources,
401
+ https_reader: RejectSources
266
402
  )
267
403
  end
268
404
  end
@@ -305,7 +441,7 @@ module Dhall
305
441
  def resolve_raw(resolver:, relative_to:)
306
442
  real_path = @expr.real_path(relative_to)
307
443
  real_path.resolve(resolver).then do |result|
308
- @expr.parse_and_check(result).resolve(
444
+ @expr.parse_and_check(result, deadline: resolver.deadline).resolve(
309
445
  resolver: resolver.child(real_path),
310
446
  relative_to: real_path
311
447
  )
@@ -316,9 +452,15 @@ module Dhall
316
452
  class FallbackResolver < ExpressionResolver
317
453
  register_for Operator::ImportFallback
318
454
 
319
- def resolve(**kwargs)
320
- ExpressionResolver.for(@expr.lhs).resolve(**kwargs).catch do
321
- ExpressionResolver.for(@expr.rhs).resolve(**kwargs)
455
+ def resolve(resolver:, relative_to:)
456
+ ExpressionResolver.for(@expr.lhs).resolve(
457
+ resolver: resolver,
458
+ relative_to: relative_to
459
+ ).catch do
460
+ @expr.rhs.resolve(
461
+ resolver: resolver.child(Import::MissingImport.new),
462
+ relative_to: relative_to
463
+ )
322
464
  end
323
465
  end
324
466
  end