summaryrefslogtreecommitdiff
path: root/deployment_scripts/puppet/files/embedded/lib/ruby/gems/2.3.0/gems/dentaku-2.0.9/lib/dentaku/ast/function.rb
blob: 2f1b82a2b31ab72ceace43d2d826e183e31347d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
require_relative 'node'

module Dentaku
  module AST
    class Function < Node
      def initialize(*args)
        @args = args
      end

      def dependencies(context={})
        @args.flat_map { |a| a.dependencies(context) }
      end

      def self.get(name)
        registry.fetch(function_name(name)) {
          fail ParseError, "Undefined function #{ name }"
        }
      end

      def self.register(name, type, implementation)
        function = Class.new(self) do
          def self.implementation=(impl)
            @implementation = impl
          end

          def self.implementation
            @implementation
          end

          def self.type=(type)
            @type = type
          end

          def self.type
            @type
          end

          def value(context={})
            args = @args.map { |a| a.value(context) }
            self.class.implementation.call(*args)
          end

          def type
            self.class.type
          end
        end

        function_class = name.to_s.capitalize
        Dentaku::AST.send(:remove_const, function_class) if Dentaku::AST.const_defined?(function_class)
        Dentaku::AST.const_set(function_class, function)

        function.implementation = implementation
        function.type = type

        registry[function_name(name)] = function
      end

      def self.register_class(name, function_class)
        registry[function_name(name)] = function_class
      end

      private

      def self.function_name(name)
        name.to_s.downcase
      end

      def self.registry
        @registry ||= {}
      end
    end
  end
end