class Dentaku::AST::FunctionRegistry
def self.arity
def self.arity @implementation.arity < 0 ? nil : @implementation.arity end
def self.default
def self.default Dentaku::AST::Function.registry end
def self.implementation
def self.implementation @implementation end
def self.implementation=(impl)
def self.implementation=(impl) @implementation = impl end
def self.max_param_count
def self.max_param_count @implementation.parameters.select { |type, _name| type == :rest }.any? ? Float::INFINITY : @implementation.parameters.count end
def self.min_param_count
def self.min_param_count @implementation.parameters.select { |type, _name| type == :req }.count end
def self.name
def self.name @name end
def self.name=(name)
def self.name=(name) @name = name end
def self.type
def self.type @type end
def self.type=(type)
def self.type=(type) @type = type end
def default
def default self.class.default end
def define_class(function_name, function)
def define_class(function_name, function) class_name = normalize_name(function_name) return if Dentaku::AST::Function.const_defined?(class_name) Dentaku::AST::Function.const_set(class_name, function) end
def function_name(name)
def function_name(name) name.to_s.downcase end
def get(name)
def get(name) name = function_name(name) return self[name] if has_key?(name) return default[name] if default.has_key?(name) nil end
def normalize_name(function_name)
def normalize_name(function_name) function_name.to_s.capitalize.gsub(/\W/, '_') end
def register(name, type, implementation)
def register(name, type, implementation) function = Class.new(Function) do def self.name=(name) @name = name end def self.name @name end 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 self.arity @implementation.arity < 0 ? nil : @implementation.arity end def self.min_param_count @implementation.parameters.select { |type, _name| type == :req }.count end def self.max_param_count @implementation.parameters.select { |type, _name| type == :rest }.any? ? Float::INFINITY : @implementation.parameters.count end def value(context = {}) args = @args.map { |a| a.value(context) } self.class.implementation.call(*args) end def type self.class.type end end define_class(name, function) function.name = name function.type = type function.implementation = implementation self[function_name(name)] = function end
def register_class(name, function_class)
def register_class(name, function_class) self[function_name(name)] = function_class end
def type
def type self.class.type end
def value(context = {})
def value(context = {}) args = @args.map { |a| a.value(context) } self.class.implementation.call(*args) end