Cannot understand error message

Chris cwitts at gmail.com
Wed Feb 13 13:53:53 EST 2008


On Feb 13, 7:29 pm, "Bill Davy" <B... at SynectixLtd.com> 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.



More information about the Python-list mailing list