33import re
44import os
55import sys
6+ from collections .abc import Sequence
7+ from pprint import pformat
68
7- from parse import pcodeParser , pcodeSemantics
9+ from parse import pcodeParser
810
911DEBUG = 0
1012
1113###############################################################################
1214# misc utils
1315###############################################################################
1416
17+ def is_seq (x ):
18+ return type (x ) not in [str , bytes ] and isinstance (x , Sequence )
19+
1520# convert "MOV (register)" text to the function that handles it
1621# ->"mov_register"
1722def convertHandlerName (name ):
@@ -43,10 +48,20 @@ def applyIndent(text, level=0):
4348class BetterNode (object ):
4449 def __init__ (self , name , children = [], semicolon = False ):
4550 self .name = name
46- self .children = children
51+ if isinstance (children , filter ):
52+ self .children = list (children )
53+ else :
54+ self .children = children
4755 self .semicolon = semicolon
4856
57+ def __repr__ (self ):
58+ if is_seq (self .children ):
59+ return 'BetterNode(%s)[%d]%s{\n %s\n }' % (self .name , len (self .children ), ';' if self .semicolon else '' , pformat (list (map (repr , self .children )), indent = 4 ))
60+ else :
61+ return 'BetterNode(%s)[%r]' % (self .name , self .children )
62+
4963 def gen (self , extra = '' ):
64+ code = 'BOGUS'
5065 # leaf nodes (no possible descent)
5166 if self .name == 'ident' :
5267 tmp = (self .children [0 ] + extra ).replace ('.' , '_' )
@@ -64,8 +79,17 @@ def gen(self, extra=''):
6479 code = '\n return %s(req, res);' % self .children [0 ]
6580 self .semicolon = 0
6681 else :
67- subCode = map (lambda x : x .gen (), self .children )
68- subCode = tuple (subCode )
82+
83+ def c_gen (c ):
84+ if type (c ) is str :
85+ return c
86+ elif is_seq (c ):
87+ c = tuple (map (c_gen , c ))
88+ return c
89+ else :
90+ return '' .join (c .gen ())
91+
92+ subCode = c_gen (self .children )
6993
7094 # binary operations translate directly to C
7195 if self .name == 'xor' :
@@ -181,7 +205,7 @@ def gen(self, extra=''):
181205 if shamt :
182206 code = '((%s >> %d) & 1)' % (subCode [0 ], shamt )
183207 else :
184- code = '(%s & 1)' % subCode [0 ]
208+ code = '(%s & 1)' % subCode [0 ]
185209 else :
186210 # there is a bit range to extract, [hi,lo]
187211 hi = int (subCode [1 ])
@@ -192,7 +216,6 @@ def gen(self, extra=''):
192216 code = '((%s >> %d) & 0x%X)' % (subCode [0 ], lo , 2 ** width - 1 )
193217 else :
194218 code = '(%s & 0x%X)' % (subCode [0 ], 2 ** width - 1 )
195-
196219 # if else
197220 elif self .name == 'if' :
198221 if len (subCode ) == 2 :
@@ -467,7 +490,7 @@ def tuple(self, ast):
467490 def expr0 (self , ast ):
468491 rv = None
469492
470- if type (ast ) == type ([] ):
493+ if is_seq (ast ):
471494 lookup = {'EOR' :'xor' , '+' :'add' , '-' :'sub' ,
472495 '&&' :'log_and' , '||' :'log_or' }
473496
@@ -493,7 +516,7 @@ def expr0(self, ast):
493516 def expr1 (self , ast ):
494517 rv = ast
495518
496- if type (ast ) == type ([] ):
519+ if is_seq (ast ):
497520 lookup = {'*' :'mul' , '/' :'div' , 'XOR' :'xor' , 'DIV' :'div' , '==' :'equals' , '!=' :'not_equals' ,
498521 '<' :'less_than' , '>' :'greater_than' , '<<' :'shl' , '>>' :'rshl' ,
499522 '>=' :'greater_than_or_equals' , '<=' :'less_than_or_equals' }
@@ -529,7 +552,7 @@ def expr2(self, ast):
529552 def expr3 (self , ast ):
530553 rv = 'BLUNDER'
531554
532- if type (ast ) == type ([] ):
555+ if is_seq (ast ):
533556 #print('ast is: ', ast)
534557
535558 # empty closure, return original
@@ -540,7 +563,7 @@ def expr3(self, ast):
540563 rv = BetterNode ('group' , [ast [1 ]])
541564 elif ast [0 ] == '!' :
542565 rv = BetterNode ('log_not' , [ast [1 ]])
543- elif type (ast [1 ] == [ ]):
566+ elif is_seq (ast [1 ]):
544567 closure = ast [1 ]
545568 assert closure [0 ][0 ] == ':'
546569 bn = BetterNode ('concat' , [ast [0 ], closure [0 ][1 ]])
@@ -657,7 +680,7 @@ def func_call(self, ast):
657680 if type (ast ) == type (u'x' ):
658681 funcName = ast [:- 2 ]
659682 # function with arguments
660- elif type (ast ) == type ([] ):
683+ elif is_seq (ast ):
661684 funcName = str (ast [0 ][:- 1 ])
662685 args = filter (lambda x : x != ',' , ast [1 :- 1 ])
663686
@@ -725,7 +748,7 @@ def genBlock(pcode, comments=True):
725748 (caseVar , indent ) = (None , 0 )
726749
727750 for l in lines :
728- #print('line is: -%s-' % l)
751+ # print('line is: -%s-' % l, file=sys.stderr )
729752 if l [0 :5 ] == 'case ' :
730753 m = re .match (r'^case (.*) of' , l )
731754 result .append ('/* pcode: %s */' % l .lstrip ())
@@ -763,6 +786,8 @@ def genBlock(pcode, comments=True):
763786 result .append ('}' )
764787 (caseVar , indent ) = (None , 0 )
765788 code = gen (l )
789+ # print(f'code is: -{code}-', file=sys.stderr)
790+
766791 result .append (code )
767792
768793 return '\n ' .join (result )
0 commit comments