pirate refactoring update

2005-08-25 Thread Michal Wallace

Hello!

Here's an update on pirate (the python to parrot compiler) from the
trenches.

Pirate started as an example that fit in one small file and it stayed
in that single file over the years while it grew into a *huge* mess:
one monolithic object performing a variety of transformations on
python's syntax tree, all in one single pass.

Thanks to a Summer of Code grant from Google and the Perl Foundation,
Curtis Hall and I have been working to refactor that mess.  Our long
term goal is to allow pirate to support multiple language front ends
(for example, PyPy and Pugs) but our immediate goal was to make the
refactoring easier to handle.

So far, we've created a generic transformation module that greatly
simplifies the work done by Visitors in the compiler module (it's
called transform.py in the pirate repository - see below)

With the generic Transformer in place, we were able to separate out a
simplification pass, so that list comprehensions (eg: [x for x in
range(10) if x  5] which evaluates to [6, 7, 8, 9]) are converted
into their corresponding for and if blocks up front, before
PirateVisitor ever sees the tree.

Curt is currently working to use this same principle to separate out
function definitions from generator definitions, another chunk of the
single-pass system that would work much better as a separate pass
through the tree.

The big questions we'v been dealing with, though, is what will pirate
look like after the refactoring?  Well, we think we have a good
answer, and we'd like your feedback.

We recognize that there are very few people out there that understand
how pirate works *today* so what we've done is create a much
simplified toy version of pirate and shown, though actual code, how
that toy version can be refactored, all in one easy to read narrative
python script. Hopefully, you'll be able to understand what's going on
even if you're not a python developer. So... Without further ado, here
is the plan:

http://pirate.versionhost.com/viewcvs.cgi/pirate/toys/refactor.py?rev=HEADcontent-type=text/vnd.viewcvs-markup

Or, if that's probably mangled:

   http://tinyurl.com/d92f3

It's short, contains test cases, and you can actually run it from
python, or step through it with a debugger.

It does *not* take us all the way to a language-neutral compiler, but
it will make that step much easier.

Anyway, Curt will be using this plan as a guide to actually implement
as much of the refactoring as possible in the time he has left for the
Summer of Code, so if you've got feedback, please share it on the
pirate list:

   http://www.cornerhost.com/mailman/listinfo/pirate

Other links:

The priate home page is here:

  http://pirate.tangentcode.com/

The code for pirate is available for browsing here:

  http://pirate.versionhost.com/viewcvs.cgi/pirate/

Thanks for reading!

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
-



Re: [pirate] Re: Python PMC's

2005-08-24 Thread Michal Wallace
On Wed, 24 Aug 2005, Sam Ruby wrote:

[huge cut]
 
 Below is from the sample that Leo provided.
 
  #  print foo.f(2)
  
  # emulate python find_name, which checks attributes too
  push_eh m_nf
  $P0 = foo.f(2)
  clear_eh
  goto m_f
  m_nf:
  # getattribute would also check if __get__ is there
  $P1 = getattribute foo, f
  $P0 = foo.$P1(2)
  m_f:
  print_item $P0
  print_newline
 
 Note that the code above would need to be emitted for *every* method
 call, as there is no way of knowing at compile time what property you
 will get and how it is defined.


Hey Sam,

I agree with what you're saying in this
thread. This is slightly off topic, but
I wanted to point something out.

In general, python has so many places
where things have to be dynamic that you 
really can't know this kind of thing at 
compile time, especially if you allow for 
eval/exec, or if you allow the code to be 
used as a module. 

However if you treat the code as a closed 
system, *and* you have access to python at 
compile time, then we can optimize away a 
lot of these questions.

For example, in your original code:

  def f(x,y):
return y

  class Foo:
f = f
def g(self,y):
  return y

  foo = Foo()

  g=foo.g

  print f(0,1)
  print foo.f(2)
  print g(3)


Once you know how python works, it's *obvious* 
that this prints 1,2,3. I see no reason why the 
compiler couldn't figure this out up front just 
by walking the tree.

In fact, a good optimizing compiler would see the
return y lines and just get rid of those methods
completely. 

I'd like to allow for the ability to do certain 
optimizations like this up front, sacrificing 
flexibility for speed. I know there are many
programs that won't allow for this, but for the
ones that do, I'd like to be able to do a sort
of static compile like this. 

In other words, sometimes a python-like language
is a desirable thing. (But of course this should
all be optional so that we can also be 100%
python compatible)

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
-



Re: [pirate] OSCON slides

2005-08-06 Thread Michal Wallace

On Fri, 5 Aug 2005, Leopold Toetsch wrote:


There are still issues e.g. with namespaces. I've put out numberless
mails on p6i where I invited HLL folks to discuss it and make some
proposals. Guess how many answers these mails got.


Zero? I don't think p6i is the right place for that.
We should have a low-traffic compiler list.

Like... this one here for pirate, which is all
about generic compiler issues. :)



And there is: http://svn.perl.org/parrot/trunk/docs/req/model_users.pod


I like that!

Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
-



Re: urgent parrot bug / PR opportunity

2005-08-04 Thread Michal Wallace

On Thu, 4 Aug 2005, Leopold Toetsch wrote:


Michal Wallace wrote:


And wouldn't you know it... A bug on the parrot
side cropped up out of nowhere to break them!



==17366== valgrind's libpthread.so: IGNORED call to: pthread_attr_destroy
==17366== Invalid read of size 4
==17366==at 0x43D5123E: Parrot_PyTuple_get_iter (in 
/home/lt/svn/parrot/leo/runtime/parrot/dynext/python_group.so)

==17366==by 0x8115576: Parrot_iter_p_p (ops/experimental.ops:231)

Unfortunately valgrind doesn't show line numbers from the shared lib, but 
PyTuple.get_iter() is short enough so that you should be able to track down 
the problem.


Thanks, Leo!!

I'm afraid this is gibberish to me, but I gave it a shot.

I compared the code for pytuple to pylist and pystring 
and noticed they use the python iterator instead of the 
enum_class one. Also, pylist references in there several

times but it only appears once for pytuple, which can't
change its length. It looks like the other length tests
for pytuple use PMC_int_val instead so I changed that.
Anyway, I have no idea what I'm doing here but it seems
to have fixed the tests. I don't have commit access.

Assuming you don't see anything horribly wrong here, 
would you mind applying this patch?


BTW, the problem is on red hat enterprise linux 3.0 with
a fresh build from subversion)

- Michal
http://withoutane.com/



Index: pytuple.pmc
===
--- pytuple.pmc (revision 8800)
+++ pytuple.pmc (working copy)
@@ -155,12 +155,12 @@
 */

 PMC* get_iter () {
-PMC *iter = pmc_new_init(INTERP, enum_class_Iterator, SELF);
+PMC *iter = pmc_new_init(INTERP, PyBuiltin_PyIter, SELF);
 PMC *key =  pmc_new(INTERP, enum_class_Key);
 PMC_struct_val(iter) = key;
 PObj_get_FLAGS(key) |= KEY_integer_FLAG;
 PMC_int_val(key) = 0;
-if (!((List *) PMC_data(SELF))-length)
+if (!((List *) PMC_int_val(SELF)))
 PMC_int_val(key) = -1;
 return iter;
 }



Re: PMCs: Should We Use Them?

2005-07-08 Thread Michal Wallace

On Thu, 7 Jul 2005, Larry Wall wrote:


On Thu, Jul 07, 2005 at 09:28:04PM -0400, Michal Wallace wrote:
: What I'd want is to be able to download the language
: specific extensions as a library from cpan. Better
: yet if users can do it themselves without having
: to bug me.

Hmm...

: Sure, I'd probably install as much as I could, but
: there's always someone who wants the version you're
: not running. :)

My new language has several additional instruction:

   break_out_of_sandbox
   be_a_zombie
   rm_minusrf
   melt_cpu


Cool! It's still not as dangerous as letting 
users run PHP. :)


Dangerous or runaway user programs are just part 
of what you have to deal with when running a hosting 
company. You set up scripts and monitors to catch

most of the problems, and if something slips through
the cracks, you address it. That's how I do things
anyway, and it seems to keep my customers happy. :)

In any case, my understanding is that right now 
parrot requires all the dynclasses to be built

as part of the parrot source tree, so they might
as well not by dynamic after all. At some point
that's supposed to change, so we'd be able to
bundle each set of PMC's separately anyway.

I also really like Dan's idea about using the built-in
pmc's as the base for other languages. I'll see what 
I can do about python. A year and a half ago, I read 
the specs and didn't think this would be possible... 
but maybe things have changed enough that we can do 
it now.


- Michal
http://withoutane.com/



Re: PMCs: Should We Use Them?

2005-07-07 Thread Michal Wallace

On Thu, 7 Jul 2005, Roger Browne wrote:


Leopold Toetsch wrote:

Well, if you have some mixed environment, you'd probably build parrot on
all machines with the PMC's needed. Something like:

   perl Configure.pl --with-tcl --with-python

to get these PMCs built on it.


I'm thinking of situations like web hosting, where the provider will in
future offer parrot alongside php etc. But you probably won't be able to
convince the average web hosting provider to reconfigure their parrot
installation to include PMCs that support your preferred niche language.



Speaking as someone who runs a web hosting company: 
you're absolutely right. This would be a nightmare.


What I'd want is to be able to download the language
specific extensions as a library from cpan. Better 
yet if users can do it themselves without having

to bug me.

Sure, I'd probably install as much as I could, but
there's always someone who wants the version you're
not running. :)

- Michal
http://withoutane.com/



Re: [pirate] Setting up Pirate Parrot

2005-07-01 Thread Michal Wallace

On Fri, 1 Jul 2005, Leopold Toetsch wrote:


Kevin Tew wrote:


I've been working on a python compiler also, feel free to take a look,,
svn co http://svn.openfoundry.org/pyparrot languages/python/pyparrot

My current boggle is how to handle the self parameter to method functions.
You can do things like this in python

def foobar( arg1, arg2 ):
   print arg1, arg2

class A():
   self.__add__ = foobar

aa = A()
print aa + 5


Well, the Python translator has to recognice that __add__ and such has a 
special meaning in CPython. Therefore the getattribute (in that case of the 
class - but not only) has to check for such special names and in that case 
store the Sub object for foobar into the A namespace under the name 
__add - that is Parrot's notation for the thingy.


The rest i.e. calling the sub on the last line, is done by Parrot's MMD 
implementation.



Hmm. I'm pretty sure this is handled automagically 
by the Python pmc's in pirate... Using the + in 
pir (or the add op) actually invokes a dispatch

method in the PMC that handles the situation. I'm
not 100% sure if Sam implemented it, but if so it
would be in the pmc's, not the code generator.

Pirate doesn't have to know anything special about
__add__ because foobar is just another pmc - one
that happens to be a callable. The only tricky
part I see is that because foobar doesn't have
the explicit self parameter, it has to be handled
differently by getattr. (In cpython there's a 
difference beween a function and a 'bound'
method, and I think the magic happens in 
getattr)


Anyway, I *think* the existing pmc's solve all
these problems.

Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
-



new list for pirate [python on parrot]

2005-06-12 Thread Michal Wallace



I just set up a new list for pirate, a python 
compiler for parrot.


Quite a bit of work has been done on pirate since I 
last updated the website back in 2003, mostly by 
Sam Ruby of http://intertwingly.net/


Sam is giving a python-on-parrot presentation at 
OSCON on August 4, so I'd like to get a few things
cleaned up before then - for example, updating the 
site, creating a development roadmap, an fixing 
the code to work with the latest version of 
parrot, etc.


If you're interested in helping out with any of 
these things, or just want to talk about pirate, 
then feel free to hop on board. The signup page 
is here:


  http://cornerhost.com/mailman/listinfo/pirate

Thanks!


- Michal
http://withoutane.com/



Re: about python on parrot

2005-05-25 Thread Michal Wallace

On Wed, 25 May 2005, [EMAIL PROTECTED] wrote:


hi

python on parrot  already have not develop?


Hi there,

I'm not sure I understand your question either...
But maybe this will help?

   http://pirate.tangentcode.com/


- Michal
http://withoutane.com/


refcounts and DOD

2005-05-25 Thread Michal Wallace


Hi all,

So I'm still thinking about a generic
wrapper for python modules. I would like 
to be able to recompile the python standard 
library (and other libraries) to run on parrot

with only a few minor patches.

I realize this is probably completely foolish,
but I'm lazy, so... :)

I've done experiments in the past running
PythonObjects outside the python VM. This 
should be possible by replacing a few generic

routines that refer to the interpreter.

One of the major issues is garbage collection.
Python's VM does refcounting. There are two 
macros it uses: Py_INCREF(x) and Py_DECREF(x).
They're pretty self-explanitory, but the docs 
are here:


   http://www.python.org/doc/2.4/ext/refcountsInPython.html

It seems to me that these macros could be 
replaced with something that puts the objects 
in the right place for parrot to deal with them.


I've read the memory_internals and pdd09_gc
docs but I'm still trying to understand how
this would work.

It seems that instead of looking at the *count*
of references, the DOD system actually walks
through the graph of references. So it seems
you could fake refcounting just by adding 
references and removing pointers from 
somewhere in the tree that gets walked.


So: Py_INCREF(x) could be rewritten to (for example)
append a reference to x in a parrot array, 
and Py_DECREF(x) would pop it off the array.


Am I on the right track here? I'm sure this is
a very naive and inefficient implementation, but
I don't see why it wouldn't work. If it would work,
is there a better way?

Also, my understanding is that parrot uses only
a Mark and Sweep system. Is that correct? pdd09
describes the three general methods, but doesn't
say which one(s) parrot actually usess. memory_internals.html
seems to imply the mark and sweep system only...
Or does parrot do all three?


- Michal
http://withoutane.com/



Re: Python on parrot

2005-05-16 Thread Michal Wallace
On Sun, 15 May 2005, Kevin Tew wrote:
I've taken the code from
http://www.intertwingly.net/stories/2004/10/05/pyrate.zip,
which I assume to be Sam's code.  It was basically stubs
with a few AST nodes implemented when I started with it.
Er. Yes. I can't speak for Sam, but I interpreted his post
as a spike of how a pirate refactoring could go, not a call
to start a whole new incompatible project.
And am working to generate a python to pir
translator/compiler that uses Sam's python pmc's I've
attached the source as it stands now.  I'm just an
aspiring parrot hacker.  I'm sure that there are a lot of
things I'm doing wrong or inefficiently.  I'm looking for
feedback and suggestions for improvement.  Please comment.
Well, one thing that's innefficient is to write your own
compiler when there are already two mostly working examples
out there.
I want to get my patches on top of Sam's initial work
imported into the parrot SVN tree.
I believe that having the python compiler code in parrots
svn tree is imperative to build a python/parrot community.
I'm absolutely bewildered that you would take that route in order
to build a community. Between pie-thon and pirate there already
are two python compilers, and pie-thon already *is* in the parrot
tree... As far as I can tell, you didn't approach either existing
group and see if you could help. You just went off and did your
own thing. You're not building a community, you're creating yet
another faction.

A python compiler in the parrot tree will lead to more
widespread exposure to other parrot developers, increased
peer review, testing by more people on a greater variety
of platforms, etc.
This is a great goal, but I'm not sure it follows that 
having it in the source tree would lead to more exposure.

To me, if you want exposure, a much better idea would be
to *talk* to people, either on mailing lists or blogs or 
whatever. In other words, market the project. You need 
things like documentation and a website. Where the code 
lives is a fairly trivial concern. It sounds like you just
want parrot developers to stumble on to your code in the
tree and pitch in.

In my mind, the target audience for pirate is python
developers (like yourself). People who might have heard
about parrot, but don't necessarily know much about it
or how it works. But if you can tell all the nice things
we get:
  - this buys us continuations without the genius-level
hacks required by stackless
  - we'll be able to leverage CPAN and code written in
other languages...
  - we'll have a native call interface
  - (etc)
... then maybe python hackers will be interested. So they
should be able to download a python file and run it. The
python file should work like every other python file, and
leverage the distutils.  It should have a setup.py install
script and if necessary, a windows installer and rpms. There
should be a link to download a binary version of parrot so
that the first step isn't to compile a virtual machine they
know nothing about - especially if they're developing on
windows without a compiler. To me, having the code burried
in the middle of the parrot tree is a huge barrier to entry
to new developers.
Of course if you're targeting parrot developers who may or may
not know python, that's another story... But from what I can 
tell, the other compilers in the parrot svn tree just aren't
getting the kind of exposure you're talking about.

I don't know, maybe I'm just rambling, but I don't see how
putting the source in the parrot repository is either
necessary or sufficient for widespread exposure. :/

Michal could you expound on your thoughts here, they sound interesting.

  I'm not sure what Kevin meant by self hosted but I've
  been thinking about this lately, and what we can do
  today is creating a back-end for the compiler that
  emits simplified python code in a way that would give us
  things like continuations (though with some loss of
  speed) without the need to duplicate the python library.
Sure. This is kind of off topic for the parrot list. I posted
a blog entry here:
  http://sabren.com/index.php?p=62

I meant a python to pir translator/compiler written in python.
Like this one: http://pirate.tangentcode.com/   ??
I've looked at the PyPy project.  They are doing cool
stuff.  I would eventually like to use their work to emit
optimized pir for python, but they still have work to do.
So why don't you want to help them with that work?  Right
now you're just reinventing the wheel. If you were writing a
backend for pypy, that would be one thing. That would
actually be useful. Better yet, not write up a little report
about what it would take to get pirate to work with pypy?
We could almost certainly leverage their type inference
engine.  I'd love to see pirate become just another backend
for pypy.  It seems to me that would do a lot more to build
community than the approach you're taking.
- Michal
http://withoutane.com/


Re: Objects: Now or forever (well, for a while) hold your peace

2004-02-19 Thread Michal Wallace
On Thu, 19 Feb 2004, Dan Sugalski wrote:

 I tried to unify attributes and properties--I really did. The
 problem is that they're horribly semantically different. Attributes
 are class private and guaranteed across all objects of a class,
 while properties are ad hoc and can be thrown on anything. Python
 attributes, since they're really done per-object, correspond to our
 properties. I don't want to force things to be one or the other,
 because then you'd be in the unpleasant position of not being able
 to add pythonic attributes to a non-python object.

Hey Dan,

Thanks for taking the time to respond. What you're doing makes a
lot more sense now. Not being able to do both would definitely
suck. So keeping them separate solves that problem. However, I
think there's an alternate solution that would work for both of
us.

First of all, in recent versions of python you CAN create classes
that have fixed slots:

class Fixed(object):
__slots__=[foo]

An instance of this class will demonstrate the problem you're worried about:

 f = Fixed()
 f.foo = 5 # no problem
 f.bar = 6 # big trouble
Traceback (most recent call last):
  File stdin, line 1, in ?
AttributeError: 'Fixed' object has no attribute 'bar'


But that's EXACTLY what SHOULD happen if I try to set .bar on
one of these objects, or on any java/perl6/ruby/whatever instance
that doesn't have a .bar slot.


However, in rare cases I might just need to do stick something
extra on that object. If you don't mind a LITTLE kool-ade, you
can use the Decorator design pattern to solve this without
having to change the class at all:


class PropDecorator(object):

This class lets you add properties to something
that wouldn't normally allow it.

def __init__(self, other):
super(PropDecorator, self).__setattr__(other, other)

def __getattr__(self, name):
try:
return super(PropDecorator, self).__getattr__(name)
except AttributeError:
return getattr(self.other, name)

def __setattr__(self, name, value):
try:
setattr(self.other, name, value)
except AttributeError:
super(PropDecorator, self).__setattr__(name, value)


Now you have it both ways:

 p = PropDecorator(f)
 assert p.foo == 5
 p.foo = 2
 assert p.foo == 2
 assert f.foo == 2
 p.bar = 6
 assert p.bar == 6


The nice thing about this is that you only have to incur the
overhead of checking both attributes and properties when you're
actually dealing with both. The compiler doesn't have to emit
anything to check... It just emits getprop, and the PMC does
the right thing.



 Unfortunately the semantics of the two systems don't have any
 overlap, at least no overlap that I can tease out.

To me, the semantics are exactly the same. I have a thing,
and I want to record some information about it. Now some
types of things might have their own ideas about what I
can know about them, and that's cool. Just because I have
a box doesn't mean I get to open it.


 I suppose python code could see all properties and all attributes as
 fully-qualified names, with anything new going into the property
 list, but that's kinda nasty too. Plus there's the issue of python
 code easily seeing attributes that, arguably, it ought not see since
 they're supposed to be mostly class-private.

This is definitely something to think about. The python attitude
is like perl 5's... You can do whatever you want with an object.
But just because you CAN, doesn't mean you SHOULD.

To me, privacy rules are like the law of the land. An American
object can't legally smoke marijuana... But if you send it over
to Amsterdam, then it's okay. :)

I think it should be the compiler's job to enforce the correct
access privileges. But in any case, this problem exists
regardless of whether you call the opcode setprop or setattr...


 I'm tempted to punt this one to Guido for his opinion.



 For callmeth, callmethcc, and tailcallmeth... I can
 understand the versions with the string... It looks
 up the method off of the PMC in P2, right? But what
 good is the version without the string?

 One of the string registers is the name of the sub or method being
 called. The no-string version is supposed to use that. I need to
 document that better. I also need to add in the redispatch ops, which
 I forgot.

Right. I understood that's what you meant. I'm just saying
that that's equivalent to invoke. So what good is it? :)

It's nice to have something that finds the right method,
but since the same work has to be done (move the object
into P2, find the method, invoke it)... Why not leave
the syntactic sugar up to imcc?



 Again, I'm wary of the separate interface for object
 stuff.

 Well... on the one hand I agree, on the other, method and sub
 dispatch really are very different things. (That might just be the
 dislike of the OO 

Re: Objects: Now or forever (well, for a while) hold your peace

2004-02-18 Thread Michal Wallace
On Wed, 18 Feb 2004, Dan Sugalski wrote:

 Just to let everyone know, if there aren't any comments on the scheme
 in PDD 15, I'm going to implement it as-is and be done with it, at
 least for now. This would be a good time to speak up--can't guarantee
 that I'll put the changes in for this rev, but I certainly can't
 think about it if I don't have them.


I think you're doing a great job here. This is a TOUGH
problem and you've really boiled it down into a clear
and simple spec.

I do have a few comments/questions:

You said in an earlier post that python won't be able to
talk to objects with attributes without a syntax change.
I don't think a syntax change will be required -- we just
need a wrapper class. But it would be *SO* much nicer if
properties and attributes were mutually exclusive, and
the same interface worked for both. I thought that was
the point of having vtables. I'm all for having both,
but the implemenation should be encapsulated. I think
it's a big mistake to create two separate interfaces.

For callmeth, callmethcc, and tailcallmeth... I can
understand the versions with the string... It looks
up the method off of the PMC in P2, right? But what
good is the version without the string? How are they
different from the normal function invocation ops?
Again, I'm wary of the separate interface for object
stuff.


For these two:


addattr Px, Sy, Sz

Add attribute Sy, with a fully-qualified name Sz, to class Px. This
will add the attribute slot to all objects of class Px and children of
class Px, with a default value of Null

removeattr Px, Sy, Sz

Remove the attribute Sy (fully qualified name Sz) from class Px,
all objects of class Px, and all objects of a child of class Px.


Shouldn't there be correspdonding vtable methods for these? And shouldn't
those methods get to decide how/if the instances are affected?



There were two parts of the spec where I just plain
didn't understand the language.

First:


The catalog metadata for objects is considered to be attributes on
the class, so to get the offset for a class for an object, you fetch
the object's class then look up the offset attribute from it. (The
class attributes are detailed later) This is safe in general, since
the only code reasonably querying a class' attribute list is the class
code itself, and if a class doesn't know whether it's a
ParrotClass-style class or not you've got bigger problems.


Does this catalog have something to do with mapping strings to the
appropriate position in the attribute array? catalog isn't mentioned
anywhere else in the file, and metadata only shows up for the
instantiate op... So I really don't get this at all.

The reason I thought a catalog might map strings to ints is because
there doesn't seem to be a vtable method for looking attributes
up by string. What's the mechanism for making this happen?


I also don't understand this opcode:

   classoffset Ix, Py, Sz
   Returns the offset of the first attribute for class Sz in object Py.

What do you do with it once you have it? Is it for when
a class has two parents with attribute X and I want to
find the one for one superclass or the other? That sounds
useful, but it's just my guess at what you're talking about. :)

I don't mean to be so grouchy, but you said to speak now
or forever hold my peace, so... This is it. I'll do my best
to make pirate work with whatever you come up with, but
I'll say this one more time: Encapsulation is our friend!
Please don't complicate the system with duplicate interfaces.

Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
-



Re: Rules for method resolution?

2004-02-15 Thread Michal Wallace
On Sun, 15 Feb 2004, Luke Palmer wrote:

 As with Perl 6.  A sub object has a Cdo trait which specifies what
 to do when it's called.

Cool.

 But I think findmethod is a good idea, cross-language-wise.  Each
 language has a different idea of what a method is, and they can
 store it that way.  As long as findmethod is vtableable, you can
 hook it up to whatever system your language uses.

I was thinking the same thing as I wrote my post
last night... But I'm not convinced.
Suppose I do something like this:

  x = parrot.find(perl::whatever)
  x.method()

Is that second line a method call or a function call?
It depends whether x is an object or not. Now maybe
in SOME cases (no dynamic input) a compiler could be
smart enough to tell for python... But how could I
ever know cross language?

How will the compiler know to emit findmethod here
rather than getproperty?

I would suggest that since perl and python both
work this way, this is the way it should work
for parrot.

If a language happens to let you do something like:

class MultiAttribute {
x : int = 2;
method x() {
  return 1;
}
}

Then getattr(x) should return some kind of smart
attribute that knows how to evaluate to 2 if it's
used as an int or 5 if it's called.

And what about this?

class MultiMethod {
   method x(a:int) { return a+1; }
   method x(a:str) { return 200; }
}


Which x does the get? or does my compiler have to be
smart enough to look at the arguments that get passed
in? I submit that's impossible to determine, too:


args = input(enter arguments)
foo.multimethod(*args)


I think all methods for all languages should act the
perl/python way for this reason. Or at least all
languages that want to talk to each other should
emit getprop (or something like it) and then if the
property is invoked, it should be called just like a
normal function. If it needs a magic self variable
or does some kind of dispatch based on the arguments,
then that should be handled internally by the method
PMC.

In fact, since I'm on the subject, properties and
attributes also have this problem. If we want our
languages to work together there should be one and
only one type of slot on an object.  It should
be up to the PMC itself to determine how that
works internally. If a more static language has
objects that are all the same size and wants attributes
instead of properties then it should handle that
internally. The interface should be the same either way.

Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
-


Re: Rules for method resolution?

2004-02-14 Thread Michal Wallace
On Fri, 13 Feb 2004, Dan Sugalski wrote:

 We also have to have a way to fetch the method PMC for a named method
 for later use, which is where the interesting bits come in.

 This is required for a number of reasons, including Python, so we
 have to have it. The question is... *When* is the name resolved? That
 is, if we do:

 findmethod P4, Pobject, methodname

 does the method PMC that gets stuck in P4 represent the method
 methodname for the object *at that point in time* or does it
 represent the method *at the time it is invoked*? That is, do we
 defer actual lookup until invocation, or do we resolve at method find
 time?


For python, you want P4 to contain the method as
it is when this op is run.

But the whole idea of a findmethod seems very
unpythonic to me. In python, a method is just another
attribute... One that happens to be callable and also
happens to know what instance it's bound to.

Consider the second line in this code:

x = input()
x.foo()

Is that a method call or a function call? The
compiler has no possible way of knowing, so the
second line should be compiled as if it were:

_temp_ = getattr(x, foo)
_temp_()
del _temp_

Maybe for python, findmethod and getprop (or whatever
the new eqivalent is) are the same... But I'd suspect
that getprop is all any (working) python compiler will
use.

Here are a couple examples of python weirdness:


EXAMPLE 1 - whose method is this, anyway?


class Alice:
def whoami(self):
return Alice
class Bruce:
def whoami(self):
return Bruce

a = Alice()
b = Bruce()

a.whoami, b.whoami = b.whoami, a.whoami
assert a.whoami()==Bruce
assert b.whoami()==Alice

# and just for kicks:
freestanding = a.whoami
assert freestanding() == Bruce


EXAMPLE 2 - callable classes as methods

class Methodical:
def __call__(self):
return muahahahaha

class Owner:
pass

x = Owner()
x.method = Methodical()
assert x.method() == muahahahaha


Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
-



Re: Rules for method resolution?

2004-02-14 Thread Michal Wallace
On Sat, 14 Feb 2004, Michal Wallace wrote:

 class Alice:
 def whoami(self):
 return Alice
 class Bruce:
 def whoami(self):
 return Bruce

 a = Alice()
 b = Bruce()

 a.whoami, b.whoami = b.whoami, a.whoami
 assert a.whoami()==Bruce
 assert b.whoami()==Alice


I'm not sure it affects my argument, but
here's a better example:

class Person:
def __init__(self, name):
self.name = name
def whoami(self):
return self.name

a = Person(alice)
b = Person(bob)
a.whoami, b.whoami = b.whoami, a.whoami

assert (a.name == alice) and (a.whoami() == bob)
assert (b.name == bob) and (b.whoami() == alice)

Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
-



Re: RT Cleanup

2004-02-09 Thread Michal Wallace
On Mon, 9 Feb 2004, Melvin Smith wrote:

 At 07:26 PM 2/5/2004 -0500, Will Coleda wrote:
 Melvin:
 
 Here's a warnocked imcc issue for you:
 int main () {
int if = 1;
 
if (if) {
  if = 0;
}
 }

 My take on it is, since it is an intermediate language, we don't need
 ability to have keywords as variables. Compilers can generate all
 variables with names like $T01JHGJ_001

That can make it kind of nasty to debug
compilers. I'm trying to move pirate towards
generating names that match the actual
variables (though I do still use _000 counters)

Would it be valuable if all variables had (or could have)
a $ in front of them? The ones that match  /\$[PINS]\d+/
would still have implicit types, and anything else
would require a .local or .global for the type
declaration.

Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
-



Re: RT Cleanup

2004-02-09 Thread Michal Wallace
On Mon, 9 Feb 2004, Melvin Smith wrote:

 At 02:00 PM 2/9/2004 -0500, Michal Wallace wrote:
 On Mon, 9 Feb 2004, Melvin Smith wrote:
   My take on it is, since it is an intermediate language, we don't need
   ability to have keywords as variables. Compilers can generate all
   variables with names like $T01JHGJ_001
 
 That can make it kind of nasty to debug
 compilers. I'm trying to move pirate towards
 generating names that match the actual
 variables (though I do still use _000 counters)

 Which can make it nasty, not having keywords as variables or
 naming them weird things? I assume you meant the latter, I agree,
 and my example was probably overexaggerated. You could simply
 mangle the high-level symbol name so if your language allows you
 to use 'if' as a variable, do $_if. Take your pick of the thousands
 of possibilities.

Yes, I meant the latter. :)

 I will at least commit a patch so IMCC will immediately flag the
 declaration of an illegal symbol name rather than allowing it and
 then getting confused later.

Good idea.

 Would it be valuable if all variables had (or could have)
 a $ in front of them? The ones that match  /\$[PINS]\d+/
 would still have implicit types, and anything else
 would require a .local or .global for the type
 declaration.

 I know how I want to answer the question, but I'd be lying if
 I said I had actually put a lot of thought in it. Any solution
 can be made to work:

I was just throwing that out there by the way. I haven't
thought much about it either. :) I'm perfectly happy
with things the way they are, but requiring the $ gets
rid of the keyword problem.


 Possibilities:

 1) Mangling scheme - potential issues with various languages as well
 as potential issues with importing external symbols unless we all agree
 on the same scheme.

You know this brings up another point for hierarchical namespaces.
Python would freak out if it saw an expression like perl.object.if.
But it'll cope with getattr(perl.object, if)...  There probably
ought to be a standard API for grabbing objects across namespaces
that goes beyond just simple syntax. (Like parrot.find(perl::object::if)
or something)


 2) Quoting symbol names - pretty much works in all cases but is a
 little annoying for hand written code

 I'll think more on the issues before giving an opinion since I'm
 sure there are some people that have already thought on it more than
 me; Larry, for instance.

:)


Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
-



python PMCs?

2004-02-02 Thread Michal Wallace

Dan,

What is your plan for getting python
objects working for the pie-thon?

I've made a small start on wrapping
PythonObjects as PMC's and that seems
to work. It's also a whole lot easier
than trying to recode them as PMCs
directly or writing them in imc/pir.
They just need to be tricked into
thinking they have a reference-counting
python interpreterer lying around.

Code is in http://pirate.versionhost.com/
under pirate/python/pmc/piobject.pmc
(it's VERY sketchy right now - only a
few lines to prove the concept).

Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--



Re: Backward branch, warnocked.

2004-02-02 Thread Michal Wallace
On Tue, 3 Feb 2004, Pete Lomax wrote:

 .sub _main
   goto L1
 test:
   $I1 = 1
   ret
 L1:
   $I2 = 2
   call test
   print $I2   # prints 1, not 2
   end
 .end
...
 Again, sorry to be a pain, but I'd like the truth/an update, please!
 Or some hints... file level variables... better ways to code this...

 Pete
 PS use parrot -o and examine the output .pasm:, $I1 and $I2 (or
 .local int i, .local int j) get assigned the same register.


Huh. That is pretty funky. The problem is that
imcc doesn't realize the two variables ought to
be distinct, right?

A workaround is to call pushtopi and poptopi
around the call statement...

What's the benefit of doing it this way, rather
than using separate subs?

Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--


Re: how to subclass dynamic PMCs?

2004-01-22 Thread Michal Wallace
On Thu, 22 Jan 2004, Leopold Toetsch wrote:

 Michal Wallace [EMAIL PROTECTED] wrote:

  I'm trying to make a dynamically loaded PMC that
  subclasses another dynamically loaded PMC.

 Its a linker problem, but not too simple. Your analysis is correct:
 pistring needs the symbol Parrot_PiSequence_get_integer, so you have to
 provide it:

Thanks Leo! You rock!!!


 I did something like this:

 $ make -C dynclasses
 $ cp dynclasses/pisequence.so blib/lib/libpisequence.so

Aha! I was trying to figure out how to do -lpisequence.
It didn't occur to me to just RENAME it. :)


 $ cd dynclasses; cc -shared -L/usr/local/lib   -o pistring.so  \
   -I../include -I../classes  -L../blib/lib  -lparrot pistring.c \
   -lpisequence   ;  cd ..
 $ cp dynclasses/pistring.so runtime/parrot/dynext/

 $ parrot wl.imc # run your test program
 51
 52

Awesome! Thanks again! :)


 I also had -Wl,-E in the Makefile, when compiling pisquence. I don't
 know if its necessary.

 Another (untested) possibility: you could try to append the 2 pi*.c
 files into another one and then compile the combined source to a shared
 lib.

That makes sense. I'll try it. If it works, I'll patch
pmc2c2.pl to do do this automatically. I'm sure this won't
be the last time someone wants to provide a whole set of
classes at once.

 leo

Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--


Re: How does perl handle HLL Ceval?

2004-01-22 Thread Michal Wallace
On Fri, 23 Jan 2004 [EMAIL PROTECTED] wrote:

 The subject says it all.

 As parrot is designed to be targetted by many langauges,
 how will it handle 'eval' opcodes for those different languages?

 Shell out to a seperate process?

You could do that, or you can provide a C-based
compiler as a PMC or you can teach your language
to compile itself... Or you can even write your
language in some other language that targets parrot. :)


 Nigel.


Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--



how to subclass dynamic PMCs?

2004-01-21 Thread Michal Wallace

Hi all,

I'm hoping this is just a simple linker option, but
I've been reading ld manuals for the past few
hours and I just don't get it. :)

I'm trying to make a dynamically loaded PMC that
subclasses another dynamically loaded PMC.
I made two files in parrot/dynclasses/ :


// file 1: pisequence.pmc
#include parrot/parrot.h
#define enum_class_PiSequence  -1
pmclass PiSequence need_ext dynpmc {
  INTVAL get_integer () {
return 0;
  }
}


// file 2: piobject.pmc
#include parrot/parrot.h
#define enum_class_PiString  -1
pmclass PiString extends PiSequence need_ext dynpmc  {
}


I added these to the Makefile, ran make -C dynclasses
and now, I have two *.so files:

% find runtime -name pi*.so
runtime/parrot/dynext/pisequence.so
runtime/parrot/dynext/pistring.so

Then I try to run this:

.sub __main__

loadlib P0, pisequence
find_type I0, PiSequence
print I0
print \n

loadlib P1, pistring
find_type I1, PiString
print I1
print \n

end
.end


Output is:


Couldn't load 'runtime/parrot/dynext/pistring': \
runtime/parrot/dynext/pistring: cannot open shared object file: \
No such file or directory
51
Couldn't load 'runtime/parrot/dynext/pistring': \
runtime/parrot/dynext/pistring: cannot open shared object file: \
No such file or directory
0


If I copy the get_integer function to PiString
instead of trying to inhert, everything works:


51
52


It seems the problem is that pistring.so can't
load because it can't find a definition for
Parrot_PiSequence_get_integer... Even though
it's defined in the other *.so file that's
already loaded.

I don't think this is a bug... I think I just
don't know what I'm doing. Can someone help? :)

Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--


Re: Events and JIT

2004-01-16 Thread Michal Wallace
On Fri, 16 Jan 2004, Dan Sugalski wrote:

   2) Those that explicitly check for events
...
 Ops like spin_in_event_loop (or whatever we call it) or checkevent is
 in category two. They check events because, well, that's what they're
 supposed to do. Compilers should emit these with some frequency,
 though it's arguable how frequent they ought to be.

I don't understand that part. Why the compiler?
If the high-level code doesn't do anything with
the events, then there's no point in checking.
If it does use the events, then shouldn't
developers call the even loop explicitly?

Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--



Re: [PATCH] new_noinit and init ops

2004-01-12 Thread Michal Wallace
On Mon, 12 Jan 2004, Luke Palmer wrote:

 I have somewhat a predicament.  I want to create a continuation, and
 have that continuation stored in the register stack that it closes
 over (this is how I'm implementing a loop with continuations).
 Unless I'm having a major braino, I don't think this is possible at
 the moment.

 I got around this by adding two ops: new_noinit and init.  I've
 included a patch that implements them.  Other solutions welcome.

Hmm. That sounds like Coroutine. Also, when you invoke
any kind of sub with the calling conventions, it's
already in P0. Can't you store that in a local variable
on the invoke?

Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--



Re: [PATCH] new_noinit and init ops

2004-01-12 Thread Michal Wallace
On Mon, 12 Jan 2004, Luke Palmer wrote:

 Michal Wallace writes:
  On Mon, 12 Jan 2004, Luke Palmer wrote:
 
   I have somewhat a predicament.  I want to create a continuation, and
   have that continuation stored in the register stack that it closes
   over (this is how I'm implementing a loop with continuations).
 
  Hmm. That sounds like Coroutine.

 Uh, how so?  Are we mixing up Continuation/Coroutine vocabulary again?

:)

Well... A Coroutine is a pausable, resumable continuation, right?
Or basically a closure with a continuation inside it.  I was just
guessing how you might be implementing the loop. It sounds like
a recursive tail call, but that struck me as a job for goto
instead of a continuation. So I thought maybe you needed the
continuation to save for later, and that made me think of a
Coroutine.

That's what was running through my head anyway. As for
why I mentioned it based on all those assumptions... uhh,
beats me. My real point was just the part about the
calling conventions the thing you're calling in P0. :)

Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--



Mr Parrot's Neighborhood

2004-01-12 Thread Michal Wallace
On Mon, 12 Jan 2004, Luke Palmer wrote:

  Well... A Coroutine is a pausable, resumable continuation, right?
  Or basically a closure with a continuation inside it.

 Both of those sentences seem wildly redundant to me.  I think we might
 be stuck on vocabulary.  We're surely both understanding the same thing
 in different ways.

Yes. I was understanding it in the wrong way. :)

 A continuation is one snapshot -- it never changes, it never runs.
 To invoke the continuation is to take you back to that snapshot and
 start running from there.  To invoke it a second time is exactly
 like invoking it the first time.

Thanks. I'd heard this a million times but putting it this way
made it click for me.

I've been thinking about continuations as if they were like
python functions. In python, functions are objects. You can
define them interactively at the prompt and then look inside
them and see some representation of their bytecode.

But with parrot, there's just one big long line of instructions.
A .pcc_sub isn't an object, just a little segment of the list of
instructions.

Okay... Here's a metaphor I'm working on to try and help me
understand how to picture all this. It's not finished (see
the end). Feedback appreciated:

===


MR PARROT'S NEIGHBORHOOD

Mr Parrot lives on a very long street. Each house on the
street contains an opcode. His job is to go door to door
and follow the instructions of the little ops.

Mr Parrot carries with him as much paper as he can carry.
Each sheet has 16 boxes on it, and he has eight different
stacks of them:

  int 0..15   int 16..31
  num 0..15   num 16..31
  str 0..15   str 16..31  # should be string, I know
  pmc 0..15   pmc 16..31

He also has about a zillion pockets on him. He can put
things in his pockets (and of course keep track of where
they are by writing it down in a pmc box). Every once
in a while, he goes through his pockets and throws out
anything he doesn't need anymore.

So starts at the first address, performs the instruction,
and then goes to whatever that opcode says. She might ask
him to write a number down in one of the boxes (set I0, 3)
or to copy one box to another (set I0, I1) or an object
to keep track of, or something equally simple.

Usually when he's done with the op, he just goes next door,
but sometimes the op tells him to go somewhere else, either
explicitly (goto label) or based on the values in the
boxes (le I0, I1, label) or the objects in his pockets
(le P0, P1, label).

Often, an op will tell him to copy the top sheet on one
(or some or all) of the stacks and put the copy on top
(push) or throw away the top sheet (pop). He gets
really mad if you tell him to throw away the last sheet,
or if a stack gets so big he can't carry it anymore.

Every once in a while, the op will tell Mr. Parrot to
do something like this:

 - make copies of all your stacks of paper
 - put the copies inside a briefcase
 - write this delivery address on the briefcase
 - (possibly) write a return address on the briefcase
 - put the briefcase in your pocket

Is that an accurate portrayal of a continuation?

##

Now... I only described the register stacks. In docs/pmc/subs.pod
it lays out the differences between the different kinds of Subs.
It has this table:


Subtype   ControlstackPadStack   UserStack  Warnings

Sub- -   - C
Closure- C   - C
Continuation   C C   C C
Coroutine  C C   C C
RetContinuationX X   X X

C ... COWed copy is in context
X ... is in context
- ... isn't.



My problem is that I don't know what a Control stack, pad stack,
user stack, and warnings are.

Here's my guess:

   ControlStack {
  This is another set of smaller papers. One box each.
  if Mr. Parrot meets a ret op, he takes the
  top sheet and goes to whatever address is on it.

  When we call a Sub, we write the return address on
  the top sheet. Same with a closure.

  ** I don't understand what happens here when we call
 a continuation.
   }

   PadStack {
  Hmm. Does this mean lexical pads? In which case, it's
  a list of friendly names that he uses to remind him
  which box or pocket a particular thing is in.
   }


   UserStack {
  By process of elimination, this would be the eight
  register stacks?
   }

   Warnings {
  ** Beats me. Is this for holding exception handlers?
   }



Final questions:

   What's a context?
   How would I picture Eval? Does that involve building new houses?




 A coroutine is like a variable that holds continuations, and updates
 itself whenever it yields.  I guess that's the best way I can put
 it with my affliction 

Re: yield op?

2004-01-11 Thread Michal Wallace
On Sun, 11 Jan 2004, Leopold Toetsch wrote:

 Michal Wallace [EMAIL PROTECTED] wrote:

  When you invoke a Coroutine, it calls swap_context()
  from src/sub.c ... There's an else clause in there
  that either swaps or restores theinterpreter  stack,
  but as far as I can tell, swap_context() is ONLY
  called when entering a coroutine - not when we're
  suspending it.

 No, swap_context() is called for each invoke of the Coroutine, that is
 ok. But (as with Continuations) the register frame stacks are *not*
 swapped. So the zero in your example (in P16) is shared between the
 Coroutine and main.

Yes, that's what I meant. It's called each time you invoke
the coroutine. I don't understand why it doesn't have to be
swapped back each time you suspend the coroutine.

But then again, I tried fixing it myself and it didn't work...
Maybe I'll understand once I see how you fix it.


 If no one hollers, I'll apply Luke's patch WRT register stacks and
 Continuations and then fix Coroutines.

Awesome! Thanks!


Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--



yield op?

2004-01-09 Thread Michal Wallace

Hey all,

When you invoke a Coroutine, it calls swap_context()
from src/sub.c ... There's an else clause in there
that either swaps or restores theinterpreter  stack,
but as far as I can tell, swap_context() is ONLY
called when entering a coroutine - not when we're
suspending it. That means all sorts of nasty things
happen when the either coroutine or the calling
context gets modified.

For example, the code below counts up from 1 to
forever. But if you uncomment the zero=0 line,
it never gets higher than 1 because zero
in __main__ and x in _iterator get assigned
to the same register, and the context isn't
properly restored.

It seems to me that invoke() is doing the right
thing by swapping the context, but that there
needs to be a yield() method (and opcode?) to
balance it out. It definitely needs more than
a savetop or an invoke of ther return
continuation, because neither of these things
would let you fire a method on the coroutine
instance. That's why I'm thinking we need a
yield op.

Am I on the right track here? Either way,
what can I do to get this working?

Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--

#!/bin/env parrot
# uncomment the second zero=0 line to see the magic bug :)

.sub __main__
.local Coroutine itr
.local object return
.local object counter
newsub itr, .Coroutine, _iterator

.local object zero
zero = new PerlInt
zero = 0

newsub return, .Coroutine, return_here
loop:
.pcc_begin non_prototyped
.pcc_call itr, return
 return_here:
.result counter
.pcc_end

print counter
print  

### zero = 0
print zero
print \n
goto loop
end
.end


.pcc_sub _iterator non_prototyped
.local object x
x = new PerlInt
x = 0
iloop:
.pcc_begin_yield
.return x
.pcc_end_yield
x = x + 1
goto iloop
.end




Re: BUG: coroutine + exception = stack_height segfault

2004-01-09 Thread Michal Wallace
On Fri, 9 Jan 2004, Jeff Clites wrote:

 On Jan 9, 2004, at 12:24 AM, Leopold Toetsch wrote:

  Michal Wallace [EMAIL PROTECTED] wrote:
  #!/bin/env parrot
  #
  # yieldbug.imc
  #
  # This program should print dots forever.
  # Instead it prints a few dots and then segfaults.
 
  It does print dots forever here.

 It does for me too. But based on a previous email, I assume you are
 getting the crash after applying Luke's continuations patch? (I haven't
 tried your script with that applied.)

Crap. Yes, this code works for me too on the
unpatched version. I should have been more
careful.

But... I had based this example on a much larger
program that has the same bug in either version of
parrot. It loops through a list of iterators. It
works fine if I comment out the two exception
handler lines:

 newsub P0, .Exception_Handler, __py__catch
 set_eh P0

But with those two lines there it segfaults immediately
with the stack_height assertion failure.

I'll try to boil it down again tonight.

Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--



Re: [PATCH] Continuations now close over register stacks

2004-01-09 Thread Michal Wallace
On Fri, 9 Jan 2004, Leopold Toetsch wrote:

 Michal Wallace [EMAIL PROTECTED] wrote:

  newsub $P1, .Continuation, done

 For returning just use a .RetContinuation. Or still better, just omit
 $P1 totally here:

  .pcc_call $P0, $P1

Aha! I like that even better. :) Thanks!

Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--



Re: [PATCH] Continuations now close over register stacks

2004-01-09 Thread Michal Wallace
On Fri, 9 Jan 2004, Luke Palmer wrote:

 Very rarely would you not savetop before creating a *real* continuation.
 But again, very rarely would you actually create a *real* continuation
 (depending on your language).  RetContinuations are almost always a
 better choice for traditional languages, and languages like Python with
 no support for continuations.

Gotcha. It just looked odd to me that you had to call
savetop... But now I see that's because I was doing the
wrong thing all along. :)

Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--


Re: yield op?

2004-01-09 Thread Michal Wallace
On Fri, 9 Jan 2004, Leopold Toetsch wrote:

 Michal Wallace [EMAIL PROTECTED] wrote:

  Hey all,

  When you invoke a Coroutine, it calls swap_context()

 Can you have a look at imcc/t/syn/pcc.t, there is an coroutine
 iterator test.

Yep, it has the same problem. The patch below exposes it.
Comment out the first zero=0 line and you get an infinite
stream of sixes. With both in there it prints two numbers
and ends. (This is without Luke's patch)

The principle seems to be that you can't modify anything
in the context without screwing up the continuation's
registers.

Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--


Index: t/syn/pcc.t
===
RCS file: /cvs/public/parrot/imcc/t/syn/pcc.t,v
retrieving revision 1.28
diff -u -r1.28 pcc.t
--- t/syn/pcc.t 16 Dec 2003 08:53:44 -  1.28
+++ t/syn/pcc.t 10 Jan 2004 03:41:28 -
@@ -489,6 +489,8 @@

 output_is('CODE', 'OUT', coroutine iterator);
 .sub _main
+  .local int zero
+  zero=0
   .local int i
   i=5
   newsub $P0, .Coroutine, _addtwo
@@ -500,6 +502,7 @@
  ret_addr:
   .result $I2
   .pcc_end
+zero = 0
 print $I2
 print \n
 savetop



RESOLVED: how do I instantiate?

2004-01-08 Thread Michal Wallace
On Wed, 7 Jan 2004, Luke Palmer wrote:

 Er, sorry, that's IMCC's fault.  This works:

 new felix, $I0

Yep! Thanks!

Here's a short example of the final script:

.sub _main
   .local object Cat
   .local object felix
   newclass Cat, Cat
   find_type $I0, Cat
   new felix, $I0
   $P0 = new PerlString
   $P0 = felix
   setprop felix, name, $P0
   getprop $P1, name, felix
   print the cat's name is 
   print $P1
   print .\n
   end
.end



 I know PerlArray accepts and stores properties: my compiler uses them.
 PerlHash probably does too.

Yeah, but I felt silly passing around a Hash or Array. :) I ALMOST
went withi this though until you showed me how to get the instantiation
working. :)


 And thanks again for all the work you're doing on Python :-)

Thanks for the register-stacks-for-continuations patch!
That should fix some bugs I've got with generators. :)

Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--



Re: how do I instantiate? -- was: Objects!

2004-01-08 Thread Michal Wallace
On Thu, 8 Jan 2004, Leopold Toetsch wrote:

 Michal Wallace [EMAIL PROTECTED] wrote:

  I'm not even trying to get objects working yet. I just
  need something that'll let me run setprop on it

 You can attach properties to all PMCs. And WRT object instantiation:
 t/pmc/object*.t but only integer attributes are done.


Thanks. I looked at those last night but I didn't
get what I was looking at. Guess I should have
been more careful.

What exactly is the difference between an
attribute and a property?


Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--



Re: how do I instantiate? -- was: Objects!

2004-01-08 Thread Michal Wallace
On Thu, 8 Jan 2004, Leopold Toetsch wrote:

 Michal Wallace [EMAIL PROTECTED] wrote:

  What exactly is the difference between an
  attribute and a property?

 $ perldoc docs/pdds/pdd15_objects.pod
 /TRANSLATION AND GLOSSARY

Thanks. Don't mind me. I'm going to go make
a card that says RTFM on my monitor here... :)

So let me see if I have this right. Attributes
are slots in a class, that get created on each
instance. Properties don't have predefined slots,
you can just attach whatever you want to any PMC.

So: a language like java would probably use
attributes, because the shape of the class is
defined before hand, whereas python would tend
to use properties... Right?

But when I actually go to fill in the slots,
I still use getprop/setprop for both types,
right? So if I setprop on an attribute-based-class
it would fill in the attribute first, and then
if the attribute slot isn't there, do something
else (like throw an exception or just make a property?)

I guess what I'm asking is: is getprop/setprop
a universal interface, or will we need some kind
of logic to know whether a particular object
uses attributes instead?

Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--



re: [PATCH] Continuations now close over register stacks

2004-01-08 Thread Michal Wallace


Luke Palmer wrote:

 This patch re-implements the register backing stacks as PObjs (so
 they can be garbage-collected), honors their COW flags, and adds
 them to the interpreter context (where they should be, honest!).

 As a healthy side-effect, it encapsulates their behavior nicely into
 register.c, when before their guts were splattered all over the
 source.

Hey Luke,

I applied this patch, ran make realclean and rebuilt parrot.
All the parrot tests pass (except the two about numbers, and I
think they were failing before) but it doesn't like the code
that pirate's generating. I boiled the problem down to this:

###
.sub __main__
newsub $P0, .Closure, _func
newsub $P1, .Continuation, done
.pcc_begin non_prototyped
.pcc_call $P0, $P1
done:
.local object result
.result result
.pcc_end
print result
print \n
end
.end

.pcc_sub _func non_prototyped
.local object res
res = new PerlString
res = hello!
.pcc_begin_return
.return res
.pcc_end_return
.end


When I run this, parrot says:

No more I register frames to pop!

I think the problem is coming from the .pcc_begin_return
line. This code works fine if I change the .Continuation to
a .Closure or .Coroutine... It also worked before the patch.
Do I have my calling conventions screwed up or is this a bug?

Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--



weird bug w/new imcc syntax

2004-01-08 Thread Michal Wallace

I love the new syntax for calling functions!
Thanks Melvin!!!

And... here's a weird bug. :)

The following code fails with the message
No Entries on UserStack! But, if you
delete either/both of the empty comment
lines and it works fine. :)



.sub _main
$P0 = new PerlString
$P0 = hello\n
$P1 = _do_print($P0)
end
.end

.pcc_sub _do_print non_prototyped
#
#
.param object s
 print s
.pcc_begin_return
.pcc_end_return
.end





Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--



BUG: coroutine + exception = stack_height segfault

2004-01-08 Thread Michal Wallace
#!/bin/env parrot
#
# yieldbug.imc
#
# This program should print dots forever.
# Instead it prints a few dots and then segfaults.
#
# parrot -t shows this bug:
#
#parrot: src/stacks.c:95: stack_height:
#Assertion `height == (top-n_chunks - 1) * 256 + top-used' failed.
#Aborted
#
# It works fine if I comment out the set_eh line.
# Can anyone help here?
#
# (Sorry for the long listing. It's as short as I could make it.)
#
# - Michal
#

.sub __main__
.local Continuation retcon
.local Coroutine it
.local object res

# create an exception handler. (this is the problem)
newsub $P0, .Exception_Handler, _on_exception
set_eh $P0

# it doesn't matter whether this comes before or
# after the exception handler
newsub it, .Coroutine, _iterator_logic

# main loop:
loop0:
savetop
newsub retcon, .Continuation, return
.pcc_begin non_prototyped
.pcc_call it
return:
.result res
.pcc_end
print res
goto loop0
.end


# this iterator just yields dots forever:
.pcc_sub _iterator_logic non_prototyped
.local object dot
loop:
dot = new PerlString
dot = '.'
.pcc_begin_yield
.return dot
.pcc_end_yield
goto loop
.end


# note that this is never actually invoked:
.pcc_sub _on_exception non_prototyped
end
.pcc_begin_return
.pcc_end_return
.end


# Sincerely,
#
# Michal J Wallace
# Sabren Enterprises, Inc.
# -
# contact: [EMAIL PROTECTED]
# hosting: http://www.cornerhost.com/
# my site: http://www.withoutane.com/
# --


Re: [PATCH] Continuations now close over register stacks

2004-01-08 Thread Michal Wallace
On Thu, 8 Jan 2004, Luke Palmer wrote:

 @pcc_sub_call_4:
 set P0, P17
 set P1, P16
 set I0, 0
 set I1, 0
 set I2, 0
 set I3, -2
 updatecc
 savetop
 invoke
 done:
 restoretop
 set P16, P5

 When the continuation is invoked, that savetop it just did is completely
 nullified, and you're back to the state before you created the
 continuation.  So, in order to get this to work properly, your first
 four lines must be:

 .sub __main__
 newsub $P0, .Closure, _func
 savetop
 newsub $P0, .Continuation, done

 So the restoretop after the invoke has something to pop (and so your
 register state isn't screwed up when you get back).


Thanks Luke.

I changed my compiler to call savetop before every function
call, and that passes my tests but I'm having trouble
visualizing why. Would I ever NOT want to call savetop
before creating a continuation?

Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--



how do I instantiate? -- was: Objects!

2004-01-07 Thread Michal Wallace
On Tue, 2 Dec 2003, Dan Sugalski wrote:

 *) Creating new objects involves calling the -init vtable entry *on
 the class*. Because of this each class gets a custom vtable where the
 init method has been swapped out for one (from objects.c) that
 creates a new object instead.

Well, cool! How do I this from parrot?

I've been trying things along the lines of:

.sub _main
   .local object Cat
   .local object felix
   newclass Cat, Cat
   P2 = Cat
   S0 = init
   callmeth
   felix = P0
   #...
   end
.end

... But haven't figured out the magic formula yet
That code above gives:

   Method 'init' not found
   in file '(unknown file)' near line -1


(If anyone can post a working example of the code
above I'd really appreciate it!)


Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--



Re: how do I instantiate? -- was: Objects!

2004-01-07 Thread Michal Wallace
On Wed, 7 Jan 2004, Luke Palmer wrote:

 Should go something like this:

 .sub _main
 .local object Cat
 .local object felix
 newclass Cat, Cat
 find_type $I0, Cat
 felix = new $I0
 # ...
 .end


Thanks, but that doesn't work either. :/
The new op expects an identifier. It won't
take a VAR, IREG, or REG.


 But note that objects are unfinished.  I ran into a certain problem
 when I assumed that attributes could be any type of data; not so --
 they can only be integers (at the moment).  I needed object support
 right away, so I simulated using a hash.  The hash has a CLASS key
 which holds the class to which it belongs.  I then use this to get
 the methods.

I'm not even trying to get objects working yet. I just
need something that'll let me run setprop on it so my
generators can make iterator things with a .next()
attached to them... I was using ParrotObjects and
ParrotClasss for a while but now you can't make a
new ParrotObject directly either. :/

Incidentally, anyone know why not? In python or
javascript it's easy to just create an object of
no particular class just to have a place to stick
things.

  foo = object()
  foo.x = 1

It was working fine in parrot too, but then it
went away. :/

Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--



Re: More object stuff

2003-12-03 Thread Michal Wallace
On Wed, 3 Dec 2003, Leopold Toetsch wrote:

 Dan Sugalski [EMAIL PROTECTED] wrote:
  At 12:17 PM +0100 12/3/03, Leopold Toetsch wrote:
 
 Create an Exception class hierarchy?
 
  I'm not 100% sure I want to go with a real OO style of exceptions,
  but that might just be the neo-luddite in me.
 
 It probably depends what HLL want to have. Anyway, I was thinking of
 pre-constructing a bunch of constant exception objects for internal
 usage.


I'm trying to understand the question here:

What is the _return_cc attribute on an
exception? Can I use it to resume the
code as if the exception never happened?
Do I have to fill it in manually? Or 
could it be automatic?

I'm picturing exceptions as continuations 
with an arbitrary message attached... Right
now that message is a string, but eventually
it could be any PMC... Is that about right?

So, if I throw a WarningException, could I
just say ignore it... go to the next line?

As for the message, I'm trying to think of 
a good reason to standardize that attached 
PMC. For example, if I try to open a file 
in python and it fails, I get an exception
of class IOError... But if I call a perl 
routine that throws the perl equivalent... 
What should happen? Should I just catch 
PerlException instead? 

Each HLL is going to want its own class
hierarchy for exceptions... But it might
be nice to have a predefined hierarchy that
parrot uses internally.

I know perl uses a return value instead of
throwing an exception (open or die, right?)..

So would parrot's internal file-opener just
throw a ParrotFileException? So perl's
open() command catches it and returns 0,
while python's open() command catches it 
and throws a new IOError?

Am I on the right track?

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




feature request: line numbers in errors?

2003-12-03 Thread Michal Wallace

Is it possible to print out the line number 
of the bad instruction when parrot encounters 
an error and fails? I'm trying to get my 
generated code to work with the latest version
of pirate and I'm having to rely on GOT THIS FAR
print statements to find the lines that are
giving me errors. 

I don't suppose there's one magic error routine 
that controls all the error messages, and someone 
could just add a line or two to handle this? :)

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--



python exceptions broken

2003-12-03 Thread Michal Wallace


Looking more at exceptions here... I
used to be able to put arbitrary
stuff in the _message slot of a 
ParrotException... Now we can only use
strings. Is that permanent?

PythonException will need to be able
to hold an arbitrary python object. 
I'm faking it by stuffing my PMC into
a string register for now... But it 
would be REALLY nice to be able to use
the base ParrotException and not have
to write my own subclass just to get
a PMC slot. 

Would it be possible to get a ['_pmc']
or something in addition to ['_message']?

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: Languages status (attention compiler maintainers)

2003-10-08 Thread Michal Wallace
On Mon, 6 Oct 2003, Melvin Smith wrote:

 In an attempt to get a handle on what the status is of all the
 language compilers we have (in various states) I added
 a file called LANGUAGES.STATUS under parrot/languages
 
 Just read the file and it explains itself. Please, if you are
 the author of one of the compilers and you don't have commit
 access, mail a 2 line summary of the state of your compiler
 to someone with commit privs.

Python: Mostly working except for classes/exec/import. For licensing 
reasons, not in parrot's cvs tree. See http://pirate.tangentcode.com/

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




setline?

2003-09-25 Thread Michal Wallace


Sorry, I've been following this list 
with one eye tied behind my back...
What happened to setline? Should I
emit something else instead?


Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: Of AST and YAL

2003-09-07 Thread Michal Wallace
On Sun, 7 Sep 2003, Leopold Toetsch wrote:

 I'm currently investigating the AST (abstract syntax tree) interface
 for Parrot. For getting a feeling, how this could look like, I've
 implemented (some parts) of Yet Another Language (YAL).

I like it. What is this written in? C or Perl or what?
If it's in perl (or python of course) I'd like to merge
in all the pirate code generation stuff.

(My plan for this week was to do something very similar,
and try to get a simple lisplike language to integrate
with python)

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: Should I target Parrot?

2003-08-24 Thread Michal Wallace
On Fri, 22 Aug 2003, Benjamin Goldberg wrote:

 Michal Wallace wrote:
  
  On Thu, 21 Aug 2003, Benjamin Goldberg wrote:
  
   If you want, instead, to serialize interpreter-microthreads,
   however... well, you'd *still* get almost the whole interpreter
   serialized, but you're getting more bang for your buck :)
  
  Well how else are we going to implement squeak? :)
 
 Squeak uses synchronous communication channels, right?  Writing blocks
 until there's a reader, and reading blocks until there's a writer.

Beats me. I was kind of being silly. But squeak does save the state of
the entire interpreter in an image file.  :)

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: Method call parameters

2003-08-24 Thread Michal Wallace
On Sun, 24 Aug 2003, Benjamin Goldberg wrote:

 Togos wrote:
  
  What's the reasoning behind putting the object a
  method is being called on in P2 instead of in the
  first parameter of the method? I have a feeling that
  putting it as the first parameter of the method would
  make the lives of the python folks a little bit
  easier. Would it make it harder for someone else?
 
 While I've no idea about that, I don't see why you can't have it both
 ways... put it in P2 *and* as the first param, if that's the way your
 language wants it.
 
 I think this would be useful for both Python and Perl5.


For what it's worth, you can do this in python:

class Whatever:
def method(self, arg):
pass

w = Whatever()
Whatever.method(w, arg=1)

This is the same as:

w = Whatever()
w.method(arg=1)

For both of those, the P2 and P5 should be w
Not to mention this looks exactly like a function
call on a module:

import module as m
m.function(arg=1)

... Which doesn't get a self parameter passed in.

Old-style classes actually do that Class.meth(instance, arg)
fairly often when overriding methods. New style classes use:

super(Thing, self).parentMethod(x,y,z)

I'm pretty sure new-style classes can also 
have classmethods that don't get passed a self
parameter either. 

I haven't really thought about how to implement
any of this stuff, but it looks like fun. :) I
guess if the python compiler knows how to send the
right things, it can't be too hard to figure out.

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: [CVS ci] PackFile-15: print warning location

2003-08-24 Thread Michal Wallace
On Sun, 24 Aug 2003, Leopold Toetsch wrote:

 We have two kinds of file/line information: Parrot source and HLL
 source.  So the C.currentline macro needs duplication or an argument
 specifying, which source it should denote.

And when parrot throws an error and complains about line 5,
which one will it mean? :)

Seems like normally you'd want the high-level source line, 
unless you're debugging the compiler, in which case you
want the low level one. Maybe this should be a command
line argument to parrot?

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: Should I target Parrot?

2003-08-22 Thread Michal Wallace
On Thu, 21 Aug 2003, Tom Locke wrote:

(not sure who you're quoting here... dan I think)

   But Parrot has continuations. Doesn't this gives me (cooperative)
   microthreads? (with a little work on my part).
 
  Sure...
 
 So these would be real cheap right? Time and space overheads similar to
 regular procedure calls?


Yes. This isn't working 100% (at least I couldn't get it working
without tweaking the opcodes a bit) but you can see an example
of some microthreads at http://pirate.tangentcode.com/ ) ... 
Microthreads is kind of a loose word for it because it's just
a list of generators that increment at each tick.

The bytecode I'm generating there is really really bad, so it
runs pretty slow, but it definitely works. You might try playing
around with that.


Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: Should I target Parrot?

2003-08-22 Thread Michal Wallace
On Thu, 21 Aug 2003, Benjamin Goldberg wrote:

 I hope you aren't planning on serializing just a single isolated
 microthread... that wouldn't work well with what I've got in mind due to
 how much stuff comes along when you serialize a continuation -- you'd
 get almost the whole interpreter serialized.
 
 If you want, instead, to serialize interpreter-microthreads, however...
 well, you'd *still* get almost the whole interpreter serialized, but
 you're getting more bang for your buck :)


Well how else are we going to implement squeak? :)

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--



Re: Should I target Parrot?

2003-08-21 Thread Michal Wallace
On Wed, 20 Aug 2003, Tom Locke wrote:

 I am currently embarking on a project to create a new language. Right now
 I'm in the process of selecting the platform that's going to give me the
 best starting point.
 
 My first choice is whether to go for a VM, or a C-Python style
 implementation. Right now I'm leaning towards VM.

Hey Tom,

I'm not sure what you mean by the difference here. CPython
does have a VM, it's just a stack-based one.

 The language will be dynamically typed, and I understand that Parrot
 is a better fit for such languages than the JVM or the CLR.

 I'm sure you're all good Parrot advocates in here, so... If I post
 some requirements I have to support my language features, would you
 folks care to talk me into targetting Parrot. Is this the right
 group for such a discussion?

Do you have a website for the language?

I've been working on a python-parrot compiler and managed
to get quite a bit working. If your language is strongly
O-O, you may need to dive into the parrot guts and submit
some patches if you want to move quickly (as classes and
objects aren't quite ready yet) but for a more functional
or imprerative style language you should be able to get
pretty far already.

If you've got some seriously weird features, who knows? Ask
and see, or try it out. :)

But: I would say, in general, if you target parrot, and you
make your language compatible with other languages, you're
more likely to get people to try your language for a small
chunk of code here and there, as people will be able to
use libraries they're familiar with your syntax. It'll help
people shorten their learning curve, in other words. (But
that's just my prediction)


Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




bug with parrot -O2

2003-08-17 Thread Michal Wallace


I haven't looked into this at ALL, but I was
curious about the IMCC optimization flags:

[~/pirate]: ./pirate.py -d weightless.py  weightless.imc
[~/pirate]: parrot weightless.imc
ended with: L 450
total time: 23
[~/pirate]: parrot -O=1 weightless.imc
ended with: L 450
total time: 22
[~/pirate]: parrot -O=2 weightless.imc
get_pmc_keyed() not implemented in class 'PerlInt'

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: there's no undef!

2003-08-17 Thread Michal Wallace
On Sun, 17 Aug 2003, Benjamin Goldberg wrote:

 Michal Wallace wrote:

  Uh-oh. I just went to implement del x
  and there's no op to remove a variable
  from a lexical pad! :)
 
 Why would you want to remove a variable from a lexical pad?
 
 Surely the right thing to do would be to create a new pad (scope),
 then add your 'x' variable which you plan to 'delete' in the future,
 then when you want to delete that variable, pop off that pad.


Hmm. Do you mean

  if for stmt in block:
 if stmt.type == undef:
flag_as_going_to_delet(stmt.varname)

So I can create a new pad when it's assigned?
It can't be a simple pop though, can it?

#!/usr/bin/perl
$x = cat;
$y = pop $x?;
undef $x;
print x = $x \n;
print y = $y \n;

Because here, $x has to be defined before $y, so
I'd have to delete the -2nd scope. Unless the
code was smart enough to work out that y is in
-2 and x is in -1... 

In any case, what does it buy me? it seems like a 
lot of work when there's already a delete_keyed 
op, and leo just made an implementation for pads. :)

I guess in perl it's not bad, since that's the
whole point of undef, you can just $x = PerlUndef
it... But in python, this throws a NameError:

   x = 1
   del x 
   x

So the easiest thing to me is just to translate 
del x as  remove this from the current pad. 

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: set vs. assign, continued: 'add' vs. 'add!'

2003-08-17 Thread Michal Wallace
On Sun, 17 Aug 2003, Luke Palmer wrote:

 Benjamin Goldberg writes:
  Hmm... I just thought of something.  Since 'set' semantics can be easily
  simulated when we have only ops for 'assign' semantics, maybe imcc
  itself could do this for us.
  
  That is, by default,
 $P0 = $P1 + $P2
  will be translated by imcc into
 add $P0, $P1, $P2
  but, if some command is given to imcc, then it will be translated into
 new $P0, .PerlUndef
 add $P0, $P1, $P2
  Or, instead of PerlUndef, the command to change to set semantics would
  indicate what to put into $P0 prior to using it as the target of an add
  (so we can initialize $P0 with any of PerlInt, PerlNum, BigInt,
  BigFloat, BigRat, ContinuedFraction, etc.)
 
 Hmm, I wonder whether this is the right approach.  What about operator
 overloading?  Let's say Python overloads + (can it do that?) and passes
 that variable to Perl.  If Perl creates a .PerlUndef and assigns to it,
 you lose the overloaded semantics.

Sure, you can do that in python:

   class Add:
  ...def __add__(self, other):
  ...print we don't need no steenkin, other
  ...
   x = Add()
   x + 1
  we don't need no steenkin 1

But if you know the types of the objects, it makes sense
to do the change Benjamin is talking about. So this probably
ought to be done at the AST code generation level.

Leo sent me a patch that does some basic type inference in pirate and
figures out when not to generate the extra PerlUndef. It's in the
method binaryExpression.  (It's just not used yet because at the time
it wasn't compatible with the way I was handling expressions; I've
been trying to get my code to work his way, but didn't go back and
check whether it worked yet.)

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: there's no undef!

2003-08-17 Thread Michal Wallace
On Mon, 18 Aug 2003, Benjamin Goldberg wrote:

  Hmm. Do you mean
  
if for stmt in block:
   if stmt.type == undef:
  flag_as_going_to_delet(stmt.varname)
  
  So I can create a new pad when it's assigned?
 
 Right.  You'd create a new pad just before the for, and put stmt
 into it.  After the for loop ends, you pop off that pad.

 
  It can't be a simple pop though, can it?
 
 Why not?

Because in my examples, I don't see how you know
it's the topmost lexical pad. 

 These are dynamic variables here; could you give an example of what
 you're trying to do with lexicals (my variables)?

Sure.
It does the exact same thing if you put my in front of each variable:

#!/usr/bin/perl
my $x = cat;
my $y = pop $x?;
undef $x;
print x = $x \n;
print y = $y \n;


 And remember, undef doesn't get rid of a variable; it merely stores
 an undef value into it.

But it has the same effect as getting rid of the variable,
since a variable that doesn't exist also returns undef. :)

 
 I mean, consider:
 
#!/usr/bin/perl
use strict;
{ my $x = cat;
  { my $y = pop $x;
# $x and $y are both in scope.
undef $x;
# $x and $y are still both in scope.
$x = 2; # no error here!
  } # $y goes out of scope.
  $x = 42; # ok.
  $y = 6*9; # but this is an error.
} # $x goes out of scope now.
$x = 13; # this is an error.
__END__
 
 There's no way, in this program, for $x to be out of scope while $y is
 in scope.

Yes, but this is just normal lexical scoping behavior. 
I'm already doing the same thing for python.

You say that in perl, undef $x means $x = PerlUndef, which
is fine. But in python, that's not the case. del x gets 
rid of the variable, so that the next find_lex should throw
a NameError. I don't see the point in creating an extra
lexical scope for every variable that gets deleted.

And that's not what you're telling me anyway.

In your innermost block, you're telling me that on the 
python equivalent of the undef $x line i should be 
popping off a lexical pad in python. I'm saying 
that's not the case. I should be removing x from the
lexical pad. If perl does the same thing, then you
get the same behavior as undef x, because an unfound
lexical in perl just returns PerlUndef anyway.

 
 x = 1
 del x
 x
 
  So the easiest thing to me is just to translate
  del x as  remove this from the current pad.
 
 Maybe.  But, what happens with:
 
x = 1
y = lambda: x
del x
z = y()
 
 Does/should this also throw a NameError?


Looks like it:

 x = 1
 y = lambda : x
 del x
 z = y()
Traceback (most recent call last):
  File stdin, line 1, in ?
  File stdin, line 1, in lambda
NameError: global name 'x' is not defined


Anyway, the short answer is I'm happy with the 
solution I've got now. It's easy and it does
what I expect. But I'll happily change it if
you send me a patch. :)

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--



Re: thanks and pow / div ops

2003-08-16 Thread Michal Wallace
On Fri, 15 Aug 2003, Leopold Toetsch wrote:

 PS: have a look at the rather new Cunless a op b opcode in PIR ;-)

Cool! :)

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




there's no undef!

2003-08-16 Thread Michal Wallace

Uh-oh. I just went to implement del x
and there's no op to remove a variable
from a lexical pad! :)

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--



save/restore on yield?

2003-08-16 Thread Michal Wallace

Just tried out Kenneth Grave's yield stuff --
it works great! 

But shouldn't .pcc_begin_yield and .pcc_end_yield 
do saveall and restoreall, respectively?

Is there a case where we wouldn't want this?

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--



Re: save/restore on yield?

2003-08-16 Thread Michal Wallace

I said:

 But shouldn't .pcc_begin_yield and .pcc_end_yield 
 do saveall and restoreall, respectively?
 
 Is there a case where we wouldn't want this?

Yes, because for python anyway, I also need to 
put pop_pad in there:

  saveall
  pop_pad
  .pcc_begin_yield
  .return whatever
  .pcc_end_yield
  restoreall

So nevermind. :)

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




try/catch bug with coroutines

2003-08-16 Thread Michal Wallace

It seems that exception handlers get tied to 
subroutines when they're created, not when 
they're actually used. For example:

## this works:
try:
f = make_function()
f.die() # raise some error
except:
pass

  
## this does not work:
f = make_function()
try:
   f.die() # raise some error
except:
   pass


This is a problem in general, but especially for me
because in python, a generator returns an object, 
and you call that object's next() over and over 
until you get a StopIteration. Unfortunately, I
can't *trap* that StopIteration in a try block 
unless I create the generator inside that same block.

Following is a detailed test case in imc that 
illustrates the problem.

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--

## generator_try_bug.imc

## this exposes a bug in parrot exception handling
## a function returns a function and that function
## throws an error. The error is not caught.

.sub __main__
new_pad 0

# count() returns a generator
.local object count
newsub count, .Closure, _count

# here's where we'll store it
.local object generator


# if try: is around the CREATION of the generator, 
# everything works fine. but we don't want that, so
# this is commented out.
#
#.local Sub handler
#newsub handler, .Exception_Handler, catch0
#set_eh handler


# call count and get the generator
.local Sub retlabel0
newsub retlabel0, .Continuation, ret0
.pcc_begin non_prototyped
.pcc_call count, retlabel0
ret0:
.result generator
.pcc_end


## HERE IS where we want the try block to start 
.local Sub handler
newsub handler, .Exception_Handler, catch0
set_eh handler


# now call the generator, which throws 'StopIteration'
.local Sub retlabel1
newsub retlabel1, .Continuation, ret1
.pcc_begin non_prototyped
.pcc_call generator, retlabel1
ret1:
.result $P3
.pcc_end

# end the try block (we never get here)
clear_eh
goto endtry0
catch0:
print caught it!
endtry0:
end
.end

# here is count(), which returns the generator
.pcc_sub _count non_prototyped
   .local object gen_fun
   .local object gen_obj
   newsub gen_fun, .Coroutine, _count_g
   .pcc_begin_return
   .return gen_fun
   .pcc_end_return
.end

# here is the generator itself
# all it does is throw StopIteration
.pcc_sub _count_g non_prototyped
.local object ex0
.local object msg0
ex0 = new Exception
msg0 = new PerlString
msg0 = 'StopIteration'
ex0['_message'] = msg0
throw ex0
.end

## end of test case ###




Re: there's no undef!

2003-08-16 Thread Michal Wallace
On Sat, 16 Aug 2003, Leopold Toetsch wrote:

 I have put in scratchpad_delete
 
 peek_pad P0
 delete P0[foo]
 
 deletes names only.

Thanks! works great!

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




getprop and find_lex?

2003-08-16 Thread Michal Wallace


I expected getprop to behave like find_lex
and throw an exception if the property doesn't
exist, but it doesn't:

.sub _main
   .local object Class
   .local object setv
   .local object getv
   Class = new ParrotClass
   setv = new PerlString
   setv = value\n
   setprop Class, name, setv  # ok
   delprop Class, name# ok
   getprop getv, name, Class  # inconsistent!
   print getv   # prints empty string
   print \n
   print type is: # this print prints
   typeof S0, getv  # type is: PerlUndef
   print S0
   print \n
   end
.end

Maybe that's just what parrotclasses do, which is
fine, but a pythonclass would need an exception 
here.

In any case, it might be nice to have a 'hasprop' or
a version of 'defined' for properties. (Nicer than
making prophash and then checking that to see if
it has a particular key)

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: getprop and find_lex?

2003-08-16 Thread Michal Wallace
On Sat, 16 Aug 2003, Sean O'Rourke wrote:

 Michal Wallace [EMAIL PROTECTED] writes:
  I expected getprop to behave like find_lex
  and throw an exception if the property doesn't
  exist, but it doesn't:
 
 Are you sure that properties are what you want to use
 here, rather than attributes (via get_pmc_keyed() or
 similar)?  IIRC parrot's properties are supposed to
 support out-of-band data like Lisp's plists or Perl 6
 properties
 (http://dev.perl.org/perl6/apocalypse/2#properties)


Yes, I think so. I asked about this earlier in
a thread called in vs on. Python objects have
both __getitem__ (for x[y]) and __getattr__ (for x.y)
Dan agreed that for python, using get_pmc_keyed and getprop
(respecitvely) was the way to go.

Granted, python *classes* wouldn't normally allow __getitem__,
but since you can pass them around like any other object,
I want to treat classes and objects the same way and 
handle their differences in the vtable.

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--



Re: pirate 0.01 ALPHA!

2003-08-16 Thread Michal Wallace
On Sat, 16 Aug 2003, Sean O'Rourke wrote:

 Michal Wallace [EMAIL PROTECTED] writes:
 
  Tadaa!
 
 /me blinks at the list comprehensions.

:) 

 
 Cool stuff.  test_microthreads failed for
 some reason I still need to look into, but
 there's a lot of cool stuff working
 already.  Time for Dan to begin thinking
 about which direction the pie will fly.

D'oh! :/ I didn't mean to include that. 
It's really broken, because things get
lost when I invoke the continuation. 

That's why the weightless.py has the two
PARROT_INLINE(...) macros in the generator
dispatch loop at the bottom.

The fix for the test is probably something
similar, but I'm not sure how to handle it.
I think the problem is some standard step
that needs to be done around  .pcc_begin_yield 
and .pcc_end_yield, but I haven't thought
it through completely.

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




thanks and pow / div ops

2003-08-15 Thread Michal Wallace


raise hell is working great 
with the new find_lex exceptions. Thanks! :)

Any plans to to add pow for PMC's?

What about separate ops for floor/true division?

  http://www.python.org/doc/2.2.1/whatsnew/node7.html

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: A certain 4 letter word (was Re: Parrot and STDOUT/STDERR)

2003-08-15 Thread Michal Wallace
On Fri, 15 Aug 2003, Leopold Toetsch wrote:

 When we have more classes like a Python hierarchy, we will see, how and
 how far the functionality does match. If we find some, we can put in an
 intermediate ParrotScalar.

I was thinking about this earlier today. Once dynamic
PMCs are working, Perl* probably ought to be loaded
dynamically, especially if perls 5 and 6 wind up
needing different implementations.

As far as python goes... I've done some reading on C 
and I think I feel confident enough to try tackling 
a pyobject - pmc two-way bridge (just a generic 
wrapper for the two vtables). I figure it would be 
nice if we could just wrap the generic pyobject 
interface, and then hopefully all the existing 
python modules will just work. :)

Aside from that, I was going to follow Dan's lead.

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




bug: clear_eh patricide after catch

2003-08-14 Thread Michal Wallace


Here's a new test case for t/pmc/sub.t


output_is('CODE', 'OUTPUT', set_eh - throw - clear_eh);
print start\n
newsub P20, .Exception_Handler, _handler
set_eh P20
new P30, .Exception
throw P30
print not reached\n
end
_handler:
clear_eh
print caught it\n
end
CODE
start
caught it
OUTPUT
#


If I run this code from the perl test harness or 
from my python test suite, it actually kills 
perl/python, leaving nothing but the message Quit.

If I run the code directly from parrot, I get:


static
Parrot VM: PANIC: Tried to clear_eh a non Exception_Handler!
C file exceptions.c, line 143
Parrot file (unknown file), line 0

We highly suggest you notify the Parrot team if you have not been working on
Parrot.  Use bugs6.perl.org or send an e-mail to [EMAIL PROTECTED]
Include the entire text of this error message and the text of the script that
generated the error.  If you've made any modifications to Parrot, please
describe them as well.

Version : 0.0.10-devel
Configured  : Sun Aug 10 16:34:12 2003
Architecture: i386-linux
JIT Capable : Yes
Interp Flags: 0x40
Exceptions  : (missing from core)

Dumping Core...
Quit
###


I don't know if my test is right or not, but I'm
expecting the exception handler to still be around
after the exception is caught. 

I don't care if it goes away after the exception is 
caught, but I need a way to clear the exception 
handler after I get out of the try/except or 
try/finally block... Otherwise later exceptions
will bring me backward in the code. :/


Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--



RE: help raise hell

2003-08-14 Thread Michal Wallace
On Mon, 11 Aug 2003, Joseph F. Ryan wrote:

 How are you currently throwing/catching exceptions?  I think it
 might be much more difficult to create a model that traps
 exceptions, rather than setting up code that just figures out how
 to handle an exception when it occurs.  Both JVM-PIR and P6C use
 continuations to handle exceptions, albeit in different ways.
 
 Anyways, since I can't read python, could you explain what you are
 using now? (-:

Sure. This:

   try:
raise 'hell'
   except:
pass

Becomes this:

   1: .sub __main__
   2: new_pad 0
   3: setline 1 # (set_lineno:85)
   4: .local Sub handler0   # (visitTryExcept:723)
   5: newsub handler0, .Exception_Handler, catch0 # (visitTryExcept:724)
   6: set_eh handler0   # (visitTryExcept:726)
   7: setline 3 # (set_lineno:85)
   8: .local object ex0 # (visitRaise:701)
   9: .local object msg0# (visitRaise:702)
  10: ex0 = new Exception   # (visitRaise:703)
  11: msg0 = new PerlString # (expressConstant:164)
  12: msg0 = 'hell' # (expressConstant:165)
  13: ex0['_message'] = msg0# (visitRaise:705)
  14: throw ex0 # (visitRaise:706)
  15: goto endtry0  # (visitTryExcept:728)
  16: catch0:
  17: noop  # (visitPass:688)
  18: endtry0:
  19: end   # (compile:817)
  20: .end
  21: .include 'pirate.imc'


If you throw an uncaught exception in python, python has a
default handler that prints out the traceback (call stack)
shows the error message, and then terminates (or optionally
invokes the python prompt). So... I'm saying all generated 
python programs should have one of these giant try-except 
blocks around them, and that's what I mean by trapping the
exception.

In the above example, if I did raise hell instead of raise 'hell',
python would throw a NameError that I could trap just like
any other exception:

try:
raise hell
except NameError:
print There is no hell.
except:
print Something else went wrong.

(my code only gives you one except: block so far, but real
python lets you have as many as you like for different
types of exceptions)

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: parrot bug: continuations/multiple return

2003-08-14 Thread Michal Wallace
On Sat, 9 Aug 2003, Benjamin Goldberg wrote:

 Michal Wallace wrote:
 [snip]
def f():
return g()
 [snip]
  # f from line 3
  .pcc_sub _sub1 non_prototyped
  .local object res1# (visitReturn:528)
  find_lex $P2, 'g' # (callingExpression:325)
  newsub $P3, .Continuation, ret0# (callingExpression:331)
  .pcc_begin non_prototyped # (callingExpression:332)
  .pcc_call $P2, $P3# (callingExpression:335)
  ret0:
  .result res1  # (callingExpression:338)
  .pcc_end  # (callingExpression:339)
  .pcc_begin_return # (visitReturn:530)
  .return res1  # (visitReturn:531)
  .pcc_end_return   # (visitReturn:532)
  .end
 
 Does python allow tail calls to be optomized?  That is, would it be
 legal python semantics if f were to become:
 
 .pcc_sub _sub1 non_prototyped
 find_lex $P2, 'g'
 .pcc_begin non_prototyped
 .pcc_call $P2, P1
 .pcc_end
 .end

Well, the real python doesn't optimize tail-calls at all.
You'll get a nasty max recursion depth exceeded traceback
if you try running def f(x): return f(x+1)

But I don't see any reason pirate shouldn't do it, since the
difference is pretty much transparent.

 
 (untested)
 Also... why is $P2 merely an imcc temporary, without a real name?  That
 is, why not do:
 
 .pcc_sub _sub1 non_prototyped
 .local object sub1
 find_lex sub1, 'g'
 .pcc_begin non_prototyped
 .pcc_call sub1, P1
 .pcc_end
 .end
 
 The more different prefixes you use (res, sub, $P), the lower the
 numbers you'll need to append to them to make the names unique.  Not to
 mention, it'll make the generated code more meaningful.
 
 Another advantage is that with '.local' names, if you accidentally use a
 name declared in one subroutine, in another, imcc will consider this to
 be an error.  Such a mistake might be otherwise difficult to spot.

Hmmm. The counters are global so there shouldn't be any conflicts.
I'd actually been trying to move away from .local now that I started
using lexicals... If there's going to be two sets of names for 
everything I'd rather one of them was just $Pxx... 

Now, if I could say:

  .lexical g

That would be really nice... :)

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




pirate status / need help with instances

2003-08-14 Thread Michal Wallace

Just wrapping up an all-night coding spree...
Py-pirate can now handle:

   - functions (closures, recursion, etc)
   - global variables
   - tuples (but they turn into lists)
   - dictionaries (create, setitem, getitem, print)
   - list comprehensions
   - raise (strings only)
   - try...except (partial)
   - try...finally
   - assert

The only tricky parts left for the code 
generator are classes, exec/eval/import,
and possibly slices.

Right now, I'm a bit stuck with classes. I've 
got the class statement working, and it creates
a parrot class... But I'm not quite sure
how to instantiate a class.

The problem is that for:

   class Clown:
   pass

I have a lexical variable Clown pointing at
a parrotclass pmc.

However, when I go to instantiate Clown, I do
this:

   bozo = Clown()

There's no new operator like in java, so
the problem is that this looks just like a 
function call to python. So I have to figure
out whether to call invoke or new... Though
now that I think about it, I'm not really sure
what operator to use to make a new instance.

Anyway, there's no way to tell at compile-time
whether something is a constructor or a normal
function... So I'm trying to decide between two
approaches:

   * make parrotclass handle invoke
 this strikes me as the most efficient,
 but I'm not really confident with C 
 so I'm hesitant to try it

   * grab the lexical, check whether it's a class, 
 and if so, do newclass instead of invoke.

I also thought about making a constructor into
just a normal function, but then the lexical would
have to bind to either the class or the function,
and that's no good because classes and functions 
can both have attributes in python.

Any advice?

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: why ~ for xor?

2003-08-14 Thread Michal Wallace
On Mon, 11 Aug 2003, Thomas Vesper wrote:

 Michal Wallace wrote:
  Out of curiosity, why does ~ map to both
  unary bitwise-not and binary bitwise-xor
  in imcc?
  
  I was expecting xor to be ^ and ^^
 
 See Apocalypse 3 for this.
 ^ was reclaimed for hyperoperators.
 Binary ~ was chosen as replacement since bitwise-not is already somehow
 like bitwise xor with only one operand.
 And so ~~ became logical xor.


Aha. I remember that now. Thanks. :)

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




why ~ for xor?

2003-08-14 Thread Michal Wallace

Out of curiosity, why does ~ map to both
unary bitwise-not and binary bitwise-xor
in imcc?

I was expecting xor to be ^ and ^^

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: generic code generator? [was: subroutines and python status]

2003-08-14 Thread Michal Wallace
On Tue, 5 Aug 2003, Dan Sugalski wrote:

 The original thought was to use the new perl 6 grammar engine/code
 to do this, but I think it'll be a while before that's ready to go.

I think perl6 is definitely the way to go, once it's ready.

BTW, what's the deal with Bundle::Perl6? I tried installing it from
cpan yesterday but it wouldn't install with my perl. (I forget why)
Is it meant to be usable today?

 
 Rather than invent an entirely new language for this (which is
 somewhat problematic) why not go for something already reasonably
 well-known? YACC and BNF grammars seem like a good place to start,
 especially as most of the languages have some form of grammar
 defined for them.

Well the new language was just for the imcc code templates.
Now I think the better path is to define a code-generating class
for each ast node.

Then PythonWhileNode can be a subclass of the generic WhileNode.
(Python while statements have an extra else block that most 
languages don't have)


 It's only a first step, as then everyone beats the heck out of the
 resulting token stream, but it's a place to start. 80-90% of the
 result will end up being generically parseable as well--x + y will
 generate the same code for all languages if x and y are PMCs, for
 example, so I'd bet we could have a lot of standard products
 designed.
 
Yep. For now, everything pypirate generates *is* pmc based,
since python doesn't have type declarations. Generic pirate
should probably have a declare node though. (Especially
if it's to handle perl6, right?)

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: generic code generator? [was: subroutines and python status]

2003-08-14 Thread Michal Wallace
On Tue, 5 Aug 2003, Joseph Ryan wrote:

 Okay, I don't have a good syntax in mind yet,
 the point is it's a template language and you
 can subclass/override/extend the template. 
 Maybe there's no syntax and it just uses 
 cleanly coded classes in some oo language.
 Or perl6 with it's grammars and rules. I
 don't know.
 
 
 I think that trying to define a new syntax for a new meta-language
 is a bad idea.  The goal of a GCG (Generic Code Generator) should be
 to allieviate the compiler writers of the responsiblity of
 generating code.  Forcing them to generate different code doesn't
 help solve the problem. (-:
 

Good point. I don't think I was very clear yesterday. Let
me try again. Let's say you're generating... I dunno.. haskell:



 haskell_parser - ast - pirate - parrot_code -- imcc - pbc
^
|
  parrot_code__templates
 

So the haskell parser only has to generate a pirate ast structure.
Either that's a very basic string (I like your XML idea) *or*, in
the future, the parser calls pirate tree-building-methods directly.

The tree-building methods are why I was talking about C, but for
now, I don't mind doing a bunch of xml-generation every time we
call eval/exec. (It's probably the simplest thing to do right now
and should be pretty easy for everyone)


 1.) Instead of forcing the compiler writer to generate code, the
 compiler writer would only have to transform the parse tree into a
 structure that is name-consistant with the GCG's standard, and then
 use any of a number of existing libraries to dump the tree as
 YAML/XML.

I like it! :)

 
 2.) Since there are more YAML/XML parsers than I can count
 implemented in nearly modern useful language I can think of, the GCG
 could be generated in any language without causing a stall on
 starting on the generic code generation part of the project. (you
 know, the important part)

Agreed!


 3.) It would be possible to handle language-specific nodes by
 defining some sort of raw node whose value could be raw imcc code.

That's where the templates come in, but since my crack
at a template language last night sucked so bad, I'm
thinking that at least for prototyping I'm going to 
use a python class.

So I'm thinking I'm going to try refactoring so that 
I can do this:

   pypirate something.py  something.xml
   cat something.xml  pirate -l python   something.imc
   imcc something.imc

or just:

   pypirate something.py | pirate -l python | imcc

or just:

   pypyrate -r something.py 

That also means the pirate command can be written in
any language we like. Probably eventually that'll be 
perl6, but for now (unless someone else wants to 
volunteer some code) I plan to work from the code
I have for python.

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: parrot bug: continuations/multiple return

2003-08-14 Thread Michal Wallace
On Sat, 9 Aug 2003, Leopold Toetsch wrote:

 As calling conventions clearly state, that the caller has to save 
 everything, its probably up to imcc/pcc.c to insert above statements, if 
 another sub gets called from a sub. I'll fix that in a minute ;-)

I just synced up with cvs and now everything works! Thanks!

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: This Week's Perl 6 Summary

2003-08-14 Thread Michal Wallace
On Tue, 5 Aug 2003, Piers Cawley wrote:

   Approaching Python
 Discussions (and coding) of the Parrot implementation of Python
 continued this week. Michal Wallace is working on taking a preexisting
 (but incomplete, it's a proof of concept only) python parse tree -

Wow, after reading these things for the past year or so I feel famous. :)

   IMCC supports the Parrot Calling Conventions
 Leo announced that IMCC's brand of assembler, PIR (I can't remember what
 it stands for, Parrot Intermediate Representation perhaps). Of course,
 there are things it doesn't quite do yet (tail call detection, only
 preserving 'necessary' registers...) and it's somewhat lacking on the
 test front, but it's a start. Yay Leo!
 
 http://xrl.us/crv75

I missed this the first time. Leo, this rocks!

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: bug: clear_eh patricide after catch

2003-08-14 Thread Michal Wallace
On Mon, 11 Aug 2003, Leopold Toetsch wrote:

 No, the exception object isn't around anymore in the handler, so you
 don't Cclear_eh there.
 
 This could of course be just my wrong implementation.

No, it makes sense. You wouldn't want an exception in
the catch: block to trigger an infinite loop.

But if that's the way to go, there ought to be a note 
in the docs. (see patch below)

  I don't care if it goes away after the exception is
  caught, but I need a way to clear the exception
  handler after I get out of the try/except or
  try/finally block... Otherwise later exceptions
  will bring me backward in the code. :/
 
 Can you insert Cclear_eh before you fall through to except/finally?

Yep. That works perfectly. Thanks. :)

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--

Index: core.ops
===
RCS file: /cvs/public/parrot/core.ops,v
retrieving revision 1.316
diff -c -r1.316 core.ops
*** core.ops8 Aug 2003 08:15:05 -   1.316
--- core.ops11 Aug 2003 23:30:55 -
***
*** 479,485 

  =item Bclear_eh()

! Clear out the most recently placed exception.

  =item Bthrow(in PMC)

--- 479,486 

  =item Bclear_eh()

! Clear out the most recently placed exception. This also
! happens automatically if an exception is thrown.

  =item Bthrow(in PMC)



Re: pirate status / need help with instances

2003-08-14 Thread Michal Wallace
On Tue, 12 Aug 2003, Leopold Toetsch wrote:

  ... So I'm trying to decide between two
  approaches:
 
  3) wait until classes and objects are done ;-)

4) simulate an object system with closures :)

I wound up getting a couple C books today. I'm
trying to see what I can do about wrapping
PyObject as a PMC...

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: IMCC hangs

2003-08-14 Thread Michal Wallace
On Sun, 10 Aug 2003, Vladimir Lipskiy wrote:

  Seems to be related with the multiple freeing reported by Michael.
 
 I thought his name was Michal (:8

yes, I was born without an e. :)

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




why new_pad *INT*?

2003-08-14 Thread Michal Wallace

Hey all,

I'm just starting to get into using pads,
and I'm not sure I understand new_pad.

Specifically, why does it take an int?

It seems to me, that 9 times out of 10,
you're going to want to create a new
pad at the next lower depth than the
one before. 

So, two questions:

 1. Should there be a new_pad that takes 
no arguments to do this, so we don't
have to keep count manually?

 2. When would you NOT want to use 
new_pad (current_depth+1) ?


Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: generic code generator? [was: subroutines and python status]

2003-08-14 Thread Michal Wallace
On Thu, 7 Aug 2003, Dan Sugalski wrote:

   haskell_parser - ast - pirate - parrot_code -- imcc - pbc
  ^
  |
parrot_code__templates
  
 
 So the haskell parser only has to generate a pirate ast structure.
 Either that's a very basic string (I like your XML idea) *or*, in
 the future, the parser calls pirate tree-building-methods directly.
 
 I'd much rather go for the AST directly for a number of reasons. Not 
 the least of which is a deep personal loathing for XML, but putting 
 that aside it seems sub-optimal to have a binary structure which we 
 then serialize to text and then deserialize all as part of a single 
 parse and compile stage.  XML has the added disadvantage of needing a 
 good XML parser, which probably means expat or something like it. 
 (Yeah, I know, we could restrict ourselves to a subset of XML so we 
 don't have to have a full parser, but that'll never last--someone'll 
 expand it to a full parser at some point)


Klaas-Jan and I spiked out a prototype last night that took 
s-expressions. We got this working:

   (while (const 1) (pass))

Where While was a class that could be subclassed for PythonWhile
(python has an extra else clause in there)

I think everyone agrees that long term, there's no point in 
passing around xml or s-expressions because it'll be dog 
slow, but for now, for prototyping, passing the flattened
AST in as an s-expression on STDIN means that anyone can
write to it and we don't have to worry about a tree-building
interface until after the code is working.

 
 Going for a full-fledged AST builder/flattener meets some of the 
 long-term goals as well, as it's been planned to be the stage between 
 the parser and IMCC for ages (pretty much since IMCC first appeared) 
 so it'd be worthwhile.

I agree. The main reason to hold off *FOR NOW* is bindings. If
everyone wrote their parsers in C, then we could just use that.
But I don't feel like learning C, so... Right now the code is 
in python. I suspect eventually this will be written in perl6 
or someting. 

 
 We should consider AST transforms as well, since a number of 
 optimizations are best performed on the AST, and many languages will 
 want to get hold of the AST before it goes any further and process it 
 in some way. (This would be how Lisp macros would act, for example)

Absolutely. I suspect that for python, I'll be turning list
comprehensions into the corresponding foreach nodes before
serializing the tree.


1.) Instead of forcing the compiler writer to generate code, the
   compiler writer would only have to transform the parse tree into a
   structure that is name-consistant with the GCG's standard, and then
   use any of a number of existing libraries to dump the tree as
   YAML/XML.
 
 I like it! :)
 
 This'd be a cool thing to be sure, and useful as a human-readable 
 form. (Though I'd prefer the AST that's frozen into the bytecode be 
 in a form that's more efficient to deserialize) I'd best go and 
 update the license terms then, to make sure there aren't any 
 problems. (Old issues raised by GCC an age ago)

I'm not sure I follow this.

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: pirate status / need help with instances

2003-08-14 Thread Michal Wallace
On Tue, 12 Aug 2003, Michal Wallace wrote:

 I wound up getting a couple C books today. I'm
 trying to see what I can do about wrapping
 PyObject as a PMC...

What's the secret to making parrot recognize
a new PMC? I've got my .pmc file but I'm
not sure what to do next. The article about
making PMC's on perl.com is WAY out of date.

(I don't care if I can't load it dynamically
yet, I just want to get it running at all!)

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




help raise hell

2003-08-14 Thread Michal Wallace


Here is how I usually trigger a generic exception
in python:

 raise hell
Traceback (most recent call last):
  File stdin, line 1, in ?
NameError: name 'hell' is not defined

Unfortunately, I can't seem to trap that in parrot,
because a find_lex failure isn't an exception.
Or am I missing something?


CAN trap this though:

 raise 'hell' 

So it's not a showstopper, but still...

Is this easily fixable? I miss my idiom... :)


Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--



Re: parrot bug: continuations/multiple return

2003-08-14 Thread Michal Wallace
On Sun, 10 Aug 2003, Leopold Toetsch wrote:

 Piers Cawley [EMAIL PROTECTED] wrote:
  Leopold Toetsch [EMAIL PROTECTED] writes:
  As calling conventions clearly state, that the caller has to save
  everything, its probably up to imcc/pcc.c to insert above
  statements, if another sub gets called from a sub. I'll fix that in
  a minute ;-)
 
  If and only if that's not a tail call of course.
 
 Good point. But I can imagine, that's by far more simple to detect tail
 calls at the AST level then inside the flattened code parrot sees. So
 the HL can emit (a TBD) flag like tailcall appended to the .pcc_call
 sequence.
 Then the call can be optimized to a Cjump opcode. The construction of
 the subroutine object (which is outside of the call sequence) will lead
 to an used once LHS, which the optimizer already can get rid of.


Well, if you write it, I'll have pirate inspect the AST 
and try it out for you. :)


Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




bug: two segfaults

2003-08-14 Thread Michal Wallace

The following code segfaults immediately.
If you uncomment the second line (print )
it works. 

However, if you then uncomment the #non_prototyped
keyword in _depth1, it segfaults immediately again.

When I say it segfaults immediately, I mean that
the initial 0 is not printed.

(Should I be reporting these somewhere else?)

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--

.sub __main__
  #print 
  new_pad 0
  print 0
  newsub $P0, .Sub, _depth1
  newsub $P1, .Continuation, ret0
  .pcc_begin non_prototyped
  .pcc_call $P0, $P1
ret0:
  .pcc_end
  print \n
  end
.end


.pcc_sub _depth1 #non_prototyped
  new_pad 1
  print 1

  newsub $P2, .Sub, _depth2
  newsub $P3, .Continuation, ret1
  .pcc_begin non_prototyped
  .pcc_call $P2, $P3
ret1:
  .pcc_end

  pop_pad
  .pcc_begin_return
  .pcc_end_return
.end


.pcc_sub _depth2 non_prototyped
  new_pad 2
  print 2
  pop_pad
  .pcc_begin_return
  .pcc_end_return
.end





RE: pirate status / need help with instances

2003-08-12 Thread Michal Wallace
On Mon, 11 Aug 2003, Brent Dax wrote:

 Sean O'Rourke:
 # * make parrotclass handle invoke
 #   this strikes me as the most efficient,
 #   but I'm not really confident with C
 #   so I'm hesitant to try it
 # 
 # This seems to me like the way to go, except you might
 # subclass parrotclass to pythonclass (since this lack-
 # of-new seems to be the Pythonic way).  The C should
 # pretty much just turn around and call pmc_new, then
 # return the original return address that was passed in.
 
 I don't think this is the answer, because...
 
   use PythonClass;
   $pyobj=PythonClass.new();   #Doesn't work--need to somehow
 invoke 
   # the class
 
   #Sorry, I'm not very familiar with Python...
   import PerlClass
   plobj=PerlClass()   #Doesn't work--need .new
 
 I think this is a syntactic issue, not a semantic issue; as such, it
 needs to be dealt with at the syntactic (bytecode) level, not the
 semantic (PMC) level.

Actually, python has a magic method called __new__.
__new__ actually creates an object (so it gives you 
the ability to make meta-classes, which we'd also
need for ruby. Once __new__ is called and the object
is around, python then calls __init__.

   plobj=PerlClass()   #Doesn't work--need .new

What DOES this do?

It seems to me that parrotclass could still have invoke
for languages that use it, and that perlclass should 
just throw an exception if you try it.

There's no problem doing PerlClass.new() from python. It
wouldn't be transparent, but that's fine. It's a small
price to pay, and if PerlClass() threw an exception
remind us to use it, then it probably wouldn't be a
problem at all.

So I think invoke on the parrotclass is the way to go.

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




okay to use iterator?

2003-08-11 Thread Michal Wallace

perlhash.pod says:


TODO: Steve Fink sayd:

  And if there were a keys() method, then 'defined' and 'exists' are
  very different. (And there ought to be, and would be if we weren't
  all ignoring Leo's iterator proposal.)

I need to read that proposal :-)


Looks like the proposal got accepted? I see iterator.c and 
read the recorresponding tests... I went ahead and used it. 
Is that cool?

 
# s is a PerlHash
dict:
unless s goto empty
.local object iter
.local object key
.local object val
.local string skey
key = new PerlString

print {
iter = new Iterator, s
iter = 0  # reset it
unless iter goto enddict
shift skey, iter
key = skey
.arg 1
.arg key
call __py__print
print : 
val = s[skey]
.arg 1
.arg val
call __py__print
enddict:
   print }
empty:
print {}
goto done


Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




parrot bug: continuations/multiple return

2003-08-11 Thread Michal Wallace

Hey all,

Sorry for the huge code listing here, but I don't
have a simpler case. This is what pirate outputs
when it compiles the following program:


   def f(x):
   if x:
   return 1
   else:
   return 0
print f(1), f(0)


As far as I can tell, I'm doing exactly the same thing
for the return 1 and return 0 branches... But the output
of this program is: 

   1 get_string() not implemented in class 'Continuation'\n

Calling f(0) causes the bug even if f(1) isn't called first.
I think this is a bug in parrot's register allocation scheme.

Or am I just doing something stupid? :)


BTW: It would be SO nice if parrot could print a line 
number for ALL its error messages. (Or if the debugger
didn't segfault g)


##

.sub __main__
new_pad 0
setline 1
newsub $P0, .Sub, _sub0
store_lex -1, 'f', $P0
.local object arg0
arg0 = new PerlInt
arg0 = 1
find_lex $P2, 'f'
newsub $P3, .Continuation, ret0
.pcc_begin non_prototyped
.arg arg0
.pcc_call $P2, $P3
ret0:
.result $P1
.pcc_end
.arg $P1
call __py__print
print  
.local object arg1
arg1 = new PerlInt
arg1 = 0
find_lex $P5, 'f'
newsub $P6, .Continuation, ret1
.pcc_begin non_prototyped
.arg arg1
.pcc_call $P5, $P6
ret1:
.result $P4
.pcc_end
.arg $P4
call __py__print
print \n
end
.end
.include 'pirate.imc'

# f from line 1
.pcc_sub _sub0 non_prototyped
.param object x
setline 2
.local object test0
test0 = new PerlInt
test0 = x
unless test0 goto elif0  ### if x return 1
.local object res0   
res0 = new PerlInt
res0 = 1
.pcc_begin_return
.return res0
.pcc_end_return
goto endif0
elif0:   ### else return 0
.local object res1
res1 = new PerlInt
res1 = 0
.pcc_begin_return
.return res1
.pcc_end_return
endif0:
.end

##


Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: calling conventions, variable-length parameter lists

2003-08-10 Thread Michal Wallace
On Fri, 8 Aug 2003, TOGoS wrote:

 I want to be able to have a function with
 this kind of signature:
 
 func ($param1, *$otherparams)
 
 AFAIK, there is no way to implement this
 with the current calling conventions. You
 would have to do something with variable
 register IDs, which we don't have and which
 would probably be a bad idea, anyway.
 
 Maybe non_prototyped pcc subs should
 always have all their parameters shoved
 into an array? (and likewise for return
 values :-). Hopefully most subroutine calls
 will be prototyped, anyway, so it wouldn't
 cause too much of an overall speed-hit, and it
 would make many things a lot simpler (not
 to mention even *possible*).

Why not make $otherparams a PerlArray? 
I haven't gotten this far with python, but
I'm not sure I understand why that 
wouldn't work?

Maybe there should be a register reserved
for an Array and another for a Hash (for
extra keyword arguments)?

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: why new_pad *INT*?

2003-08-10 Thread Michal Wallace
On Sat, 9 Aug 2003, Sean O'Rourke wrote:

 The problem is that when adder() gets returned, it
 needs to remember the enclosing pad.  So this needs to
 be
 
 newsub $P1, .Closure, _sub1
 
 which (IIRC) will save the lexical environment in which
 it was created (see closure.pmc), then restore that
 when it is invoked.

Thanks! I see the light. :)

I just made all python routines closures for now, 
and all my tests passed.

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: parrot bug: continuations/multiple return

2003-08-10 Thread Michal Wallace
On Sat, 9 Aug 2003, Leopold Toetsch wrote:

 Nice coincidence. S. Togos' bug report too.
 Anyway, its already fixed.

Gosh you're quick. Thanks!

Want another one? :)

  def g():
  return 0
  def f():
  return g()
  print f()


This prints:

  'No more I register frames to pop!'


I was hoping those two were the same problem, 
but it doesn't look like it. This happens any 
time one function calls another, whether it passes
in arguments or not. The bug seems to happen on
the return 0 line.

(It may very well be my generated code, but I 
can't find it if it is)

##

.sub __main__
new_pad 0
setline 1 # (set_lineno:81)
newsub $P0, .Sub, _sub0   # (genFunction:378)
store_lex -1, 'g', $P0# (genFunction:380)
setline 3 # (set_lineno:81)
newsub $P1, .Sub, _sub1   # (genFunction:378)
store_lex -1, 'f', $P1# (genFunction:380)
find_lex $P5, 'f' # (callingExpression:325)
newsub $P6, .Continuation, ret1# (callingExpression:331)
.pcc_begin non_prototyped # (callingExpression:332)
.pcc_call $P5, $P6# (callingExpression:335)
ret1:
.result $P4   # (callingExpression:338)
.pcc_end  # (callingExpression:339)
.arg $P4  # (visitPrint:394)
call __py__print  # (visitPrint:395)
print \n# (visitPrintnl:403)
end   # (compile:574)
.end
.include 'pirate.imc'

# g from line 1
.pcc_sub _sub0 non_prototyped
.local object res0# (visitReturn:528)
res0 = new PerlInt# (expressConstant:153)
res0 = 0  # (expressConstant:154)
.pcc_begin_return # (visitReturn:530)
.return res0  # (visitReturn:531)
.pcc_end_return   # (visitReturn:532)
.end


# f from line 3
.pcc_sub _sub1 non_prototyped
.local object res1# (visitReturn:528)
find_lex $P2, 'g' # (callingExpression:325)
newsub $P3, .Continuation, ret0# (callingExpression:331)
.pcc_begin non_prototyped # (callingExpression:332)
.pcc_call $P2, $P3# (callingExpression:335)
ret0:
.result res1  # (callingExpression:338)
.pcc_end  # (callingExpression:339)
.pcc_begin_return # (visitReturn:530)
.return res1  # (visitReturn:531)
.pcc_end_return   # (visitReturn:532)
.end



Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




pirate guide

2003-08-10 Thread Michal Wallace

Just got the parrot calling conventions working for Py-Pirate.

I also wrote a guide that explains how the code is laid out
for people who don't know python:

http://pirate.versionhost.com/viewcvs.cgi/pirate/GUIDE?rev=1.1


Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: why new_pad *INT*?

2003-08-09 Thread Michal Wallace
On Sat, 9 Aug 2003, Sean O'Rourke wrote:

 Remember, the pad depth reflects lexical scope nesting,
 not dynamic scoping.  So if you mean current_depth as
 current compile-time depth above, then you're right,
 but the VM would have no way to tell.  If you mean
 run-time depth, which the compiler could know
 about... A top-level sub should not create a new pad at
 depth + 1, since that would put it inside its caller's
 lexical scope, which would just be weird.

Okay, I definitely need some help understanding this.

Here's some python code that defines a closure:

def make_adder(base):
def adder(x):
return base+x
return adder
h = make_adder(10)
print h(5)

When I run this in python 2.2, it prints 15.

When I run it through pirate, I get this:

   -scratch_pad: too deep

Now, in my mind:

depth 0 has: make_adder, h
depth 1 has: base, adder
depth 2 has: x

The top level .sub should start with 'new_pad 0'
The make_adder .pcc_sub should start with 'new_pad 1'
The adder .pcc_sub should start with 'new_pad 2'

I think the error happens  because I'm calling a depth 2 
function from depth 0, but if I change adder's new_pad 
depth to 1, it can't find base.

I don't know how to get this to work the way I want.
Can anyone help me out here?

(Generated code follows - note the GETS HERE line)

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--

.sub __main__
new_pad 0
setline 2
newsub $P0, .Sub, _sub0
store_lex -1, 'make_adder', $P0
.local object h
.local object arg0
arg0 = new PerlInt
arg0 = 10
find_lex $P5, 'make_adder'
newsub $P6, .Continuation, ret0
.pcc_begin non_prototyped
.arg arg0
.pcc_call $P5, $P6
ret0:
.result h
.pcc_end
store_lex -1, 'h', h
.local object arg1
arg1 = new PerlInt
arg1 = 5
find_lex $P8, 'h'
newsub $P9, .Continuation, ret1
.pcc_begin non_prototyped
.arg arg1
.pcc_call $P8, $P9
ret1:
.result $P7
.pcc_end
.arg $P7
call __py__print
print \n
end
.end
.include 'pirate.imc'


# make_adder from line 2
.pcc_sub _sub0 non_prototyped
.param object base
new_pad 1
store_lex -1, 'base', base
setline 3
newsub $P1, .Sub, _sub1
store_lex -1, 'adder', $P1
.local object res1
find_lex res1, 'adder'

pop_pad
.pcc_begin_return
.return res1
.pcc_end_return
.end

# adder from line 3
.pcc_sub _sub1 non_prototyped
print GETS HERE!\n   
new_pad 2
print WON'T GET HERE!\n  
.param object x
store_lex -1, 'x', x
.local object res0
find_lex $P2, 'base'
find_lex $P3, 'x'
$P4 = new PerlUndef
$P4 = $P2 + $P3
res0 = $P4

pop_pad
.pcc_begin_return
.return res0
.pcc_end_return
.end




repeat() not implemented in PerlInt

2003-08-06 Thread Michal Wallace


After running cvs up -d
and then make, a bunch of my
tests broke. Here's the problem
boiled down to the simplest case I
can find:


[~/pirate]: cat bug.imc
.sub __main__
$P2 = new PerlInt
$P2 = 1
$P3 = new PerlInt
$P3 = 1
if $P2 == $P3 goto cmp1
cmp1:
end
.end
[~/pirate]: imcc bug.imc
repeat() not implemented for PerlInt


What happened!? :)

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: generic code generator? [was: subroutines and python status]

2003-08-05 Thread Michal Wallace
On Sun, 3 Aug 2003, K Stol wrote:

  What do you think? Want to try squishing pirate/python
  and pirate/lua together? :)
 
 Yeah, I like the idea. Let's try this out.


Well, I finished reading your report[1] and 
posted some of my (rather unorganized) thoughts
up at [2]

It does seem like there are some snags getting
languages to talk to each other, even with the
calling conventions, but even so, I'm even more
convinced now that a generic, overridable
code-generator is the way to go. 

It seems to me that if we want to maximize the
number of languages using it, the generic 
compiler shouldn't depend on anything but 
C and parrot... But until we get it working,
I'd like to stick to a dynamic language like
python/perl/lua/scheme. And, well, my code's
already in python... :) [though I'd actually
love to try out some lua 5]

What I'm picturing is a template system for
specifying chunks of IMCC. Something like this:


ast generic:
   on @while(test, body):
   % while= gensym(while)
   % endwhile = gensym(endwhile)
   % test = gensym($I)

   {while}:
   {test} = @expr
   unless {test} goto {endwhile}
   @body
   {endwhile}:

   on @if(test, elif*, else?):
  ...

ast python(generic):
   on @while(test, body, else?):
  ...


Okay, I don't have a good syntax in mind yet,
the point is it's a template language and you
can subclass/override/extend the template. 
Maybe there's no syntax and it just uses 
cleanly coded classes in some oo language.
Or perl6 with it's grammars and rules. I
don't know.

Once the templates are defined, you pass
the compiler your AST and it walks it and
applies the template. 

So the C api basically is just about building
the tree and saying generate with this 
language file. Then the language designer's
job is just to transform an outside ast 
into a generic ast. 

Anyway, I'm talking a lot of nonsense. I'd
rather just see what I can do about decoupling
my code generator from python and sharing 
it with another language instead.

[1] lua report: http://members.home.nl/joeijoei/parrot/report.pdf
[2] http://pirate.versionhost.com/viewcvs.cgi/pirate/INTEROP?rev=1.1

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




Re: generic code generator? [was: subroutines and python status]

2003-08-05 Thread Michal Wallace
On Tue, 5 Aug 2003, Stephen Thorne wrote:

  It seems to me that if we want to maximize the
  number of languages using it, the generic
  compiler shouldn't depend on anything but
  C and parrot... But until we get it working,
  I'd like to stick to a dynamic language like
  python/perl/lua/scheme. And, well, my code's
  already in python... :) [though I'd actually
  love to try out some lua 5]
 
 I like the concept, but I have a comment about the
 implementation. For PHP, and even for Python, it is necessery to do
 code generation on the fly, for things like eval() and dynamic
 imports (php's include is always a dynamic import).

definitely.
 
 Thus the code generator is best suited to be in a language that can
 be run from within the parrot machine, otherwise statements like
 'eval()' would not be possible without binding parrot to a
 non-portable C library.

 I would instead suggest that we pick a suitable 'dynamic' language
 to write the code generator in, so it can be self-hosting.
 
Sure. That's why I said stick to C or parrot. I'm not sure
I understand why C wouldn't be portable... (I don't know c
at all but I thought that was the point)?? I'd much rather
use parrot. Where parrot means something else compiled 
down to parrot, and something else means python. :)


Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




generic code generator? [was: subroutines and python status]

2003-08-03 Thread Michal Wallace
On Fri, 1 Aug 2003, K Stol wrote:

  From: Leon Brocard [EMAIL PROTECTED]
...
  I don't like things becoming dead-ends. How much work do you think
  it'd be to extend it some more and update it to latest Lua?
...
 2: I misdesigned the code generator; that is, at the point where I
 couldn't start over, it was too late, the code generator was too big
 already (it was unmaintainable). But because I had a time schedule,
 I kept it this way (the product itself wasn't the most important
 thing, I was writing an undergraduate report for the last semester
 of my education (for the record: the project served me well, I
 finished this education))

  Would it be worth checking this into parrot CVS?

 Only if the thing would be working, otherwise it would only be a
 source of confusion and frustration.  Now I'm just thinking very
 hard to decide if I've got enough spare time to rewrite the code
 generator

Hmm. I've only messed around with Lua for a few hours
though, and it was several months ago, but the Lua 
language seems to be pretty similar to python.

Really, there's a ton of overlap between the various
high level languages that parrot wants to support.
Maybe we could put together a generic code generator
that everyone could use? Obviously, it would have to
be set up so you could override the parts for each
language, but it shouldn't be too terribly hard.

What do you think? Want to try squishing pirate/python 
and pirate/lua together? :)

Sincerely,
 
Michal J Wallace
Sabren Enterprises, Inc.
-
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--




  1   2   >