Ejemplo n.º 1
0
    def test_nat(self, get_visitor):
        file = "test_cases/store/symbol_table_nat.bs"
        st = self.get_symbols(get_visitor(file))

        output = st.get_local('a', 'main')

        assert ChemTypeResolver.is_number_in_set(output.types) and ChemTypeResolver.is_mat_in_set(output.types)
Ejemplo n.º 2
0
    def visitMath(self, ctx: BSParser.MathContext):
        deff = self.visitVariableDefinition(ctx.variableDefinition())
        symbol = Symbol(deff['name'], self.scope_stack[-1],
                        ChemTypeResolver.numbers())

        for use in ctx.primary():
            var = self.visitPrimary(use)

            # This places any constants into the global symbol table.
            # By doing this, it makes it significantly easier to handle
            # arithmetic later in the compilation process.
            if 'value' in var.keys() and not self.symbol_table.get_global(
                    var['name']):
                globalz = Symbol(var['name'], 'global',
                                 ChemTypeResolver.numbers())
                globalz.value = Number(var['name'], 1, var['value'])
                self.symbol_table.add_global(globalz)

            if not ChemTypeResolver.is_number_in_set(var['types']):
                local = self.symbol_table.get_local(var['name'])
                if not local:
                    raise UndefinedVariable("{} is not defined.".format(
                        var['name']))
                local.types.update(ChemTypeResolver.numbers())
                if ChemTypes.UNKNOWN in local.types:
                    local.types.remove(ChemTypes.UNKNOWN)
                self.symbol_table.update_symbol(local)

        self.symbol_table.add_local(symbol)

        return None
Ejemplo n.º 3
0
    def test_mat_args(self, get_visitor):
        file = "test_cases/function/symbol_table_mat_args.bs"
        st = self.get_symbols(get_visitor(file))

        arg1 = st.get_local(st.functions['foo'].args[0], 'foo')
        output = st.get_local('b', 'main')

        assert ChemTypeResolver.is_only_material(arg1.types)
        assert ChemTypeResolver.is_only_material(output.types)
Ejemplo n.º 4
0
    def test_mat_nat(self, get_visitor):
        file = "test_cases/math/symbol_table_mat_nat.bs"
        st = self.get_symbols(get_visitor(file))

        input_1 = st.get_local('a', 'main')
        output = st.get_local('b', 'main')

        assert ChemTypeResolver.is_number_in_set(input_1.types) and ChemTypeResolver.is_number_in_set(input_1.types)
        assert ChemTypeResolver.is_only_numeric(output.types)
Ejemplo n.º 5
0
    def test_two_mats(self, get_visitor):
        file = "test_cases/gradient/symbol_table_two_mats.bs"
        st = self.get_symbols(get_visitor(file))

        input_1 = st.get_local('a', 'main')
        input_2 = st.get_local('b', 'main')
        output = st.get_local('c', 'main')

        assert ChemTypeResolver.is_only_material(input_1.types)
        assert ChemTypeResolver.is_only_material(input_2.types)
        assert ChemTypeResolver.is_only_material(output.types)
Ejemplo n.º 6
0
    def test_return_nat(self, get_visitor):
        file = "test_cases/function/symbol_table_ret_nat.bs"
        st = self.get_symbols(get_visitor(file))

        ret_val = st.get_local('a', 'foo')
        output = st.get_local('a', 'main')
        func = st.functions['foo']

        assert ChemTypeResolver.is_only_numeric(ret_val.types)
        assert ChemTypeResolver.is_only_numeric(output.types)
        assert ChemTypeResolver.is_only_numeric(func.types)
Ejemplo n.º 7
0
    def test_nat(self, get_visitor):
        file = "test_cases/split/symbol_table_nat.bs"
        st = self.get_symbols(get_visitor(file))

        input_1 = st.get_local('a', 'main')
        output = st.get_local('b', 'main')

        assert ChemTypeResolver.is_number_in_set(input_1.types)
        assert ChemTypeResolver.is_number_in_set(output.types) and ChemTypeResolver.is_mat_in_set(output.types)
        assert input_1.scope == 'main'
        assert output.scope == 'main'
Ejemplo n.º 8
0
    def test_nat(self, get_visitor):
        file = "test_cases/detect/symbol_table_nat.bs"
        st = self.get_symbols(get_visitor(file))

        input_1 = st.get_local('a', 'main')
        mod = st.get_global('mod')
        output = st.get_local('b', 'main')

        assert ChemTypeResolver.is_mat_in_set(input_1.types) and ChemTypeResolver.is_number_in_set(input_1.types)
        assert ChemTypes.MODULE in mod.types and len(mod.types) == 1
        assert ChemTypeResolver.is_number_in_set(output.types)
Ejemplo n.º 9
0
    def test_nat_args(self, get_visitor):
        file = "test_cases/function/symbol_table_nat_args.bs"
        st = self.get_symbols(get_visitor(file))

        arg1 = st.get_local(st.functions['foo'].args[0], 'foo')
        arg2 = st.get_local(st.functions['foo'].args[1], 'foo')
        output = st.get_local('a', 'main')

        assert ChemTypeResolver.is_only_numeric(arg1.types)
        assert ChemTypeResolver.is_only_numeric(arg2.types)
        assert ChemTypeResolver.is_only_numeric(output.types)
        assert st.get_symbol('CONST_2') is not None
Ejemplo n.º 10
0
    def test_manifests(self, get_visitor):
        file = "test_cases/header/manifest.bs"
        tree = get_visitor(file)
        st = FrontEndBase.run_globals(tree, SymbolTable())

        mod = st.get_global('mod')
        stat = st.get_global('stat')
        mani = st.get_global('aaa')

        assert ChemTypes.MODULE in mod.types and len(mod.types) == 1
        assert ChemTypeResolver.is_mat_in_set(stat.types)
        assert ChemTypeResolver.is_mat_in_set(mani.types)
Ejemplo n.º 11
0
 def visitNumberAssignment(self, ctx: BSParser.NumberAssignmentContext):
     deff = self.visitVariableDefinition(ctx.variableDefinition())
     symbol = Symbol(deff['name'], self.scope_stack[-1],
                     ChemTypeResolver.numbers())
     self.symbol_table.add_local(symbol)
     # Yes, this is assigning value to something,
     # But this is a constant.  So we know all
     # of the values up front.  This also makes
     # the IRVisitor easier to work with.
     value = self.visitLiteral(ctx.literal())
     const = Symbol('CONST_{}'.format(value), 'global',
                    ChemTypeResolver.numbers())
     const.value = Number('CONST_{}'.format(value), 1, value)
     self.symbol_table.add_global(const)
Ejemplo n.º 12
0
    def visitRepeat(self, ctx: BSParser.RepeatContext):
        # 'repeat value times' is translated in the IR as while (value > 0), with a decrement
        #   appended to the end of the expression block; hence,
        #    to ease translation later, we add a global for const(0) and const(1)
        if not self.symbol_table.get_global('CONST_0'):
            globalz = Symbol('CONST_0', 'global', ChemTypeResolver.numbers())
            globalz.value = Number('CONST_0', 1, 0)
            self.symbol_table.add_global(globalz)

        if not self.symbol_table.get_global('CONST_1'):
            globalz = Symbol('CONST_1', 'global', ChemTypeResolver.numbers())
            globalz.value = Number('CONST_1', 1, 1)
            self.symbol_table.add_global(globalz)

        self.visitChildren(ctx)
Ejemplo n.º 13
0
    def test_numeric_assignment(self, get_visitor):
        file = "test_cases/math/symbol_table_numeric_assignment.bs"
        st = self.get_symbols(get_visitor(file))

        output = st.get_local('a', 'main')

        assert ChemTypeResolver.is_only_numeric(output.types)
Ejemplo n.º 14
0
    def test_mat(self, get_visitor):
        file = "test_cases/store/symbol_table_mat.bs"
        st = self.get_symbols(get_visitor(file))

        output = st.get_local('a', 'main')

        assert ChemTypeResolver.is_only_material(output.types)
Ejemplo n.º 15
0
    def visitGradient(self, ctx: BSParser.GradientContext):
        deff = self.visitVariableDefinition(ctx.variableDefinition())
        symbol = Symbol(deff['name'], self.scope_stack[-1],
                        self.resolve_types(deff))
        for var_def in ctx.variable():
            use = self.visitVariable(var_def)
            var = self.symbol_table.get_local(use['name'],
                                              self.scope_stack[-1])
            if not var:
                raise UndefinedVariable("{} is not defined.".format(
                    use['name']))
            if not ChemTypeResolver.is_mat_in_set(var.types):
                var.types.add(ChemTypes.MAT)
            self.symbol_table.update_symbol(var)
            symbol.types.update(var.types)

        self.symbol_table.add_local(symbol)

        start = float(ctx.FLOAT_LITERAL(0).__str__())
        end = float(ctx.FLOAT_LITERAL(1).__str__())
        at = float(ctx.FLOAT_LITERAL(2).__str__())

        if start >= end:
            raise UnsupportedOperation(
                "The beginning concentration must be smaller than the ending concentration."
            )
        if at <= 0.0:
            raise UnsupportedOperation("You cannot have a negative rate.")

        return None
Ejemplo n.º 16
0
    def visitMix(self, ctx: BSParser.MixContext):
        deff = self.visitVariableDefinition(ctx.variableDefinition())

        symbol = Symbol(deff['name'], self.scope_stack[-1],
                        self.resolve_types(deff))
        # Look through the RHS vars.
        for fluid in ctx.variable():
            temp = self.visitVariable(fluid)
            var = self.symbol_table.get_local(temp['name'])
            if not var:
                raise UndefinedVariable("{}.{} is not defined.".format(
                    self.scope_stack[-1], temp['name']))
            if not ChemTypeResolver.is_mat_in_set(var.types):
                # This is the best we can do at this point.
                # We won't be able to further classify anything
                # further because if the identifier hasn't
                # figured anything out by now, it won't.
                var.types.update(
                    self.resolve_types({
                        'name': var.name,
                        'types': var.types
                    }))
            # Update the RHS types.
            self.symbol_table.update_symbol(var)
            # Union the types of the RHS with the LHS
            symbol.types.update(var.types)
        # Add the symbol to the table.
        self.symbol_table.add_local(symbol)
        return None
Ejemplo n.º 17
0
    def test_defined_manifest(self, get_visitor):
        file = "test_cases/dispense/symbol_table_defined.bs"
        st = self.get_symbols(get_visitor(file))

        output = st.get_local('a', 'main')

        assert ChemTypeResolver.is_mat_in_set(output.types)
        assert output.scope == 'main'
Ejemplo n.º 18
0
    def visitBinops(self, ctx: BSParser.BinopsContext):
        op1 = self.visitPrimary(ctx.primary(0))
        op2 = self.visitPrimary(ctx.primary(1))

        # This places any constants into the global symbol table.
        # By doing this, it makes it significantly easier to handle
        # arithmetic later in the compilation process.
        if 'value' in op1.keys() and not self.symbol_table.get_global(
                op1['name']):
            globalz = Symbol(op1['name'], 'global', ChemTypeResolver.numbers())
            globalz.value = Number(op1['name'], 1, op1['value'])
            self.symbol_table.add_global(globalz)
        if 'value' in op2.keys() and not self.symbol_table.get_global(
                op2['name']):
            globalz = Symbol(op2['name'], 'global', ChemTypeResolver.numbers())
            globalz.value = Number(op2['name'], 1, op2['value'])
            self.symbol_table.add_global(globalz)
Ejemplo n.º 19
0
 def visitDispose(self, ctx: BSParser.DisposeContext):
     name = self.visitVariable(ctx.variable())['name']
     use = self.symbol_table.get_local(name)
     if not use:
         raise UndefinedVariable("{} is not defined.".format(name))
     if not ChemTypeResolver.is_mat_in_set(use.types):
         use.types.add(ChemTypes.MAT)
         self.symbol_table.update_symbol(use)
     return None
Ejemplo n.º 20
0
 def visitStore(self, ctx: BSParser.StoreContext):
     use = self.visitVariable(ctx.variable())
     symbol = self.symbol_table.get_local(use['name'])
     if not symbol:
         raise UndefinedVariable("{} is not defined.".format(use['name']))
     if not ChemTypeResolver.is_mat_in_set(symbol.types):
         symbol.types.add(ChemTypes.MAT)
         self.symbol_table.update_symbol(symbol)
     return None
Ejemplo n.º 21
0
 def visitPrimary(self, ctx: BSParser.PrimaryContext):
     if ctx.variable():
         primary = self.visitVariable(ctx.variable())
     else:
         value = self.visitLiteral(ctx.literal())
         # It's a constant, thus, the size must be 1 and index 0.
         primary = {
             'name': "{}{}".format(self.const, value),
             "index": 0,
             'value': value,
             'types': ChemTypeResolver.numbers()
         }
     return primary
Ejemplo n.º 22
0
 def visitDetect(self, ctx: BSParser.DetectContext):
     deff = self.visitVariableDefinition(ctx.variableDefinition())
     self.symbol_table.add_local(
         Symbol(deff['name'], self.scope_stack[-1],
                ChemTypeResolver.numbers()))
     use = self.visitVariable(ctx.variable())
     var = self.symbol_table.get_local(use['name'])
     if not var:
         raise UndefinedVariable("{} is not defined.".format(use['name']))
     module = self.symbol_table.get_global(ctx.IDENTIFIER().__str__())
     if not module:
         raise UndefinedVariable(
             "{} isn't declared in the manifest.".format(
                 ctx.IDENTIFIER().__str__()))
     if ChemTypes.MODULE not in module.types:
         raise UndefinedVariable(
             "There is no module named {} declared in the manifest.".format(
                 module.name))
     if not ChemTypeResolver.is_mat_in_set(var.types):
         var.types.add(ChemTypes.MAT)
         self.symbol_table.update_symbol(var)
     return None
Ejemplo n.º 23
0
 def visitSplit(self, ctx: BSParser.SplitContext):
     deff = self.visitVariableDefinition(ctx.variableDefinition())
     use = self.visitVariable(ctx.variable())
     if not self.symbol_table.get_local(use['name']):
         raise UndefinedVariable("{} is not defined.".format(use['name']))
     if not ChemTypeResolver.is_mat_in_set(deff['types']):
         deff['types'].update(
             self.identifier.identify(deff['name'], deff['types']))
     if ChemTypes.UNKNOWN in deff['types']:
         deff['types'].remove(ChemTypes.UNKNOWN)
     deff['types'].update(self.symbol_table.get_local(use['name']).types)
     self.symbol_table.add_local(
         Symbol(deff['name'], self.scope_stack[-1], deff['types']))
     return None
Ejemplo n.º 24
0
    def visitMethodInvocation(self, ctx: BSParser.MethodInvocationContext):
        deff = self.visitVariableDefinition(ctx.variableDefinition())
        # Get the symbol.
        symbol = self.symbol_table.get_local(deff['name'],
                                             self.scope_stack[-1])
        # Grab the function.
        function = self.visitMethodCall(ctx.methodCall())
        # Update the types of the symbol.
        symbol.types.update(function['types'])
        if ChemTypeResolver.is_only_numeric(symbol.types):
            symbol.value = Number(symbol.name, deff['index'])
        else:
            symbol.value = Movable(symbol.name, deff['index'])

        # Save the symbol.
        self.symbol_table.update_symbol(symbol)
Ejemplo n.º 25
0
    def visitReturnStatement(self, ctx: BSParser.ReturnStatementContext):
        # It's either a primary or a method call
        types = set()
        if ctx.primary():
            var = self.visitPrimary(ctx.primary())
            local = self.symbol_table.get_local(var['name'],
                                                self.scope_stack[-1])
            # If we don't have a local, this is a constant.
            if local:
                types = self.symbol_table.get_local(var['name']).types
            else:
                types = ChemTypeResolver.numbers()
        elif ctx.methodCall():
            method_name, args = self.visitMethodCall(ctx.methodCall())
            types = self.symbol_table.functions[method_name].types
        else:
            raise UnsupportedOperation(
                "Only method calls or values are returnable.")

        return types
Ejemplo n.º 26
0
    def test_ret_method(self, get_visitor):
        file = "test_cases/function/symbol_table_ret_method.bs"
        st = self.get_symbols(get_visitor(file))

        assert ChemTypeResolver.is_only_material(st.functions['foo'].types)
Ejemplo n.º 27
0
 def visitTypeType(self, ctx: BSParser.TypeTypeContext):
     if ctx.primitiveType():
         return ChemTypeResolver.string_to_type(
             self.visitPrimitiveType(ctx.primitiveType()))
     else:
         return self.visitChemicalType(ctx.chemicalType())
Ejemplo n.º 28
0
    def build_declares(self):
        if self.types_used == TypesUsed.COMPLEX:
            types = ChemTypeResolver._available_types
        else:
            types = ChemTypeResolver._naive_types
            types.add(ChemTypes.UNKNOWN)

        declares = ""
        defines = ""
        asserts = ""

        for name, var in self.symbol_table.globals.items():
            """
            Declare the constants for all global variables.
            """
            if ChemTypes.UNKNOWN in var.types:
                var.types.remove(ChemTypes.UNKNOWN)
            if ChemTypes.INSUFFICIENT_INFORMATION_FOR_CLASSIFICATION in var.types:
                var.types.remove(
                    ChemTypes.INSUFFICIENT_INFORMATION_FOR_CLASSIFICATION)

            declares += f"; Declaring constants for: {self.get_smt_name(var).upper()}{self.nl}"
            for enum in types:
                declares += f"(declare-const {self.get_smt_name(var, ChemTypes(enum))} Bool){self.nl}"
            declares += self.nl
            defines += f"; Defining the assignment of: {self.get_smt_name(var).upper()}{self.nl}"
            for t in var.types:
                """
                Now we actually state the typing assignment of each variable.
                """
                defines += "(assert (= {} true)){}".format(
                    self.get_smt_name(var, t), self.nl)

            if self.types_used == TypesUsed.SIMPLE:
                """
                If it's naive, then make sure that unknown is false.
                In other words, we must have a nat/real/mat type.
                """
                defines += "; Ensure that {} is a not unknown type{}".format(
                    self.get_smt_name(var).upper(), self.nl)
                defines += "(assert (= {} false)){}".format(
                    self.get_smt_name(var, ChemTypes.UNKNOWN), self.nl)
        for name, scope in self.symbol_table.scope_map.items():
            """
            Declare the constants for all local variables.
            """
            for symbol in scope.locals:
                var = scope.locals[symbol]
                if ChemTypes.UNKNOWN in var.types and ChemTypes.INSUFFICIENT_INFORMATION_FOR_CLASSIFICATION in var.types:
                    if len(var.types) > 2:
                        var.types.remove(
                            ChemTypes.
                            INSUFFICIENT_INFORMATION_FOR_CLASSIFICATION)
                        var.types.remove(ChemTypes.UNKNOWN)
                else:
                    if ChemTypes.UNKNOWN in var.types and len(var.types) > 1:
                        var.types.remove(ChemTypes.UNKNOWN)
                    elif ChemTypes.INSUFFICIENT_INFORMATION_FOR_CLASSIFICATION in var.types and len(
                            var.types) > 1:
                        var.types.remove(
                            ChemTypes.
                            INSUFFICIENT_INFORMATION_FOR_CLASSIFICATION)
                declares += "; Declaring constants for: {}{}".format(
                    self.get_smt_name(var).upper(), self.nl)
                for enum in types:
                    """
                    Declare the constants for all scoped variables.
                    """
                    declares += "(declare-const {} Bool){}".format(
                        self.get_smt_name(var, ChemTypes(enum)), self.nl)

                declares += self.nl
                defines += "; Defining the assignment of: {}{}".format(
                    self.get_smt_name(var).upper(), self.nl)
                for t in var.types:
                    defines += "(assert (= {} true)){}".format(
                        self.get_smt_name(var, t), self.nl)

                if self.types_used == TypesUsed.SIMPLE:
                    """
                    If it's naive, then make sure that unknown is false.
                    In other words, we must have a nat/real/mat type.
                    """
                    defines += "; Ensure that {} is not unknown type{}".format(
                        self.get_smt_name(var).upper(), self.nl)
                    defines += "(assert (= {} false)){}".format(
                        self.get_smt_name(var, ChemTypes.UNKNOWN), self.nl)
                if var.types & ChemTypeResolver.numbers():
                    """
                    Build the asserts for things that are numbers.
                    We will only check naively: in that if we intersect,
                    And we have something, then we know it's a number.
                    """
                    asserts += self.assert_material(var, False)
                if var.types & ChemTypeResolver.materials():
                    """
                    Build the asserts for things that are numbers.
                    We will only check naively: in that if we intersect,
                    And we have something, then we know it's a mat.
                    """
                    asserts += self.assert_material(var)
        self.add_smt(
            "; ==============={}; Declaring Constants{}; ==============={}".
            format(self.nl, self.nl, self.nl))
        self.add_smt(declares)
        # self.add_smt("; ==============={}; Declaring typing{}; ==============={}".format(self.nl, self.nl, self.nl))
        # self.add_smt(defines)
        self.add_smt(
            "; ==============={}; Declaring Asserts{}; ==============={}".
            format(self.nl, self.nl, self.nl))
        self.add_smt(asserts)
Ejemplo n.º 29
0
    def visitRepeat(self, ctx: BSParser.RepeatContext):
        # get the (statically defined!) repeat value and add to local symbol table
        value = self.visitLiteral(ctx)
        val = {
            'name': "REPEAT_{}".format(value),
            "index": 0,
            'value': value,
            'types': ChemTypeResolver.numbers()
        }

        if 'value' in val.keys() and not self.symbol_table.get_local(
                val['name']):
            localz = Symbol(val['name'], 'global', ChemTypeResolver.numbers())
            localz.value = Number(val['name'], 1, val['value'])
            self.symbol_table.add_local(localz)

        # finished with this block
        self.functions[self.scope_stack[-1]]['blocks'][
            self.current_block.nid] = self.current_block

        # insert header block for the conditional
        header_block = BasicBlock()
        header_label = Label("bsbbr_{}_h".format(header_block.nid))
        self.labels[header_label.name] = header_block.nid
        header_block.add(header_label)
        self.graph.add_node(header_block.nid,
                            function=self.scope_stack[-1],
                            label=header_label.label)
        self.functions[self.scope_stack[-1]]['blocks'][
            header_block.nid] = header_block
        self.graph.add_edge(self.current_block.nid, header_block.nid)

        zero = self.symbol_table.get_global('CONST_0')
        op = BinaryOp(left={
            'name': val['name'],
            'offset': 0,
            'size': 1,
            'var': self.symbol_table.get_local(val['name'])
        },
                      right={
                          'name': zero.name,
                          'offset': 0,
                          'size': 1,
                          'var': zero
                      },
                      op=RelationalOps.GT)
        condition = Conditional(
            RelationalOps.GT, op.left,
            op.right)  # Number('Constant_{}'.format(0), 1, 0))
        header_block.add(condition)

        self.control_stack.append(header_block)

        # set up the true block
        true_block = BasicBlock()
        true_label = Label("bsbbr_{}_t".format(true_block.nid))
        self.labels[true_label.name] = true_block.nid
        true_block.add(true_label)
        self.graph.add_node(true_block.nid, function=self.scope_stack[-1])
        self.functions[self.scope_stack[-1]]['blocks'][
            true_block.nid] = true_block
        condition.true_branch = true_label
        self.graph.add_edge(header_block.nid, true_block.nid)

        self.current_block = true_block
        self.visitBlockStatement(ctx.blockStatement())

        # repeat is translated to a while loop as: while (exp > 0);
        # hence, we update exp by decrementing.
        one = self.symbol_table.get_global('CONST_1')

        ir = Math(
            {
                'name': val['name'],
                'offset': 0,
                'size': 1,
                'var': self.symbol_table.get_local(val['name'])
            }, {
                'name': val['name'],
                'offset': 0,
                'size': 1,
                'var': self.symbol_table.get_local(val['name'])
            }, {
                'name': one.name,
                'offset': 0,
                'size': 1,
                'var': one
            }, BinaryOps.SUBTRACT)

        self.current_block.add(ir)

        # the block statement may contain nested loops
        # If so, the current block is the last false block created for the inner-most loop
        #    otherwise, the current block is the true_block created above
        # Either way, we can pop the control stack to find where to place the back edge
        #   and immediately make the back edge (from 'current block' to the parent
        parent_block = self.control_stack.pop()
        self.graph.add_edge(self.current_block.nid, parent_block.nid)

        # we now deal with the false branch
        false_block = BasicBlock()

        false_label = Label("bsbbr_{}_f".format(false_block.nid))
        self.labels[false_label.name] = false_block.nid
        false_block.add(false_label)
        condition.false_branch = false_label
        self.graph.add_edge(header_block.nid, false_block.nid)
        # We are done, so we need to handle the book keeping for
        # next basic block generation.
        self.graph.add_node(false_block.nid, function=self.scope_stack[-1])
        self.functions[self.scope_stack[-1]]['blocks'][
            false_block.nid] = false_block

        self.current_block = false_block

        return NOP()
Ejemplo n.º 30
0
 def identify(self, search_for: str, types: Set = set()) -> Set[ChemTypes]:
     if not ChemTypeResolver.is_mat_in_set(types):
         types.add(ChemTypes.MAT)
     return types