module Klam::CompilationStages::ConstantizeConstructedConstants

Public Instance Methods

constantize_constructed_constants(sexp) click to toggle source
# File lib/klam/compilation_stages/constantize_constructed_constants.rb, line 4
def constantize_constructed_constants(sexp)
  constant_bindings = []
  converted_sexp = extract_constructed_constants(sexp, constant_bindings)
  if constant_bindings.empty?
    sexp
  else
    bind_constants(converted_sexp, constant_bindings)
  end
end

Private Instance Methods

bind_constants(sexp, bindings) click to toggle source
# File lib/klam/compilation_stages/constantize_constructed_constants.rb, line 39
def bind_constants(sexp, bindings)
  if sexp.kind_of?(Array) && sexp[0] == :defun
    sexp[0] = :"[DEFUN-CLOSURE]"
  end

  until bindings.empty?
    binding = bindings.pop
    sexp = [:let, binding[0], binding[1], sexp]
  end
  sexp
end
constant?(sexp) click to toggle source
# File lib/klam/compilation_stages/constantize_constructed_constants.rb, line 51
def constant?(sexp)
  case sexp
  when FalseClass, TrueClass, String, Symbol, Numeric, Klam::Constant
    true
  when []
    true
  else
    false
  end
end
extract_constructed_constants(sexp, constant_bindings) click to toggle source
# File lib/klam/compilation_stages/constantize_constructed_constants.rb, line 16
def extract_constructed_constants(sexp, constant_bindings)
  if sexp.kind_of?(Array)
    if sexp.size == 3 && sexp[0] == :cons
      hd_expr = extract_constructed_constants(sexp[1], constant_bindings)
      tl_expr = extract_constructed_constants(sexp[2], constant_bindings)
      converted_cons = [:cons, hd_expr, tl_expr]
      if constant?(hd_expr) && constant?(tl_expr)
        const = fresh_constant
        constant_bindings << [const, converted_cons]
        const
      else
        converted_cons
      end
    else
      sexp.map do |expr|
        extract_constructed_constants(expr, constant_bindings)
      end
    end
  else
    sexp
  end
end