Module: Atomy

Defined in:
lib/atomy.rb,
lib/atomy/errors.rb,
lib/atomy/locals.rb,
lib/atomy/method.rb,
lib/atomy/module.rb,
lib/atomy/parser.rb,
lib/atomy/pattern.rb,
lib/atomy/version.rb,
lib/atomy/code/nil.rb,
lib/atomy/compiler.rb,
lib/atomy/bootstrap.rb,
lib/atomy/code/list.rb,
lib/atomy/code/self.rb,
lib/atomy/code/send.rb,
lib/atomy/code/true.rb,
lib/atomy/code/block.rb,
lib/atomy/code/false.rb,
lib/atomy/code/quote.rb,
lib/atomy/code/assign.rb,
lib/atomy/code/define.rb,
lib/atomy/code/symbol.rb,
lib/atomy/code/integer.rb,
lib/atomy/code/pattern.rb,
lib/atomy/code/constant.rb,
lib/atomy/code/sequence.rb,
lib/atomy/code/variable.rb,
lib/atomy/code/undefined.rb,
lib/atomy/code/quasi_quote.rb,
lib/atomy/message_structure.rb,
lib/atomy/code/define_method.rb,
lib/atomy/code/class_variable.rb,
lib/atomy/code/string_literal.rb,
lib/atomy/code/define_function.rb,
lib/atomy/code/instance_variable.rb

Defined Under Namespace

Modules: BootstrapHelper, Code, Compiler, Parser Classes: EvalLocalState, Grammar, InconsistentArgumentForms, LocalState, MessageMismatch, MessageStructure, Method, Module, Pattern, PatternMismatch, UnknownCode, UnknownPattern

Constant Summary collapse

VERSION =
"0.7.1"
Bootstrap =
Atomy::Module.new do
  def expand(node)
    node.accept(NodeExpander.new(self)) || super
  end

  def pattern(node)
    node.accept(PatternExpander.new(self)) || super
  end

  def macro_definer(pattern, body)
    BootstrapHelper::WithGrammar.new(Atomy::Code::DefineMethod.new(:expand, body, nil, [pattern]))
  end

  def pattern_definer(pattern, body)
    BootstrapHelper::WithGrammar.new(Atomy::Code::DefineMethod.new(:pattern, body, nil, [pattern]))
  end

  def make_send(recv, msg, args = [])
    Atomy::Code::Send.new(recv, msg.text, args)
  end

  def make_constant(name, parent = nil)
    Atomy::Code::Constant.new(name, parent)
  end

  def make_sequence(nodes)
    Atomy::Grammar::AST::Sequence.new(nodes)
  end

  def make_quasiquote(node)
    Atomy::Grammar::AST::QuasiQuote.new(node)
  end

  private

  class NodeExpander
    def initialize(mod)
      @module = mod
    end

    def visit(node)
      structure = Atomy::MessageStructure.new(node)

      block = nil
      if block_arg = structure.block
        block = Atomy::Code::Block.new(
          Atomy::Code::Sequence.new(block_arg.body),
          block_arg.arguments,
          nil,
          false,
        )
      end

      Code::Send.new(
        structure.receiver,
        structure.name,
        structure.arguments,
        structure.splat_argument,
        structure.proc_argument,
        block,
      )
    rescue Atomy::MessageStructure::UnknownMessageStructure
    end

    def visit_stringliteral(node)
      Code::StringLiteral.new(node.value)
    end

    def visit_sequence(node)
      Code::Sequence.new(node.nodes)
    end

    def visit_list(node)
      Code::List.new(node.nodes)
    end

    def visit_word(node)
      case node.text
      when :self
        Code::Self.new
      else
        Code::Variable.new(node.text)
      end
    end

    def visit_constant(node)
      Code::Constant.new(node.text)
    end

    def visit_number(node)
      Code::Integer.new(node.value)
    end

    def visit_quote(node)
      Code::Quote.new(node.node)
    end

    def visit_quasiquote(node)
      Code::QuasiQuote.new(node.node)
    end
  end

  class PatternExpander
    def initialize(mod)
      @module = mod
    end

    def visit(_)
      nil
    end

    def visit_word(node)
      name = nil
      if node.text != :_
        name = node.text
      end

      Code::Pattern::Wildcard.new(name)
    end

    def visit_number(node)
      Code::Pattern.new(
        Code::Send.new(
          Code::Constant.new(
            :Equality,
            Code::Constant.new(
              :Pattern,
              Code::Constant.new(:Atomy))),
          :new,
          [node]))
    end

    def visit_quote(node)
      Code::Pattern.new(
        Code::Send.new(
          Code::Constant.new(
            :Equality,
            Code::Constant.new(
              :Pattern,
              Code::Constant.new(:Atomy))),
          :new,
          [node]))
    end

    def visit_quasiquote(node)
      Code::Pattern::QuasiQuote.new(node, @module)
    end

    def visit_prefix(node)
      if node.operator == :*
        Code::Pattern::Splat.new(@module.pattern(node.node))
      end
    end

    def visit_infix(node)
      if node.operator == :&
        Code::Pattern::And.new(@module.pattern(node.left), @module.pattern(node.right))
      end
    end

    def visit_constant(node)
      Code::Pattern.new(
        Code::Send.new(
          Code::Constant.new(
            :KindOf,
            Code::Constant.new(
              :Pattern,
              Code::Constant.new(:Atomy))),
          :new,
          [node]))
    end
  end
end

Class Method Summary collapse

Class Method Details

.define_branch(binding, name, branch) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/atomy.rb', line 21

def define_branch(binding, name, branch)
  target =
    if branch.receiver
      branch.receiver.target
    else
      binding.lexical_scope.for_method_definition
    end

  method, branch = register_branch(target, name, branch)

  if branch.name
    Rubinius.add_method(branch.name, branch.as_method, target, binding.lexical_scope, 0, :public)
  end

  Rubinius.add_method(name, method.build, target, binding.lexical_scope, 0, :public)
end

.register_branch(target, name, branch) ⇒ Object



14
15
16
17
18
19
# File 'lib/atomy.rb', line 14

def register_branch(target, name, branch)
  methods = target.atomy_methods
  method = methods[name] ||= Atomy::Method.new(name)
  branch = method.add_branch(branch)
  [method, branch]
end