Module: Myco

Defined in:
lib/myco/eval.rb,
lib/myco/misc.rb,
lib/myco/version.rb,
lib/myco/code_loader.rb,
lib/myco/dev/counter.rb,
lib/myco/dev/profile.rb,
lib/myco/bootstrap/meme.rb,
lib/myco/bootstrap/void.rb,
lib/myco/dev/call_sites.rb,
lib/myco/bootstrap/tuple.rb,
lib/myco/bootstrap/instance.rb,
lib/myco/bootstrap/component.rb,
lib/myco/bootstrap/undefined.rb,
lib/myco/bootstrap/add_method.rb,
lib/myco/bootstrap/empty_object.rb,
lib/myco/bootstrap/file_toplevel.rb,
lib/myco/bootstrap/find_constant.rb

Defined Under Namespace

Modules: Component, DEV, InstanceMethods, MemeBindable, PrimitiveInstanceMethods Classes: Backtrace, CodeLoader, ConstantReference, Meme, VoidClass

Constant Summary collapse

MYCO_VERSION =
'0.1.10'
MYCO_REQUIRED_GEMS =
[
  ['rubinius-toolset',  '~> 2.3'],
  ['rubinius-compiler', '~> 2.2'],
]
Void =
VoidClass.new
Instance =
Class.new nil do
  include InstanceMethods
  
  # These are not included in InstanceMethods because they should not shadow
  # existing method definitions when extended into an existing object. 
  
  def method_missing name, *args
    msg = "#{to_s} has no method called '#{name}'"
    ::Kernel.raise ::NoMethodError.new(msg, name, args)
  end
  
  def to_s
    "#<#{__component__.to_s}>"
  end
  
  def inspect(pretty: true)
    vars = __ivar_names__.map { |var|
      [var.to_s[1..-1], __get_ivar__(var).inspect].join(": ")
    }
    
    vars = if vars.empty?
      ""
    elsif vars.size == 1
      vars.first
    elsif !pretty
      vars.join(", ")
    else
      "\n  " + vars.join("\n").gsub("\n", "\n  ") + "\n"
    end
    
    "#{__component__.to_s}#(#{vars})"
  end
  
  alias_method :hash,   :__hash__   # TODO: remove?
  alias_method :equal?, :__equal__  # TODO: remove?
  alias_method :==,     :__equal__  # TODO: remove?
  
  def != other
    self == other ? false : true
  end
  
  alias_method :"!", :false?
end
EmptyObject =
Component.new
FileToplevel =

This empty, barebones component will be replaced after bootstrapping.

Component.new
SingletonClass =
Myco.singleton_class

Class Method Summary collapse

Class Method Details

.activate_required_gemsObject

TODO: move elsewhere?



11
12
13
14
15
# File 'lib/myco/version.rb', line 11

def self.activate_required_gems
  MYCO_REQUIRED_GEMS.each do |name, version|
    gem name, version
  end
end

.add_dynamic_method(mod, name, file = "(dynamic)", line = 1) {|g| ... } ⇒ Object

Use instead of Module#dynamic_method

Yields:

  • (g)


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

def self.add_dynamic_method mod, name, file="(dynamic)", line=1
  g = Rubinius::ToolSets::Runtime::Generator.new
  g.name = name.to_sym
  g.file = file.to_sym
  g.set_line Integer(line)

  yield g

  g.close
  g.use_detected
  g.encode

  code = g.package Rubinius::CompiledCode
  cscope = Rubinius::ConstantScope.new(mod, Rubinius::ConstantScope.new(Myco))

  add_method(mod, name, code, cscope)
end

.add_method(mod, name, executable, cscope) ⇒ Object

In Myco, try to always use Myco.add_method instead of Rubinius.add_method to bypass all of the Ruby-specific logic therein.



6
7
8
9
# File 'lib/myco/bootstrap/add_method.rb', line 6

def self.add_method mod, name, executable, cscope
  mod.method_table.store(name, nil, executable, cscope, 0, :public)
  Rubinius::VM.reset_method_cache(mod, name)
end

.add_thunk_method(mod, name, value) ⇒ Object

Use instead of Module#thunk_method



16
17
18
# File 'lib/myco/bootstrap/add_method.rb', line 16

def self.add_thunk_method mod, name, value
  add_method(mod, name, Rubinius::Thunk.new(value), nil)
end

.branch_op(type, left) ⇒ Object

Logical branching operator with lazy evaluation of right hand



5
6
7
8
9
10
11
12
13
14
# File 'lib/myco/misc.rb', line 5

def self.branch_op type, left
  case type
  when :"&&"; return left if left.false?
  when :"||"; return left unless left.false?
  when :"??"; return left unless left.void?
  when :"&?"; return ::Myco::Void if left.false?
  when :"|?"; return ::Myco::Void unless left.false?
  end
  return yield # evaluate and return right hand
end

.cscopeObject

Get the “current” ConstantScope (from the caller’s perspective)



131
132
133
# File 'lib/myco/bootstrap/find_constant.rb', line 131

def self.cscope
  Rubinius::ConstantScope.of_sender
end

.eval(string, call_depth: 1) ⇒ Object

TODO: deprecate with proper import set of functions



5
6
7
8
9
10
# File 'lib/myco/eval.rb', line 5

def self.eval string, call_depth:1
  loader = Myco::CodeLoader::MycoLoader.new("(eval)")
  loader.bind_to(call_depth: call_depth + 1)
  loader.string = string
  loader.load
end

.eval_file(path, load_paths = nil, get_last = true, scope = Rubinius::ConstantScope.new(::Myco, nil)) ⇒ Object

TODO: deprecate with proper import set of functions



13
14
15
16
17
# File 'lib/myco/eval.rb', line 13

def self.eval_file path, load_paths=nil, get_last=true, scope=Rubinius::ConstantScope.new(::Myco, nil)
  load_paths ||= [File.dirname(Rubinius::VM.backtrace(1).first.file)]
  file_toplevel = CodeLoader.load(path, load_paths, cscope:scope, call_depth:1)
  get_last ? file_toplevel.component.__last__ : file_toplevel.component
end

.find_constant(name, scope = Rubinius::ConstantScope.of_sender) ⇒ Object



135
136
137
# File 'lib/myco/bootstrap/find_constant.rb', line 135

def self.find_constant(name, scope=Rubinius::ConstantScope.of_sender)
  scope.get_myco_constant_ref(name).value
end

.rescueObject

TODO: replace backtrace in a different way, without this hack



20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/myco/eval.rb', line 20

def self.rescue
  begin
    yield
  rescue Exception=>e
    unless e.is_a? SystemExit
      puts e.awesome_backtrace.show
      puts e.awesome_backtrace.first_color + e.message + "\033[0m"
      puts
      exit(1)
    end
  end
end

.tuple(*ary) ⇒ Object



9
10
11
# File 'lib/myco/bootstrap/tuple.rb', line 9

def tuple(*ary)
  ary.__tuple__
end