Sha256: 462ac4bc63465322daf9d0c0a15050b315f3194c80ef44e284579525e2b37369

Contents?: true

Size: 1.99 KB

Versions: 5

Compression:

Stored size: 1.99 KB

Contents

require 'tsort'
module Alf
  class Compiler
    class Plan

      def initialize(compiler = Compiler.new)
        @parser        = Lang::Parser::Lispy.new
        @compilers     = {}
        @compiled      = {}
        @usage_count   = Hash.new{|h,k| h[k] = 0 }
        @main_compiler = compiler
        join(compiler)
      end
      attr_reader :parser, :main_compiler

      def join(compiler)
        @compilers[compiler] ||= compiler.join(self)
        compiler
      end

      def options(compiler)
        @compilers[compiler]
      end

      # Pre-visit
      def compile(sexpr)
        visit(sexpr)
        _compile(sexpr)
      end

      # Post-visit, pre-reuse
      def _compile(expr)
        compiled = @compiled[expr]
        return @compiled[expr] = __compile(expr) unless compiled
        return __compile(expr) unless compiler = compiled.compiler
        return __compile(expr) unless compiler.supports_reuse?
        compiler.reuse(self, compiled)
      end

      # Real compilation, post-reuse
      def __compile(expr = nil, compiled = nil, &bl)
        expr      ||= bl.call(parser)
        compiled  ||= children(expr).map{|op| _compile(op) }
        compiler    = compiler(compiled)
        usage_count = @usage_count[expr]
        compiler.compile(self, expr, compiled, usage_count)
      rescue NotSupportedError
        main_compiler.compile(self, expr, compiled, usage_count)
      end

      def recompile(*compiled, &bl)
        __compile(nil, compiled, &bl)
      end

      def visit(expr)
        @usage_count[expr] += 1
        children(expr).each{|op| visit(op) }
      end

    private

      EMPTY_CHILDREN = []

      def children(expr)
        return EMPTY_CHILDREN unless expr.is_a?(Algebra::Operator)
        expr.operands
      end

      def compiler(compiled)
        candidates = compiled.map(&:compiler).uniq
        candidates.size > 1 ? main_compiler \
                            : candidates.first || main_compiler
      end

    end # class Plan
  end # class Compiler
end # module Alf

Version data entries

5 entries across 5 versions & 1 rubygems

Version Path
alf-core-0.16.3 lib/alf/compiler/plan.rb
alf-core-0.16.2 lib/alf/compiler/plan.rb
alf-core-0.16.1 lib/alf/compiler/plan.rb
alf-core-0.16.0 lib/alf/compiler/plan.rb
alf-core-0.15.0 lib/alf/compiler/plan.rb