~singpolyma/dhall-ruby

1bddacedec62934c1a3c02a3e6f70ac8f0f31e9c — Stephen Paul Weber 4 years ago d153b88
First pass refactor
2 files changed, 109 insertions(+), 54 deletions(-)

M lib/dhall/ast.rb
M lib/dhall/normalize.rb
M lib/dhall/ast.rb => lib/dhall/ast.rb +99 -0
@@ 20,6 20,57 @@ module Dhall
		def to_proc
			method(:call).to_proc
		end

		def +(other)
			Operator::Plus.new(lhs: self, rhs: other)
		end

		def *(other)
			Operator::Times.new(lhs: self, rhs: other)
		end

		def <<(other)
			Operator::TextConcatenate.new(lhs: self, rhs: other)
		end

		def concat(other)
			case other
			when EmptyList
				self
			else
				Operator::ListConcatenate.new(lhs: self, rhs: other)
			end
		end

		def &(other)
			if self == other
				self
			elsif other.is_a?(Bool)
				other & self
			else
				Operator::And.new(lhs: self, rhs: other)
			end
		end

		def |(other)
			if self == other
				self
			elsif other.is_a?(Bool)
				other | self
			else
				Operator::Or.new(lhs: self, rhs: other)
			end
		end

		def dhall_eq(other)
			if self == other
				Bool.new(value: true)
			elsif other.is_a?(Bool)
				other.dhall_eq(self)
			else
				Operator::Equal.new(lhs: self, rhs: other)
			end
		end
	end

	class Application < Expression


@@ 55,6 106,18 @@ module Dhall
		def reduce(when_true, when_false)
			value ? when_true : when_false
		end

		def &(other)
			reduce(other, with(value: false))
		end

		def |(other)
			reduce(with(value: true), other)
		end

		def dhall_eq(other)
			reduce(other, super)
		end
	end

	class Variable < Expression


@@ 124,6 187,14 @@ module Dhall
		def reverse
			with(elements: elements.reverse)
		end

		def concat(other)
			if other.is_a?(List) && !other.is_a?(EmptyList)
				with(elements: elements + other.elements)
			else
				super
			end
		end
	end

	class EmptyList < List


@@ 158,6 229,10 @@ module Dhall
		def reverse
			self
		end

		def concat(other)
			other
		end
	end

	class Optional < Expression


@@ 320,6 395,22 @@ module Dhall
			value (0..Float::INFINITY)
		end)

		def +(other)
			if other.is_a?(Natural)
				with(value: value + other.value)
			else
				super
			end
		end

		def *(other)
			if other.is_a?(Natural)
				with(value: value * other.value)
			else
				super
			end
		end

		def to_s
			value.to_s
		end


@@ 357,6 448,14 @@ module Dhall
		include(ValueSemantics.for_attributes do
			value ::String
		end)

		def <<(other)
			if other.is_a?(Text)
				with(value: value + other.value)
			else
				super
			end
		end
	end

	class TextLiteral < Expression

M lib/dhall/normalize.rb => lib/dhall/normalize.rb +10 -54
@@ 48,46 48,19 @@ module Dhall
	class Operator
		class Or
			def normalize
				normalized = super
				if normalized.lhs.is_a?(Bool)
					normalized.lhs.reduce(Bool.new(value: true), normalized.rhs)
				elsif normalized.rhs.is_a?(Bool)
					normalized.rhs.reduce(Bool.new(value: true), normalized.lhs)
				elsif normalized.lhs == normalized.rhs
					normalized.lhs
				else
					normalized
				end
				lhs.normalize | rhs.normalize
			end
		end

		class And
			def normalize
				normalized = super
				if normalized.lhs.is_a?(Bool)
					normalized.lhs.reduce(normalized.rhs, Bool.new(value: false))
				elsif normalized.rhs.is_a?(Bool)
					normalized.rhs.reduce(normalized.lhs, Bool.new(value: false))
				elsif normalized.lhs == normalized.rhs
					normalized.lhs
				else
					normalized
				end
				lhs.normalize & rhs.normalize
			end
		end

		class Equal
			def normalize
				normalized = super
				if normalized.lhs == Bool.new(value: true)
					normalized.rhs
				elsif normalized.rhs == Bool.new(value: true)
					normalized.lhs
				elsif normalized.lhs == normalized.rhs
					Bool.new(value: true)
				else
					normalized
				end
				lhs.normalize.dhall_eq(rhs.normalize)
			end
		end



@@ 109,14 82,12 @@ module Dhall
		class Plus
			def normalize
				normalized = super
				if [normalized.lhs, normalized.rhs].all? { |x| x.is_a?(Natural) }
					Natural.new(value: normalized.lhs.value + normalized.rhs.value)
				elsif normalized.lhs == Natural.new(value: 0)
				if normalized.lhs == Natural.new(value: 0)
					normalized.rhs
				elsif normalized.rhs == Natural.new(value: 0)
					normalized.lhs
				else
					normalized
					normalized.lhs + normalized.rhs
				end
			end
		end


@@ 124,9 95,7 @@ module Dhall
		class Times
			def normalize
				normalized = super
				if [normalized.lhs, normalized.rhs].all? { |x| x.is_a?(Natural) }
					Natural.new(value: normalized.lhs.value * normalized.rhs.value)
				elsif [normalized.lhs, normalized.rhs]
				if [normalized.lhs, normalized.rhs]
				      .any? { |x| x == Natural.new(value: 0) }
					Natural.new(value: 0)
				elsif normalized.lhs == Natural.new(value: 1)


@@ 134,7 103,7 @@ module Dhall
				elsif normalized.rhs == Natural.new(value: 1)
					normalized.lhs
				else
					normalized
					normalized.lhs * normalized.rhs
				end
			end
		end


@@ 142,32 111,19 @@ module Dhall
		class TextConcatenate
			def normalize
				normalized = super
				if [normalized.lhs, normalized.rhs].all? { |x| x.is_a?(Text) }
					Text.new(value: normalized.lhs.value + normalized.rhs.value)
				elsif normalized.lhs == Text.new(value: "")
				if normalized.lhs == Text.new(value: "")
					normalized.rhs
				elsif normalized.rhs == Text.new(value: "")
					normalized.lhs
				else
					normalized
					normalized.lhs << normalized.rhs
				end
			end
		end

		class ListConcatenate
			def normalize
				normalized = super
				if [normalized.lhs, normalized.rhs].all? { |x| x.is_a?(List) }
					List.new(
						elements: normalized.lhs.elements + normalized.rhs.elements
					)
				elsif normalized.lhs.is_a?(EmptyList)
					normalized.rhs
				elsif normalized.rhs.is_a?(EmptyList)
					normalized.lhs
				else
					normalized
				end
				lhs.normalize.concat(rhs.normalize)
			end
		end
	end