예제 #1
0
 def validate_array_indexes(self):
     last_index = 0
     index_var = {
         index.variable: index.range
         for index in self.context.index_variables
     }
     for index in self.indices:
         if isinstance(index, LiteralExpression):
             yield Diagnostic(Diagnostic.Messages.ARRAY_INDEX_NOT_VALID,
                              index.value,
                              parseinfo=self.ast.parseinfo)
         else:
             idx = 0
             try:
                 idx = list(index_var).index(index.variable)
             except ValueError:
                 yield Diagnostic(Diagnostic.Messages.ARRAY_INDEX_NOT_VALID,
                                  index.variable_name,
                                  parseinfo=self.ast.parseinfo)
             if idx < last_index:
                 yield Diagnostic(
                     Diagnostic.Messages.ARRAY_INDEX_WRONG_ORDER,
                     self.variable_name,
                     parseinfo=self.ast.parseinfo)
             last_index = idx
예제 #2
0
 def validate(self):
     if self.return_type is not None and not isinstance(
             self.return_type, ScalarType):
         yield Diagnostic(
             Diagnostic.Messages.RETURN_TYPE_MUST_BE_SCALAR,
             parseinfo=self.ast.declarator.return_type.parseinfo,
         )
예제 #3
0
def assert_error(text, error, *args):
    i = InterfaceDefinition.compile(text)
    error = Diagnostic.build_message(error, *args)
    for m in i.validate():
        print(m)
        if m.message == error:
            return
    raise AssertionError
예제 #4
0
 def validate(self, lvalue=False):
     if not self.variable:
         yield Diagnostic(Diagnostic.Messages.VARIABLE_NOT_DECLARED,
                          self.variable_name,
                          parseinfo=self.ast.parseinfo)
     elif self.variable not in self.context.initialized_variables and not lvalue:
         yield Diagnostic(Diagnostic.Messages.VARIABLE_NOT_INITIALIZED,
                          self.variable.name,
                          parseinfo=self.ast.parseinfo)
     elif isinstance(self.variable.value_type, ArrayType):
         if self.variable not in self.context.allocated_variables_mapping:
             yield Diagnostic(Diagnostic.Messages.VARIABLE_NOT_ALLOCATED,
                              self.variable.name,
                              parseinfo=self.ast.parseinfo)
         for index in self.indices:
             yield from index.validate()
         if lvalue:
             yield from self.validate_array_indexes()
예제 #5
0
    def validate(self):
        yield from super().validate()

        new_context = self.context_after
        for var in self.context.global_variables:
            if var not in new_context.initialized_variables:
                yield Diagnostic(
                    Diagnostic.Messages.GLOBAL_VARIABLE_NOT_INITIALIZED,
                    var.name,
                    parseinfo=self.ast.parseinfo)
예제 #6
0
    def validate_parameters(self):
        fun = self.function
        if len(self.parameters) != len(fun.parameters):
            yield Diagnostic(
                Diagnostic.Messages.CALL_WRONG_ARGS_NUMBER,
                fun.name, len(fun.parameters), len(self.parameters),
                parseinfo=self.ast.parseinfo,
            )
        for parameter, expression in zip(fun.parameters, self.parameters):
            expr_value_type = expression.value_type

            if expr_value_type != parameter.value_type:
                yield Diagnostic(
                    Diagnostic.Messages.CALL_WRONG_ARGS_TYPE,
                    parameter.name, fun.name, parameter.value_type, expr_value_type,
                    parseinfo=expression.ast.parseinfo,
                )

            yield from expression.validate()
예제 #7
0
 def validate(self):
     if not self.body.context_after.has_flushed_output:
         for statement in self.body.statements:
             if isinstance(statement, FlushStatement):
                 break
             if isinstance(statement, ReadStatement):
                 yield Diagnostic(
                     "missing flush between write and read instructions",
                     parseinfo=self.ast.parseinfo)
     yield from self.body.validate()
예제 #8
0
    def validate(self):
        yield from super().validate()

        invalid_parameter = next(
            (a for p, a in zip(self.parameters, self.ast.declarator.parameters)
             if not isinstance(p.value_type, ScalarType)), None)

        if invalid_parameter is not None:
            yield Diagnostic(
                Diagnostic.Messages.CALLBACK_PARAMETERS_MUST_BE_SCALARS,
                parseinfo=invalid_parameter.parseinfo,
            )
예제 #9
0
 def validate_return_value(self):
     fun = self.function
     return_type = fun.return_type
     if self.return_value is not None:
         yield from self.return_value.validate(lvalue=True)
     if return_type is not None and self.return_value is None:
         yield Diagnostic(
             Diagnostic.Messages.CALL_NO_RETURN_EXPRESSION, fun.name, return_type,
             parseinfo=self.ast.parseinfo,
         )
     if return_type is None and self.return_value is not None:
         yield Diagnostic(
             Diagnostic.Messages.FUNCTION_DOES_NOT_RETURN_VALUE, fun.name,
             parseinfo=self.ast.return_value.parseinfo,
         )
     return_expression_type = self.return_value and self.return_value.value_type
     if self.return_value is not None and return_expression_type != return_type:
         yield Diagnostic(
             Diagnostic.Messages.CALL_WRONG_RETURN_EXPRESSION, fun.name, return_type, return_expression_type,
             parseinfo=self.ast.return_value.parseinfo,
         )
예제 #10
0
 def validate(self):
     if self.global_variables and not self.init_body:
         yield Diagnostic(Diagnostic.Messages.INIT_BLOCK_MISSING,
                          parseinfo=self.body.ast.parseinfo)
     yield from self.body.validate()
예제 #11
0
 def validate(self):
     if not self.function:
         yield Diagnostic(Diagnostic.Messages.FUNCTION_NOT_DECLARED, self.function_name, parseinfo=self.ast.parseinfo)
     else:
         yield from self.validate_parameters()
         yield from self.validate_return_value()
예제 #12
0
 def validate(self):
     for var in self.variables:
         if var.name in self.context.variable_mapping.keys():
             yield Diagnostic(Diagnostic.Messages.VARIABLE_REDECLARED, var.name, parseinfo=self.ast.parseinfo)
예제 #13
0
 def validate(self):
     if not self.context.has_flushed_output:
         yield Diagnostic(Diagnostic.Messages.MISSING_FLUSH,
                          parseinfo=self.ast.parseinfo)
     for exp in self.arguments:
         yield from exp.validate(lvalue=True)