M lib/dhall/ast.rb => lib/dhall/ast.rb +33 -5
@@ 609,11 609,9 @@ module Dhall
def call(value)
if record.is_a?(UnionType)
- type = record.alternatives.fetch(selector)
- body = Union.from(record, selector, Variable[selector])
- Function.new(var: selector, type: type, body: body).call(value)
+ record.get_constructor(selector).call(value)
else
- super
+ Application.new(function: self, argument: value)
end
end
@@ 678,6 676,12 @@ module Dhall
block_given? ? yield : (default || raise)
end
+ def get_constructor(selector)
+ type = alternatives.fetch(selector)
+ body = Union.from(self, selector, Variable[selector])
+ Function.new(var: selector, type: type, body: body)
+ end
+
def constructor_types
alternatives.each_with_object({}) do |(k, type), ctypes|
ctypes[k] = Forall.new(var: k, type: type, body: self)
@@ 709,8 713,32 @@ module Dhall
)
end
+ def selection_syntax
+ RecordSelection.new(
+ record: alternatives.merge(
+ UnionType.new(alternatives: { tag => value&.type })
+ ),
+ selector: tag
+ )
+ end
+
+ def syntax
+ if value.nil?
+ selection_syntax
+ else
+ Application.new(
+ function: selection_syntax,
+ argument: value.respond_to?(:value) ? value.value : value
+ )
+ end
+ end
+
def as_json
- [12, tag, value.as_json, alternatives.as_json.last]
+ if value.nil? || value.respond_to?(:type)
+ syntax.as_json
+ else
+ [12, tag, value&.as_json, alternatives.as_json.last]
+ end
end
end
M lib/dhall/normalize.rb => lib/dhall/normalize.rb +9 -0
@@ 303,6 303,15 @@ module Dhall
end
class Union
+ def normalize
+ val = if value.is_a?(TypeAnnotation)
+ value.with(ExpressionVisitor.new(&:normalize).visit(value))
+ else
+ value&.normalize
+ end
+
+ with(value: val, alternatives: alternatives.normalize)
+ end
end
class If
M test/test_as_json.rb => test/test_as_json.rb +1 -0
@@ 16,6 16,7 @@ class TestAsJson < Minitest::Test
define_method("test_#{test}") do
skip "double as_json" if test =~ /doubleB/
skip "deprecated syntax" if test =~ /collectionImportTypeB|annotationsB/
+ skip "deprecated syntax" if test =~ /largeExpressionB/
assert_equal(
CBOR.decode(path.read),
Dhall.from_binary(path.read).as_json
M test/test_normalization.rb => test/test_normalization.rb +5 -7
@@ 3,9 3,7 @@
require "minitest/autorun"
require "pathname"
-require "dhall/ast"
-require "dhall/parser"
-require "dhall/normalize"
+require "dhall"
class TestNormalization < Minitest::Test
DIRPATH = Pathname.new(File.dirname(__FILE__))
@@ 15,12 13,12 @@ class TestNormalization < Minitest::Test
test = path.relative_path_from(TESTS).to_s.sub(/A\.dhall$/, "")
define_method("test_#{test}") do
- skip "requires resolve" if test =~ /prelude\/|remoteSystems/
-
Dhall::Function.disable_alpha_normalization! if test !~ /α/
assert_equal(
- Dhall::Parser.parse_file(TESTS + "#{test}B.dhall").value,
- Dhall::Parser.parse_file(path).value.normalize
+ Dhall::Parser.parse_file(TESTS + "#{test}B.dhall").value.to_binary,
+ Dhall::Parser.parse_file(path).value.resolve(
+ relative_to: Dhall::Import::Path.from_string(path)
+ ).then(&:normalize).sync.to_binary
)
Dhall::Function.enable_alpha_normalization! if test !~ /α/
end
M test/test_parser.rb => test/test_parser.rb +1 -1
@@ 13,8 13,8 @@ class TestParser < Minitest::Test
Pathname.glob(TESTS + "success/**/*A.dhall").each do |path|
test = path.relative_path_from(TESTS).to_s.sub(/A\.dhall$/, "")
define_method("test_#{test}") do
- skip "very slow" if !ENV["CI"] && test =~ /largeExpression/
skip "deprecated syntax" if test =~ /collectionImportType|annotations/
+ skip "deprecated syntax" if test =~ /largeExpression/
match = Dhall::Parser.parse_file(path)
assert(match)
assert_kind_of(Dhall::Expression, match.value)