On Feb 13, 7:29 pm, "Bill Davy" <[EMAIL PROTECTED]> wrote: > The following code produces an error message (using Idle with Py 2.4 and > 2.5). "There's an error in your program: EOL while scanning single-quoted > string". It comes just after "s = ''" (put there to try and isolate the > broken string). > > It would be good if the error message pointed me to the start of said single > quoted string. > > The colouring in IDLE does not indicate a bad string. > > Puzzled. > > Bill > > # > > # The traceback module is used to provide a stack trace to > > # show the user where the error occured. See Error(). > > # > > import traceback > > # > > # The math module is used to convert numbers between the Python real format > > # and the Keil real format. See KeilToFloatingPoint() and FloatingToKeil(). > > # > > import math > > LOAD_LIT = 1 > > LOAD_REG = 1 > > STORE_REG = 1 > > ADD_LIT_FP = 2 + 8 > > ADD_LIT_INT = 2 + 16 > > ADD_REG_FP = 2 + 32 > > ADD_REG_INT = 9 > > SUB_LIT_FP = 11 > > SUB_LIT_INT = 12 > > SUB_REG_FP = 13 > > SUB_REG_INT =14 > > MUL_LIT_FP = 11 > > MUL_LIT_INT = 12 > > MUL_REG_FP = 13 > > MUL_REG_INT =14 > > DIV_LIT_FP = 11 > > DIV_LIT_INT = 12 > > DIV_REG_FP = 13 > > DIV_REG_INT =14 > > AND_LIT_INT = 12 > > AND_REG_INT =14 > > OR_LIT_INT = 12 > > OR_REG_INT =14 > > NEGATE_FP = 11 > > NEGATE_INT = 12 > > ABSOLUTE_FP = 13 > > ABSOLUTE_INT = 14 > > INVERT_INT = 15 > > JUMP_OPCODE = 15 > > JLT_OPCODE = 15 > > JGT_OPCODE = 15 > > JLE_OPCODE = 15 > > JGE_OPCODE = 15 > > JEQ_OPCODE = 15 > > JNE_OPCODE = 15 > > BinaryOps={ > > > "LOAD":{float:{"L":LOAD_LIT,"R":LOAD_REG},int:{"L":LOAD_LIT,"R":LOAD_REG}}, > > "STORE":{float:{"R":STORE_REG},int:{"R":STORE_REG}}, > > > "ADD":{float:{"L":ADD_LIT_FP,"R":ADD_REG_FP},int:{"L":ADD_LIT_INT,"R":ADD_REG_INT}}, > > > "SUB":{float:{"L":SUB_LIT_FP,"R":SUB_REG_FP},int:{"L":SUB_LIT_INT,"R":SUB_REG_INT}}, > > > "MUL":{float:{"L":MUL_LIT_FP,"R":MUL_REG_FP},int:{"L":MUL_LIT_INT,"R":MUL_REG_INT}}, > > > "DIV":{float:{"L":DIV_LIT_FP,"R":DIV_REG_FP},int:{"L":DIV_LIT_INT,"R":DIV_REG_INT}}, > > "AND":{int:{"L":AND_LIT_INT,"R":AND_REG_INT}}, > > "OR":{int:{"L":OR_LIT_INT,"R":OR_REG_INT}} > > } > > UnaryOps={ > > "NEGATE":{float:NEGATE_FP, int:NEGATE_INT}, > > "ABSOLUTE":{float:ABSOLUTE_FP, int:ABSOLUTE_INT}, > > "INVERT":{int:INVERT_INT} > > } > > JumpOps={ > > "JUMP":JUMP_OPCODE, > > "JLT":JLT_OPCODE, > > "JGT":JGT_OPCODE, > > "JLE":JLE_OPCODE, > > "JGE":JGE_OPCODE, > > "JEQ":JEQ_OPCODE, > > "JNE":JNE_OPCODE > > } > > def IsOpCode(s): > > if ( s in BinaryOps ): return True; > > if ( s in UnaryOps ): return True; > > if ( s in JumpOps ): return True; > > return False > > class Register: > > """ > > This class provides us with a register (say) 0..32 > > In addtion to a number, a register can be given a name. > > It allows LOAD(arg) and other opcodes to distinguish between > > references to a register and a literal value. > > """ > > def __init__(self,Id,Name=None): > > self.Number = Id > > if ( Name == None): > > self.Name = "R%d" % Id > > else: > > self.Name = Name > > def RegisterNumber(self): > > return self.Number > > def RegisterName(self): > > return self.Name > > R0=Register(0) > > R1=Register(1) > > R2=Register(2) > > Now=Register(2,"Now") > > def IsRegister(arg): > > return hasattr( arg, "RegisterNumber") > > assert not IsRegister(0) > > assert not IsRegister(1.2) > > assert IsRegister(R1) > > assert IsRegister(Now) > > # > > # ErrorCount is global as it is shared by all slaves. > > # > > ErrorCount = 0 > > def Error(Message): > > """ > > work back through the traceback until you find a function whose name is > in one of the > > opcode dictionaries and trace back from there. This will keep internal > > implemenataion functions private but still allow the suer to define > functions > > that generate code. > > """ > > global ErrorCount > > ErrorCount += 1 > > """ > > [ > > ('<string>', 1, '?', None), > > ('C:\\Python24\\lib\\idlelib\\run.py', 90, 'main', 'ret = method(*args, > **kwargs)'), > > ('C:\\Python24\\lib\\idlelib\\run.py', 283, 'runcode', 'exec code in > self.locals'), > > ('H:\\Husky Experiments\\Viper1\\tmp.py', 434, '?', 'STORE(1)'), > > ('H:\\Husky Experiments\\Viper1\\tmp.py', 147, 'STORE', > 'self.BINOP("STORE",Arg,Msg)'), > > ('H:\\Husky Experiments\\Viper1\\tmp.py', 198, 'BINOP', 'return > Error("Cannot perform %s on %s" % (Op,Arg))'), > > ('H:\\Husky Experiments\\Viper1\\tmp.py', 106, 'Error', 'tb = > traceback.extract_stack()') > > ] > > """ > > tb = traceback.extract_stack() > > BeforePrinting = True > > IsPrinting = False > > for i in range(len(tb)-1,0,-1): > > frame = tb[i] > > if ( BeforePrinting ): > > # Looking to start > > if IsOpCode(frame[2]): # start printing > > IsPrinting = True > > BeforePrinting = False > > print "John: %s\nTrace back follows:" % Message > > elif ( IsPrinting ): > > print '\tFile "%s", line %u, %s' % (frame[0], frame[1], > frame[3]) > > # Stop when we find the curious function "?" > > if (frame[2] == "?"): > > break > > if BeforePrinting: > > print "John: %s (no trace back)" % Message > > class Slave: > > "This is a slave class" > > Listing = "" > > Number = 0 > > Mode = 0; # Will be int or float when defined > > def __init__(self,Id): > > self.Number = Id > > self.Line = 0 > > # > > # The listing, built as we go along > > # > > self.Listing = "" > > self.Mode = None > > def SetMode(self, arg): > > self.Mode = arg > > def LOAD(self,Arg,Msg=""): > > self.BINOP("LOAD",Arg,Msg) > > def STORE(self,Arg,Msg=""): > > self.BINOP("STORE",Arg,Msg) > > def ADD(self,Arg,Msg=""): > > self.BINOP("ADD",Arg,Msg) > > def SUB(self,Arg,Msg=""): > > self.BINOP("SUB",Arg,Msg) > > def MUL(self,Arg,Msg=""): > > self.BINOP("MUL",Arg,Msg) > > def DIV(self,Arg,Msg=""): > > self.BINOP("DIV",Arg,Msg) > > def AND(self,Arg,Msg=""): > > self.BINOP("AND",Arg,Msg) > > def OR(self,Arg,Msg=""): > > selfBINOPOP("OR",Arg,Msg) > > def NEGATE(self,Msg=""): > > self.UNOP("NEGATE",Msg) > > def ABSOLUTE(self,Msg=""): > > self.UNOP("ABSOLUTE",Msg) > > def INVERT(self,Msg=""): > > self.UNOP("INVERT",Msg) > > def JUMP(self,Arg,Msg=""): > > self.JUMPOP("JUMP",Arg,Msg) > > def JLT(self,Arg,Msg=""): > > self.JUMPOP("JLT",Arg,Msg) > > def JGT(self,Arg,Msg=""): > > self.JUMPOP("JGT",Arg,Msg) > > def JLE(self,Arg,Msg=""): > > self.JUMPOP("JLE",Arg,Msg) > > def JGE(self,Arg,Msg=""): > > self.JUMPOP("JGE",Arg,Msg) > > def JEQ(self,Arg,Msg=""): > > self.JUMPOP("JEQ",Arg,Msg) > > def JNE(self,Arg,Msg=""): > > self.JUMPOP("JNE",Arg,Msg) > > def BINOP(self,Op,Arg,Msg): > > entry = BinaryOps.get(Op) > > assert entry != None, "Who gave me %s to look up?" % op > > entry = entry.get(self.Mode) > > if entry == None : > > return Error("Cannot perform %s on %s, mode=%s" % ( > > Op,Arg,self.Mode)) > > if ( IsRegister(Arg) ): > > ot = entry.get("R") # Register > > if ot == None: > > return Error("Cannot perform %s on %s" % (Op,Arg)) > > self.Listing += "%x \t \t%s\t%s\t# %s\n" % ( > > len(self.Memory), Op,Arg.RegisterName(), Msg) > > self.Memory.append(ot) > > self.Memory.append(Arg.RegisterNumber()) > > else: > > ot = entry.get("L") # Literal > > if ot == None: > > return Error("Cannot perform %s on %s" % (Op,Arg)) > > self.Listing += "%x \t \t%s\t%s\t# %s\n" % ( > > len(self.Memory), Op, Arg, Msg) > > self.Memory.append(ot) > > cArg = self.Mode(Arg) > > if self.Mode == int: > > try: > > iArg = int(Arg) > > except TypeError: > > return Error("Argument %r is not an integer" % Arg) > > except: > > return Error("Unexpected error:", sys.exc_info()[0]) > > if ( iArg != Arg ): > > return Error("Argument %r is not an integer" % Arg) > > self.Memory.append((iArg >> 24) & 0xFF) > > self.Memory.append((iArg >> 16) & 0xFF) > > self.Memory.append((iArg >> 8) & 0xFF) > > self.Memory.append((iArg >> 0) & 0xFF) > > elif self.Mode == float: > > try: > > fArg = float(Arg) > > except TypeError: > > return Error("Argument %r is not a float" % Arg) > > except: > > return Error("Unexpected error:", sys.exc_info()[0]) > > if ( fArg != Arg ): > > return Error("Argument %r is not a float" % Arg) > > FourBytes = FloatingToKeil(fArg) > > self.Memory.append(FourBytes[0]) > > self.Memory.append(FourBytes[1]) > > self.Memory.append(FourBytes[2]) > > self.Memory.append(FourBytes[3]) > > else: > > return Error("No or bad mode (%r)set for slave %u" % ( > > self.Mode,self.SlaveNumber)) > > def JUMPOP(self,Op,Name,Msg): > > entry = JumpOps.get(Op) > > assert entry != None, "Who gave me %s to look up?" % op > > """ > > Generate code for a jump to the given target > > May enter target into the table. > > """ > > self.Listing += "%x \t \t%s\t%s\t# %s\n" % ( > > len(self.Memory),Op,Name, Msg) > > self.Memory.append(entry) > > self.AddReference(Name,len(self.Memory)) # for patching up later > > self.Memory.append(0) # Space for destination of jump > > # > > # The memory image of this Slave. > > # > > Memory = [] > > def ListProgram(self): > > """Generate a user friendly listing of the program for this Slave. > > """" > > s = '' > > print "%s" % self.Number > > print "%s\n" % ("#" * 64) > > print "%s" % self.Listing > > pass > > def EmitProgram(self): > > """Emit a C code data structure of the program for this Slave. > > """ > > s=\ > > "%s\n/* C data structure for slave %d */\n"\ > > "struct\n"\ > > "\t{\n"\ > > "\tunsigned SlaveId;\n"\ > > "\tunsigned nBytes;\n"\ > > "\tunsigned char[%d];\n"\ > > "\t} Slave%d=\n"\ > > "\t{%u,%u\n"\ > > "\t{\n\t"\ > > % ('#'*64, self.Number, len(self.Memory), self.Number, self.Number, > len(self.Memory)) > > for i in range(0,len(self.Memory)): > > if (i>0) : s+= ", " > > s += "0x%x" % (self.Memory[i]) > > if ( (i % 16) == 15 ): > > s += '\n\t' > > s+="\n\t}\n\t};\n" > > print s; > > # > > # Dictionary of Labels > > # Maps Name onto (Set of Locations, List of references)) > > # Users define a label using Label(Name) > > # Users reference a label using Jump(Name) > > # > > LabelTable = {} > > def AddReference(self,Name,Reference): > > """ > > Add a reference to the given Name. > > Name may not yet be defined > > """ > > Entry = self.LabelTable.get(Name) > > if ( Entry == None ): > > self.LabelTable[Name] = [ [] , [Reference] ] > > else: > > Entry[1].append(Reference) > > def AddDefinition(self,Name,Location): > > """ > > Add a definition to the given Name. > > Name may not yet be defined. > > If it is defined, it may not be given a different Location. > > """ > > Entry = self.LabelTable.get(Name) > > if ( Entry == None ): > > # Add location to a new name > > self.LabelTable[Name] = [ [Location] , [] ] > > elif len(Entry[0]) == 0: > > # Provide an initial location for a known name > > Entry[0].append(Location) > > elif Entry[0].count(Location) == 1: > > # The same location, harmless but odd > > pass > > else: > > # This is an additional definition but that does not matter > > # unless it is used and we find that out when we call > FixUpLabels() > > # at the end. > > Entry[0].append(Location) > > def Label(self, Name, Msg=""): > > """ > > Lays down a label for the user. > > """ > > self.AddDefinition(Name,len(self.Memory)) > > self.Listing += "%x \t%s: \t \t \t# %s\n" % (len(self.Memory), Name, > Msg) > > def EmitLabelTable(self): > > print "%s\nSymbol table for Slave %u" % ('#' * 64, self.Number) > > for Name in self.LabelTable.keys(): > > s = "Name=%s" % Name > > entry = self.LabelTable[Name] > > if ( len(entry[0])==1 and len(entry[1]) == 0): > > s += ", is not referenced" > > if ( len(entry[0])==0 and len(entry[1]) > 0): > > s += ", is not defined" > > if ( len(entry[0])>1 and len(entry[1]) > 0): > > s += ", is multiply-defined" > > if ( len(entry[0]) > 0): > > s += ", Location:" > > for i in entry[0]: > > s += " %x" % i > > if ( len(entry[1]) > 0 ): > > s += ", references:" > > for i in range(0,len(entry[1])): > > s += " %x" % entry[1][i] > > print s > > def FixUpLabels(self): > > print "%s\nFixing labels for Slave %u" % ('#' * 64, self.Number) > > for Name in self.LabelTable.keys(): > > entry = self.LabelTable[Name] > > if ( len(entry[0])==1 and len(entry[1]) == 0): > > print "Warning: %s is not referenced" % Name > > elif ( len(entry[0])==0 and len(entry[1]) > 0): > > Error("%s is not defined" % Name) > > elif ( len(entry[0])>1 and len(entry[1]) > 0): > > Error("%s is multiply-defined" % Name) > > else: > > for i in range(0,len(entry[1])): > > self.Memory[entry[1][i]] = entry[0][0] > > # > > # Construct a vector of Slaves > > # > > S=[(Slave(i)) for i in range(6)] > > def SetSlave(New): > > """ > > Make global functions generate code for a specified slave. > > """ > > # > > # This sets the mode for the assembler and applies in the order of > > # assembly, not in the execution order. The mode is embedded in the > opcode. > > # > > global SetMode > > SetMode = S[New].SetMode > > # > > # Labels are local to a slave. > > # > > global Label > > Label = S[New].Label; > > global LOAD, STORE, ADD, SUB, MUL, DIV, AND, OR > > global NEGATE, ABSOLUTE, INVERT > > global JUMP, JLT, JGT, JLE, JGE, JEQ, JNE > > LOAD = S[New].LOAD > > JUMP = S[New].JUMP > > LOAD = S[New].LOAD > > STORE = S[New].STORE > > ADD = S[New].ADD > > SUB = S[New].SUB > > MUL = S[New].MUL > > DIV = S[New].DIV > > AND = S[New].AND > > OR = S[New].OR > > NEGATE = S[New].NEGATE > > ABSOLUTE = S[New].ABSOLUTE > > INVERT = S[New].INVERT > > JUMP = S[New].JUMP > > JLT = S[New].JLT > > JGT = S[New].JGT > > JLE = S[New].JLE > > JGE = S[New].JGE > > JEQ = S[New].JEQ > > JNE = S[New].JNE > > print "hi" > > SetSlave(1) > > SetMode(int) > > LOAD(4,"Into S1 hopefully") > > Label("Loop") > > LOAD(R1,"Comment") > > JUMP("Loop") > > LOAD(Now) > > JUMP("Loop") > > STORE(1) > > Label("Loop") > > class TemporaryLabelClass: > > DefaultBaseName = "TL_" > > Instances = {DefaultBaseName:0} > > def __init__(self, BaseName=None): > > de = self.Instances.get(BaseName) > > if de == None: > > self.Instances[BaseName] = 0 # new temporary BaseName > > else: > > self.Instances[BaseName] += 1 # using an existing BaseName again > > self.BaseName = BaseName; > > def Instance(self): > > return self.Instances[self.BaseName] > > def TemporaryLabel(BaseName=None): > > t = TemporaryLabelClass(BaseName) > > if ( BaseName == None ): > > BaseName = t.DefaultBaseName > > elif ( BaseName == t.DefaultBaseName): > > return Error("Do not call TemporaryLabel(%s)" % t.DefaultBaseName) > > return "%s%u" % (BaseName,t.Instance()) > > a = TemporaryLabel() > > b = TemporaryLabel("MY") > > c = TemporaryLabel() > > d = TemporaryLabel("MY") > > e = TemporaryLabel() > > f = TemporaryLabel("TL_") > > del a, b, c, d, e, f > > def BusyIdleLoop(Time, Register): > > label = TemporaryLabel() > > LOAD(Now) > > ADD(Time) > > STORE(Register) > > Label(label) > > LOAD(Now) > > SUB(Register) > > JLT(label) > > BusyIdleLoop(5000,R0) > > S[1].FixUpLabels() > > S[1].EmitProgram() > > S[1].EmitLabelTable() > > S[1].ListProgram() > > def KeilToFloatingPoint(Bytes): > > #print Bytes > > temp = ((((((Bytes[0]<<8)+Bytes[1])<<8)+Bytes[2])<<8)+Bytes[3]) > > if ( temp == 0): > > return 0.0 > > Mantissa = 0x800000 + (temp&0x7fffff) > > if ( temp & 0x80000000 ): > > Mantissa = -Mantissa > > temp -= 0x80000000 > > Exponent = (0xFF & (temp>>23)) - 127; > > Mantissa = float(Mantissa) / (1<<23) > > #print "Mantissa=%f" % Mantissa > > #print "Exponent=%x" % Exponent > > return math.ldexp(Mantissa, Exponent) > > def FloatingToKeil(arg): > > """ > > The flooating point format used by Keil follows > > the IEEE-754 standard > > The fields are (from MSB to LSB, and first byte to last): > > S (one bit) 1 is posirtive, 0 is negative > > E (eight bits) Exponent + 127 > > M (23 bits) The twenty four bit (MSB omitted) mantissa > > """ > > Mantissa, Exponent = math.frexp( arg ) > > Mantissa *= 2 > > Exponent -= 1 > > if ( Mantissa >= 0 ): > > if ( Exponent == 0 ): > > return (0,0,0,0) > > S = 0 > > else: > > S = 1 > > Mantissa = -Mantissa > > Mantissa *= (1<<23) > > Mantissa = int(Mantissa + 0.5) # round > > if ( Mantissa >> 24 ): > > # Renormalise > > Mantissa >>= 1 > > Exponent += 1 > > assert ( (Mantissa >> 24) == 0) > > Mantissa -= (1<<23) # Remove the "assumed" 1 before the binary point > > assert ( (Mantissa >> 23) == 0 ) > > Exponent += 127 > > if ( Exponent < 0 ): > > # Number is too small to represent; call it zero > > FourBytes = 0,0,0,0 > > temp = KeilToFloatingPoint(FourBytes) > > print "Truncating %r to %r" % (arg, temp) > > elif ( Exponent > 0xFF): > > # Number is too big to represent; make the maximum with the right > sign > > FourBytes = (S<<7)+0x7F,0xFF,0xFF,0xFF > > temp = KeilToFloatingPoint(FourBytes) > > print "Truncating %r to %r" % (arg, temp) > > else: > > temp = (S<<31) + (Exponent<<23) + Mantissa > > FourBytes = ((temp>>24),0xFF&(temp>>16),0xFF&(temp>>8),0xFF&(temp)) > > temp = KeilToFloatingPoint(FourBytes) > > return FourBytes > > FloatingToKeil(-12.5) > > FloatingToKeil(-1e-200) ## should become zero > > FloatingToKeil(-1e+200) ## should saturate > > FloatingToKeil(math.ldexp((1<<24)-1,-24)) ## Exact conversion > > FloatingToKeil(math.ldexp((1<<25)-1,-25)) ## Should make renormalise happen > > print "Byeee"
Just before s = '' you have 4 double quotes to close to doc-string instead of 3. -- http://mail.python.org/mailman/listinfo/python-list