module Klam::CompilationStages::SimplifyBooleanOperations

Simplify Boolean Operations

Kl defines four special forms for boolean operations: if, or, and, and cond. Having if or cond alone is sufficient for implementing the complete set. This compilation stages recasts or, and, and cond in terms of if.

Public Instance Methods

simplify_boolean_operations(sexp) click to toggle source
# File lib/klam/compilation_stages/simplify_boolean_operations.rb, line 9
def simplify_boolean_operations(sexp)
  if sexp.instance_of?(Array)
    case sexp[0]
    when :and
      simplify_and(sexp)
    when :cond
      simplify_cond(sexp)
    when :or
      simplify_or(sexp)
    else
      sexp.map { |form| simplify_boolean_operations(form) }
    end
  else
    sexp
  end
end

Private Instance Methods

simplify_and(sexp) click to toggle source
# File lib/klam/compilation_stages/simplify_boolean_operations.rb, line 28
def simplify_and(sexp)
  # Only convert the fully-applied case
  if sexp.length == 3
    _, expr1, expr2 = sexp
    expr1 = simplify_boolean_operations(expr1)
    expr2 = simplify_boolean_operations(expr2)

    [:if, expr1, expr2, false]
  else
    sexp.map { |form| simplify_boolean_operations(form) }
  end
end
simplify_cond(sexp) click to toggle source
# File lib/klam/compilation_stages/simplify_boolean_operations.rb, line 41
def simplify_cond(sexp)
  # Cond expressions are of the form:
  #   (cond (Test1 Expr1) ... (TestN ExprN))
  clauses = sexp[1..-1]
  simplify_cond_clauses(clauses)
end
simplify_cond_clauses(clauses) click to toggle source
# File lib/klam/compilation_stages/simplify_boolean_operations.rb, line 48
def simplify_cond_clauses(clauses)
  if clauses.empty?
    # An error is raised if none of the clauses match.
    [:"simple-error", 'cond failure']
  else
    test, expr = clauses[0]
    test = simplify_boolean_operations(test)
    expr = simplify_boolean_operations(expr)
    [:if, test, expr, simplify_cond_clauses(clauses[1..-1])]
  end
end
simplify_or(sexp) click to toggle source
# File lib/klam/compilation_stages/simplify_boolean_operations.rb, line 60
def simplify_or(sexp)
  # Only convert the fully-applied case
  if sexp.length == 3
    _, expr1, expr2 = sexp
    expr1 = simplify_boolean_operations(expr1)
    expr2 = simplify_boolean_operations(expr2)

    [:if, expr1, true, expr2]
  else
    sexp.map { |form| simplify_boolean_operations(form) }
  end
end