2012/6/25 Léonard de Haro <leonard.de.haro@ens.fr>
Hi everyone!

First of all, thaks for your answers last time. Second of all, I need your help again.

I'm coding an imperative version of my interpret and to do so, I coded continuations. I used a similat technique to the one used in the Prolog interpret you advised me to take a look at last time.

I define a serie of class all inheriting from a simulated-abstract Contk class. Every class has a method apply which contains instruction for what's next to do. All these methods take the same arguments and (except in one case) return the same kind of tuple.

The interpret function uses 4 variables that are updated: expr, env, cont, val. Thus, the result of .apply(_,_,_,_) is the tuple for update.

class Contk(object):
   def __init__(self,*arg):
       raise NotImplementedError("For abstract class")

   def apply(self,expr,env,val):
       raise NotImplementedError("For abstract class")

class Endk(Contk):
   def __init__(self,val):
       self.val = val

   def apply(self,expr, env, val):
       return self.val

class Idk(Contk):
   def __init__(self):

   def apply(self, expr, env, val):
       return expr, env, Endk(val), val

Even if RPython needs no explicit declaration, its constraints are similar to C++ or Java:
overridden methods must have a compatible signature, arguments and return value.
Here, Idk.apply returns a 4-tuple, whereas Endk returned a single value.
There is a class for each continuation needed by the interpret.

The trouble is, I get this error:

[translation:ERROR]  AnnotatorError': annotation of 'union' degenerated to SomeObject()
[translation:ERROR] Simple call of incompatible family:
[translation:ERROR]       (KeyError getting at the binding!)
[translation:ERROR] In <FunctionGraph of (RPinterpretImperative:27)Idk.apply at 0x1b31be8>:
[translation:ERROR] Happened at file RPinterpretImperative.py line 28
[translation:ERROR] ==>         return expr, env, Endk(val), val
[translation:ERROR] Previous annotation:
[translation:ERROR]   (none)
[translation:ERROR]     .. v0 = simple_call((classobj Endk), val_0)
[translation:ERROR]     .. '(RPinterpretImperative:27)Idk.apply'
[translation:ERROR] Processing block:
[translation:ERROR]  block@12 is a <class 'pypy.objspace.flow.flowcontext.SpamBlock'>
[translation:ERROR]  in (RPinterpretImperative:27)Idk.apply
[translation:ERROR]  containing the following operations:
[translation:ERROR]        v0 = simple_call((classobj Endk), val_0)
[translation:ERROR]        v1 = newtuple(expr_0, env_0, v0, val_0)
[translation:ERROR]  --end--

So at first I thought it was due to tuple that would not accept newly created objects, but after a few tests, it appears that not. Then I tought the annotator couldn't realize by himself that returning an Endk object is the same as returning a Contk, so I annotated the whole file with assertion to force him to realize that my variable cont should be a Contk not any other kind of subclass, but it didn't work either.

So I don't know what to do now.

I've even tried to implement apply outside of the classes, or to make a function for each parameters returned, but nothing worked.

You can find the source here : https://github.com/zebign1/RPython-internship/tree/master/Interpreters/ifF1WAE
(treeClass.py and parser.py as tools, the bugged file is RPinterpretImperative.py)

Thanks again.

pypy-dev mailing list

Amaury Forgeot d'Arc