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)
endWhat 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
endThe 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
endThis 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
god I want a proper case statement.
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