def typecheck(
     self,
     state: "TypeChecker.TypecheckingState" = None
 ) -> List[Tuple[TypeChecker.Types, str]]:
     if state is None:
         return self.typecheck(TypeChecker.TypecheckingState())
     if self.__next is None:
         val = TypeChecker.Types(self.__identifier_type)
         try:
             state.lookup_variable(str(self.__identifier))
             super().typecheckException(
                 "TYPECHECK ERROR: Variable {0} already defined".format(
                     str(self.__identifier)))
         except TypeChecker.TypecheckingStateException:
             state.bind_variable(str(self.__identifier), val)
         val = (val, str(self.__identifier))
         return [val]
     val = self.__next.typecheck(state)
     val2 = TypeChecker.Types(self.__identifier_type)
     try:
         state.lookup_variable(str(self.__identifier))
         super().typecheckException(
             "TYPECHECK ERROR: Variable {0} already defined".format(
                 str(self.__identifier)))
     except TypeChecker.TypecheckingStateException:
         state.bind_variable(str(self.__identifier), val2)
     val2 = (val2, str(self.__identifier))
     val.insert(0, val2)
     return val
def gen_assign_exp_token(assign_tree, call_from_main):
    """
    generate correct and incorrect string tokens from the AssignmentExpression tree
    args:
        assign_tree : the test tree of AssignmentExpression type
        call_from_main : to check function is called my main or as a part of sub expression
    return:
        list of correct and incorrect string tokens
    """

    # get assignment operator
    op = assign_tree.operator
    x_pos = []
    x_neg = []

    # get the left and right tree
    left, _ = TypeChecker.check_type_get_token(assign_tree.left)
    right, _ = TypeChecker.check_type_get_token(assign_tree.right)

    # form the correct example
    x_pos = x_pos + left
    x_pos = x_pos + [op]
    x_pos = x_pos + right

    return x_pos, x_neg
Beispiel #3
0
 def typecheck(self, state: "TypeChecker.TypecheckingState" = None) -> TypeChecker.Types:
     if state is None:
         return self.typecheck(TypeChecker.TypecheckingState())
     try:
         state.lookup_variable(str(self.__identifier))
         super().typecheckException(
             "TYPECHECK ERROR: Variable '{0}' already declared".format(str(self.__identifier)))
     except TypeChecker.TypecheckingStateException:
         state.bind_variable(str(self.__identifier), TypeChecker.Types(self.__variable_type))
     return TypeChecker.Types(self.__variable_type)  # type is string
Beispiel #4
0
def gen_binary_exp_token(assign_tree, call_from_main):
    """
    generate correct and incorrect string tokens from the binary expression tree
    args:
        assign_tree : the test tree of BinaryExpression type
        call_from_main : to check function is called my main or as a part of sub expression
    return:
        list of correct and incorrect string tokens
    """
    # Keys : all binary operators, values : coressponding wrong operator
    wrong_op = {
        ">": "<",
        "<": "> ",
        ">=": "<=",
        "<=": ">=",
        "!=": "==",
        "==": "!=",
        "===": "!==",
        "!==": "===",
        "&": "&&",
        "|": "||",
        "+": "-",
        "-": "+",
        "/": "*",
        "*": "/",
        "%": "/",
        "<<": ">>",
        ">>": "<<",
        ">>>": "<<<"
    }

    # binary operator
    op = assign_tree.operator

    x_pos = []
    x_neg = []

    # get the tokens of the left and right tree of binary expression
    left, _ = TypeChecker.check_type_get_token(assign_tree.left)
    right, _ = TypeChecker.check_type_get_token(assign_tree.right)

    # form list of tokens
    x_pos = x_pos + left
    x_pos = x_pos + [op]
    x_pos = x_pos + right

    # Type 5: Wrong operator
    # replace binary operator with corresponding wrong operator to generate incorrect examples
    if op in wrong_op.keys():
        x_neg = x_neg + left
        x_neg = x_neg + [wrong_op[op]]
        x_neg = x_neg + right

    return x_pos, x_neg
Beispiel #5
0
 def typecheck(self, state: "TypeChecker.TypecheckingState" = None) -> Union[TypeChecker.Types, List[dict]]:
     if state is None:
         return self.typecheck(TypeChecker.TypecheckingState())
     val = self.__expression.typecheck(state)
     if val != TypeChecker.Types.BOOL:
         super().typecheckException("TYPECHECK ERROR: Expected boolean condition got {0}".format(val.value))
     ret = None
     if self.__statement is not None:
         res = self.__statement.typecheck(state)
         if type(res) == dict and type(ret) != list:
             ret = list()
             ret.append(res)
         elif type(res) == dict and type(ret) == list:
             ret.append(res)
         elif type(res) == list and type(ret) != list:
             ret = res
         elif type(res) == list and type(ret) == list:
             for x in res:
                 ret.append(x)
     if self.__else_statement is not None:
         res = self.__else_statement.typecheck(state)
         if type(res) == dict and type(ret) != list:
             ret = list()
             ret.append(res)
         elif type(res) == dict and type(ret) == list:
             ret.append(res)
         elif type(res) == list and type(ret) != list:
             ret = res
         elif type(res) == list and type(ret) == list:
             for x in res:
                 ret.append(x)
     if ret is None:
         ret = TypeChecker.Types.VOID
     return ret
Beispiel #6
0
 def typecheck(self, state: "TypeChecker.TypecheckingState" = None) -> TypeChecker.Types:
     if state is None:
         return self.typecheck(TypeChecker.TypecheckingState())
     state.enter_scope()
     ret_type = TypeChecker.Types(self.__return_type)
     if self.__params is not None:
         self.__params = self.__params.typecheck(state)
     else:
         self.__params = list()
     try:
         state.lookup_function(str(self.__identifier))
         super().typecheckException("TYPECHECK EXCEPTION: Function with same name already declared")
     except TypeChecker.TypecheckingStateException:
         state.bind_function(str(self.__identifier), (ret_type, self.__params, self.__body, super().get_line(), super().get_column()))
     state.exit_scope()
     return ret_type
 def typecheck(self, state: TypeChecker.TypecheckingState = None) -> TypeChecker.Types:
     if state is None:
         return self.typecheck(TypeChecker.TypecheckingState())
     try:
         return state.lookup_variable(str(self.__identifier))
     except TypeChecker.TypecheckingStateException as e:
         super().typecheckException(str(e))
 def typecheck(
         self,
         state: TypeChecker.TypecheckingState = None) -> TypeChecker.Types:
     if state is None:
         return self.typecheck(TypeChecker.TypecheckingState())
     if str(self.__identifier) == "print":
         self.__expression.typecheck(state)
         self.__expected_return_type = TypeChecker.Types.VOID
         return self.__expected_return_type
     try:
         # funct[0] == ret_Type; funct[1] == list(params_type)
         funct = state.lookup_function(str(self.__identifier))
         # args_type == list(types)
         args_type = self.__expression.typecheck(state)
         if len(funct[1]) != len(args_type):
             super().typecheckException(
                 "TYPECHECK ERROR: Parameters quantity mismatch")
         for i in range(len(funct[1])):
             if funct[1][i][0] != args_type[i]:
                 super().typecheckException(
                     "TYPECHECK ERROR: Parameter type mismatch")
         self.__expected_return_type = funct[0]
         return self.__expected_return_type
     except TypeChecker.TypecheckingStateException as e:
         super().typecheckException(str(e))
def gen_unary_exp_token(unary_tree, call_from_main):
    """
    generate correct and incorrect string tokens from the unary expression tree
    args:
        unary_tree : the test tree of UnaryExpression type
        call_from_main : to check function is called my main or as a part of sub expression
    return:
        list of correct and incorrect string tokens
    """

    # get the unary operator
    op = unary_tree.operator
    x_pos = []
    x_neg = []

    #unary_operator = ["!", "~", "-"]
    unary_operator = ["!"]

    # get the argument of the unary tree
    arg, _ = TypeChecker.check_type_get_token(unary_tree.argument)

    # form the correct token
    x_pos = x_pos + [op]
    x_pos = x_pos + arg

    # Type 4: negated condition
    # add only the argument, remove the ! unary operator
    if op in unary_operator:
        x_neg += arg

    return x_pos, x_neg
Beispiel #10
0
 def typecheck(self, state: "TypeChecker.TypecheckingState" = None) -> TypeChecker.Types:
     if state is None:
         return self.typecheck(TypeChecker.TypecheckingState())
     val = self.__expression.typecheck(state)
     if val != TypeChecker.Types.BOOL:
         super().typecheckException("TYPECHECK ERROR: Expected boolean condition got {0}".format(val.value))
     ret = None
     if self.__body is not None:
         res = self.__body.typecheck(state)
         if type(res) == dict and type(ret) != list:
             ret = list()
             ret.append(res)
         elif type(res) == dict and type(ret) == list:
             # noinspection PyUnresolvedReferences
             ret.append(res)  # ret is not none, ret is list
         elif type(res) == list and type(ret) != list:
             ret = res
         elif type(res) == list and type(ret) == list:
             # noinspection PyTypeChecker
             for x in res:  # res is not none, res is list
                 # noinspection PyUnresolvedReferences
                 ret.append(x)  # ret is not none, ret is list
     if ret is None:
         ret = TypeChecker.Types.VOID
     return ret
    def typecheck(
            self,
            state: TypeChecker.TypecheckingState = None) -> TypeChecker.Types:
        if state is None:
            return self.typecheck(TypeChecker.TypecheckingState())
        val1 = self.__left.typecheck(state)
        val2 = self.__right.typecheck(state)

        if self.__bin_op_type == BinaryOperatorType.PLUS or self.__bin_op_type == BinaryOperatorType.MINUS or \
                self.__bin_op_type == BinaryOperatorType.MULTIPLY or self.__bin_op_type == BinaryOperatorType.DIVIDE \
                or self.__bin_op_type == BinaryOperatorType.MODULUS:
            self.__expected_parameters_type = TypeChecker.Types.INT
            if val1 != self.__expected_parameters_type:
                super().typecheckException(
                    "TYPECHECK ERROR: Expected integer type got {0}".format(
                        val1.value))
            if val2 != self.__expected_parameters_type:
                super().typecheckException(
                    "TYPECHECK ERROR: Expected integer type got {0}".format(
                        val2.value))
            return TypeChecker.Types.INT

        if self.__bin_op_type == BinaryOperatorType.GREATER or self.__bin_op_type == BinaryOperatorType.LOWER or \
                self.__bin_op_type == BinaryOperatorType.GREATER_EQUAL or \
                self.__bin_op_type == BinaryOperatorType.LOWER_EQ:
            self.__expected_parameters_type = TypeChecker.Types.INT
            if val1 != self.__expected_parameters_type:
                super().typecheckException(
                    "TYPECHECK ERROR: Expected integer type got {0}".format(
                        val1.value))
            if val2 != self.__expected_parameters_type:
                super().typecheckException(
                    "TYPECHECK ERROR: Expected integer type got {0}".format(
                        val2.value))
            return TypeChecker.Types.BOOL

        if self.__bin_op_type == BinaryOperatorType.AND or self.__bin_op_type == BinaryOperatorType.OR:
            self.__expected_parameters_type = TypeChecker.Types.BOOL
            if val1 != self.__expected_parameters_type:
                super().typecheckException(
                    "TYPECHECK ERROR: Expected boolean type got {0}".format(
                        val1.value))
            if val2 != self.__expected_parameters_type:
                super().typecheckException(
                    "TYPECHECK ERROR: Expected boolean type got {0}".format(
                        val2.value))
            return TypeChecker.Types.BOOL

        if self.__bin_op_type == BinaryOperatorType.EQUALS or self.__bin_op_type == BinaryOperatorType.NOT_EQUALS:
            if val1 != val2:
                super().typecheckException(
                    "TYPECHECK ERROR: Expected same type got {0} and {1}".
                    format(val1.value, val2.value))
            self.__expected_parameters_type = val1
            return TypeChecker.Types.BOOL

        super().typecheckException(
            "TYPECHECK ERROR: Unknown binary operator {0}".format(
                self.__bin_op_type.value))
 def typecheck(self, state: TypeChecker.TypecheckingState = None) -> TypeChecker.Types:
     if state is None:
         return self.typecheck(TypeChecker.TypecheckingState())
     try:
         int(self.__num)
     except ValueError:
         super().typecheckException("INTERPRETATION ERROR: expected integer got {0}".format(self.__num))
     return TypeChecker.Types.INT
Beispiel #13
0
 def typecheck(self, state: "TypeChecker.TypecheckingState" = None) -> List[TypeChecker.Types]:
     if state is None:
         state = TypeChecker.TypecheckingState()
         self.typecheck(state)
         try:
             state.lookup_function("main")
         except TypeChecker.TypecheckingStateException as e:
             super().typecheckException(str(e))
         for key in state.get_all_functions():
             state.enter_scope()
             fun = state.lookup_function(key)
             state.set_current_function_name(key)
             ret_type = fun[0]
             for elem in fun[1]:
                 # elem_type = elem[0]
                 # elem_name = elem[1]
                 state.bind_variable(elem[1], elem[0])
             if fun[2] is not None:
                 body = fun[2].typecheck(state)
             if not body:
                 body = TypeChecker.Types.VOID
             if type(body) == list:
                 for ret in body:
                     if ret['return'] != ret_type:
                         super().typecheckException(
                             "TYPECHECK ERROR: Return type mismatch: function '{0}' should return {1}, "
                             "{2} returned instead on line {3} column {4}".format(key, ret_type.value, ret['return'].value, fun[3, fun[4]]))
             elif body != ret_type:
                 super().typecheckException(
                     "TYPECHECK ERROR: Return type mismatch: function '{0}' should return {1}, "
                     "{2} returned instead on line {3} column {4}".format(key, ret_type.value, body.value, fun[3], fun[4]))
             state.exit_scope()
         return True
     ret = list()
     res = self.__head.typecheck(state)
     if type(res) == dict and type(ret) != list:
         ret = list()
         ret.append(res)
     elif type(res) == dict and type(ret) == list:
         ret.append(res)
     elif type(res) == list and type(ret) != list:
         ret = res
     elif type(res) == list and type(ret) == list:
         for x in res:
             ret.append(x)
     if self.__tail is not None and self.__tail != "":
         res = self.__tail.typecheck(state)
         if type(res) == dict and type(ret) != list:
             ret = list()
             ret.append(res)
         elif type(res) == dict and type(ret) == list:
             ret.append(res)
         elif type(res) == list and type(ret) != list:
             ret = res
         elif type(res) == list and type(ret) == list:
             for x in res:
                 ret.append(x)
     return ret
Beispiel #14
0
def gen_logical_exp_token(logical_tree, call_from_main):
    """
    generate correct and incorrect string tokens from the logical expression tree
    args:
        logical_tree : the test tree of LogicalExpression type
        call_from_main : to check function is called my main or as a part of sub expression
    """

    # fetch the logical operator from the AST tree
    op = logical_tree.operator

    x_pos = []
    x_neg = []
    x_neg_list = []

    # obtain the left and right tree from the corresponding trees
    left, _ = TypeChecker.check_type_get_token(logical_tree.left)
    right, _ = TypeChecker.check_type_get_token(logical_tree.right)

    x_pos = x_pos + left
    x_pos = x_pos + [op]
    x_pos = x_pos + right

    cond1_type = ["Identifier", "Literal"]
    cond2_type = ["MemberExpression", "CallExpression"]

    # incorrect token formation
    if op == "&&":
        # Type 1 : Incomplete Conditional Expression
        # store only the right tree
        if (logical_tree.left.type
                == "Identifier") and (logical_tree.right.type
                                      not in cond1_type):
            x_neg = right

        # Type 2 : incorrectly ordered Boolean expression
        # swap the left and right tree on both sides of the operator
        else:
            if logical_tree.right.type in cond2_type:

                x_neg = x_neg + right
                x_neg = x_neg + [op]
                x_neg = x_neg + left

    return x_pos, x_neg
Beispiel #15
0
 def typecheck(self, state: "TypeChecker.TypecheckingState" = None) -> TypeChecker.Types:
     if state is None:
         return self.typecheck(TypeChecker.TypecheckingState())
     if self.__statement is not None:
         state.enter_scope()
         val = self.__statement.typecheck(state)
         state.exit_scope()
         return val
     return TypeChecker.Types.VOID
 def typecheck(
     self,
     state: TypeChecker.TypecheckingState = None
 ) -> List[TypeChecker.Types]:
     if state is None:
         return self.typecheck(TypeChecker.TypecheckingState())
     if self.__expression is not None:
         return self.__expression.typecheck(state)
     return []
 def typecheck(self, state: TypeChecker.TypecheckingState = None) -> List[TypeChecker.Types]:
     if state is None:
         return self.typecheck(TypeChecker.TypecheckingState())
     if self.__next_expression is None:
         val = self.__current_expression.typecheck(state)
         return [val]
     val = self.__next_expression.typecheck(state)
     val2 = self.__current_expression.typecheck(state)
     val.insert(0, val2)
     return val
 def typecheck(
         self,
         state: TypeChecker.TypecheckingState = None) -> TypeChecker.Types:
     if state is None:
         return self.typecheck(TypeChecker.TypecheckingState())
     if self.__boolean != 'true' and self.__boolean != 'false':
         super().typecheckException(
             "TYPECHECK ERROR: expected boolean got {0}".format(
                 self.__boolean))
     return TypeChecker.Types.BOOL
Beispiel #19
0
 def typecheck(self, state: "TypeChecker.TypecheckingState" = None) -> dict:
     if state is None:
         return self.typecheck(TypeChecker.TypecheckingState())
     ret = TypeChecker.Types.VOID
     if self.__expression is not None:
         ret = self.__expression.typecheck(state)
     self.__expected_return_type = state.lookup_function(state.get_current_function_name())[0]
     if ret != self.__expected_return_type:
         super().typecheckException("TYPECHECK ERROR: Return type missmatch, expected {0} got {1}".format(self.__expected_return_type.value, ret.value))
     return {"type": ret, "return": ret}
def gen_logical_exp_token(Call_tree, call_from_main=False):
    """
    generate correct and incorrect string tokens from the callee expression tree
    args:
        Call_tree : the test tree of CalleeExpression type
        call_from_main : to check function is called my main or as a part of sub expression
    return:
        list of correct and incorrect string tokens
    """

    x_pos = []
    x_neg = []

    argument_vector = []
    wrong_arg_done = False

    # get the token for the callee
    callee, _ = TypeChecker.check_type_get_token(Call_tree.callee)

    # get the string token for each argument from the AST tree
    for arg in Call_tree.arguments:
        arg_token, _ = TypeChecker.check_type_get_token(arg)
        argument_vector.append(arg_token)

    # geenrate correct sample
    x_pos = x_pos + callee

    for arg in argument_vector:
        x_pos = x_pos + arg

    # Type 3: Wrong Identifier
    # generate incorrect sample by changing the argument  to "incorrect"
    if call_from_main == True:
        x_neg = x_neg + callee
        for arg in argument_vector:
            if not wrong_arg_done and len(arg) == 1:
                arg = ["wrong_arg"]
                wrong_arg_done = True

            x_neg = x_neg + arg

    return x_pos, x_neg
Beispiel #21
0
 def typecheck(self, state: "TypeChecker.TypecheckingState" = None) -> TypeChecker.Types:
     if state is None:
         return self.typecheck(TypeChecker.TypecheckingState())
     val = self.__expr.typecheck(state)
     try:
         var_type = state.lookup_variable(str(self.__identifier))
         if var_type != val:
             super().typecheckException("TYPECHECK ERROR: Expected {0} got {1}".format(var_type.value, val.value))
         return var_type
     except TypeChecker.TypecheckingStateException as e:
         super().typecheckException(str(e))
def gen_member_exp_token(member_tree, call_from_main=False):
    """
    generate correct and incorrect string tokens from the member expression tree
    args:
        member_tree : the test tree of MemberExpression type
        call_from_main : to check function is called my main or as a part of sub expression
    return:
        list of correct and incorrect string tokens
    """
    x_pos = []
    x_neg = []

    # get the object and property sub tree tree
    obj, _ = TypeChecker.check_type_get_token(member_tree.object)
    prop, _ = TypeChecker.check_type_get_token(member_tree.property)

    # form the correct token
    x_pos = x_pos + obj
    x_pos = x_pos + prop

    return x_pos, x_neg
 def typecheck(self, state: TypeChecker.TypecheckingState = None) -> TypeChecker.Types:
     if state is None:
         return self.typecheck(TypeChecker.TypecheckingState())
     val = self.__expression.typecheck(state)
     if self.__unary_op_type == UnaryOperatorType.NOT:
         if val != TypeChecker.Types.BOOL:
             super().typecheckException("TYPECHECK ERROR: Expected boolean type got {0}".format(val.value))
         return TypeChecker.Types.BOOL
     if self.__unary_op_type == UnaryOperatorType.MINUS:
         if val != TypeChecker.Types.INT:
             super().typecheckException("TYPECHECK ERROR: Expected integer type got {0}".format(val.value))
         return TypeChecker.Types.INT
     super().typecheckException("TYPECHECK ERROR: Unknown unary operator {0}".format(self.__unary_op_type.value))
Beispiel #24
0
def gen_update_exp_token(update_tree, call_from_main):
    """
    generate correct and incorrect string tokens from the update expression tree
    args:
        Call_tree : the test tree of UpdateExpression type
        call_from_main : to check function is called my main or as a part of sub expression
    return:
        list of correct and incorrect string tokens
    """

    # get the operator of the update expression
    op = update_tree.operator

    # type of update expression, pre operation or post operation
    prefix = update_tree.prefix

    x_pos = []
    x_neg = []

    # string token of the argument
    arg, _ = TypeChecker.check_type_get_token(update_tree.argument)

    # form correct token
    # Type 3: wrong identifier
    # if the argument is of type identifier, change the identifier to "incorrect"
    if prefix == "True":
        x_pos = x_pos + [op]
        x_pos = x_pos + arg

        if update_tree.argument.type == "Identifier":
            x_neg = x_neg + [op]
            x_neg = ["incorrect"]
    else:
        x_pos = x_pos + arg
        x_pos = x_pos + [op]

        if update_tree.argument.type == "Identifier":
            x_neg = ["incorrect"]
            x_neg = x_neg + [op]

    return x_pos, x_neg
 def typecheck(
         self,
         state: TypeChecker.TypecheckingState = None) -> TypeChecker.Types:
     if state is None:
         return self.typecheck(TypeChecker.TypecheckingState())
     return self.__expression.typecheck(state)
 def typecheckException(self, msg: str):
     if self.__line is not None:
         msg += " on line: " + str(self.__line)
         if self.__column is not None:
             msg += " column: " + str(self.__column)
     raise TypeChecker.TypecheckerException(msg)
Beispiel #27
0
from TreePrinter import TreePrinter
import TypeChecker
import Interpreter

if __name__ == '__main__':

    try:
        filename = sys.argv[1] if len(sys.argv) > 1 else "pi.m"
        file = open(filename, "r")
    except IOError:
        print("Cannot open {0} file".format(filename))
        sys.exit(0)

    parser = yacc.yacc(module=Mparser)
    text = file.read()
    ast = parser.parse(text, lexer=scanner.lexer)
    if not Mparser.incorrect_input:
        typeChecker = TypeChecker.TypeChecker()
        typeChecker.visit(ast)  # or alternatively ast.accept(typeChecker)
        if not TypeChecker.typo:
            interpreter = Interpreter.Interpreter()
            interpreter.interpret(ast)
    #     ast.printTree()

    # Below code shows how to use visitor

    # in future
    # ast.accept(OptimizationPass1())
    # ast.accept(OptimizationPass2())
    # ast.accept(CodeGenerator())
Beispiel #28
0
 def typecheck(self, state: "TypeChecker.TypecheckingState" = None) -> TypeChecker.Types:
     if state is None:
         return self.typecheck(TypeChecker.TypecheckingState())