def call(self, *args): '''evaluate the content of the function with the passed args mapped to the function's args. returns simplified object''' # create a scope for the call call_scope = Let() if self.parent: self.parent.reparent(call_scope) # to make lexical scope work call_scope.put(copy(self.child)) # load args into the call's scope arg_map = Map() if len(self.args) != len(args): raise fern.errors.SemanticError('calling function with %d arguments, should be %d' % (len(args), len(self.args))) for k, v in zip(self.args, args): arg_map.put(KVPair(k, v)) call_scope.names = arg_map return call_scope.eval()
def start(self): # Start time func-s funcs = {'fade': Enduring.I} Enduring.__init__(self, Act.secFading, funcs) self.fade = 1.0 debug('eat', 'init Fading. abs:', self.act.abs) # Nodes of Redex abs = self.act.abs appl = self.act.appl # Replace Redex (Appl and Abs) with new created Let let = Let(be=None, expr=None) appl.subst(let) let.be = appl.arg let.expr = appl.func abs.subst(abs.expr) # let.expr.replace( {abs: let} ) -- # Do not reref to Let. Else we will go through let-bound vars at down.bubblesDraw() for eating in self.act.eatings: debug('eat', '\nFading: eating', eating.appl) # Get Noke of new Let letnoke = Noke(let, eating.appl.key) debug('eat', 'init Fading. let:', letnoke) self.act.letnoke = letnoke # Save last Let to Act # Save Abs-Bubble to Let Noke for Fading absbubble = eating.abs() absbubble.fading = self letnoke.set(absbubble) self.faded.append(letnoke) debug('eat', 'Abs-Bubble saved to Let:', letnoke(), letnoke().group) # Prepare Eaten # Det Cover Transformation (Lambda Bubble covers Eaten Bubbles) absbubbleTransform = TransformMatrix(ring=absbubble.ring) lens = TransformMatrix() lens.setTranspose(0, 0, Figure.holeLens) # Lens-effect in Hole cover = (absbubbleTransform * lens).inverse() # Transform all eaten Bubbles, as they are in Hole, not in Group for b in eating.eaten: bubble = b() bubble.ring = bubble.ring.transform(cover) # Redet position bubble.group = None debug('eat', 'eaten transformed and ungrouped', eating.eaten) # Descend def descent(noke, group, matrix): # If 'noke' has Bubble, Bubble.ring already set. debug('eat', 'descend:', noke) if APPL == noke.node.type: # Group inside some Lambda, 'matrix' must be None debug('eat', 'appl found', noke) group = noke.group() for b in noke.bubblesDraw(): # b().ring stays on its place matrix = TransformMatrix(ring=b().ring) descent( b, group, matrix ) # Pass matrix, because there inside fading vars may be bubbles of this group elif ABS == noke.node.type: noke = noke['expr'].through( ) # Noke inside Abs - no position needed descent(noke, None, None) elif VAR == noke.node.type and abs == noke.node.ref: # Mark Bubble as fading bubble = noke() if not bubble: # This Var may be inside Lambda and do not have 'bubble' bubble = Bubble() # Create Bubble without 'group' noke.set(bubble) bubble.fading = self self.faded.append(noke) debug('eat', 'it s hole. added to faded:', self.faded) if not matrix: matrix = TransformMatrix() matrix.unit() # Copy eaten branch to inside of fading Var noke = Noke(letnoke.node.be, addkey(noke.node, noke.key)) debug('eat', 'ref-be:', noke) debug('eat', 'eaten:', eating.eaten) for b, h in zip(noke.bubblesDraw(), eating.eaten): debug('eat', 'found in Hole:', b, h) # Copying Eaten Bubble bubble = Bubble() bubble.ring = h().ring.transform( matrix) # Redet position bubble.group = group b.set(bubble) # Copy remained Bubbles inside Eaten if are if ABS == b.node.type: for b,h in zip( b['expr'].bubbleNokes(), \ h['expr'].bubbleNokes() ): Noke.copyBubble(b, h) # Get next Node down the fading Lambda group = eating.group matrix = absbubbleTransform * Figure.lambdaMatrix.inverse() down = letnoke['expr'].through() # Step inside Lambda debug('eat', 'down', down, down()) if APPL == down.node.type: # Appl after fading Lambda # Redet 'group' and positions of Bubbles of Group for b in down.bubblesDraw(): bubble = b() matrix1 = matrix * bubble.transform() bubble.ring = Ring.unit.transform( matrix1) # Reset Position of Bubble bubble.group = group # and Group descent( b, group, matrix1 ) # Pass matrix, because there inside fading vars may be bubbles of this group else: # VAR or ABS # Create Bubble and set 'group' bubble = Bubble() bubble.ring = Ring.unit.transform(matrix) bubble.group = group down.set(bubble) descent(down, group, matrix) # Delete Bubbles on eaten branch for h in eating.eaten: h.remove() # Reref now let.expr.replace({abs: let}) debug('eat', '\n') return Enduring.start(self)
def start( self ): # Start time func-s funcs = { 'fade': Enduring.I } Enduring.__init__( self, Act.secFading, funcs ) self.fade = 1.0 debug( 'eat', 'init Fading. abs:', self.act.abs ) # Nodes of Redex abs = self.act.abs appl = self.act.appl # Replace Redex (Appl and Abs) with new created Let let = Let( be= None, expr= None ) appl.subst( let ) let.be = appl.arg let.expr = appl.func abs.subst( abs.expr ) # let.expr.replace( {abs: let} ) -- # Do not reref to Let. Else we will go through let-bound vars at down.bubblesDraw() for eating in self.act.eatings: debug('eat', '\nFading: eating', eating.appl ) # Get Noke of new Let letnoke = Noke( let, eating.appl.key ) debug( 'eat', 'init Fading. let:', letnoke ) self.act.letnoke = letnoke # Save last Let to Act # Save Abs-Bubble to Let Noke for Fading absbubble = eating.abs() absbubble.fading = self letnoke.set( absbubble ) self.faded.append( letnoke ) debug( 'eat', 'Abs-Bubble saved to Let:', letnoke(), letnoke().group ) # Prepare Eaten # Det Cover Transformation (Lambda Bubble covers Eaten Bubbles) absbubbleTransform = TransformMatrix( ring= absbubble.ring ) lens = TransformMatrix() lens.setTranspose( 0,0, Figure.holeLens ) # Lens-effect in Hole cover = ( absbubbleTransform * lens ).inverse() # Transform all eaten Bubbles, as they are in Hole, not in Group for b in eating.eaten: bubble = b() bubble.ring = bubble.ring.transform( cover ) # Redet position bubble.group = None debug('eat','eaten transformed and ungrouped', eating.eaten ) # Descend def descent( noke, group, matrix ): # If 'noke' has Bubble, Bubble.ring already set. debug( 'eat', 'descend:', noke ) if APPL == noke.node.type: # Group inside some Lambda, 'matrix' must be None debug('eat','appl found',noke) group = noke.group() for b in noke.bubblesDraw(): # b().ring stays on its place matrix = TransformMatrix( ring= b().ring ) descent( b, group, matrix ) # Pass matrix, because there inside fading vars may be bubbles of this group elif ABS == noke.node.type: noke = noke['expr'].through() # Noke inside Abs - no position needed descent( noke, None, None ) elif VAR == noke.node.type and abs == noke.node.ref: # Mark Bubble as fading bubble = noke() if not bubble: # This Var may be inside Lambda and do not have 'bubble' bubble = Bubble() # Create Bubble without 'group' noke.set( bubble ) bubble.fading = self self.faded.append( noke ) debug('eat','it s hole. added to faded:', self.faded ) if not matrix: matrix = TransformMatrix() matrix.unit() # Copy eaten branch to inside of fading Var noke = Noke( letnoke.node.be, addkey( noke.node, noke.key ) ) debug('eat','ref-be:',noke) debug('eat','eaten:',eating.eaten) for b,h in zip( noke.bubblesDraw(), eating.eaten ): debug( 'eat', 'found in Hole:', b, h ) # Copying Eaten Bubble bubble = Bubble() bubble.ring = h().ring.transform( matrix ) # Redet position bubble.group = group b.set( bubble ) # Copy remained Bubbles inside Eaten if are if ABS == b.node.type: for b,h in zip( b['expr'].bubbleNokes(), \ h['expr'].bubbleNokes() ): Noke.copyBubble( b, h ) # Get next Node down the fading Lambda group = eating.group matrix = absbubbleTransform * Figure.lambdaMatrix.inverse() down = letnoke['expr'].through() # Step inside Lambda debug('eat','down',down,down()) if APPL == down.node.type: # Appl after fading Lambda # Redet 'group' and positions of Bubbles of Group for b in down.bubblesDraw(): bubble = b() matrix1 = matrix * bubble.transform() bubble.ring = Ring.unit.transform( matrix1 ) # Reset Position of Bubble bubble.group = group # and Group descent( b, group, matrix1 ) # Pass matrix, because there inside fading vars may be bubbles of this group else: # VAR or ABS # Create Bubble and set 'group' bubble = Bubble() bubble.ring = Ring.unit.transform( matrix ) bubble.group = group down.set( bubble ) descent( down, group, matrix ) # Delete Bubbles on eaten branch for h in eating.eaten: h.remove() # Reref now let.expr.replace( {abs:let} ) debug('eat', '\n' ) return Enduring.start( self )