Skip to content

Instantly share code, notes, and snippets.

@baroquebobcat
Created September 21, 2012 01:55
Show Gist options
  • Select an option

  • Save baroquebobcat/3759358 to your computer and use it in GitHub Desktop.

Select an option

Save baroquebobcat/3759358 to your computer and use it in GitHub Desktop.
Mirah Code Reading Notes

Looking at this https://github.com/mirah/mirah/compare/2875d54b68...6fa6472b90

What's a binding_type? It is the "Type" of the binding generated to mush shared state into a closure.

Here's something interesting https://github.com/mirah/mirah/blob/6fa6472b90cbf9b7345dfbae65b2648d5c787ace/src/org/mirah/typer/closures.mirah#L124

  def build_constructor(enclosing_body:NodeList, klass:ClassDefinition, parent_scope:Scope):void
    parent_scope.binding_type ||= begin
      binding_klass = build_class(klass.position, nil)
      enclosing_body.insert(0, binding_klass)
      @typer.infer(binding_klass, true).resolve
    end
    binding_type_name = makeTypeName(klass.position, parent_scope.binding_type)
    args = Arguments.new(klass.position, [RequiredArgument.new(SimpleString.new('binding'), binding_type_name)],
                         Collections.emptyList, nil, Collections.emptyList, nil)
    body = FieldAssign.new(SimpleString.new('binding'), LocalAccess.new(SimpleString.new('binding')), nil)
    constructor = ConstructorDefinition.new(SimpleString.new('initialize'), args, SimpleString.new('void'), [body], nil)
    klass.body.add(constructor)
  end

What it looks like this does is:

    parent_scope.binding_type ||= begin
      binding_klass = build_class(klass.position, nil)
      enclosing_body.insert(0, binding_klass)
      @typer.infer(binding_klass, true).resolve
    end

set the binding type for the parent scope (the scope of the closure class in this case) if it doesn't already exist. It does this by generating a class for it at the position that klass was generated at. It then inserts that as a node in the enclosing_body whatever that is. I'm guessing it's probably the body of the outer class. Then it runs the inference engine to get a type for it.

enclosing_body is a MethodDefinition's body, or a Script's body. Hmm, Why not Zoidberg^H^H^H a class? https://github.com/mirah/mirah/blob/6fa6472b90cbf9b7345dfbae65b2648d5c787ace/src/org/mirah/typer/closures.mirah#L35

    enclosing_node = block.findAncestor {|node| node.kind_of?(MethodDefinition) || node.kind_of?(Script)}
    enclosing_body = if enclosing_node.kind_of?(MethodDefinition)
      MethodDefinition(enclosing_node).body
    else
      Script(enclosing_node).body
    end

The file has a TODO in it to clean it up. Maybe that'd be a good entrance into the new code base.

I don't get why this change is necessary. I don't doubt it is, I just don't know why. https://github.com/mirah/mirah/compare/2875d54b68...6fa6472b90#L5R36

  def parent=(parent:LocalFuture)
    @parent = parent
    parent.addChild(self)
+    me = self
+    parent.onUpdate do |x, resolved|
+      me.resolved(resolved)
+    end
    checkAssignments
  end

This is ugly https://github.com/mirah/mirah/compare/2875d54b68...6fa6472b90#L7L53

class SimpleScoper; implements Scoper
  def initialize
    @scopes = {}
  end
  def initialize(factory:ScopeFactory)
    @factory = factory
    @scopes = {}
  end
  def getScope(node)
    orig = node
    until node.parent.nil? # truthyness would make this nicer, maybe better would be to have this encapsulated somehow.
      node = node.parent
      scope = Scope(@scopes[node])
      return scope if scope 
    end
    Scope(@scopes[node]) || addScope(node)
  end
  def getIntroducedScope(node:Node)
    Scope(@scopes[node])
  end
  def addScope(node)
    Scope(@scopes[node]) || begin
      scope = if @factory   # a null object would be nice to avoid this
        @factory.newScope(self, node)
      else
        SimpleScope.new
      end
      @scopes[node] = scope
      scope
    end
  end
  def copyScopeFrom(from, to)
    @scopes[to] = getScope(from)
  end
end

On an unrelated Repo,

god I want a proper case statement.

https://github.com/anthonymoralez/hello-android-sudoku/blob/master/src/com/example/sudoku/Sudoku.mirah#L49

  def onClick(v)
    view_id = v.getId
    if (view_id == R.id.about_button) 
      startActivity(Intent.new(self, About.class))
    elsif (view_id == R.id.continue_button)
      startGame(getResources.getInteger(R.integer.continue_difficutly))
    elsif (view_id == R.id.new_game_button) 
      openNewGameDialog
    elsif (view_id == R.id.exit_button) 
      finish
    end
  end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment