Sha256: 9a31302a85ec022c94c7a2aea341afb28027e823a1caa8e4dc7e7feb52bf5495

Contents?: true

Size: 1.77 KB

Versions: 1

Compression:

Stored size: 1.77 KB

Contents

require 'dry/core/constants'

require 'dry/logic/rule'
require 'dry/logic/rule/predicate'

module Dry
  module Logic
    class RuleCompiler
      include Core::Constants

      attr_reader :predicates

      def initialize(predicates)
        @predicates = predicates
      end

      def call(ast)
        ast.map { |node| visit(node) }
      end

      def visit(node)
        name, nodes = node
        send(:"visit_#{name}", nodes)
      end

      def visit_check(node)
        keys, predicate = node
        Operations::Check.new(visit(predicate), keys: keys)
      end

      def visit_not(node)
        Operations::Negation.new(visit(node))
      end

      def visit_key(node)
        name, predicate = node
        Operations::Key.new(visit(predicate), name: name)
      end

      def visit_attr(node)
        name, predicate = node
        Operations::Attr.new(visit(predicate), name: name)
      end

      def visit_set(node)
        Operations::Set.new(*call(node))
      end

      def visit_each(node)
        Operations::Each.new(visit(node))
      end

      def visit_predicate(node)
        name, params = node
        predicate = Rule::Predicate.new(predicates[name])

        if params.size > 1
          args = params.map(&:last).reject { |val| val == Undefined }
          predicate.curry(*args)
        else
          predicate
        end
      end

      def visit_and(node)
        left, right = node
        visit(left).and(visit(right))
      end

      def visit_or(node)
        left, right = node
        visit(left).or(visit(right))
      end

      def visit_xor(node)
        left, right = node
        visit(left).xor(visit(right))
      end

      def visit_implication(node)
        left, right = node
        visit(left).then(visit(right))
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
dry-logic-0.5.0 lib/dry/logic/rule_compiler.rb