docs: def evaluate(self, s, value, insert=None):
          """Expression evaluator.
  
          * For expressions, returns the value of the expression.
  
          * For Blocks, returns a generator (or the empty list []).
  
          """
          assert not isinstance(value, kurt.Script)
  
          if insert and insert.unevaluated:
              return value
  
          if isinstance(value, kurt.Block):
              if value.type.shape == "hat":
                  return []
  
              if value.type not in self.COMMANDS:
                  if getattr(value.type, '_workaround', None):
                      value = value.type._workaround(value)
                      if not value:
                          raise kurt.BlockNotSupported(value.type)
                  else:
                      raise kurt.BlockNotSupported(value.type)
  
              f = self.COMMANDS[value.type]
  
              args = [self.evaluate(s, arg, arg_insert)
                      for (arg, arg_insert)
                      in zip(list(value.args), value.type.inserts)]
              value = f(s, *args)
  
              def flatten_generators(gen):
                  for item in gen:
                      if inspect.isgenerator(item):
                          for x in flatten_generators(item):
                              yield x
                      else:
                          yield item
              if inspect.isgenerator(value):
                  value = flatten_generators(value)
  
              if value is None:
                  value = []
  
          if insert:
              if isinstance(value, basestring):
                  value = unicode(value)
  
                  if insert.shape in ("number", "number-menu", "string"):
                      try:
                          value = float(value)
                      except (TypeError, ValueError):
                          if insert.shape == "number":
                              value = 0
  
              if isinstance(value, float) and value == int(value):
                  value = int(value)
  
              if insert.kind in ("spriteOrStage", "spriteOrMouse", "stageOrThis",
                                 "spriteOnly", "touching"):
                  if value not in ("mouse-pointer", "edge"):
                      value = (self.project.stage if value == "Stage"
                               else self.project.get_sprite(value))
              elif insert.kind == "var":
                  if value in s.variables:
                      value = s.variables[value]
                  else:
                      value = s.project.variables[value]
              elif insert.kind == "list":
                  if value in s.lists:
                      value = s.lists[value]
                  else:
                      value = s.project.lists[value]
              elif insert.kind == "sound":
                  for sound in s.sounds:
                      if sound.name == value:
                          value = sound
                          break
  
          return value