eval(parse()) not having same effect as repl in edited version of norvig's lispy.py interpreter

Viewed 34

I'm trying to edit Norvig's lispy.py scheme-to-python interpreter for a racket program in which, in addition to the procedures he includes, I use string->jsexpr and string-replace.

To do this, I edited his add_globals function as follows.


    def add_globals(self):
        "Add some Scheme standard procedures."
        import math, cmath, operator as op
        self.update(vars(math))
        self.update(vars(cmath))
        self.update({
         '+':op.add, '-':op.sub, '*':op.mul, '/':op.div, 'not':op.not_, 
         '>':op.gt, '<':op.lt, '>=':op.ge, '<=':op.le, '=':op.eq, 
         'equal?':op.eq, 'eq?':op.is_, 'length':len, 'cons':cons,
         'car':lambda x:x[0], 'cdr':lambda x:x[1:], 'append':op.add,  
         'list':lambda *x:list(x), 'list?': lambda x:isa(x,list),
         'null?':lambda x:x==[], 'symbol?':lambda x: isa(x, Symbol),
         'boolean?':lambda x: isa(x, bool), 'pair?':is_pair, 
         'port?': lambda x:isa(x,file), 'apply':lambda proc,l: proc(*l), 
         'eval':lambda x: eval(expand(x)), 'load':lambda fn: load(fn), 'call/cc':callcc,
         'open-input-file':open,'close-input-port':lambda p: p.file.close(), 
         'open-output-file':lambda f:open(f,'w'), 'close-output-port':lambda p: p.close(),
         'eof-object?':lambda x:x is eof_object, 'read-char':readchar, 
        #  Additions below
         'reverse':lambda x: x[::-1],
         'string->jsexpr':lambda x: json.loads(x),
         'string-replace':lambda strng,x,y: strng.replace(x, y),
        #  Additions above
         'read':read, 'write':lambda x,port=sys.stdout:port.write(to_string(x)),
         'display':lambda x,port=sys.stdout:port.write(x if isa(x,str) else to_string(x))})
        return self

In the lispy repl, string-replace seems to succeed:


    % python lispy.py
    Lispy version 2.0
    lispy> (string-replace "[['Noth', '<b>ing</b>'], ' in']" "\'" "\"")
    "[[\"Noth\", \"<b>ing</b>\"], \" in\"]"
    lispy>

However when, at the end of lispy.py, I run


    if __name__ == '__main__':
        x = eval(parse("""(begin
        (string-replace "[['Noth', '<b>ing</b>'], ' in']" "\'" "\"")
        )
        """
        ))
    
        print x

instead of running this (which is how the file came),


    if __name__ == '__main__':
        repl()

the program hangs — and when I trace it, I see that there's an infinite loop.

Any ideas?

1 Answers

Got it. I needed to add an extra backslash to escape the escape in the triple quoted section, like this

 if __name__ == '__main__':
        x = eval(parse("""(begin
        (string-replace "[['Noth', '<b>ing</b>'], ' in']" "\\'" "\\"")
        )
        """
        ))
    
        print x
Related