def visit_Let(self, expr, **_): saved_bindings = self.bindings if isinstance(expr, expression.LetAny): union_semantics = True elif isinstance(expr, expression.LetEach): union_semantics = False else: union_semantics = None if not isinstance(expr.context, expression.Binding): raise ValueError( "Left operand of Let must be a Binding expression.") # Context to rebind to. This is the key that will be selected from # current bindings and become the new bindings for ever subexpression. context = expr.context.value try: rebind = associative.resolve(saved_bindings, context) if not rebind: # No value from context. return None if union_semantics is None: # This is a simple let, which does not permit superposition # semantics. if superposition.insuperposition(rebind): raise TypeError( "A Let expression doesn't permit superposition " "semantics. Use LetEach or LetAny instead.") self.bindings = rebind return self.visit(expr.expression) # If we're using union or intersection semantics, the type of # rebind MUST be a Superposition, even if it happens to have # only one state. If the below throws a type error then the # query is invalid and should fail here. result = False for state in superposition.getstates(rebind): self.bindings = state result = self.visit(expr.expression) if result and union_semantics: return result if not result and not union_semantics: return False return result finally: self.bindings = saved_bindings
associative.IAssociative.implement( for_type=obj.Array, implementations={ associative.select: lambda obj, key: obj[key], associative.resolve: getattr } ) associative.IAssociative.implement( for_type=obj.Pointer, implementations={ associative.select: lambda ptr, key: associative.select(ptr.deref(), key), associative.resolve: lambda ptr, key: associative.resolve(ptr.deref(), key) } ) # What this implementation SHOULD do is run the plugin, select the column from # each row and then return a repeated value. However, that'll be implemented # once we've converted most plugins to typed plugins. Right now, this never # actually gets called and exists mainly to get infer_type to shut up about # Command not implementing IAssociative. associative.IAssociative.implement( for_type=plugin.Command, implementations={ associative.select: lambda x, idx: list(x)[idx], associative.resolve: lambda x, idx: list(x)[idx] }