From 1bddacedec62934c1a3c02a3e6f70ac8f0f31e9c Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Thu, 7 Mar 2019 20:27:38 -0500 Subject: [PATCH] First pass refactor --- lib/dhall/ast.rb | 99 ++++++++++++++++++++++++++++++++++++++++++ lib/dhall/normalize.rb | 64 +++++---------------------- 2 files changed, 109 insertions(+), 54 deletions(-) diff --git a/lib/dhall/ast.rb b/lib/dhall/ast.rb index 08cd4d6..2c54dee 100644 --- a/lib/dhall/ast.rb +++ b/lib/dhall/ast.rb @@ -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 diff --git a/lib/dhall/normalize.rb b/lib/dhall/normalize.rb index 435f90c..ed5e4ff 100644 --- a/lib/dhall/normalize.rb +++ b/lib/dhall/normalize.rb @@ -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 -- 2.38.5