Skip to content

Commit 856e1da

Browse files
committed
updates toml reader to accept simple conditionals
1 parent 6f0d0fe commit 856e1da

File tree

1 file changed

+171
-1
lines changed

1 file changed

+171
-1
lines changed

builder/toml_reader.py

Lines changed: 171 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
class TOMLMeta(type):
1616

1717
def __call__(cls, name, parent=None, **kwargs):
18+
if name and name == 'conditional':
19+
return TOMLConditional(name, None, **kwargs)
20+
1821
children = {}
1922
for key, value in list(kwargs.items()):
2023
if isinstance(value, dict):
@@ -130,6 +133,9 @@ def var_names(self):
130133
var_names = []
131134

132135
for child in self.__children:
136+
if isinstance(child, TOMLConditional):
137+
continue
138+
133139
var_names.extend(child.var_names)
134140

135141
return var_names
@@ -153,6 +159,9 @@ def constants(self):
153159
self.__kwargs[key] = f'_{key_upper}'
154160
else:
155161
for child in self.__children:
162+
if isinstance(child, TOMLConditional):
163+
continue
164+
156165
res.extend(child.constants)
157166

158167
return res
@@ -165,14 +174,19 @@ def __str__(self):
165174
output.extend(self.constants)
166175

167176
for child in self.__children:
168-
if child.name not in global_variable_names:
177+
if isinstance(child, TOMLConditional):
178+
output.append('')
179+
180+
elif child.name not in global_variable_names:
169181
module = child.fqn.split('.')[0]
170182
if module not in self.imports and module not in used_imports:
171183
self.imports.append(module)
172184
used_imports.append(module)
173185
output.extend(['', f'import {module}', ''])
174186

175187
output.append(str(child))
188+
if isinstance(child, TOMLConditional):
189+
output.append('')
176190

177191
if output:
178192
output = [
@@ -271,6 +285,162 @@ def __str__(self):
271285
return '\n'.join(output)
272286

273287

288+
class TOMLConditionalObject:
289+
290+
def __init__(self, name, parent=None, **kwargs):
291+
self.name = name
292+
self.parent = parent
293+
self.__children = []
294+
295+
for key, value in list(kwargs.items())[:]:
296+
if isinstance(value, dict):
297+
self.__children.append(TOMLConditionalObject(key, self, **value))
298+
del kwargs[key]
299+
300+
self.__kwargs = kwargs
301+
302+
def get_conditional(self):
303+
if 'not_equal' in self.__kwargs:
304+
return f'{self.name} != {self.__kwargs["not_equal"]}'
305+
elif 'equal' in self.__kwargs:
306+
return f'{self.name} == {self.__kwargs["equal"]}'
307+
elif 'greater_than' in self.__kwargs:
308+
return f'{self.name} > {self.__kwargs["greater_than"]}'
309+
elif 'less_than' in self.__kwargs:
310+
return f'{self.name} < {self.__kwargs["less_than"]}'
311+
elif 'greater_than_or_equal' in self.__kwargs:
312+
return f'{self.name} >= {self.__kwargs["greater_than_or_equal"]}'
313+
elif 'less_than_or_equal' in self.__kwargs:
314+
return f'{self.name} <= {self.__kwargs["less_than_or_equal"]}'
315+
elif 'is' in self.__kwargs:
316+
return f'{self.name} is {self.__kwargs["is"]}'
317+
elif 'is_not' in self.__kwargs:
318+
return f'{self.name} is not {self.__kwargs["is_not"]}'
319+
elif 'in' in self.__kwargs:
320+
return f'{self.name} in {self.__kwargs["in"]}'
321+
elif 'not_in' in self.__kwargs:
322+
return f'{self.name} not in {self.__kwargs["not_in"]}'
323+
else:
324+
for child in self.__children:
325+
res = child.get_conditional()
326+
if res is not None:
327+
return f'{self.name}.{res}'
328+
329+
def is_conditional(self):
330+
cond = self.get_conditional()
331+
return cond is not None and not cond.startswith(f'{self.name}.')
332+
333+
def get_objects(self):
334+
res = []
335+
336+
base_conditional = self.parent
337+
while not isinstance(base_conditional, TOMLConditional):
338+
base_conditional = base_conditional.parent
339+
340+
if self.is_conditional():
341+
for child in self.__children:
342+
res.extend(child.get_objects())
343+
else:
344+
if 'value' in self.__kwargs:
345+
names = []
346+
parent = self.parent
347+
while parent.name and not isinstance(parent, TOMLConditional):
348+
names.insert(0, parent.name)
349+
parent = parent.parent
350+
351+
while names and not base_conditional.has_variable_name('.'.join(names)):
352+
names.pop(0)
353+
354+
names.append(self.name)
355+
var_name = '.'.join(names)
356+
base_conditional.add_variable_name(var_name)
357+
res.append(f'{var_name} = {self.__kwargs["value"]}')
358+
359+
elif 'params' in self.__kwargs:
360+
params = ', '.join(str(item) for item in self.__kwargs['params'])
361+
if self.name == 'del':
362+
res.append(f'{self.name} {params}')
363+
else:
364+
res.append(f'{self.name}({params})')
365+
366+
return res
367+
368+
for child in self.__children:
369+
lines = child.get_objects()
370+
371+
for line in lines:
372+
if ' = ' in line:
373+
var_name = line.split(' = ', 1)[0]
374+
if base_conditional.has_variable_name(var_name):
375+
res.append(line)
376+
continue
377+
else:
378+
try:
379+
func_name = line.split('(', 1)[0]
380+
if base_conditional.has_variable_name(func_name):
381+
res.append(line)
382+
continue
383+
384+
func_name = func_name.split('.', 1)[0]
385+
if base_conditional.has_variable_name(func_name):
386+
res.append(line)
387+
continue
388+
except IndexError:
389+
pass
390+
391+
if line.startswith('del '):
392+
res.append(line)
393+
else:
394+
res.append(f'{self.name}.{line}')
395+
return res
396+
397+
def is_variable(self):
398+
return 'value' in self.__kwargs
399+
400+
def is_function(self):
401+
return 'params' in self.__kwargs
402+
403+
404+
class TOMLConditional:
405+
406+
def __init__(self, name, parent=None, **kwargs):
407+
self.name = name
408+
self.parent = parent
409+
self.__children = []
410+
self.__variable_names = []
411+
412+
for key, value in list(kwargs.items())[:]:
413+
if isinstance(value, dict):
414+
self.__children.append(TOMLConditionalObject(key, self, **value))
415+
del kwargs[key]
416+
417+
self.__kwargs = kwargs
418+
419+
code = []
420+
for child in self.__children:
421+
cond = child.get_conditional()
422+
if cond is not None:
423+
code.append(f'if {cond}:')
424+
break
425+
else:
426+
raise RuntimeError('Unable to locate conditional argument')
427+
428+
for child in self.__children:
429+
code.extend([f' {line}' for line in child.get_objects()])
430+
431+
self.__code = '\n'.join(code)
432+
433+
def add_variable_name(self, name):
434+
if name not in self.__variable_names:
435+
self.__variable_names.append(name)
436+
437+
def has_variable_name(self, name):
438+
return name in self.__variable_names
439+
440+
def __str__(self):
441+
return self.__code
442+
443+
274444
class TOMLmcu:
275445

276446
def __init__(self, mcu):

0 commit comments

Comments
 (0)