• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

CityOfZion / neo3-boa / 5c8eab45-f99f-4697-a4ff-d2c04d4d17ac

01 Feb 2024 09:59PM UTC coverage: 92.107% (+0.5%) from 91.625%
5c8eab45-f99f-4697-a4ff-d2c04d4d17ac

push

circleci

Mirella de Medeiros
Bump version: 1.1.0 → 1.1.1

1 of 1 new or added line in 1 file covered. (100.0%)

302 existing lines in 22 files now uncovered.

20784 of 22565 relevant lines covered (92.11%)

2.76 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.5
/boa3/internal/model/builtin/classmethod/indexsequencemethod.py
1
import ast
3✔
2
from typing import Dict, Optional
3✔
3

4
from boa3.internal.model.builtin.classmethod.indexmethod import IndexMethod
3✔
5
from boa3.internal.model.expression import IExpression
3✔
6
from boa3.internal.model.type.collection.sequence.sequencetype import SequenceType
3✔
7
from boa3.internal.model.type.itype import IType
3✔
8
from boa3.internal.model.variable import Variable
3✔
9
from boa3.internal.neo.vm.opcode.Opcode import Opcode
3✔
10

11

12
class IndexSequenceMethod(IndexMethod):
3✔
13

14
    def __init__(self, sequence_type: Optional[SequenceType] = None, arg_value: Optional[IType] = None):
3✔
15
        from boa3.internal.model.type.type import Type
3✔
16
        if not isinstance(sequence_type, SequenceType):
3✔
17
            sequence_type = Type.sequence
3✔
18
        if not isinstance(arg_value, IType):
3✔
19
            arg_value = Type.any
3✔
20

21
        args: Dict[str, Variable] = {
3✔
22
            'self': Variable(sequence_type),
23
            'x': Variable(arg_value),
24
            'start': Variable(Type.int),
25
            'end': Variable(Type.int),
26
        }
27

28
        start_default = ast.parse("{0}".format(0)
3✔
29
                                  ).body[0].value
30
        end_default = ast.parse("-1").body[0].value.operand
3✔
31
        end_default.n = -1
3✔
32

33
        super().__init__(args, defaults=[start_default, end_default])
3✔
34

35
    def validate_parameters(self, *params: IExpression) -> bool:
3✔
UNCOV
36
        if 2 <= len(params) <= 4:
×
UNCOV
37
            return False
×
UNCOV
38
        if not all(isinstance(param, IExpression) for param in params):
×
39
            return False
×
40

41
        from boa3.internal.model.type.itype import IType
×
42
        sequence_type: IType = params[0].type
×
43

44
        if not isinstance(sequence_type, SequenceType):
×
45
            return False
×
UNCOV
46
        from boa3.internal.model.type.collection.sequence.mutable.listtype import ListType
×
47
        from boa3.internal.model.type.collection.sequence.tupletype import TupleType
×
48
        from boa3.internal.model.type.collection.sequence.rangetype import RangeType
×
49
        if not isinstance(sequence_type, (ListType, TupleType, RangeType)):
×
50
            return False
×
51
        return True
×
52

53
    @property
3✔
54
    def exception_message(self) -> str:
3✔
55
        return "x not in sequence"
3✔
56

57
    def generate_internal_opcodes(self, code_generator):
3✔
58
        from boa3.internal.model.builtin.builtin import Builtin
3✔
59
        from boa3.internal.model.operation.binaryop import BinaryOp
3✔
60

61
        # receives: end, start, x, sequence
62
        code_generator.swap_reverse_stack_items(4)
3✔
63

64
        # if index < 0:
65
        code_generator.duplicate_stack_top_item()
3✔
66
        code_generator.convert_literal(0)
3✔
67
        is_negative_index = code_generator.convert_begin_if()
3✔
68
        # # if index >= 0, jump to verify_big_end
69
        code_generator.change_jump(is_negative_index, Opcode.JMPGE)
3✔
70

71
        #   # gets the correspondent positive value of end
72
        #   end = end + len(sequence) + 1
73
        code_generator.duplicate_stack_item(4)
3✔
74
        code_generator.convert_builtin_method_call(Builtin.Len, is_internal=True)
3✔
75
        code_generator.convert_operation(BinaryOp.Add, is_internal=True)
3✔
76
        code_generator.insert_opcode(Opcode.INC)
3✔
77

78
        #   if index < 0:
79
        code_generator.duplicate_stack_top_item()
3✔
80
        code_generator.convert_literal(0)
3✔
81
        is_still_negative_index = code_generator.convert_begin_if()
3✔
82
        #   # if end is not negative anymore, start verifying start
83
        code_generator.change_jump(is_still_negative_index, Opcode.JMPGE)
3✔
84

85
        #       index = 0
86
        code_generator.remove_stack_top_item()
3✔
87
        code_generator.convert_literal(0)
3✔
88

89
        code_generator.convert_end_if(is_negative_index, is_internal=True)
3✔
90

91
        # if end > len(sequence)
92
        code_generator.duplicate_stack_top_item()
3✔
93
        code_generator.duplicate_stack_item(5)
3✔
94
        code_generator.convert_builtin_method_call(Builtin.Len, is_internal=True)
3✔
95
        is_big_end = code_generator.convert_begin_if()
3✔
96
        # # if end <= len(sequence), start verifying start
97
        code_generator.change_jump(is_big_end, Opcode.JMPLE)
3✔
98

99
        #   end = len(sequence)
100
        code_generator.remove_stack_top_item()
3✔
101
        code_generator.duplicate_stack_item(3)
3✔
102
        code_generator.convert_builtin_method_call(Builtin.Len, is_internal=True)
3✔
103

104
        code_generator.convert_end_if(is_still_negative_index, is_internal=True)
3✔
105
        code_generator.convert_end_if(is_big_end, is_internal=True)
3✔
106
        code_generator.swap_reverse_stack_items(2)
3✔
107

108
        # if index < 0:
109
        code_generator.duplicate_stack_top_item()
3✔
110
        code_generator.convert_literal(0)
3✔
111
        is_negative_index = code_generator.convert_begin_if()
3✔
112
        # # if index >= 0, jump to verify_big_start
113
        code_generator.change_jump(is_negative_index, Opcode.JMPGE)
3✔
114

115
        #   # gets the correspondent positive value of end
116
        #   start = start + len(sequence) + 1
117
        code_generator.duplicate_stack_item(4)
3✔
118
        code_generator.convert_builtin_method_call(Builtin.Len, is_internal=True)
3✔
119
        code_generator.convert_operation(BinaryOp.Add, is_internal=True)
3✔
120
        code_generator.insert_opcode(Opcode.INC)
3✔
121

122
        #   if index < 0:
123
        code_generator.duplicate_stack_top_item()
3✔
124
        code_generator.convert_literal(0)
3✔
125
        is_still_negative_index = code_generator.convert_begin_if()
3✔
126
        #   # if start is not negative anymore
127
        code_generator.change_jump(is_still_negative_index, Opcode.JMPGE)
3✔
128

129
        #       index = 0
130
        code_generator.remove_stack_top_item()
3✔
131
        code_generator.convert_literal(0)
3✔
132

133
        code_generator.convert_end_if(is_negative_index, is_internal=True)
3✔
134

135
        # if start > len(sequence)
136
        code_generator.duplicate_stack_top_item()
3✔
137
        code_generator.duplicate_stack_item(5)
3✔
138
        code_generator.convert_builtin_method_call(Builtin.Len, is_internal=True)
3✔
139
        is_big_end = code_generator.convert_begin_if()
3✔
140
        # # if start <= len(sequence), start verifying start
141
        code_generator.change_jump(is_big_end, Opcode.JMPLE)
3✔
142

143
        #   start = len(sequence)
144
        code_generator.remove_stack_top_item()
3✔
145
        code_generator.duplicate_stack_item(3)
3✔
146
        code_generator.convert_builtin_method_call(Builtin.Len, is_internal=True)
3✔
147

148
        code_generator.convert_end_if(is_still_negative_index, is_internal=True)
3✔
149
        code_generator.convert_end_if(is_big_end, is_internal=True)
3✔
150

151
        # begin while
152
        # while self[index] != x:
153
        while_start = code_generator.convert_begin_while()
3✔
154

155
        #   index += 1
156
        code_generator.insert_opcode(Opcode.INC)
3✔
157

158
        while_condition = code_generator.bytecode_size
3✔
159
        #   if end <= index
160
        code_generator.duplicate_stack_item(2)
3✔
161
        code_generator.duplicate_stack_item(2)
3✔
162
        invalid_index = code_generator.convert_begin_if()
3✔
163
        code_generator.change_jump(invalid_index, Opcode.JMPGT)
3✔
164
        #       raise error
165
        code_generator.convert_literal(self.exception_message)
3✔
166
        code_generator.convert_raise_exception()
3✔
167

168
        invalid_index = code_generator.convert_begin_else(invalid_index, is_internal=True)
3✔
169

170
        code_generator.convert_end_if(invalid_index, is_internal=True)
3✔
171

172
        #   self[index] == x:
173
        code_generator.duplicate_stack_item(4)
3✔
174
        code_generator.duplicate_stack_item(2)
3✔
175
        code_generator.convert_get_item(index_inserted_internally=True)
3✔
176
        code_generator.duplicate_stack_item(4)
3✔
177
        code_generator.convert_operation(BinaryOp.NumNotEq, is_internal=True)
3✔
178

179
        code_generator.convert_end_while(while_start, while_condition, is_internal=True)
3✔
180

181
        for _ in range(1, len(self.args)):
3✔
182
            code_generator.remove_stack_item(2)
3✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc