From 9f7e93abc01b328ca62b0466895a8eeedf71060e Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Fri, 3 Apr 2020 13:05:53 -0700 Subject: [PATCH] power parser should work --- src/soc/decoder/power_pseudo.py | 63 +++++++++---------- src/soc/decoder/pseudo/parser.py | 102 +++++++++++++++++-------------- 2 files changed, 88 insertions(+), 77 deletions(-) diff --git a/src/soc/decoder/power_pseudo.py b/src/soc/decoder/power_pseudo.py index f2e575e8..cab7321f 100644 --- a/src/soc/decoder/power_pseudo.py +++ b/src/soc/decoder/power_pseudo.py @@ -103,10 +103,11 @@ code = cnttzd #code = addpcis #code = bpermd + def tolist(num): l = [] for i in range(64): - l.append(1 if (num & (1<", " ".join(map(str,args))) + print("args", args) + print("-->", " ".join(map(str, args))) from soc.decoder.helpers import (EXTS64, EXTZ64, ROTL64, ROTL32, MASK,) @@ -195,9 +196,9 @@ def test(): gsc.gpr.set_form(form) getform = gsc.parser.sd.sigforms[form]._asdict() #print ("getform", form) - #for k, f in getform.items(): - #print (k, f) - #d[k] = getform[k] + # for k, f in getform.items(): + #print (k, f) + #d[k] = getform[k] compiled_code = compile(source, mode="exec", filename="") @@ -205,7 +206,7 @@ def test(): comb = m.d.comb instruction = Signal(32) - m.submodules.decode = decode = gsc.parser.sd + m.submodules.decode = decode = gsc.parser.sd comb += decode.raw_opcode_in.eq(instruction) sim = Simulator(m) @@ -222,29 +223,29 @@ def test(): # uninitialised regs, drop them into dict for function for rname in gsc.parser.uninit_regs: - d[rname] = SelectableInt(0, 64) # uninitialised (to zero) - print ("uninitialised", rname, get_reg_hex(d[rname])) + d[rname] = SelectableInt(0, 64) # uninitialised (to zero) + print("uninitialised", rname, get_reg_hex(d[rname])) # read regs, drop them into dict for function for rname in gsc.parser.read_regs: regidx = yield getattr(decode.sigforms['X'], rname) d[rname] = gsc.gpr[regidx] - print ("read reg", rname, regidx, get_reg_hex(d[rname])) + print("read reg", rname, regidx, get_reg_hex(d[rname])) - exec (compiled_code, d) # code gets executed here in dict "d" - print ("Done") + exec(compiled_code, d) # code gets executed here in dict "d" + print("Done") - print (d.keys()) # shows the variables that may have been created + print(d.keys()) # shows the variables that may have been created - print (decode.sigforms['X']) + print(decode.sigforms['X']) x = yield decode.sigforms['X'].RS ra = yield decode.sigforms['X'].RA - print ("RA", ra, d['RA']) - print ("RS", x) + print("RA", ra, d['RA']) + print("RS", x) for wname in gsc.parser.write_regs: reg = getform[wname] - print ("write regs", wname, d[wname], reg) + print("write regs", wname, d[wname], reg) regidx = yield reg gsc.gpr[regidx] = d[wname] @@ -254,7 +255,7 @@ def test(): sim.run() for i in range(len(gsc.gpr)): - print ("regfile", i, get_reg_hex(gsc.gpr[i])) + print("regfile", i, get_reg_hex(gsc.gpr[i])) if __name__ == '__main__': diff --git a/src/soc/decoder/pseudo/parser.py b/src/soc/decoder/pseudo/parser.py index 68551b5c..4766ee25 100644 --- a/src/soc/decoder/pseudo/parser.py +++ b/src/soc/decoder/pseudo/parser.py @@ -20,9 +20,11 @@ from soc.decoder.pseudo.lexer import IndentLexer import ast # Helper function + + def Assign(left, right): names = [] - print ("Assign", left, right) + print("Assign", left, right) if isinstance(left, ast.Name): # Single assignment on left # XXX when doing IntClass, which will have an "eq" function, @@ -45,7 +47,7 @@ def Assign(left, right): ls = left.slice if isinstance(ls, ast.Slice): lower, upper, step = ls.lower, ls.upper, ls.step - print ("slice assign", lower, upper, step) + print("slice assign", lower, upper, step) if step is None: ls = (lower, upper, None) else: @@ -54,11 +56,11 @@ def Assign(left, right): return ast.Call(ast.Name("selectassign"), [left.value, ls, right], []) else: - print ("Assign fail") + print("Assign fail") raise SyntaxError("Can't do that yet") -## I implemented INDENT / DEDENT generation as a post-processing filter +# I implemented INDENT / DEDENT generation as a post-processing filter # The original lex token stream contains WS and NEWLINE characters. # WS will only occur before any other tokens on a line. @@ -70,7 +72,7 @@ def Assign(left, right): # see if the new line has changed indication level. -## No using Python's approach because Ply supports precedence +# No using Python's approach because Ply supports precedence # comparison: expr (comp_op expr)* # arith_expr: term (('+'|'-') term)* @@ -81,19 +83,28 @@ def Assign(left, right): def make_le_compare(arg): (left, right) = arg return ast.Compare(left, [ast.LtE()], [right]) + + def make_ge_compare(arg): (left, right) = arg return ast.Compare(left, [ast.GtE()], [right]) + + def make_lt_compare(arg): (left, right) = arg return ast.Compare(left, [ast.Lt()], [right]) + + def make_gt_compare(arg): (left, right) = arg return ast.Compare(left, [ast.Gt()], [right]) + + def make_eq_compare(arg): (left, right) = arg return ast.Compare(left, [ast.Eq()], [right]) + binary_ops = { "&": ast.BitAnd(), "|": ast.BitOr(), @@ -111,13 +122,14 @@ unary_ops = { "+": ast.UAdd(), "-": ast.USub(), "¬": ast.Invert(), - } +} + -def check_concat(node): # checks if the comparison is already a concat - print ("check concat", node) +def check_concat(node): # checks if the comparison is already a concat + print("check concat", node) if not isinstance(node, ast.Call): return [node] - print ("func", node.func.id) + print("func", node.func.id) if node.func.id != 'concat': return [node] return node.args @@ -131,12 +143,13 @@ def check_concat(node): # checks if the comparison is already a concat class PowerParser: precedence = ( - ("left", "BITOR", "BITAND"), ("left", "EQ", "GT", "LT", "LE", "GE", "LTU", "GTU"), + ("left", "BITOR"), + ("left", "BITAND"), ("left", "PLUS", "MINUS"), ("left", "MULT", "DIV"), ("left", "INVERT"), - ) + ) def __init__(self): self.gprs = {} @@ -148,12 +161,12 @@ class PowerParser: # The grammar comments come from Python's Grammar/Grammar file - ## NB: compound_stmt in single_input is followed by extra NEWLINE! + # NB: compound_stmt in single_input is followed by extra NEWLINE! # file_input: (NEWLINE | stmt)* ENDMARKER def p_file_input_end(self, p): """file_input_end : file_input ENDMARKER""" - print ("end", p[1]) + print("end", p[1]) p[0] = p[1] def p_file_input(self, p): @@ -165,16 +178,16 @@ class PowerParser: if len(p) == 3: p[0] = p[1] else: - p[0] = [] # p == 2 --> only a blank line + p[0] = [] # p == 2 --> only a blank line else: if len(p) == 3: p[0] = p[1] + p[2] else: p[0] = p[1] - # funcdef: [decorators] 'def' NAME parameters ':' suite # ignoring decorators + def p_funcdef(self, p): "funcdef : DEF NAME parameters COLON suite" p[0] = ast.FunctionDef(p[2], p[3], p[5], ()) @@ -184,15 +197,15 @@ class PowerParser: """parameters : LPAR RPAR | LPAR varargslist RPAR""" if len(p) == 3: - args=[] + args = [] else: args = p[2] p[0] = ast.arguments(args=args, vararg=None, kwarg=None, defaults=[]) - # varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME] | # '**' NAME) | # highly simplified + def p_varargslist(self, p): """varargslist : varargslist COMMA NAME | NAME""" @@ -243,7 +256,7 @@ class PowerParser: def p_expr_stmt(self, p): """expr_stmt : testlist ASSIGN testlist | testlist """ - print ("expr_stmt", p) + print("expr_stmt", p) if len(p) == 2: # a list of expressions #p[0] = ast.Discard(p[1]) @@ -254,10 +267,11 @@ class PowerParser: elif isinstance(p[1], ast.Subscript): name = p[1].value.id if name in self.gprs: - self.uninit_regs.append(name) # add to list of uninitialised - print ("expr assign", name, p[1]) + # add to list of uninitialised + self.uninit_regs.append(name) + print("expr assign", name, p[1]) if name in self.gprs: - self.write_regs.append(name) # add to list of regs to write + self.write_regs.append(name) # add to list of regs to write p[0] = Assign(p[1], p[3]) def p_flow_stmt(self, p): @@ -269,7 +283,6 @@ class PowerParser: "return_stmt : RETURN testlist" p[0] = ast.Return(p[2]) - def p_compound_stmt(self, p): """compound_stmt : if_stmt | while_stmt @@ -322,7 +335,6 @@ class PowerParser: else: p[0] = p[3] - def p_stmts(self, p): """stmts : stmts stmt | stmt""" @@ -351,7 +363,7 @@ class PowerParser: | comparison APPEND comparison | power""" if len(p) == 4: - print (list(p)) + print(list(p)) if p[2] == 'u': @@ -360,7 +372,7 @@ class PowerParser: l = check_concat(p[1]) + check_concat(p[3]) p[0] = ast.Call(ast.Name("concat"), l, []) elif p[2] in ['<', '>', '=', '<=', '>=']: - p[0] = binary_ops[p[2]]((p[1],p[3])) + p[0] = binary_ops[p[2]]((p[1], p[3])) else: p[0] = ast.BinOp(p[1], binary_ops[p[2]], p[3]) elif len(p) == 3: @@ -384,23 +396,23 @@ class PowerParser: if p[2][0] == "CALL": #p[0] = ast.Expr(ast.Call(p[1], p[2][1], [])) p[0] = ast.Call(p[1], p[2][1], []) - #if p[1].id == 'print': + # if p[1].id == 'print': # p[0] = ast.Printnl(ast.Tuple(p[2][1]), None, None) - #else: + # else: # p[0] = ast.CallFunc(p[1], p[2][1], None, None) else: - print ("subscript atom", p[2][1]) + print("subscript atom", p[2][1]) #raise AssertionError("not implemented %s" % p[2][0]) subs = p[2][1] if len(subs) == 1: idx = subs[0] else: idx = ast.Slice(subs[0], subs[1], None) - p[0] = ast.Subscript(p[1], idx) + p[0] = ast.Subscript(p[1], idx, ast.Load()) def p_atom_name(self, p): """atom : NAME""" - p[0] = ast.Name(p[1], ctx=ast.Load()) + p[0] = ast.Name(id=p[1], ctx=ast.Load()) def p_atom_number(self, p): """atom : BINARY @@ -408,7 +420,7 @@ class PowerParser: | STRING""" p[0] = ast.Constant(p[1]) - #'[' [listmaker] ']' | + # '[' [listmaker] ']' | def p_atom_listmaker(self, p): """atom : LBRACK listmaker RBRACK""" @@ -425,13 +437,13 @@ class PowerParser: def p_atom_tuple(self, p): """atom : LPAR testlist RPAR""" - print ("tuple", p[2]) + print("tuple", p[2]) if isinstance(p[2], ast.Name): - print ("tuple name", p[2].id) + print("tuple name", p[2].id) if p[2].id in self.gprs: - self.read_regs.append(p[2].id) # add to list of regs to read + self.read_regs.append(p[2].id) # add to list of regs to read #p[0] = ast.Subscript(ast.Name("GPR"), ast.Str(p[2].id)) - #return + # return p[0] = p[2] # trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME @@ -449,7 +461,7 @@ class PowerParser: "trailer_subscript : LBRACK subscript RBRACK" p[0] = ("SUBS", p[2]) - #subscript: '.' '.' '.' | test | [test] ':' [test] + # subscript: '.' '.' '.' | test | [test] ':' [test] def p_subscript(self, p): """subscript : test COLON test @@ -465,9 +477,9 @@ class PowerParser: else: p[0] = [p[1]] - # testlist: test (',' test)* [','] # Contains shift/reduce error + def p_testlist(self, p): """testlist : testlist_multi COMMA | testlist_multi """ @@ -496,18 +508,17 @@ class PowerParser: # singleton -> tuple p[0] = [p[1], p[3]] - # test: or_test ['if' or_test 'else' test] | lambdef # as I don't support 'and', 'or', and 'not' this works down to 'comparison' + def p_test(self, p): "test : comparison" p[0] = p[1] - - # arglist: (argument ',')* (argument [',']| '*' test [',' '**' test] # | '**' test) # XXX INCOMPLETE: this doesn't allow the trailing comma + def p_arglist(self, p): """arglist : arglist COMMA argument | argument""" @@ -522,12 +533,12 @@ class PowerParser: p[0] = p[1] def p_error(self, p): - #print "Error!", repr(p) + # print "Error!", repr(p) raise SyntaxError(p) class GardenSnakeParser(PowerParser): - def __init__(self, lexer = None): + def __init__(self, lexer=None): PowerParser.__init__(self) if lexer is None: lexer = IndentLexer(debug=0) @@ -539,7 +550,7 @@ class GardenSnakeParser(PowerParser): self.sd = create_pdecode() def parse(self, code): - #self.lexer.input(code) + # self.lexer.input(code) result = self.parser.parse(code, lexer=self.lexer, debug=False) return ast.Module(result) @@ -554,13 +565,12 @@ class GardenSnakeCompiler(object): def compile(self, code, mode="exec", filename=""): tree = self.parser.parse(code) - print ("snake") + print("snake") pprint(tree) return tree #misc.set_filename(filename, tree) return compile(tree, mode="exec", filename="") - #syntax.check(tree) + # syntax.check(tree) gen = pycodegen.ModuleCodeGenerator(tree) code = gen.getCode() return code - -- 2.30.2