예제 #1
0
def _generate_binop(self, node, ext_info):
    left_type = self.get_type(node.left)
    right_type = self.get_type(node.right)
    extra_code = ext_info.get('extra_code', '')

    if left_type.is_void or right_type.is_void:
        raise CompileError('Void type is not able to operate.')

    if left_type.is_number and right_type.is_number:
        op = self.generate_numeric_op(node.op, ext_info)
        if len(op) is 0:
            raise SyntaxNotSupportError("%s operation is not support yet." %
                                        node.op.__class__.__name__)

        left_name, extra_code = get_node_name_with_extra_code(
            self, node.left, extra_code)
        right_name, extra_code = get_node_name_with_extra_code(
            self, node.right, extra_code)

        return '$(( %s %s %s ))' % (left_name, op, right_name), extra_code
    elif (left_type.is_string or right_type.is_string) and isinstance(
            node.op, ast.Add):
        _ext_info = {'extra_code': extra_code}
        left = self.dispatch(node.left, _ext_info)
        right = self.dispatch(node.right, _ext_info)

        return left + right, _ext_info['extra_code']
    else:
        raise SyntaxNotSupportError("%s operation is not support yet." %
                                    node.op.__class__.__name__)
예제 #2
0
    def get_type(self, node):
        if isinstance(node, ast.BinOp):
            left_type = self.get_type(node.left)
            right_type = self.get_type(node.right)

            if isinstance(node.op, ast.Add):
                if left_type.is_number and right_type.is_number:
                    return Type.NUMBER
                else:
                    return Type.STRING
            elif left_type.is_number and right_type.is_number:
                return Type.NUMBER
            else:
                raise CompileError("Can not '%s' operator with string." % node.op.__class__.__name__)
        elif isinstance(node, ast.UnaryOp):
            if isinstance(operand, ast.Num):
                return Type.NUMBER
            else:
                raise SyntaxNotSupportError("Not support unary operator except number.")

        elif isinstance(node, ast.Num):
            return Type.NUMBER

        elif isinstance(node, ast.Str):
            return Type.STRING
        elif isinstance(node, ast.List):
            return Type.LIST
        elif isinstance(node, ast.Call):
            args_type = [self.get_type(arg) for arg in node.args]
            return self.get_function_return_type(node.func.id, args_type)
        elif isinstance(node, ast.Name):
            return self.variables[node.id].var_type
예제 #3
0
 def generate(self):
     if self.node is None:
         self.node = ast.parse(self.code)
     if isinstance(self.node, ast.Module):
         for x in self.node.body:
             code_slice = self.dispatch(x)
             if code_slice is not None:
                 self.code_buffer.append(code_slice)
         return '\n'.join(self.code_buffer) + '\n'
     elif isinstance(self.node, ast.FunctionDef):
         if self.function_info is None:
             raise FunctionIsNotAnalyzedError(self.node.name)
         if not len(self.node.decorator_list) == 0:
             raise SyntaxNotSupportError('Function decoration is not support yet.')
         arguments_list = []
         for i, x in enumerate(self.node.args.args):
             if self.function_info.args_type[i].is_list:
                 arguments_list.append('declare -a %s=("${!%i}")' % (self.dispatch(x), i + 1))
             else:
                 arguments_list.append('%s=$%i' % (self.dispatch(x), i + 1))
         arguments_code = '\n'.join(arguments_list)
         for x in self.node.body:
             self.code_buffer.append(self.dispatch(x, {'func_name': self.node.name}))
         return 'function %s() {\n%s\n%s\n}' % (self.node.name, arguments_code, '\n'.join(self.code_buffer))
     else:
         raise CompileError("code section must be function or module node")
예제 #4
0
def generate_list(self, node, ext_info):
    for x in node.elts:
        if isinstance(x, ast.List):
            raise SyntaxNotSupportError(
                "Multiple dimension array is not support in shellscript language."
            )
    return '(%s)' % ' '.join([self.dispatch(x, ext_info) for x in node.elts])
예제 #5
0
def generate_aug_assign(self, node, ext_info):
    tmp_name = self.temp_variable.get_new_name()
    tmp_assign_code = '%s=%s' % (tmp_name, self.dispatch(node.value))
    self.code_buffer.append(tmp_assign_code)
    target = self.dispatch(node.target)
    target_type = self.get_type(node.target)
    if target_type.is_number:
        op = self.generate_numeric_op(node.op, ext_info)
        return '%s=$(( $%s %s $%s ))' % (target, target, op, tmp_name)
    elif target_type.is_string:
        if isinstance(node.op, ast.Add):
            return '%s=%s$%s' % (target, target, tmp_name)
        else:
            raise SyntaxNotSupportError("%s operation is not support yet." %
                                        node.op.__class__.__name__)
예제 #6
0
def generate_compare_op(self, node, ext_info):
    left = self.dispatch(node.left, ext_info)
    right = self.dispatch(node.comparators[0], ext_info)
    op_node = node.ops[0]
    left_type = self.get_type(node.left)
    right_type = self.get_type(node.comparators[0])

    op_code = None

    if left_type.is_number and right_type.is_number:
        op_code = number_compare_op_table.get(op_node.__class__)
    elif left_type.is_string and right_type.is_string:
        op_code = string_compare_op_table.get(op_node.__class__)

    if op_code is None:
        raise SyntaxNotSupportError(
            '%s and %s can not compare with `%s` operator' %
            (left_type, right_type, op_node.__class__.__name__))

    return '%s %s %s' % (left, op_code, right)
예제 #7
0
 def analysis_assign_node(self, variables, node):
     if len(node.targets) > 1:
         raise SyntaxNotSupportError('Tuple assignment is not support yet.')
     target = node.targets[0]
     variables.append(Variable(name=target.id, var_type=self.get_type(node.value)))
예제 #8
0
 def dispatch(self, node, ext_info={}):
     from sherlock.codelib.generator.dispatcher import AST_NODE_DISPATCHER
     generator = AST_NODE_DISPATCHER.get(node.__class__)
     if generator is None:
         raise SyntaxNotSupportError("%s is not support yet." % node.__class__.__name__)
     return generator(self, node, ext_info)
예제 #9
0
def generate_unaryop(self, node, ext_info):
    if isinstance(node.op, ast.Not):
        return '! ' + self.dispatch(node.operand, ext_info)
    else:
        SyntaxNotSupportError("%s is not support yet" % node.op.__class__.__name__)
예제 #10
0
def generate_numeric_op(self, node, ext_info):
    op = NUMERIC_OP_TABLE.get(node.__class__)
    if op is None:
        SyntaxNotSupportError("%s is not support yet" % node.__class__.__name__)
    return op