Esempio n. 1
0
 def call(self, frame, anchor, args, kwargs):
     from pyntch.basic_types import StrType
     from pyntch.aggregate_types import DictType, TupleType
     from pyntch.expression import TupleUnpack, TupleSlice
     # Process keyword arguments first.
     varsleft = list(self.argvars)
     varikwargs = []
     for (kwname, kwvalue) in kwargs.iteritems():
         for var1 in varsleft:
             if isinstance(var1, Variable) and var1.name == kwname:
                 var1.bind(kwvalue)
                 # When a keyword argument is given, remove that name from the remaining arguments.
                 varsleft.remove(var1)
                 break
         else:
             if self.kwarg:
                 varikwargs.append(kwvalue)
             else:
                 frame.raise_expt(ErrorConfig.InvalidKeywordArgs(kwname))
     # Process standard arguments.
     variargs = []
     for arg1 in args:
         assert arg1 != None, args
         if varsleft:
             var1 = varsleft.pop(0)
             assign_arg(frame, anchor, var1, arg1)
         elif self.variarg:
             variargs.append(arg1)
         else:
             # Too many arguments.
             frame.raise_expt(
                 ErrorConfig.InvalidNumOfArgs(len(self.argvars), len(args)))
     if len(self.defaults) < len(varsleft):
         # Too few arguments.
         frame.raise_expt(
             ErrorConfig.InvalidNumOfArgs(len(self.argvars), len(args)))
     # Handle remaining arguments: kwargs and variargs.
     if self.variarg and variargs:
         self.space[self.variarg].bind(TupleType.create_tuple(variargs))
     if self.kwarg:
         if varikwargs:
             self.space[self.kwarg].bind(
                 DictType.create_dict(key=StrType.get_object(),
                                      value=varikwargs))
         else:
             self.space[self.kwarg].bind(DictType.create_null(
                 frame, anchor))
     # Remember where this is called from.
     self.frames.add(frame)
     # Propagate the exceptions upward.
     self.frame.connect(frame.recv)
     return self.body
Esempio n. 2
0
 def call(self, frame, anchor, args, kwargs):
   from pyntch.basic_types import StrType
   from pyntch.aggregate_types import DictType, TupleType
   from pyntch.expression import TupleUnpack, TupleSlice
   # Process keyword arguments first.
   varsleft = list(self.argvars)
   varikwargs = []
   for (kwname, kwvalue) in kwargs.iteritems():
     for var1 in varsleft:
       if isinstance(var1, Variable) and var1.name == kwname:
         var1.bind(kwvalue)
         # When a keyword argument is given, remove that name from the remaining arguments.
         varsleft.remove(var1)
         break
     else:
       if self.kwarg:
         varikwargs.append(kwvalue)
       else:
         frame.raise_expt(ErrorConfig.InvalidKeywordArgs(kwname))
   # Process standard arguments.
   variargs = []
   for arg1 in args:
     assert arg1 != None, args
     if varsleft:
       var1 = varsleft.pop(0)
       assign_arg(frame, anchor, var1, arg1)
     elif self.variarg:
       variargs.append(arg1)
     else:
       # Too many arguments.
       frame.raise_expt(ErrorConfig.InvalidNumOfArgs(len(self.argvars), len(args)))
   if len(self.defaults) < len(varsleft):
     # Too few arguments.
     frame.raise_expt(ErrorConfig.InvalidNumOfArgs(len(self.argvars), len(args)))
   # Handle remaining arguments: kwargs and variargs.
   if self.variarg and variargs:
     self.space[self.variarg].bind(TupleType.create_tuple(variargs))
   if self.kwarg:
     if varikwargs:
       self.space[self.kwarg].bind(DictType.create_dict(key=StrType.get_object(), value=varikwargs))
     else:
       self.space[self.kwarg].bind(DictType.create_null(frame, anchor))
   # Remember where this is called from.
   self.frames.add(frame)
   # Propagate the exceptions upward.
   self.frame.connect(frame.recv)
   return self.body
Esempio n. 3
0
 def recv_target(self, src):
   from pyntch.aggregate_types import DictType
   for obj in src:
     if obj in self.received: continue
     self.received.add(obj)
     if obj.is_type(DictType.get_typeobj()):
       MethodCall(self.frame, self.anchor, obj, 'iteritems').connect(self.recv)
     else:
       self.raise_expt(ErrorConfig.TypeCheckerError(src, obj, 'dict'))
   return
Esempio n. 4
0
 def recv_target(self, src):
     from pyntch.aggregate_types import DictType
     for obj in src:
         if obj in self.received: continue
         self.received.add(obj)
         if obj.is_type(DictType.get_typeobj()):
             MethodCall(self.frame, self.anchor, obj,
                        'iteritems').connect(self.recv)
         else:
             self.raise_expt(ErrorConfig.TypeCheckerError(src, obj, 'dict'))
     return
Esempio n. 5
0
def build_expr(reporter, frame, space, tree, evals):
  from pyntch.basic_types import BUILTIN_OBJECT, IntType
  from pyntch.aggregate_types import IterType, GeneratorType, ListType, SetType, DictType, TupleType

  if isinstance(tree, ast.Const):
    typename = type(tree.value).__name__
    expr = BUILTIN_OBJECT[typename]

  elif isinstance(tree, ast.Name):
    try:
      expr = space[tree.name]
    except KeyError:
      ExecutionFrame(frame, tree).raise_expt(ErrorConfig.NameUndefined(tree.name))
      expr = UndefinedTypeNode(tree.name)

  elif isinstance(tree, ast.CallFunc):
    func = build_expr(reporter, frame, space, tree.node, evals)
    args = tuple( build_expr(reporter, frame, space, arg1, evals)
                  for arg1 in tree.args if not isinstance(arg1, ast.Keyword) )
    kwargs = dict( (arg1.name, build_expr(reporter, frame, space, arg1.expr, evals))
                   for arg1 in tree.args if isinstance(arg1, ast.Keyword) )
    star = dstar = None
    if tree.star_args:
      star = build_expr(reporter, frame, space, tree.star_args, evals)
    if tree.dstar_args:
      dstar = build_expr(reporter, frame, space, tree.dstar_args, evals)
    expr = FunCall(ExecutionFrame(frame, tree), tree, func, args, kwargs, star, dstar)

  elif isinstance(tree, ast.Getattr):
    obj = build_expr(reporter, frame, space, tree.expr, evals)
    expr = AttrRef(ExecutionFrame(frame, tree), tree, obj, tree.attrname)

  elif isinstance(tree, ast.Subscript):
    obj = build_expr(reporter, frame, space, tree.expr, evals)
    subs = [ build_expr(reporter, frame, space, sub, evals) for sub in tree.subs ]
    if len(subs) == 1:
      expr = SubRef(ExecutionFrame(frame, tree), tree, obj, subs[0])
    else:
      expr = SliceRef(ExecutionFrame(frame, tree), tree, obj, subs)
      
  elif isinstance(tree, ast.Slice):
    obj = build_expr(reporter, frame, space, tree.expr, evals)
    lower = upper = IntType.get_object() # maxint is given when omitted.
    if tree.lower:
      lower = build_expr(reporter, frame, space, tree.lower, evals)
    if tree.upper:
      upper = build_expr(reporter, frame, space, tree.upper, evals)
    assert lower != None and upper != None
    expr = SliceRef(ExecutionFrame(frame, tree), tree, obj, [lower, upper])

  elif isinstance(tree, ast.Sliceobj):
    elements = [ build_expr(reporter, frame, space, node, evals) for node in tree.nodes ]
    expr = SliceObject(ExecutionFrame(frame, tree), tree, elements)
    
  elif isinstance(tree, ast.Tuple):
    elements = [ build_expr(reporter, frame, space, node, evals) for node in tree.nodes ]
    expr = TupleType.create_tuple(elements)

  elif isinstance(tree, ast.List):
    elements = [ build_expr(reporter, frame, space, node, evals) for node in tree.nodes ]
    expr = ListType.create_list(CompoundTypeNode(elements))

  elif isinstance(tree, ast.Set):
    elements = [ build_expr(reporter, frame, space, node, evals) for node in tree.nodes ]
    expr = SetType.create_set(CompoundTypeNode(elements))

  elif isinstance(tree, ast.Dict):
    items = [ (build_expr(reporter, frame, space, k, evals),
               build_expr(reporter, frame, space, v, evals))
              for (k,v) in tree.items ]
    expr = DictType.create_dict(items)

  # +, -, *, /, %, //, **, <<, >>
  elif isinstance(tree, (ast.Add, ast.Sub, ast.Mul, ast.Div,
                         ast.Mod, ast.FloorDiv, ast.Power,
                         ast.LeftShift, ast.RightShift)):
    op = tree.__class__.__name__
    left = build_expr(reporter, frame, space, tree.left, evals)
    right = build_expr(reporter, frame, space, tree.right, evals)
    expr = BinaryOp(ExecutionFrame(frame, tree), tree, op, left, right)
    
  # &, |, ^
  elif isinstance(tree, (ast.Bitand, ast.Bitor, ast.Bitxor)):
    op = tree.__class__.__name__
    nodes = [ build_expr(reporter, frame, space, node, evals) for node in tree.nodes ]
    expr = nodes.pop(0)
    for right in nodes:
      expr = BinaryOp(ExecutionFrame(frame, tree), tree, op, expr, right)
  
  # ==, !=, <=, >=, <, >, in, not in, is, is not
  elif isinstance(tree, ast.Compare):
    left = build_expr(reporter, frame, space, tree.expr, evals)
    for (op,node) in tree.ops:
      right = build_expr(reporter, frame, space, node, evals)
      expr = CompareOp(ExecutionFrame(frame, tree), tree, op, left, right)
      left = right

  # +,-,~
  elif isinstance(tree, (ast.UnaryAdd, ast.UnarySub, ast.Invert)):
    op = tree.__class__.__name__
    value = build_expr(reporter, frame, space, tree.expr, evals)
    expr = UnaryOp(ExecutionFrame(frame, tree), tree, op, value)

  # and, or
  elif isinstance(tree, (ast.And, ast.Or)):
    op = tree.__class__.__name__
    nodes = [ build_expr(reporter, frame, space, node, evals) for node in tree.nodes ]
    expr = BooleanOp(ExecutionFrame(frame, tree), tree, op, nodes)

  # not
  elif isinstance(tree, ast.Not):
    value = build_expr(reporter, frame, space, tree.expr, evals)
    expr = NotOp(ExecutionFrame(frame, tree), tree, value)

  # lambda
  elif isinstance(tree, ast.Lambda):
    defaults = [ build_expr(reporter, frame, space, value, evals) for value in tree.defaults ]
    expr = LambdaFuncType(reporter, frame, space, tree, tree.argnames,
                          defaults, tree.varargs, tree.kwargs, tree)

  # list comprehension
  elif isinstance(tree, ast.ListComp):
    elements = [ build_expr(reporter, frame, space, tree.expr, evals) ]
    expr = ListType.create_list(CompoundTypeNode(elements))
    for qual in tree.quals:
      seq = build_expr(reporter, frame, space, qual.list, evals)
      elem = IterElement(ExecutionFrame(frame, qual.list), qual.list, seq)
      build_assign(reporter, frame, space, qual.assign, elem, evals)
      for qif in qual.ifs:
        build_expr(reporter, frame, space, qif.test, evals)

  # generator expression
  elif isinstance(tree, ast.GenExpr):
    gen = tree.code
    elements = [ build_expr(reporter, frame, space, gen.expr, evals) ]
    expr = IterType.create_iter(CompoundTypeNode(elements))
    for qual in gen.quals:
      seq = build_expr(reporter, frame, space, qual.iter, evals)
      elem = IterElement(ExecutionFrame(frame, qual.iter), qual.iter, seq)
      build_assign(reporter, frame, space, qual.assign, elem, evals)
      for qif in qual.ifs:
        build_expr(reporter, frame, space, qif.test, evals)

  # yield (for python 2.5)
  elif isinstance(tree, ast.Yield):
    value = build_expr(reporter, frame, space, tree.value, evals)
    slot = GeneratorType.create_slot(value)
    evals.append(('y', slot))
    expr = slot.received

  # ifexp
  elif isinstance(tree, ast.IfExp):
    test = build_expr(reporter, frame, space, tree.test, evals)
    then = build_expr(reporter, frame, space, tree.then, evals)
    else_ = build_expr(reporter, frame, space, tree.else_, evals)
    expr = IfExpOp(ExecutionFrame(frame, tree), tree, test, then, else_)

  # Backquote (unsupported)
  elif isinstance(tree, ast.Backquote):
    ExecutionFrame(frame, tree).raise_expt(ErrorConfig.NotSupported('backquote notation'))
    expr = UndefinedTypeNode('backquote')

  # Ellipsis
  elif isinstance(tree, ast.Ellipsis):
    ExecutionFrame(frame, tree).raise_expt(ErrorConfig.NotSupported('ellipsis'))
    expr = UndefinedTypeNode('ellipsis')
  
  else:
    # unsupported AST.
    raise SyntaxError('unsupported syntax: %r (%s:%r)' % (tree, tree._module.get_path(), tree.lineno))

  assert isinstance(expr, (TypeNode, tuple)), expr
  evals.append((None, expr))
  return expr