예제 #1
0
 def check_code(self, args):
     if len(args) < len(self.args):
         raise StaticTypeError(f"Not enough arguments (needs {len(self.args)}), given {args}")
     if len(args) > len(self.args):
         raise StaticTypeError(f"Too many arguments (needs {len(self.args)})")
     for i, (supplied, needed) in enumerate(zip(args, self.args)):
         if not needed.can_coerce_from(supplied.tp):
             raise StaticTypeError(f"Argument {i + 1} should be {needed}, but is {supplied.tp} ")
예제 #2
0
 def assign_target(self, node, value):
     if isinstance(value.tp, EmptyList):
         func_node = ast.Expr(value=ast.Call(
             func=ast.Attribute(value=node, attr="clear"), args=[]))
         try:
             self.visit(func_node)
         except UnknownVariable:
             raise StaticTypeError(
                 "Must specify a list type when assigning an empty list")
         return
     if isinstance(node, ast.Name):
         left = self.context.assign_type(node.id, value.tp)
         self.start_line("{} = {};\n".format(left.code, value.as_value()))
     elif isinstance(node, ast.Subscript):
         container = self.get_expression_code(node.value)
         if isinstance(node.slice, ast.Index):
             index = self.get_expression_code(node.slice.value)
             setter = container.tp.get_method("set_item")
             code = setter.get_code(self.context, container, index, value)
             self.start_line(f"{code.code};\n")
         else:
             raise UnimplementedFeature("Slices not yet implemented")
     elif isinstance(node, ast.Attribute):
         owner = self.get_expression_code(node.value)
         owner.tp.set_attr(node.attr, value)
         left = self.get_expression_code(node)
         self.start_line(f"{left.code} = {value.code};\n")
예제 #3
0
 def get_attr_code(self, attr: str, obj: Code) -> Code:
     if attr in self.cls.class_vars:
         return self.cls.class_vars[attr]
     else:
         try:
             val = self.cls.members[attr]
             text = f"{obj.as_accessor()}{attr}"
             return Code(tp=val.tp, code=text)
         except KeyError:
             raise StaticTypeError(f"Instance of {self.name} has no attribute {attr}")
예제 #4
0
 def process_list(self, subscript: ast.AST):
     if isinstance(subscript, ast.Index):
         return TypeDB.get_list([self.visit(subscript.value)])
     elif isinstance(subscript, ast.Slice):
         if isinstance(subscript.upper, ast.Num) and isinstance(
                 subscript.upper.n, int):
             return TypeDB.get_list([self.visit(subscript.lower)],
                                    maxlen=subscript.upper.n)
         else:
             raise StaticTypeError("List length must be integer")
예제 #5
0
 def assign_type(self, tp, additional_text=""):
     if self.tp is None:
         self.tp = tp
         return
     if self.tp.can_coerce_from(tp):
         return
     elif tp.can_coerce_from(self.tp):
         self.tp = tp
         return
     # not been able to match types - raise error
     raise StaticTypeError(f"Assigning {tp} to {self.tp}{additional_text}")
예제 #6
0
 def get_binary_op_code(self, left: Code, op: ast.AST, right: Code):
     method_name = OPS_MAP[op.__class__]
     operation = op.__class__.__name__
     try:
         func = left.tp.get_method(method_name)
         if not isinstance(func, InlineCMethod):
             raise StaticTypeError(f"Can't use {operation} at module level")
         result = func.get_code(self.context, left, right)
     except (StaticTypeError, InvalidOperation):
         try:
             func = right.tp.get_method(
                 method_name)  # ok try using right as function origin...
             if not isinstance(func, InlineCMethod):
                 raise StaticTypeError(
                     f"Can't use {operation} at module level")
             result = func.get_code(self.context, left, right)
         except (StaticTypeError, InvalidOperation):
             raise StaticTypeError(
                 f"Arguments {left.tp}, {right.tp} not valid for operation {operation}"
             )
     return result
예제 #7
0
파일: module.py 프로젝트: furbrain/pymbo
 def visit_Assign(self, node: ast.Assign):
     right = get_constant_code(node.value, self.context)
     for n in node.targets:
         if isinstance(n, ast.Name):
             if n.id in self.context:
                 raise StaticTypeError("Cannot redefine global variables")
             self.context[n.id] = Code(tp=right.tp, code=n.id)
             left = self.context[n.id]
             self.globals += [
                 f"{left.tp.c_type} {n.id} = {right.as_value()};\n"
             ]
         else:
             raise InvalidOperation("Can only initialise global variables")
예제 #8
0
 def get_binary_op_code(self, left, op, right):
     method_name = OPS_MAP[op.__class__]
     try:
         func = left.tp.get_method(method_name)
         result = func.get_code(self.context, left, right)
     except (StaticTypeError, InvalidOperation):
         try:
             func = right.tp.get_method(
                 method_name)  # ok try using right as function origin...
             result = func.get_code(self.context, left, right)
         except (StaticTypeError, InvalidOperation):
             operation = op.__class__.__name__
             raise StaticTypeError(
                 f"Arguments {left.tp}, {right.tp} not valid for operation {operation}"
             )
     return result
예제 #9
0
 def generic_visit(self, node):
     raise StaticTypeError(
         f"{node.__class__.__name__} not permitted in global definition")
예제 #10
0
 def visit_Subscript(self, node: ast.Subscript):
     if isinstance(node.value, ast.Name):
         if node.value.id == "List":
             return self.process_list(node.slice)
     raise StaticTypeError("Annotation base must be List or Dict or Tuple")
예제 #11
0
파일: basics.py 프로젝트: furbrain/pymbo
def combine_types(a: "InferredType", b: "InferredType"):
    if a.can_coerce_from(b):
        return a
    if b.can_coerce_from(a):
        return b
    raise StaticTypeError(f"Incompatible types: {a} {b}")