Class: Kapusta::Compiler::MacroLowerer

Inherits:
Object
  • Object
show all
Defined in:
lib/kapusta/compiler/macro_lowerer.rb

Constant Summary collapse

FN_HEADS =
%w[fn lambda λ].freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(error_class:) ⇒ MacroLowerer

Returns a new instance of MacroLowerer.



20
21
22
23
# File 'lib/kapusta/compiler/macro_lowerer.rb', line 20

def initialize(error_class:)
  @error_class = error_class
  @gensyms = {}
end

Class Method Details

.compile(params:, body:, path:, error_class:) ⇒ Object



10
11
12
13
14
# File 'lib/kapusta/compiler/macro_lowerer.rb', line 10

def self.compile(params:, body:, path:, error_class:)
  callable = new(error_class:).callable_form(params, body)
  ruby = Compiler.compile_forms([callable], path:)
  TOPLEVEL_BINDING.eval(ruby, path, 1)
end

.lower_module_form(form, error_class:) ⇒ Object



16
17
18
# File 'lib/kapusta/compiler/macro_lowerer.rb', line 16

def self.lower_module_form(form, error_class:)
  new(error_class:).lower_module_form(form)
end

Instance Method Details

#callable_form(params, body) ⇒ Object



25
26
27
# File 'lib/kapusta/compiler/macro_lowerer.rb', line 25

def callable_form(params, body)
  List.new([Sym.new('fn'), params, *lowered_body_with_gensyms(body)])
end

#lower(form) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/kapusta/compiler/macro_lowerer.rb', line 35

def lower(form)
  case form
  when Quasiquote then copy_position(lower_quasi(form.form), form)
  when Unquote, UnquoteSplice
    raise @error_class, Kapusta::Errors.format(:unquote_outside_quasiquote)
  when AutoGensym
    raise @error_class, Kapusta::Errors.format(:auto_gensym_outside_quasiquote, name: form.name)
  when List then copy_position(List.new(form.items.map { |item| lower(item) }), form)
  when Vec then copy_position(Vec.new(form.items.map { |item| lower(item) }), form)
  when HashLit
    copy_position(
      HashLit.new(form.entries.map do |entry|
        entry.is_a?(Array) ? [lower(entry[0]), lower(entry[1])] : entry
      end),
      form
    )
  else
    form
  end
end

#lower_module_form(form) ⇒ Object



29
30
31
32
33
# File 'lib/kapusta/compiler/macro_lowerer.rb', line 29

def lower_module_form(form)
  return lower_fn_form(form) if fn_form?(form)

  lower(form)
end