Example #1
0
 def wrapper(cls, name):
     print 'in verify_private_procedure for checking {}, for {}'.format(
         name.is_private, name.name)
     if name.is_private:
         if kwargs.get('suppress'):
             raise mylang_errors.VariableNotDeclared(
                 "procedure '{}' not declared".format(name.name))
         raise mylang_errors.PrivateVariableDeclaration(
             "procedure '{}' is private".format(name.name))
Example #2
0
 def variable_exists(self, var):
     if var.value.value not in self.variables:
         if var.value.value not in self.scopes:
             raise mylang_errors.VariableNotDeclared(
                 "At line {}, near '{}': variable '{}' not declared".format(
                     var.value.line_number, var.value.value,
                     var.value.value))
         return self.scopes[var.value.value]
     return self.variables[var.value.value]
Example #3
0
 def wrapper(cls, val_name):
     print 'val_name here', val_name
     if val_name in cls.private_variables:
         if kwargs.get('suppress'):
             raise mylang_errors.VariableNotDeclared(
                 "Scope value '{}' not declared".format(val_name))
         raise mylang_errors.PrivateVariableDeclaration(
             "Scope value '{}' is a private member variable".format(
                 val_name))
     return f(cls, val_name)
Example #4
0
    def parse_assign(self, line):

        operation_converters = {
            'PLUS': lambda x, y: x + y,
            'BAR': lambda x, y: x - y,
            'STAR': lambda x, y: x * y,
            'FORWARDSLASH': lambda x, y: x / y
        }
        current = next(line, None)
        if current.type == 'VARIABLE':
            test_final = next(line, None)
            if not test_final:
                if current.value.value not in self.variables:
                    raise mylang_errors.VariableNotDeclared(
                        "At line {}, '{}' not declared".format(
                            current.value.line_number, current.value.value))
                return self.variables[current.value.value]
            current.value.isValid(test_final.value)
            if test_final.type == 'DOT':
                path = collections.deque([current.value.value])
                end_line = False
                last_seen = None
                while True:
                    temp_path = next(line, None)
                    if not temp_path:
                        end_line = True
                        break
                    check = next(line, None)
                    if not check:
                        path.append(temp_path.value.value)
                        break
                    temp_path.value.isValid(check.value)
                    if check.type in operation_converters:
                        last_seen = check
                        path.append(temp_path.value.value)
                        break
                    if temp_path.type == 'VARIABLE':
                        path.append(temp_path.value.value)
                    if temp_path.type in operation_converters:
                        last_seen = temp_path
                        break
                print 'self.scopes', self.scopes
                if path[0] not in self.scopes:
                    raise mylang_errors.AttributeNotFound(
                        "At line {}, near {}: variable '{}' has no attribute '{}'"
                        .format(current.value.line_number, current.value.value,
                                current.value.value, path[1]))
                scope_result = self.scopes
                while path:
                    val = path.popleft()
                    scope_result = scope_result[val]
                if last_seen:
                    try:
                        final_part = self.parse_assign(line)
                        print 'scope_result', scope_result, type(scope_result)
                        return operation_converters[last_seen.type](
                            scope_result, final_part)
                    except:
                        raise mylang_errors.IncompatableTypes(
                            "Cannot {} value of type '{}' to type '{}'".format(
                                {
                                    'PLUS': 'contactinate',
                                    'BAR': 'subtract',
                                    'STAR': 'multiply',
                                    'FORWARDSLASH': 'divide'
                                }[last_seen.type],
                                type(scope_result).__name__,
                                type(final_part).__name__))
                print "scope_result", scope_result
                return scope_result
            '''
            if test_final.type == 'PLUS':
                returned_val = self.parse_assign(line)
                return self.variables[current.value.value]+(string.ascii_lowercase+string.ascii_uppercase)[52%returned_val] if isinstance(returned_val, int) and isinstance(self.variables[current.value.value], str) else self.variables[current.value.value]+returned_val
            '''
            if test_final.type in operation_converters:
                returned_val = self.parse_assign(line)
                if type(returned_val) != type(
                        self.variables[current.value.value]):
                    raise mylang_errors.IncompatableTypes(
                        "At line {}, near {}, cannot {} variable of type '{}' to type '{}'"
                        .format(
                            current.value.line_number, current.value.value, {
                                'PLUS': 'concatinate',
                                'BAR': 'subtract',
                                'STAR': 'multiply',
                                'FORWARDSLASH': 'divide'
                            }[test_final.type],
                            type(self.variables[current.value.value]).__name__,
                            type(returned_val).__name__))
                return operation_converters[test_final.type](
                    self.variables[current.value.value], returned_val)
        if current.type == 'DIGIT':
            test_final = next(line, None)
            if not test_final:
                return int(current.value.value)
            current.value.isValid(test_final.value)
            '''
            if test_final.type == 'PLUS':
                returned_val = self.parse_assign(line)
                if not isinstance(returned_val, int):
                    raise mylang_errors.IncompatableTypes("At line {}, cannot concatinate type 'INT' to type {}".format(test_final.value.line_number, type(returned_val)))
                return int(current.value.value) + self.parse_assign(line)
            '''
            if test_final.type in operation_converters:
                if test_final.type == 'STAR':
                    second = next(line, None)
                    print('second', second.value.value, current.value.value)
                    if second.type != 'DIGIT':

                        raise mylang_errors.IncompatableTypes(
                            "At line {}, cannot multiply type 'INT' to type {}"
                            .format(second.value.line_number,
                                    type(second.value.value).__name__))
                    operator = next(line, None)
                    if not operator:
                        return int(second.value.value) * int(
                            current.value.value)
                    returned_val = self.parse_assign(line)

                    return operation_converters[operator.type](
                        int(current.value.value) * int(second.value.value),
                        returned_val)
                returned_val = self.parse_assign(line)

                if type(returned_val) != type(int(current.value.value)):
                    raise mylang_errors.IncompatableTypes(
                        "At line {}, near {}, cannot {} variable of type 'INT' to type '{}'"
                        .format(
                            current.value.line_number, current.value.value, {
                                'PLUS': 'concatinate',
                                'BAR': 'subtract',
                                'STAR': 'multiply',
                                'FORWARDSLASH': 'divide'
                            }[test_final.type],
                            type(returned_val).__name__))
                return operation_converters[test_final.type](int(
                    current.value.value), returned_val)
        if current.type == 'STRING':
            test_final = next(line, None)
            if not test_final:
                return current.value.value[1:-1]
            current_line.value.isValid(test_final.value)
            if test_final.type == 'PLUS':
                returned_val = self.parse_assign(line)
                if not isinstance(returned_val, str) or not isinstance(
                        returned_val, int):
                    raise mylang_errors.IncompatableTypes(
                        "At line {}, cannot concatinate type 'STRING' to type {}"
                        .format(test_final.value.line_number,
                                type(returned_val)))
                return current.value.value[1:-1] + (
                    string.ascii_lowercase +
                    string.ascii_uppercase)[52 % returned_val] if isinstance(
                        returned_val,
                        int) else current.value.value[1:-1] + returned_val
            if test_final.type in operation_converters:
                raise mylang_errors.IncompatableTypes(
                    "At line {}, cannot {} type 'string' to type '{}'".format(
                        current.value.line_number, {
                            'PLUS': 'concatinate',
                            'BAR': 'subtract',
                            'STAR': 'multiply',
                            'FORWARDSLASH': 'divide'
                        }[test_final.type],
                        type(returned_val).__name__))
Example #5
0
    def parse_expression(self, line):
        operation_converters = {
            'PLUS': lambda x, y: x + y,
            'BAR': lambda x, y: x - y,
            'STAR': lambda x, y: x * y,
            'FORWARDSLASH': lambda x, y: x / y
        }
        current = next(line, None)
        print 'current here', current
        #print 'current here', current
        if not current:
            return None
        if current.type == 'VARIABLE':
            next_val = next(line, None)
            if not next_val or next_val.type == 'COMMA' or next_val.type == 'CPAREN' or next_val.type == 'CBRACKET':
                self.line = iter([next_val] + [i for i in line])
                return self.variable_exists(current)
            current.value.isValid(next_val.value)

            if next_val.type == 'OPAREN':
                check_next_v = next(line, None)
                if not check_next_v:
                    raise mylang_errors.ParameterSytnaxError(
                        "At line {}, near '{}': reached unexpected end of procedure call"
                        .format(current.value.line_number,
                                current.value.value))
                if check_next_v.type == 'CPAREN':
                    if current.value.value not in self.procedures:
                        raise mylang_errors.AttributeNotFound(
                            "At line {}, near '{}': procedure '{}' not found".
                            format(current.value.line_number,
                                   current.value.value, current.value.value))
                    result, namespace = self.procedures[current.value.value]()
                    self.variables = namespace if namespace else self.variables
                    check_last_v = next(line, None)
                    if check_last_v.type in ['COMMA', 'CPAREN', 'CBRACKET']:
                        self.line = iter([check_last_v] + [i for i in line])
                        return result
                    if check_last_v.type in operation_converters:
                        final_result = self.parse_expression(line)
                        if type(result) != type(final_result):
                            raise mylang_errors.IncompatableTypes(
                                "At line {}, near '{}' cannot {} value of type '{}' to type '{}'"
                                .format(
                                    check_last_v.value.line_number,
                                    check_last_v.value.value, {
                                        'PLUS': 'concatinate',
                                        'BAR': 'subtract',
                                        'STAR': 'multiply',
                                        'FORWARDSLASH': 'divide'
                                    }[check_last_v.type],
                                    type(result).__name__,
                                    type(final_result).__name__))
                        return operation_converters[check_last_v.type](
                            result, final_result)
                if current.value.value not in self.procedures:
                    raise mylang_errors.VariableNotDeclared(
                        "At line {}: procedure '{}' not declared".format(
                            current.value.line_number, current.value.value))
                self.line = iter([check_next_v] + [i for i in line])
                params = []
                while True:
                    current_param = self.parse_expression(line)
                    can_continue = next(line, None)
                    params.append(current_param)
                    if not can_continue or can_continue.type == 'CPAREN':
                        break
                    self.line = iter([can_continue] + [i for i in line])
                print 'PARAMS HERE', params
                result, namespace = self.procedures[current.value.value](
                    *params)
                self.variables = namespace if namespace else self.variables
                checking_next_v = next(line, None)
                if not checking_next_v or checking_next_v.type in [
                        'COMMA', 'CPAREN', 'CBRACKET'
                ]:
                    self.line = iter([checking_next_v] + [i for i in line])
                    return result
                if checking_next_v.type in operation_converters:
                    returned_result = self.parse_expression(line)
                    if type(result) != type(returned_result):
                        raise mylang_errors.IncompatableTypes(
                            "At line {}, near '{}' cannot {} value of type '{}' to type '{}'"
                            .format(
                                checking_next_v.value.line_number,
                                checking_next_v.value.value, {
                                    'PLUS': 'concatinate',
                                    'BAR': 'subtract',
                                    'STAR': 'multiply',
                                    'FORWARDSLASH': 'divide'
                                }[checking_next_v.type],
                                type(result).__name__,
                                type(returned_result).__name__))
                    return operation_converters[checking_next_v.type](
                        result, returned_result)
            if next_val.type == 'DOT':
                path = [current.value.value]

                seen_operator = False
                while True:
                    current_attr = next(line, None)
                    if not current_attr:
                        raise mylang_errors.InvalidAttributeCall(
                            "At line {}, near '{}'".format(
                                next_val.value.line_number,
                                next_val.value.value))
                    if current_attr.type == 'VARIABLE':

                        checking_next = next(line, None)
                        if not checking_next:
                            path.append(current_attr.value.value)
                            break
                        current_attr.value.isValid(checking_next.value)
                        path.append(current_attr.value.value)
                        if checking_next.type == 'OPAREN':

                            method_params = []
                            while True:
                                current_param = self.parse_expression(line)
                                method_params.append(current_param)
                                check_next_final = next(line, None)

                                if not check_next_final or check_next_final.type == "CPAREN" or check_next_final.type == 'COMMA':

                                    break

                                self.line = iter([check_next_final] +
                                                 [i for i in line])

                            current_scope_selection = self.scopes if path[
                                0] not in self.variables else self.variables
                            path = list(path)
                            the_method = path[-1]
                            copy_path = list(copy.deepcopy(path))
                            start = path[0]
                            path = path[:-1]
                            while path:
                                current_scope_selection = current_scope_selection[
                                    path[0]]
                                path = path[1:]
                            Scope.private_procedure_check(
                                current_scope_selection.procedures[the_method])
                            to_return, namespace = current_scope_selection.procedures[
                                the_method](*method_params)
                            base = self.scopes if start not in self.variables else self.variables
                            base[start].update_namespace(copy_path,
                                                         namespace,
                                                         start=start,
                                                         end=copy_path[-1])
                            return to_return
                        if checking_next.type in operation_converters or checking_next.type == 'CPAREN' or checking_next.type == 'COMMA' or checking_next.type == 'CBRACKET':
                            seen_operator = None if (
                                checking_next.type == 'CPAREN'
                                or checking_next.type == 'COMMA'
                                or checking_next.type
                                == 'CBRACKET') else checking_next.type
                            self.line = iter([checking_next] +
                                             [i for i in line])
                            break

                start_scope = path[0]
                flag = False
                if start_scope not in self.scopes:
                    if start_scope not in self.variables:
                        raise mylang_errors.VariableNotDeclared(
                            "Scope '{}' not declared".format(start_scope))
                    flag = True
                current_value_attr = self.scopes if not flag else self.variables
                while path:
                    try:
                        new_val = current_value_attr[path[0]]
                        print 'in try block', new_val
                    except:
                        if path[0] not in current_value_attr.scopes:
                            raise mylang_errors.AttributeNotFound(
                                "At line {}, near '{}':scope '{}' has no attribute '{}'"
                                .format(current_attr.value.line_number,
                                        current_attr.value.value, start_scope,
                                        path[0]))
                        current_value_attr = current_value_attr.scopes[path[0]]
                        path = path[1:]
                    else:
                        current_value_attr = new_val
                        path = path[1:]
                if seen_operator:
                    returned_val = self.parse_expression(line)
                    if type(current_value_attr) != type(returned_val):
                        raise mylang_errors.IncompatableTypes(
                            "At line {}, near '{}': cannot {} value of type '{}' to type '{}'"
                            .format(
                                current_attr.value.line_number,
                                current_attr.value.value, {
                                    'PLUS': 'concatinate',
                                    'BAR': 'subtract',
                                    'STAR': 'multiply',
                                    'FORWARDSLASH': 'divide'
                                }[seen_operator],
                                type(current_value_attr).__name__,
                                type(returned_val).__name__))
                    return operation_converters[seen_operator](
                        current_value_attr, returned_val)

                return current_value_attr
            returned_val = self.parse_expression(line)
            if type(self.variables[current.value.value]) != type(returned_val):
                raise mylang_errors.IncompatableTypes(
                    "At line {}, near '{}': cannot {} variable of type '{}' to type '{}'"
                    .format(
                        current.value.line_number, current.value.value, {
                            'PLUS': 'concatinate',
                            'BAR': 'subtract',
                            'STAR': 'multiply',
                            'FORWARDSLASH': 'divide'
                        }[next_val.type],
                        type(self.variables[current.value.value]).__name__,
                        type(returned_val).__name__))
            return operation_converters[next_val.type](
                self.variables[current.value.value], returned_val)
        if current.type == 'DIGIT':
            next_val = next(line, None)
            if not next_val or next_val.type == 'COMMA' or next_val.type == 'CPAREN' or next_val.type == 'CBRACKET':

                self.line = iter([next_val] + [i for i in line])
                return int(current.value.value)
            current.value.isValid(next_val.value)
            return_val = self.parse_expression(line)
            if not isinstance(return_val, int):
                raise mylang_errors.IncompatableTypes(
                    "At line {}, near '{}': cannot {} variable of type '{}' to type '{}'"
                    .format(
                        current.value.line_number, current.value.value, {
                            'PLUS': 'concatinate',
                            'BAR': 'subtract',
                            'STAR': 'multiply',
                            'FORWARDSLASH': 'divide'
                        }[next_val.type],
                        type(self.variables[current.value.value]).__name__,
                        type(return_val).__name__))
            return operation_converters[next_val.type](int(
                current.value.value), return_val)
        if current.type == 'STRING':
            next_val = next(line, None)
            if not next_val or next_val.type == 'COMMA' or next_val.type == 'CPAREN' or next_val.type == 'CBRACKET':

                self.line = iter([next_val] + [i for i in self.line])
                return current.value.value[1:-1]
            return_val = self.parse_expression(line)
            if not isinstance(return_val, str):
                raise mylang_errors.IncompatableTypes(
                    "At line {}, near '{}': cannot {} variable of type '{}' to type '{}'"
                    .format(
                        current.value.line_number, current.value.value, {
                            'PLUS': 'concatinate',
                            'BAR': 'subtract',
                            'STAR': 'multiply',
                            'FORWARDSLASH': 'divide'
                        }[next_val.type],
                        type(current.value.value).__name__,
                        type(return_val).__name__))
            if next_val.type == "PLUS":
                return current.value.value[1:-1] + return_val
        raise mylang_errors.NotYetSupportedError("Operation not yet supported")