1import lcapy.grammar as grammar
2from lcapy.parser import Parser
3
4
5class NetfileMixin(object):
6
7    def _init_parser(self, cpts):
8        self.parser = Parser(cpts, grammar)
9        self.namespace = ''
10        self._anon = {}
11
12    def _make_anon(self, kind):
13        """Make identifier for anonymous component"""
14
15        if kind not in self._anon:
16            self._anon[kind] = 0
17        self._anon[kind] += 1
18        return 'anon' + str(self._anon[kind])
19
20    def _include(self, string):
21
22        parts = string.split(' ')
23        if len(parts) < 2 or parts[0] != '.include':
24            raise ValueError('Expecting include filename in %s' % string)
25        filename = parts[1]
26        if len(parts) == 2:
27            return self._netfile_add(filename, self.namespace)
28
29        if len(parts) != 4 and parts[2] != 'as':
30            raise ValueError('Expecting include filename as name in %s' % string)
31        name = parts[3]
32        namespace = self.namespace
33        self.namespace = name + '.' + namespace
34        ret = self._netfile_add(filename, self.namespace)
35        self.namespace = namespace
36        return ret
37
38    def _parse(self, string, namespace=''):
39        """The general form is: 'Name Np Nm symbol'
40        where Np is the positive node and Nm is the negative node.
41
42        A positive current is defined to flow from the positive node
43        to the negative node.
44        """
45
46        if string == '':
47            return None
48
49        if string[0] == ';':
50            if hasattr(self, 'opts'):
51                self.opts.add(string[1:])
52            return None
53
54        if string[0:9] == '.include ':
55            self._include(string)
56            return None
57
58        cpt = self.parser.parse(namespace + string, self)
59        return cpt
60
61    def add(self, string):
62        """Add a component to the netlist.
63        The general form is: 'Name Np Nm args'
64        where Np is the positive node and Nm is the negative node.
65
66        A positive current is defined to flow from the positive node
67        to the negative node.
68        """
69
70        self._add(string)
71        self._invalidate()
72
73    def _add(self, string, namespace=''):
74        """The general form is: 'Name Np Nm symbol'
75        where Np is the positive node and Nm is the negative node.
76
77        A positive current is defined to flow from the positive node
78        to the negative node.
79        """
80
81        if '\n' in string:
82            lines = string.split('\n')
83            for line in lines:
84                self._add(line.strip(), namespace)
85            return
86
87        cpt = self._parse(string, namespace)
88        if cpt is not None:
89            self._cpt_add(cpt)
90
91    def _netfile_add(self, filename, namespace=''):
92        """Add the nets from file with specified filename"""
93
94        file = open(filename, 'r')
95
96        lines = file.readlines()
97
98        for line in lines:
99            self._add(line, namespace)
100