|
1 | | - |
| 1 | +r""" |
| 2 | +The Parser owns (and initializes) the Library object. |
| 3 | +""" |
2 | 4 |
|
3 | 5 | from debug import * |
4 | 6 |
|
|
9 | 11 | import config |
10 | 12 |
|
11 | 13 |
|
| 14 | +def strip( expr ): |
| 15 | + return expr.strip(' \t\n\r') |
12 | 16 |
|
13 | | -class Library: |
14 | | - |
15 | | - def __init__( self ): |
16 | | - |
17 | | - self.dict = {} |
18 | | - |
19 | | - self.numbers = True # Simulate numbers in library |
20 | | - |
21 | | - |
22 | | - |
23 | | - def __setitem__( self, key, value ): |
24 | | - self.dict[ key ] = isinstance( value, let.Expression ) \ |
25 | | - and value \ |
26 | | - or self.parser.parse( value ) |
27 | 17 |
|
28 | | - def __getitem__( self, key ): |
| 18 | +class Library: |
29 | 19 |
|
30 | | - if key in self.dict: |
31 | | - #return copy.deepcopy( self.dict[ key ] ) |
32 | | - debug( 4, 'library. asked', key, self.dict[ key ] ) |
33 | | - return self.dict[ key ].copy( ({},{}) ) |
| 20 | + def __init__( self, parser ): |
| 21 | + self.parser = parser |
34 | 22 |
|
35 | | - elif self.numbers and key.isdigit(): |
36 | | - return self.number( int( key ) ) |
| 23 | + self.globalItems = {} # loaded from (e.g.) "library.txt" always available |
| 24 | + self.localItems = {} # loaded from workspace; reset on workspace reload |
37 | 25 |
|
| 26 | + self.generateNumbers = True # Generate numbers by demand |
| 27 | + |
| 28 | + |
| 29 | + def add_item( self, key, value, isGlobal = True ): |
| 30 | + if not isinstance( value, let.Expression ): |
| 31 | + value = self.parser.parse( value ) |
| 32 | + if isGlobal: |
| 33 | + self.globalItems[ key ] = value |
38 | 34 | else: |
39 | | - raise KeyError(key) |
| 35 | + self.localItems[ key ] = value |
40 | 36 |
|
41 | | - |
42 | | - def __iter__( self ): |
43 | | - return self.dict.__iter__() |
44 | 37 |
|
| 38 | + def reset_local_items( self ): |
| 39 | + self.localItems = {} |
45 | 40 |
|
| 41 | + |
| 42 | + def add_line( self, line, isGlobal = True ): |
| 43 | + line = strip(line) |
| 44 | + if not line or line[0] == '#': return False |
| 45 | + if '=' not in line: return False |
| 46 | + key, value = tuple(map( strip, line.split('=', 1) )) |
| 47 | + self.add_item( key, value, isGlobal ) |
46 | 48 |
|
47 | | - def init( self, parser ): |
48 | | - |
49 | | - self.parser = parser |
50 | | - |
51 | | - def getDefs( lines, spaces ): |
52 | | - |
53 | | - def strip( s ): |
54 | | - return s.strip( spaces ) |
55 | | - |
56 | | - while lines: |
57 | | - line = strip( lines.pop(0) ) |
58 | | - |
59 | | - while lines and lines[0] and lines[0][0] in spaces: |
60 | | - next = strip( lines.pop(0) ) |
61 | | - if next: line += ' ' + next |
62 | | - |
63 | | - if line and not '#'==line[0]: |
64 | | - yield list(map( strip, line.split('=',1) )) |
65 | | - |
66 | 49 |
|
67 | | - |
| 50 | + def init( self ): |
68 | 51 | # Read library from txt |
69 | | - txt = config.get( 'library', 'library.txt' ) |
| 52 | + libraryFile = config.get( 'library', 'library.txt' ) |
70 | 53 | try: |
71 | | - f = open( txt ) |
| 54 | + f = open( libraryFile, 'r' ) |
72 | 55 | except IOError: |
73 | | - print("Warning: no library found", txt) |
| 56 | + print("Warning: can't open library file", libraryFile) |
| 57 | + return |
74 | 58 | else: |
75 | 59 | lines = f.readlines() |
76 | 60 | f.close() |
77 | 61 |
|
78 | | - for d in getDefs( lines, ' \t\n\r' ): |
79 | | - self[ d[0] ] = d[1] # Add synonym to Library |
| 62 | + for line in lines: |
| 63 | + self.add_line( line, isGlobal = True ) |
80 | 64 |
|
81 | | - |
82 | 65 |
|
83 | | - def number( self, n ): |
| 66 | + def find_item( self, key ): |
| 67 | + value = self.localItems.get( key ) or \ |
| 68 | + self.globalItems.get( key ) |
| 69 | + if value: |
| 70 | + debug( 4, 'library. asked', key, value ) |
| 71 | + return value.copy( ({},{}) ) |
| 72 | + |
| 73 | + elif self.generateNumbers and key.isdigit(): |
| 74 | + return self.generate_number( int( key ) ) |
| 75 | + |
| 76 | + else: |
| 77 | + return None |
| 78 | + |
| 79 | + |
| 80 | + def generate_number( self, n ): |
84 | 81 | "Generates Number Expression" |
85 | 82 |
|
86 | 83 | lf = let.Abstraction( expr= None ) |
87 | 84 | lx = let.Abstraction( expr= None ) |
88 | 85 |
|
89 | 86 | x = let.Variable( lx ) |
90 | 87 |
|
91 | | - for _ in range( n ): |
| 88 | + for _ in range( n ): |
92 | 89 | f = let.Variable( lf ) |
93 | 90 | x = let.Application( func= f, arg= x ) |
94 | 91 |
|
|
0 commit comments