~singpolyma/dhall-ruby

aa7930ea0382c434726fc82a0611e5273f59e5c9 — Stephen Paul Weber 5 years ago 0184ae1
Clean up style
M .rubocop.yml => .rubocop.yml +10 -0
@@ 4,6 4,10 @@ AllCops:
Metrics/LineLength:
  Max: 80

Layout/AlignHash:
  EnforcedHashRocketStyle: table
  EnforcedColonStyle: table

Layout/Tab:
  Enabled: false



@@ 37,9 41,15 @@ Style/Documentation:
Style/FormatString:
  EnforcedStyle: percent

Style/RegexpLiteral:
  AllowInnerSlashes: true

Style/StringLiterals:
  EnforcedStyle: double_quotes

Style/StringLiteralsInInterpolation:
  EnforcedStyle: double_quotes

Style/SymbolArray:
  EnforcedStyle: brackets


M Gemfile => Gemfile +1 -0
@@ 4,3 4,4 @@ source "https://rubygems.org"

gem "cbor"
gem "value_semantics"
gem "rubocop"

M lib/dhall/ast.rb => lib/dhall/ast.rb +19 -13
@@ 132,6 132,7 @@ module Dhall

		def call(*args)
			return super if args.length > 1

			body.substitute(
				Variable.new(name: var),
				args.first.shift(1, var, 0)


@@ 311,14 312,14 @@ module Dhall
		include(ValueSemantics.for_attributes do
			record Expression
			input  Expression
			type  Either(Expression, nil)
			type   Either(Expression, nil)
		end)

		def map_subexpressions(&block)
			with(
				record: block[record],
				input: block[input],
				type: type.nil? ? nil : block[type]
				input:  block[input],
				type:   type.nil? ? nil : block[type]
			)
		end
	end


@@ 328,6 329,7 @@ module Dhall

		def initialize(record)
			raise ArgumentError, "You meant EmptyRecordType?" if record.empty?

			@record = record
		end



@@ 337,6 339,7 @@ module Dhall

		def deep_merge_type(other)
			return super unless other.is_a?(RecordType)

			self.class.new(Hash[record.merge(other.record) { |_, v1, v2|
				v1.deep_merge_type(v2)
			}.sort])


@@ 352,7 355,7 @@ module Dhall
	end

	class EmptyRecordType < Expression
		include ValueSemantics.for_attributes { }
		include(ValueSemantics.for_attributes {})

		def map_subexpressions
			self


@@ 368,6 371,7 @@ module Dhall

		def initialize(record)
			raise ArgumentError, "You meant EmptyRecord?" if record.empty?

			@record = record
		end



@@ 389,6 393,7 @@ module Dhall

		def deep_merge(other)
			return super unless other.is_a?(Record)

			self.class.new(Hash[record.merge(other.record) { |_, v1, v2|
				v1.deep_merge(v2)
			}.sort])


@@ 396,6 401,7 @@ module Dhall

		def merge(other)
			return super unless other.is_a?(Record)

			self.class.new(Hash[record.merge(other.record).sort])
		end



@@ 409,7 415,7 @@ module Dhall
	end

	class EmptyRecord < Expression
		include ValueSemantics.for_attributes { }
		include(ValueSemantics.for_attributes {})

		def map_subexpressions
			self


@@ 488,8 494,8 @@ module Dhall
				var:  k,
				type: record.fetch(k),
				body: Union.new(
					tag: k,
					value: Variable.new(name: k),
					tag:          k,
					value:        Variable.new(name: k),
					alternatives: self.class.new(record.dup.tap { |r| r.delete(k) })
				)
			)


@@ 533,8 539,8 @@ module Dhall
		def map_subexpressions(&block)
			with(
				predicate: block[predicate],
				then: block[self.then],
				else: block[self.else]
				then:      block[self.then],
				else:      block[self.else]
			)
		end
	end


@@ 590,7 596,7 @@ module Dhall
		end)

		def to_s
			"#{value >= 0 ? "+" : ""}#{value.to_s}"
			"#{value >= 0 ? "+" : ""}#{value}"
		end
	end



@@ 684,9 690,9 @@ module Dhall

		def map_subexpressions(&block)
			with(
				var: var,
				var:    var,
				assign: block[assign],
				type: type.nil? ? nil : block[type]
				type:   type.nil? ? nil : block[type]
			)
		end
	end


@@ 714,7 720,7 @@ module Dhall
		def map_subexpressions(&block)
			with(
				value: block[value],
				type: block[type]
				type:  block[type]
			)
		end
	end

M lib/dhall/binary.rb => lib/dhall/binary.rb +10 -10
@@ 34,7 34,7 @@ module Dhall
	class Application
		def self.decode(f, *args)
			new(
				function: Dhall.decode(f),
				function:  Dhall.decode(f),
				arguments: args.map(&Dhall.method(:decode))
			)
		end


@@ 44,7 44,7 @@ module Dhall
		def self.decode(var_or_type, type_or_body, body_or_nil=nil)
			if body_or_nil.nil?
				new(
					var: "_",
					var:  "_",
					type: Dhall.decode(var_or_type),
					body: Dhall.decode(type_or_body)
				)


@@ 52,7 52,7 @@ module Dhall
				raise ArgumentError, "explicit var named _" if var_or_type == "_"

				new(
					var: var_or_type,
					var:  var_or_type,
					type: Dhall.decode(type_or_body),
					body: Dhall.decode(body_or_nil)
				)


@@ 94,7 94,7 @@ module Dhall
			else
				Optional.new(
					value: Dhall.decode(value),
					type: type.nil? ? type : Dhall.decode(type)
					type:  type.nil? ? type : Dhall.decode(type)
				)
			end
		end


@@ 104,8 104,8 @@ module Dhall
		def self.decode(record, input, type=nil)
			new(
				record: Dhall.decode(record),
				input: Dhall.decode(input),
				type: type.nil? ? nil : Dhall.decode(type)
				input:  Dhall.decode(input),
				type:   type.nil? ? nil : Dhall.decode(type)
			)
		end
	end


@@ 155,8 155,8 @@ module Dhall
	class Union
		def self.decode(tag, value, alternatives)
			new(
				tag: tag,
				value: Dhall.decode(value),
				tag:          tag,
				value:        Dhall.decode(value),
				alternatives: UnionType.decode(alternatives)
			)
		end


@@ 166,8 166,8 @@ module Dhall
		def self.decode(pred, thn, els)
			new(
				predicate: Dhall.decode(pred),
				then: Dhall.decode(thn),
				else: Dhall.decode(els)
				then:      Dhall.decode(thn),
				else:      Dhall.decode(els)
			)
		end
	end

M lib/dhall/builtins.rb => lib/dhall/builtins.rb +9 -8
@@ 176,16 176,16 @@ module Dhall
				else
					arg.call(
						Application.new(
							function: Variable.new(name: "List"),
							function:  Variable.new(name: "List"),
							arguments: [@type]
						),
						Function.new(
							var: "_",
							var:  "_",
							type: @type,
							body: Function.new(
								var:  "_",
								type: Application.new(
									function: Variable.new(name: "List"),
									function:  Variable.new(name: "List"),
									arguments: [@type.shift(1, "_", 0)]
								),
								body: Operator::ListConcatenate.new(


@@ 194,7 194,7 @@ module Dhall
									),
									rhs: Variable.new(name: "_")
								)
							),
							)
						),
						EmptyList.new(type: @type)
					)


@@ 306,22 306,21 @@ module Dhall
				else
					arg.call(
						Application.new(
							function: Variable.new(name: "Optional"),
							function:  Variable.new(name: "Optional"),
							arguments: [@type]
						),
						Function.new(
							var: "_",
							var:  "_",
							type: @type,
							body: Optional.new(
								value: Variable.new(name: "_"),
								type: @type
								type:  @type
							)
						),
						OptionalNone.new(type: @type)
					)
				end
			end

		end

		class Optional_fold < Builtin


@@ 374,6 373,8 @@ module Dhall
			end
		end

		# rubocop:enable Style/ClassAndModuleCamelCase

		ALL = Hash[constants.map { |c| [c.to_s.tr("_", "/"), const_get(c)] }]
	end
end

M lib/dhall/normalize.rb => lib/dhall/normalize.rb +14 -11
@@ 22,6 22,7 @@ module Dhall
	class Application
		def normalize
			return fuse.normalize if fuse

			normalized = super
			return normalized.fuse if normalized.fuse



@@ 35,17 36,18 @@ module Dhall

		def fuse
			if function.is_a?(Application)
				@fused ||= function.function.fusion(*function.arguments, *arguments)
				return @fused if @fused
				@fuse ||= function.function.fusion(*function.arguments, *arguments)
				return @fuse if @fuse
			end

			@fused ||= function.fusion(*arguments)
			@fuse ||= function.fusion(*arguments)
		end
	end

	class Function
		def shift(amount, name, min_index)
			return super unless var == name

			with(
				type: type.shift(amount, name, min_index),
				body: body.shift(amount, name, min_index + 1)


@@ 71,6 73,7 @@ module Dhall
	class Variable
		def shift(amount, name, min_index)
			return self if self.name != name || min_index > index

			with(index: index + amount)
		end



@@ 130,7 133,7 @@ module Dhall
			def normalize
				normalized = super
				if [normalized.lhs, normalized.rhs]
				      .any? { |x| x == Natural.new(value: 0) }
				   .any? { |x| x == Natural.new(value: 0) }
					Natural.new(value: 0)
				elsif normalized.lhs == Natural.new(value: 1)
					normalized.rhs


@@ 258,8 261,8 @@ module Dhall

			normalized = with(
				predicate: pred,
				then: self.then.normalize,
				else: self.else.normalize
				then:      self.then.normalize,
				else:      self.else.normalize
			)

			if normalized.trivial?


@@ 312,20 315,20 @@ module Dhall
		end

		def desugar
			lets.reverse.reduce(body) { |inside, let|
			lets.reverse.reduce(body) do |inside, let|
				Application.new(
					function: Function.new(
						var: let.var,
					function:  Function.new(
						var:  let.var,
						type: let.type,
						body: inside
					),
					arguments: [let.assign]
				)
			}
			end
		end

		def shift(amount, name, min_index)
			desugar.shift(amont, name, min_index)
			desugar.shift(amount, name, min_index)
		end
	end


M test/test_normalization.rb => test/test_normalization.rb +16 -17
@@ 9,9 9,11 @@ require "dhall/normalize"

DIRPATH = Pathname.new(File.dirname(__FILE__))
UNIT = DIRPATH + "normalization/beta/"
STANDARD = DIRPATH + 'normalization/standard/'
STANDARD = DIRPATH + "normalization/standard/"

class TestParser < Minitest::Test
# Tests are not the place for abstractions, but for concretions
# rubocop:disable Metrics/MethodLength
class TestNormalization < Minitest::Test
	Pathname.glob(UNIT + "*A.dhallb").each do |path|
		test = path.basename("A.dhallb").to_s
		define_method("test_#{test}") do


@@ 23,12 25,13 @@ class TestParser < Minitest::Test
	end

	Pathname.glob(STANDARD + "**/*A.dhallb").each do |path|
		test = path.relative_path_from(STANDARD).to_s.sub(/A\.dhallb$/, '')
		test = path.relative_path_from(STANDARD).to_s.sub(/A\.dhallb$/, "")
		next if test =~ /prelude\//
		next if test =~ /remoteSystems/
		next if test =~ /constructorsId$/
		next if test =~ /multiline\//
		define_method("test_#{test.gsub(/\//, '_')}") do

		define_method("test_#{test.gsub(/\//, "_")}") do
			assert_equal(
				Dhall.from_binary(STANDARD + "#{test}B.dhallb"),
				Dhall.from_binary(path.read).normalize


@@ 65,29 68,24 @@ class TestParser < Minitest::Test
	end

	def test_shift_closed
		assert_equal(
			Dhall::Function.new(
				var: "x",
				type: Dhall::Variable.new(name: "Type"),
				body: Dhall::Variable.new(name: "x", index: 0)
			),
			Dhall::Function.new(
				var: "x",
				type: Dhall::Variable.new(name: "Type"),
				body: Dhall::Variable.new(name: "x", index: 0)
			).shift(1, "x", 0)
		expr = Dhall::Function.new(
			var:  "x",
			type: Dhall::Variable.new(name: "Type"),
			body: Dhall::Variable.new(name: "x", index: 0)
		)

		assert_equal(expr, expr.shift(1, "x", 0))
	end

	def test_shift_free
		assert_equal(
			Dhall::Function.new(
				var: "y",
				var:  "y",
				type: Dhall::Variable.new(name: "Type"),
				body: Dhall::Variable.new(name: "x", index: 1)
			),
			Dhall::Function.new(
				var: "y",
				var:  "y",
				type: Dhall::Variable.new(name: "Type"),
				body: Dhall::Variable.new(name: "x", index: 0)
			).shift(1, "x", 0)


@@ 124,3 122,4 @@ class TestParser < Minitest::Test
		)
	end
end
# rubocop:enable Metrics/MethodLength