# notes on language interop for pirate # from reading K Stol's report on his # lua->parrot compiler (also called pirate): # # http://members.home.nl/joeijoei/parrot/report.pdf # # dotted numbers indicate sections in his report 6.2.1 break - semantics are same as in python 6.2.2 return - same, but he uses save for multiple return values whereas I treat it as a tuple 6.2.3 if/then - very very similar... what is "false" in lua/python/imcc ?? 6.2.4 while - same 6.2.5 repeat - (not possible in python) 6.2.6 for - completely different; essentially while + a counter he uses .namespace / .endnamespace for all his temp vars. probably good practice, even with my mangled names. 6.3 assignments in lua lua: "as section 1.2.5 described, when a global variable is accessed or assigned to, then that should be handled as an event multiple assignments # good point: (need to test once indexes work) i=3 i,a[i] = 4, 100 # a[i] should be a[3] 6.4 functions """ All function calls in Lua do follow the calling conventions, but not the returning conventions. This is because of the way how Lua handles assignment statements. According to the calling conventions, return values should be stored into registers. However, Lua functions save their return values onto the run-time stack. This way, another module will not be able to receive values returned by a Lua function. """ exporting functions: function stubs? (but didn't he say it had first clast functions?) For python, how will people find _sub0001?? Maybe just create a bunch of Subs and store as variables in the namespace... that's basically what python does with import... (and what about if __name__ =="__main__" ?) (ah.. that's exactly what says he "should" do if not for i,a[i]=...) .sub _f P0 = global "f" # get current value of f invoke # invoke it restore P5 restore P6 restore P7 ret # return to calling function .end Actually, since parrot is designed this way, that's probably how I should be doing my return values, and then just make the parser handle i,a[i] (i,a.i wouldn't have that problem - it's only for [i]) Hmm: >>> def f(x): ... if x: return 1 ... else: return 1,2,3 ... >>> f(0) (1, 2, 3) >>> a = f(0) >>> a (1, 2, 3) >>> a,b = f(1) Traceback (most recent call last): File "", line 1, in ? TypeError: unpack non-sequence >>> a,b,c = f(1) Traceback (most recent call last): File "", line 1, in ? TypeError: unpack non-sequence >>> (a,b,c) = f(0) >>> a,b = f(0) Traceback (most recent call last): File "", line 1, in ? ValueError: unpack tuple of wrong size Looks like we can just test register I3 (retun value count) and compare left and right sides if it's a function call. (see the calling convention docs, i guess) Actually, it looks like his functions DO follow the conventions, but the wrapper stubs do not! Then we should just say in x-lang development, you never just jump to a label, but get it out of a variable instead. (??) In other words, functions should always be PMC's. That ought to be defined in the calling convention docs. (maybe it is??) 6.4.2 translating function defs yep: """ The translation of a function involves translating all statements in the function. The function will get an internal name, which is automatically generated by Pi- rate. This is because a function in Lua does not really have a name. """ but: """ Because all Lua data types are implemented as pmcs, it is not enough for a function to have a set of local variables, one for each parameter, and then copy the actual parameters into those local variables. Somehow, a 'deeper' copy must be made. Parrot has an instruction for that: clone. """ why would you clone a number? (can you put a tag method on "5" ??) cloning strings make sense IF strings are mutable in lua (they're immutable in python). Otherwise, why is it needed? i don't understand this. """ section 5.4: All arguments in Lua are passed by value. This means that when a function is called with some parameters, then the function receives copies of those values. However, one thing is very important to note: LuaTables objects are stored as references. This means that when a LuaTable object is passed as an argument, the reference to the table must be copied, not the table itself. """ In any case, this means the code generator for subs would have to use a template method: class SubroutineGenerator(CodeGenerator): def __init__(self, params=[], code): self.params = params self.retvals = [] self.code = code def generate(self): self.gen_params() # .local by default, clone for lua self.gen_body() self.gen_return() ... what happens if a call by reference language and a call by value language try to talk to each other? I'm still not convinced he has to do what he's doing here. I don't really understand what the distinction is except for mutable strings. # @TODO: ask him for test case 6.4.3 dealing with "self": """ Lua has a special syntax for calling so-called methods. These are functions stored in tables. This allows for a kind object oriented programming (be it somewhat artificial). When such a function is called, the table... in which the function is stored, is passed as these first parameter. This does not change the way parameters are passed, though. """ 6.5 local declarations # i probably ought to be using store_lex too (or is that imcc .local?) for each name in namelist: store_lex -1, name, $Px 6.6.2 field references looks like in lua, a.i and a["i"] are the same. (but a[i] is still different) in python they're different in imcc, there's just setprop/getprop so xlang wouldn't quite be transparent @TODO: ask about on/in distinction on p6-internals! in python, one will resolve to __getitem__ and one to __getattr__ or __setitem__ and __setattr__ or __delitem__ and __delattr_, which also means the generator will need to know which SIDE of the equal sign we live on, and generate code differently depending. (lua probably does this too, given the i,a[i] thing... check the code) 6.7 tags """ A tag is just a property of an entity. Each type of entity has its own tag. This means, for example, that all numbers in Lua have the same tag. For numbers, in fact, for all types, except tables, the tag cannot be changed. """ 7.1 imcc optimizations strength reduction: augmented assigns should do this at the ast level 7.3 lua-pirate optimization lua code always has a main() function... 8.1 lua standard libraries do we really want a library for each language? (probably stuck with it) how does the parrot debugger work? can we wrap it to look like python/lua? 9.3.1 calling conventions apparently, .arg doesn't follow the calling conventions yet! (i think this is still true, considering leo's recent remarks) 9.3.2 exchanging data good points. probably need to address each of these w/python why is luatable troublesome if passed to perl? as long as .x and [x] both work, it should be fine, right? (but again, imc makes no distinction between in and on) definitely need to talk about the pass-by-reference/value thing. #5 is a good test case, but I don't buy that lua and a statically typed language can't interact, IF, for xlang, the args are always PMCs (but this fits with the notion of being able to jump safely into a second point in the structure) 10.3.1 "known issues" "Lua has a special for statement for iterating over a table. However, at this moment there is no iterator PMC available." C1 parrot calling conventions "P2 holds the object the function was called on (as a method call). Not used in Pirate." (why not, if the table is passed in first?)