def Assembly(aprog): """ convert atomic program aprog to assembly program asprog """ asprog = {} subj, wk, dl = exp.WhereD(aprog) if exp.VarP(subj): subj = exp.Operation1C(exp.IDWord, subj) odef = exp.DefinitionC(exp.VarC(exp.OUTPUTWord), pop.EQUALWord, subj) dl = pop.Cons(odef, dl) asprog = {} #initialize the assembly program, a dictionary #that assigns to every variable name a tuple consisting #of the operation symbol and the array of the names of the variables #all python strings while dl != pop.Empty: #loop through the definitions of the atomized program df, dl = pop.DeCons(dl) lhs, es, rhs = exp.DefinitionD(df) #dismantle current definition vname = pio.Words(exp.Var(lhs)) #get name of var being defined if exp.LiteralP( rhs): #if its a literal treat quote mark as a pseudo op asprog[vname] = ('"', exp.LiteralValue(rhs)) continue if exp.VarP(rhs): # rhs a single variable, add id operator rhs = exp.Operation1C(exp.IDWord, rhs) #its an operation applied to operands o, ods = exp.OperationD( rhs) #break rhs into operation symbol and operand list odsa = [] #initialize array of operands while ods != pop.Empty: #iterate through operand list vw, ods = pop.ConsD(ods) #get current operand, a var, and advance vws = pio.Words( exp.Var(vw)) #name of current operand, a var, as a string odsa.append(vws) #append to the array #finished looping throug operands, so odsa complete asprog[vname] = (pio.Words(o), odsa) return asprog
def Adefinition(df): """atomize a definition, returning atomic def and deflist""" rhs = exp.Rhs(df); lhs = exp.Lhs(df) assert exp.VarP(lhs), 'cannot handle compund definitions' if exp.LiteralP(rhs): #equated to a literal, no action return df,pop.Empty arhs, defs = Aexpr(rhs) return exp.DefinitionC(lhs,pop.EQUALWord, arhs), defs
def Aexpr(e): """ returns e1 dl where dl is the list of atomic definitions generated and e1 is the new atomic expression """ if exp.OperationP(e): return Aoperation(e) if exp.VarP(e): return e, pop.Empty if exp.WhereP(e): return Awhere(e) assert not exp.CallP(e), ' cannot do function calls ' assert exp.LiteralP(e), ' bad arg to Aexpr' v = VarGen() d = exp.DefinitionC(v,pop.EQUALWord,e) return v, pop.List1(d)
def Definition(ig): """ pick up a definition """ lhs = Expr(ig) if lhs == '': return '' lex = pio.NextItem(ig) if lex != exp.EQUALWord and lex != exp.ISWord: pro.printf('Expected = or is') print('Found '); pio.Dump5(ig) print() exit() rhs = Expr(ig) df = exp.DefinitionC(lhs,lex,rhs) if not Expect(exp.SEMICOLONWord,ig): return Interm(df) return df
def Aoperation(e): """ returns e1 dl where dl is the list of atomic definitions generated and e1 is the new atomic expression """ o = exp.OperationSymbol(e) #operator l = exp.OperationOperandL(e) #operands vl = pop.Empty #new variables introduced aeqs = pop.Empty #list of equations generated while l != pop.Empty: #iterate down operand list opd = pop.Head(l);l = pop.Tail(l) #get next operand and advance if exp.VarP(opd): #if it's a var nothing to do vl = pop.Cons(opd,vl) continue ae, dl = Aexpr(opd) # process the operand aeqs = pop.Append(dl,aeqs) # collect equations generated if not exp.VarP(ae): nv = VarGen() # generate a new variable vl = pop.Cons(nv,vl) # save it d = exp.DefinitionC(nv,pop.EQUALWord,ae) # generate new atomic definition aeqs = pop.Cons(d,aeqs) else: vl = pop.Cons(ae,vl) vl = pop.Reverse(vl) # variables accumulated in reverse order e1 = exp.OperationC(o,vl) # new atomic expression return e1, aeqs # return the atomic expression and equations generated