示例#1
0
    def check_external_attr(self, node, attr):
        if attr.args is not None:
            msg = 'external attribute takes no arguments'
            raise DumbTypeError(msg, loc=attr.loc)

        if node.body is not None:
            msg = ('function with external attribute should '
                   'define only prototype')
            raise DumbTypeError(msg, loc=node.loc)
示例#2
0
def _validate_logical_binop(node, left_ty, right_ty):
    if node.op in (Operator.EQ, Operator.NE):
        return
    if left_ty != BuiltinTypes.BOOL or right_ty != BuiltinTypes.BOOL:
        msg = 'invalid operand types to logical expression (%r and %r)' % (
            left_ty.name, right_ty.name)
        raise DumbTypeError(msg, loc=node.loc)
示例#3
0
 def visit_BinaryOp(self, node):
     op = node.op
     left_ty = self.visit(node.left)
     right_ty = self.visit(node.right)
     result_ty = _builtin_type_conversion(left_ty, right_ty)
     if result_ty is None:
         msg = 'invalid operands to binary expression (%r and %r)' % (
             left_ty.name, right_ty.name)
         raise DumbTypeError(msg, loc=node.loc)
     if Operator.logical(op):
         _validate_logical_binop(node, left_ty, right_ty)
     elif Operator.bitwise(op):
         _validate_bitwise_binop(node, left_ty, right_ty)
     elif Operator.shift(op):
         _validate_shift_binop(node, left_ty, right_ty)
     else:
         _validate_arithmetic_binop(node, left_ty, right_ty)
     # Promote left and right operand to the common type.
     node.ty = result_ty
     left_promote_ty = _builtin_type_promotion(left_ty, result_ty)
     right_promote_ty = _builtin_type_promotion(right_ty, result_ty)
     if left_promote_ty:
         node.left = ast.Cast(node.left, left_promote_ty, left_ty)
     if right_promote_ty:
         node.right = ast.Cast(node.right, right_promote_ty, right_ty)
     if Operator.relational(op):
         result_ty = BuiltinTypes.BOOL
     return result_ty
示例#4
0
 def visit_If(self, node):
     cond_ty = self.visit(node.cond)
     if cond_ty != BuiltinTypes.BOOL:
         msg = "condition expression must be of the type 'bool'"
         raise DumbTypeError(msg, loc=node.loc)
     self.visit(node.then)
     if node.otherwise is not None:
         self.visit(node.otherwise)
示例#5
0
 def visit_Var(self, node):
     value_ty = self.visit(node.initial_value)
     if not node.ty:
         node.ty = value_ty
     elif node.ty not in BuiltinTypes.VAR_TYPES:
         raise DumbTypeError('unknown type %r' % node.ty.name, loc=node.loc)
     if node.ty != value_ty:
         promote_to = _builtin_type_promotion(value_ty, node.ty)
         if promote_to:
             node.initial_value = ast.Cast(node.initial_value,
                                           promote_to,
                                           value_ty)
         else:
             msg = 'cannot implicitly cast %r to %r' % (
                 value_ty.name, node.ty.name)
             raise DumbTypeError(msg, loc=node.loc)
     self.symbol_table.set(node.name, node.ty)
示例#6
0
 def visit_Return(self, node):
     proto = self.curr_function.proto
     if proto.ret_ty == BuiltinTypes.VOID and node.value is not None:
         msg = 'unexpected return value'
         raise DumbTypeError(msg, loc=node.loc)
     if proto.ret_ty != BuiltinTypes.VOID and node.value is None:
         msg = 'expected %r return value' % proto.ret_ty.name
         raise DumbTypeError(msg, loc=node.loc)
     if not node.value:
         return
     value_ty = self.visit(node.value)
     if value_ty == proto.ret_ty:
         return
     promote_to = _builtin_type_promotion(value_ty, proto.ret_ty)
     if not promote_to:
         msg = 'cannot implicitly cast %r to %r' % (
             value_ty.name, proto.ret_ty.name)
         raise DumbTypeError(msg, loc=node.loc)
     node.value = ast.Cast(node.value, proto.ret_ty, value_ty, loc=node.loc)
示例#7
0
 def visit_TranslationUnit(self, node):
     for decl in node.decls:
         if not isinstance(decl, ast.Function):  # pragma: nocover
             continue
         if decl.proto.name == 'main':
             if decl.proto.ret_ty != ast.BuiltinTypes.I32:
                 msg = 'main function has to return i32'
                 raise DumbTypeError(msg, loc=decl.loc)
             return
     raise DumbNameError('no main func was found')
示例#8
0
 def visit_FuncCall(self, node):
     func = self.func_table.get(node.name)
     if not func:
         msg = 'name %r is not defined' % node.name
         raise DumbNameError(msg, loc=node.loc)
     proto = func.proto
     if len(node.args) != len(proto.args):
         msg = '%s() takes %d arguments (%d given)' % (
             proto.name, len(proto.args), len(node.args))
         raise DumbTypeError(msg, loc=node.loc)
     for i, value in enumerate(node.args):
         arg_ty = proto.args[i].ty
         value_ty = self.visit(value)
         if arg_ty == value_ty:
             continue
         promote_to = _builtin_type_promotion(value_ty, arg_ty)
         if not promote_to:
             msg = 'cannot implicitly cast %r to %r' % (
                 value_ty.name, arg_ty.name)
             raise DumbTypeError(msg, loc=node.loc)
         node.args[i] = ast.Cast(value, arg_ty, value_ty)
     return proto.ret_ty
示例#9
0
 def visit_Function(self, node):
     self.symbol_table.push()
     for arg in node.proto.args:
         if self.symbol_table.has(arg.name):
             msg = 'name %r has been defined' % arg.name
             raise DumbNameError(msg, loc=arg.loc)
         if arg.ty == BuiltinTypes.VOID:
             msg = 'invalid argument type (%r)' % arg.ty.name
             raise DumbTypeError(msg, loc=arg.loc)
         self.symbol_table.set(arg.name, arg.ty)
     if node.body:
         self.curr_function = node
         self.visit(node.body)
         self.curr_function = None
     self.symbol_table.pop()
示例#10
0
 def visit_Assignment(self, node):
     lvalue_ty = self.visit(node.lvalue)
     rvalue_ty = self.visit(node.rvalue)
     node.ty = lvalue_ty
     _validate_assignment(node, lvalue_ty, rvalue_ty)
     if node.op is not None:
         expr = ast.BinaryOp(node.op, node.lvalue, node.rvalue,
                             loc=node.loc)
         self.visit(expr)
     if lvalue_ty == rvalue_ty:
         return lvalue_ty
     promote_to = _builtin_type_promotion(rvalue_ty, lvalue_ty)
     if not promote_to:
         msg = 'cannot implicitly cast %r to %r' % (
             rvalue_ty.name, lvalue_ty.name)
         raise DumbTypeError(msg, loc=node.loc)
     node.rvalue = ast.Cast(node.rvalue, lvalue_ty, rvalue_ty)
     return lvalue_ty
示例#11
0
 def check_no_attrs(self, node):
     if node.body is None:
         msg = 'function body expected %r' % node.proto.name
         raise DumbTypeError(msg, loc=node.loc)
示例#12
0
def _validate_assignment(node, left_ty, right_ty):
    if not isinstance(node.lvalue, ast.Identifier):
        msg = 'lvalue required as left operand of assignment'
        raise DumbTypeError(msg, loc=node.loc)
示例#13
0
def _validate_logical_not_unaryop(node, value_ty):
    if value_ty != BuiltinTypes.BOOL:
        msg = 'invalid operand type %r' % value_ty.name
        raise DumbTypeError(msg, loc=node.loc)
示例#14
0
def _validate_shift_binop(node, left_ty, right_ty):
    integer_types = BuiltinTypes.INTEGERS
    if left_ty not in integer_types or right_ty not in integer_types:
        msg = 'invalid operands to shift expression (%r and %r)' % (
            left_ty.name, right_ty.name)
        raise DumbTypeError(msg, loc=node.loc)
示例#15
0
def _validate_not_unaryop(node, value_ty):
    if value_ty not in BuiltinTypes.INTEGERS:
        msg = 'invalid operand type %r (integer type expected)' % value_ty.name
        raise DumbTypeError(msg, loc=node.loc)
示例#16
0
def _validate_arithmetic_unaryop(node, value_ty):
    if value_ty not in BuiltinTypes.NUMERICAL:
        msg = 'invalid operand type %r (integral type expected)' % value_ty.name
        raise DumbTypeError(msg, loc=node.loc)
示例#17
0
 def visit_While(self, node):
     cond_ty = self.visit(node.cond)
     if cond_ty != BuiltinTypes.BOOL:
         msg = "condition expression must be of the type 'bool'"
         raise DumbTypeError(msg, loc=node.loc)
     self.visit(node.body)
示例#18
0
def _validate_cast(node, src_ty, dst_ty):
    if dst_ty in (BuiltinTypes.STR, BuiltinTypes.VOID):
        msg = 'invalid type'
        raise DumbTypeError(msg, loc=node.loc)
示例#19
0
def _validate_arithmetic_binop(node, left_ty, right_ty):
    numerical_types = BuiltinTypes.NUMERICAL
    if left_ty not in numerical_types or right_ty not in numerical_types:
        msg = 'invalid operands to arithmetic expression (%r and %r)' % (
            left_ty.name, right_ty.name)
        raise DumbTypeError(msg, loc=node.loc)