Key question

2005-07-05 Thread Klaas-Jan Stol

Hi,

currently I'm experimenting a bit with Keys. It seems that a Key *can* 
be set to a number (floating point), but that this results in a 
segfault, when using that key.


So:

.sub main
   P0 = new .Key
   P1 = new .Hash
   P2 = new .Integer
   # set the key to a number
   P0 = 1.23
   P2 = 42
   P1[P0] = P2
   end
.end

does not work. Is this behaviour to be expected (it's supposed not to 
work), or is this just not implemented yet (it will work in the future)?


Thanks,
klaas-jan





Re: Calling Super Methods

2005-07-23 Thread Klaas-Jan Stol

Leopold Toetsch wrote:


Matt Diephouse wrote:


There's currently no way to call a superclass' method. I've just run
into this and leo suggested I sent a note to the list.

Here's what I want to do:

I have a ParrotClass (a class defined in PIR) that is derived from the
String class. I want to override it's set_string_native method to do
some processing before I store the value. My first attempt was this:

.sub __set_string_native method
  .param string value
  self = value
  print "assign\n"
.end



While we haven't something like:


  self.SUPER::__set_string_native(value)



... it's still possible to call super for some methods like the 
__set_string_native, by extracting the first attribute:


.sub __set_string_native method
   .param string s
   $I0 = classoffset self, "MyClass"
   $P0 = getattribute self, $I0
   $P0 = s
.end

see also t/pmc/object-meths_30.pir (r8674)

The question ramains of course, why you should do that, as the 
inherited method just does the same, that is - just don't declare 
__set_string_native, *if* there isn't any difference in implementation.

leo


I've been in situations that you would want to call the superclass' 
constructor from the child's constructor, this is handy in situations 
that you want to add some extra things to the constructor, and you don't 
want to duplicate the code. So, in my opinion it would be handy.
A somewhat related point to this, as well as related to an earlier 
question of mine wrt implementing PMCs in PIR; is it possible to access 
the internal datastructure of the PMC in PIR? So, for example, if you 
would want to set/get the integer value of a PMC in PIR, how would you 
do that? (or will there be supporting syntax for that?)


klaas-jan

















pmc syntax

2005-07-27 Thread Klaas-Jan Stol

hi,

Is there any documentation about the complete syntax for pmc files when 
writing PMCs (this time in C)? I found genclass.pl and pmc2c.pl, but I 
couldn't find anything about all keywords that can be used. In 
particular, I wrote down some scenarios. Maybe there are some more cases 
than these.


Case 1:

pmclass Foo {

[ vtable methods here]

}

This one is simple. It just creates a new PMC class, as a superclass. If 
I understand correctly, when writing such a class, you would start with 
genclass.pl. Or, would extending "default" be ok as well?


Case 2:

pmclass Foo extends Bar {

[vtable methods here]

}

A PMC class extending from Bar. Extra vtable methods for Bar's extra 
functionality (WRT Foo), or vtable methods with different behaviour than 
Bar, must be written.


Case 3:

pmclass Foo does Bar {

[vtable methods here]

}

I don't really understand what this does. I understand the "does" 
keyword says something about an interface ("Bar") that is implemented by 
this class ("Foo"). Why would you do this? Why does one need this? I saw 
in pmc2cl.pl that there are a number of interfaces defined already. Is 
there anything written about these interfaces?



Thanks,

klaas-jan




Compiling dynamic PMCs

2005-07-28 Thread Klaas-Jan Stol

hi,

as my attempt to write a lua compiler is continuing (slowly but surely), 
and quite some stuff is working already (although rather s l o w), I 
decided it was time to write the PMCs representing the various Lua 
datatypes. I understood from my previous postings (and replies on those) 
that PMCs can be either implemented in PIR (although they are really 
created as objects, right?), or in C as .pmc files. I get the feeling 
writing them in C as .pmc files is the way to go, so I started with the 
first pmc for the lua language: LuaNil.pmc. Whenever a variable hasn't 
been assigned a value, its 'value' is "nil". (pretty much the same as 
None, I think).


According to the README file in the 'dynclasses' directory, adding 
dynamic PMCs can be done by:


1. write the PMC
2. edit parrot/config/gen/makefiles/dynclasses.in
3. make

In my case this didn't work. Editing the dynclasses.in file didn't 
trigger the make system to make my PMC.
After getting a fresh parrot, before making it, I added my pmc file, 
edited the dynclasses.in file, and started making parrot. This works (of 
course), but it's a bit cumbersome to do this everytime I'm adding a 
PMC. Anybody got an idea what may go wrong?


thanks,

klaas-jan





Re: pmc syntax

2005-07-28 Thread Klaas-Jan Stol

hi,
Will Coleda wrote:



On Jul 27, 2005, at 4:00 PM, Klaas-Jan Stol wrote:


hi,

Is there any documentation about the complete syntax for pmc files  
when writing PMCs (this time in C)?




I think that's technically the only way to write PMCs. (things  
written in PIR are Objects). And, as you've seen, pmc2c.pl is  
currently where most of this documentation lives.


yep, thanks. In a previous posting (or blog entry? I can't find it at 
this moment), I think Dan mentioned that "the plan" was to be able to 
write PMCs either in PIR or in C. Depending on the server running 
Parrot, one of both implementations would be used; sometimes it may not 
be possible to have you own custom PMCs installed, so you would have to 
use the PIR version.


But you're right, creating PMCs in PIR uses the newclass/subclass 
syntax, which makes them objects. But, if I understood correctly, they 
behave more or less the same, right? (in that case, effectively it 
wouldn't make any difference)




I found genclass.pl and pmc2c.pl, but I couldn't find anything  about 
all keywords that can be used. In particular, I wrote down  some 
scenarios. Maybe there are some more cases than these.


Case 1:

pmclass Foo {

[ vtable methods here]

}

This one is simple. It just creates a new PMC class, as a  
superclass. If I understand correctly, when writing such a class,  
you would start with genclass.pl. Or, would extending "default" be  
ok as well?




A note: genclass gives you a PMC with a *lot* of empty methods. You  
should delete all the ones that you don't actually want to override.


You don't need to extend default, that's the default if you don't  
override something.


You mean, this is done implicitly, right? (in Java terms: writing a 
"class Foo { ... }" would mean  Foo is extending "Object")




Also note that you can put in methods that don't correspond to vtables.


These would be called as... ehm... "methods" :-), right?




Case 2:

pmclass Foo extends Bar {

[vtable methods here]

}

A PMC class extending from Bar. Extra vtable methods for Bar's  extra 
functionality (WRT Foo), or vtable methods with different  behaviour 
than Bar, must be written.




Yup. Note that you can specify multiple extendees.


I don't know very much about multiple inheritance, but I do know a bit 
of C++ (not very fluently); what if you would inherit from 2 classes 
that both offer the same method?
Which one is called? (I think C++ just won't compile, but it's been some 
time I used it)





Case 3:

pmclass Foo does Bar {

[vtable methods here]

}

I don't really understand what this does. I understand the "does"  
keyword says something about an interface ("Bar") that is  
implemented by this class ("Foo"). Why would you do this? Why does  
one need this? I saw in pmc2cl.pl that there are a number of  
interfaces defined already. Is there anything written about these  
interfaces?




Does corresponds to the C opcode: there's no formal definition  
of these interfaces, so there's no concrete list: it's only a  
convention at this point. pmc2c.pl has a fairly recent list of what's  
in play, and I've updated the POD to reflect these comments below  
(some of which are WAGs).





array: container PMC with numerically-keyed elements
event: PMC that can be used with event queue
hash : container PMC with string-keyed elements
library  : PMC that corresponds to a dynamic library
ref  : PMC that references another PMC
scalar   : (only used by the sample dynclasses/foo.pmc)

I'm guessing scalar might correspond directly to things Integer,  
String, PerlNum, but no one is using that at the moment.


So, to sum up: when you use does in your PMC, you're not actually  
contractually obligated to say that the PMC is going to act a certain  
way; so, when I use does in my PASM, I'm not guaranteed anything  
other than that you put that keyword in your PMC def.


This will change later, right? Otherwise your PMC could be lying, saying 
it *does* something, which it doesn't.




Regards.


I came across another thing WRT PMC writing singleton.

Suppose I would want to have my own custom representation of "None". I 
created a class extending None, but this child class is no singleton 
anymore (I created 2 instances, compared them: they proved to be 2 
different objects). Looking in none.pmc:


  INTVAL is_equal(PMC* other) {
MMD_None: {
   return 1;
   }
MMD_DEFAULT: {
   return 0;
   }
   }
}

What should I do to have my child class be a singleton too? (just 
extending singleton as well?)


thanks for your help,
klaas-jan




[PATCH] Readme file dynclasses

2005-07-28 Thread Klaas-Jan Stol

hi,

attached a patch that changes the README file in dynclasses directory. 
The original doesn't mention you have to do "perl Configure.pl" after 
adding a new PMC file.


klaas-jan
--- README  2005-07-28 13:10:51.0 +0200
+++ README.new  2005-07-28 13:10:32.0 +0200
@@ -58,8 +58,10 @@
 =item 2
 
 Edit C<../config/gen/makefiles/dynclasses.in> and append your PMC(s) to
-the build target and:
-
+the build target. The dynclasses.in file is processed by Configure.pl to 
+create the real makefiles. So, invoke the configure script, then make:
+   
+   $ perl Configure.pl
$ make
 
 =item 3


Re: Compiling dynamic PMCs

2005-07-28 Thread Klaas-Jan Stol

Leopold Toetsch wrote:


Klaas-Jan Stol wrote:


1. write the PMC
2. edit parrot/config/gen/makefiles/dynclasses.in
3. make

In my case this didn't work.



The .in files are processed by Configure.pl to create the real files.

perl Configure.pl ...

should do it, possibly after 'make realclean'.


thanks, that works. I sent a patch to update this document a minute ago 
(it's only a minor detail, but it may help other beginning PMC writers 
and prevend this question being asked again)


kj




Re: pmc syntax

2005-07-28 Thread Klaas-Jan Stol

Leopold Toetsch wrote:


Klaas-Jan Stol wrote:

Suppose I would want to have my own custom representation of "None". 



What should I do to have my child class be a singleton too? (just 
extending singleton as well?)



None isn't a singleton. But have a look at the Null PMC or better 
env.pmc.


$ grep singletion classes/*.pmc


mmm, I looked at classes/none.pmc, this is a copy/paste:
===
#include 

static PMC * Py_None;

pmclass None singleton {

===
Maybe this is wrong?
I'll have a look at the null pmc, thanks!


(the way to create singletons might change though)


thanks for your help,
klaas-jan



leo


klaas-jan




Re: pmc syntax

2005-07-28 Thread Klaas-Jan Stol

Leopold Toetsch wrote:


Klaas-Jan Stol wrote:


mmm, I looked at classes/none.pmc, this is a copy/paste:
===
#include 

static PMC * Py_None;

pmclass None singleton {



Ah, yep - None is a singleton too - sorry for my confusion.

So it should be rather easy to subclass None, implement 
get/set_pointer and use a distinct file-static PMC* storage for your 
singleton.


leo

ah great. it works! :-). Apparently, inheriting from a singleton class 
doesn't make the child class a singleton, you have to add the 
"singleton" keyword in the class definition header.


one more question though:

1a: when are set_pointer and get_pointer actually called?
1b: in set_pointer (I copied it from None.pmc) an assertion is done. Why 
is this? (this is also part of question 1a: set_pointer is called once, 
apparently?)


void set_pointer(void* ptr) {
 assert(!Lua_Nil);
   Lua_Nil = (PMC*) ptr;
}

Anyway:

   P0 = new "LuaNil"
   print P0

prints "nil". Great! :-)

thanks.
klaas-jan



Accessing Hash with strings/keys

2005-07-29 Thread Klaas-Jan Stol

Hi,

I'm trying to extend the standard Hash PMC, if it returns "None", 
because there was no value at the specified key, then I want to override 
this behaviour by returning something else. In order to do that, I 
should know what methods are called. That's where I'm running into 
trouble. I can just do a
  
   fprintf(stderr, "");


to check if the method is called.
Now, when I do:

P0 = new .Hash
P1 = P0[42]

and

I0 = 42
P1 = P0[I0]

the method

   PMC *get_pmc_keyed_int(INTVAL)

gets called (as I would expect). So, I can just override this method, 
and if the return value of SUPER() is "None", then I return my own stuff 
("nil" to be exact). So, when I try to index the hash with a string like:


P1 = P0["hi"]

or

S0 = "hi"
P1 = P0[S0]

I would expect the method

   PMC *get_pmc_keyed_str(STRING *)

gets called. It seems to me this is not the case. The same is true for 
indexing with a PMC:


P2 = new .Key
P2 = "hello"
P1 = P0[P2]

This should call (I think)

   PMC *get_pmc_keyed(PMC *)

Well, that would be logical, right? (I can't find any other suitable 
methods in hash.pmc that could be called, because the return value 
should be a PMC)

Anybody an idea what I'm doing wrong here?

Thanks,
klaas-jan



Re: Accessing Hash with strings/keys

2005-07-31 Thread Klaas-Jan Stol

Leopold Toetsch wrote:



On Jul 29, 2005, at 10:38, Klaas-Jan Stol wrote:


Anybody an idea what I'm doing wrong here?



By far the simplest thing is either look at the opcode in 
ops/core_ops.c or use a debugger and set a breakpoint at the 
appropriate opcode, e.g.


Parrot_set_p_p_kc   (or _kic)


From ops/set.ops, I can see:

=head2 Keyed get operations: Ax = Px[ KEY ]

=item B(out PMC, in PMC, in KEY)
inline op set (out PMC, in PMC, in KEY) :base_core {
   $1 = $2->vtable->get_pmc_keyed(interpreter, $2, $3);
   goto NEXT();
}

So, whenever an instruction like "Ax = Px[KEY]" is executed, 
get_pmc_keyed() is called from the vtable of $2, in my case the Hash 
PMC. This .ops file is preprocessed to a C file, which in fact says the 
same thing:

from ops/core_ops.c, I found:

opcode_t * Parrot_set_p_p_k (opcode_t *cur_opcode, Interp * interpreter);
opcode_t *
Parrot_set_p_p_k (opcode_t *cur_opcode, Interp * interpreter)  {
#line 516 "ops/set.ops"
   PREG(1) = VTABLE_get_pmc_keyed(interpreter, PREG(2), PREG(3));
   return (opcode_t *)cur_opcode + 4;

(the same is true for Parrot_set_p_p_kc)
So, apparently, it seems to me the get_pmc_keyed method is called. I 
tried to run the Parrot Debugger (pdb), but I get this:


PackFile_unpack: Bytecode not valid for this interpreter: fingerprint 
mismatch

Parrot VM: Can't unpack packfile .//./tabletest.pbc.

So unfortunately, this doesnt' work currently (at least, here it 
doesnt'). I couldn't find any more instructions on running the pdb 
except in the docs section. Maybe I'm doing something wrong/forgetting 
something?



and step on from there

(The keyed_str variants are only used internally to avoid constructing 
key PMCs at runtime. For opcodes this isn't a problem because these 
key pmcs are created just once at PBC load tine)




Thanks,
klaas-jan



leo


klaas-jan



ANSI escape characters

2005-08-02 Thread Klaas-Jan Stol

hi,

I'm not very familiar with this, so forgive me for my ignorance with 
this. I don't know whether this issue is related to Parrot, or that it's 
something else I don't understand. I read a bit about ANSI escape codes, 
and I'm wondering if this should work in Parrot. That is, when writing 
these commands:


"\027[2J"-- ANSI clear screen
"\027[H"-- ANSI home cursor

The screen should be cleared and the cursor should be set to it's 
original position. However, when I use these codes, it doesn't work, the 
first time

I write something to the screen, I get this:

[2J[H

and after this,

[H

is displayed before the rest of the things being printed.
Again, I don't know if this is a Parrot issue, or it's me doing 
somehting wrong. Anybody got a clue?


Maybe a related issue: WHen trying to store characters like "¥" and "þ" 
in a string, it doesnt' work. I couldn't really find status info on 
strings. (should this be working already? or is it under construction)


Thanks,
klaas-jan



Re: Accessing Hash with strings/keys

2005-08-02 Thread Klaas-Jan Stol

Leopold Toetsch wrote:


Klaas-Jan Stol wrote:



Leopold Toetsch wrote:



By far the simplest thing is either look at the opcode in 
ops/core_ops.c or use a debugger and set a breakpoint at the 
appropriate opcode, e.g.




So, apparently, it seems to me the get_pmc_keyed method is called. 



Yep


.. I tried to run the Parrot Debugger (pdb), but I get this:



pdb is useless for such things - I ment of course gdb or some such 
i.e. an executable debugger.



klaas-jan



leo


Thanks for your help. I figured it out, but it was something different: 
apparently I forgot an end-of-comment marker "*/", strangely the pmc2c 
script doesnt' care about a missing "}". Oh well, it's working now as I 
expected. Thanks again!


klaas-jan



Lua project

2005-08-02 Thread Klaas-Jan Stol

Hi,
as my little project is progressing step by step, I figured it's time 
show something to the world. The current version of the Lua compiler 
targeting Parrot is 0.2.1. If people want to have a look, you can get it 
at http://members.home.nl/joeijoei/parrot. Please read the README file 
in the distribution for setting things up and getting things to work. If 
it's not working, please email me, I'll try to fix it.


However, it's far from complete (so don't expect too much of it :-), and 
not all things are working correctly, especially function calls,  (with 
variable number of arguments, return values). Simple stuff is working. 
Also, the PMCs are not complete, but have very basic functionality.


I also included the life.lua test file. It shows what kind of complex 
lua code it can already handle.


Thanks to all people answering my questions and getting me this far.
klaas-jan



Re: ANSI escape characters

2005-08-03 Thread Klaas-Jan Stol

Nick Glencross wrote:


Nick Glencross wrote:


Klaas-Jan,

'Escape' is 27 decimal, or 033 octal.

http://www.nntp.perl.org/group/perl.perl6.internals/9381
http://www.nntp.perl.org/group/perl.perl6.internals/9814

Nick



I may have been overly concise! What I meant was that \0xx notation is 
octal, and so \033 is Escape. Haven't tried the Jako example, but the 
pasm one still works!


Nick



Thanks Nick! It works :-)
I'm only wondering why Lua writes the string "\027..." to the screen, 
with the same effect. Can it have something to do with the encoding? 
(ascii, iso-8859-1, unicode)


Thanks again,
klaas-jan



Calling SUPER methods

2005-08-07 Thread Klaas-Jan Stol

Hi,

I was wondering if it is possible to call specific methods from a parent 
PMC from another method in your (child) PMC, for some other object than 
SELF.

My situation may be a bit complex, so I'll explain:

I have a LuaTable PMC, extending the Hash PMC.
I override the "add" method, because users may override the "add" method 
for Tables (which normally does not exist). These user-overriden methods
are stored in yet another LuaTable. This other LuaTable, the "metatable" 
of methods (like 'add', 'subtract', etc.) is stored as a property (setprop).


So, when trying to add 2 tables together, this is what happens:

1. "add" in LuaTable is called (because of "Px + Py")
2. while in add, check if this LuaTable (you could say "SELF") has a 
property "metatable".
3. if it has such a metatable, check if it has a field "add" (this would 
contain the user-defined add function for adding tables).

4. if is has not, give an error saying you can't add tables.


However, in step 3, the "get_pmc_keyed" method is called of this 
'metatable' PMC (which was stored as the "metatable" property). Users 
may *also* override _these_ methods (so, set/get_pmc_keyed). That would 
mean, that while handling this "add" method, another user-overriden 
method is called. This should not happen. So, what I'd like to do, is to 
call the "get_pmc_keyed" in the Hash PMC, for this 'metatable' PMC.


So, instead of doing this:

   VTABLE_get_pmc_keyed(INTERP, metatable, key);

which calls the get_pmc_keyed method of the LuaTable PMC, I'd like to 
call this get_pmc__keyed method of the Hash PMC for this metatable object.


So, something along the lines of

   SUPER.VTABLE_get_pmc_keyed(INTERP, metatable, key);
   // call "get_pmc_keyed" in the Hash PMC for the object 'metatable'

I hope my question is clear. Is there any way to do this?


[[ A somewhat related question to this is: would it be handy to add 
syntax to call an arbitrary method from a parent class? So, in pmc2c.pl, 
it says it's possible to call a method in a parent class by means of:


   SUPER(...)

but that only allows for calling the _same_ method (so, when in the 
method "add" for example, you can only call SUPER's add, not SUPER's 
subtract or something). It might be handy to be able to do something like:


   SUPER.method(...)

Or is there any other way to do this?
]]

Thanks,

klaas-jan



Re: How to add a new opcode?

2005-08-09 Thread Klaas-Jan Stol

Gerd Pokorra wrote:


For tests I want to add a new opcode to Parrot. I created a file
ops/my.ops and do the configuration and make again, but I don't find my
opcode in the file lib/Parrot/OpLib/core.pm. How to add a new opcode?
Can you give me an example.

  Gerd Pokorra

pokorra[at]uni-siegen.de



 

I think the easiest thing to do is have a look at the dynoplibs 
directory. In this directory are a few test files with user-defined ops. 
read the README file. It doesn't quite work for me as it is described 
there, but that's probably something with my path settings.


Anyhow, this works for me:

according to the readme file, type this: (in the parrot root dir, not in 
the dynoplibs directory)


   parrot$ export LD_LIBRARY_PATH=.:blib/lib
   parrot$ make -s
   parrot$ make shared
   parrot$ make -C dynoplibs

Then, I have to edit the test.pasm file in the dynoplibs directory a 
bit: instead of loading "myops_ops", I write:


   loadlib P1, "dynoplibs/myops_ops"

The same is true for the ohter loadlib instructions in the file.
And I run the test.pasm file from the parrot root dir, not from the 
dynoplibs directory. So:


   parrot$ parrot dynoplibs/test.pasm

Hope this helps,

klaas-jan



NCI: passing PMCs and using them

2005-08-22 Thread Klaas-Jan Stol

hi,

I'm currently trying to check out the NCI. As my Lua compiler only uses 
PMCs (and not I/N/S registers), calling C functions will only be done 
with PMCs.


I couldn't find info on this matter: suppose I have this string PMC, how 
can I access the actual string in it?


so, when calling:

void print_pmc(void *PMC)
{
   // how to access the string in P?
}

Thanks,
klaas-jan



Re: NCI: passing PMCs and using them

2005-08-23 Thread Klaas-Jan Stol

Leopold Toetsch wrote:


Klaas-Jan Stol wrote:



hi,

I'm currently trying to check out the NCI. As my Lua compiler only 
uses PMCs (and not I/N/S registers), calling C functions will only be 
done with PMCs.


I couldn't find info on this matter: suppose I have this string PMC, 
how can I access the actual string in it?


so, when calling:

void print_pmc(void *PMC)
{
   // how to access the string in P?
}



If it's a stringish PMC, then STRING *s = VTABLE_get_string(INTERP, 
p); will do it.


The C code is just in a .c file, it's not like a PMC or something. So, I 
don't think I can use "INTERP", or VTABLE_get_string() at all. Or should 
I link to parrotlib.a or something?
Is there some public API for accessing the fields in a PMC (for standard 
PMCs, so accessing the intval for the Integer PMC and its decendents, 
floatval for Float PMC, stringval for String PMCs, etc) ?


You might also consider switching to branches/leo-ctx5. The new 
calling conventions do auto-conversion betwen PMCs and I/S/N in both 
directions for NCI too.


Forgive my ignorance, but I don't really understand. I'm only using 
PMCs, no I/S/N values. Why would using these auto-conversions be 
interesting?



Btw, I also got this leo-ctx5 branch, compiled it, and run it from the 
directory where my lua stuff is, like this:


   $ ../leo-ctx5/parrot a.pir

it says:

   PackFile_FixupTable_unpack: Unknown fixup type 1953066601!
   PackFile_unpack segment 'FIXUP_luaglobals.pir' failed
   Segmentation fault

I got this branch by doing this: (was not sure about the command, but I 
considered this most probable)


   svn checkout http://svn.perl.org/parrot/branches/leo-ctx5

Any idea what's wrong and causing the error?

klaas-jan




[PATCH] PIR Syntax: (end)namespace

2005-08-25 Thread Klaas-Jan Stol

hi,

In the current docs of PIR, the

.namespace 
.endnamespace 

directives are not mentioned.

This patch adds a short description of both to syntax.pod.

Regards,
klaas-jan
--- syntax.pod  2005-08-08 19:44:47.0 +0200
+++ syntax_patched.pod  2005-08-25 16:02:33.0 +0200
@@ -1,4 +1,4 @@
-# Copyright: 2001-2005 The Perl Foundation.  All Rights Reserved.
+# Copyright: 2001-2005 The Perl Foundation.  All Rights Reserved.
 # $Id: syntax.pod 8745 2005-07-30 17:35:35Z chromatic $
 
 =head1 NAME
@@ -176,6 +176,29 @@
 
 Define a named constant of style I and value I.
 
+=item .namespace 
+
+Open a new scope block. This "namespace" is not the same as the 
+.namespace [  ] syntax, which is used for storing subroutines
+in a particular namespace in the global symboltable.
+This directive is useful in cases such as (pseudocode):
+
+   local x = 1;
+   print(x);   # prints 1
+   do  # open a new 
namespace/scope block
+   local x = 2;# this x hides the previous x
+   print(x);   # prints 2
+   end # close the 
current namespace
+   print(x);   # prints 1 again
+   
+All types of common language constructs such as if, for, while, repeat and such
+that have nested scopes, can use this directive.
+
+=item .endnamespace 
+
+Closes the scope block that was opened with .namespace .
+
+
 =item .namespace [  ]
 
 =item .namespace [  ;  ]


Re: [PATCH] PIR Syntax: (end)namespace

2005-08-25 Thread Klaas-Jan Stol
woops, I used tabs to indent, that gives ugly layout. Here's a NEW 
version with spaces.


regards,
klaas-jan

Klaas-Jan Stol wrote:


hi,

In the current docs of PIR, the

.namespace 
.endnamespace 

directives are not mentioned.

This patch adds a short description of both to syntax.pod.

Regards,
klaas-jan



--- syntax.pod  2005-08-08 19:44:47.0 +0200
+++ syntax_patched.pod  2005-08-25 16:02:33.0 +0200
@@ -1,4 +1,4 @@
-# Copyright: 2001-2005 The Perl Foundation.  All Rights Reserved.
+# Copyright: 2001-2005 The Perl Foundation.  All Rights Reserved.
# $Id: syntax.pod 8745 2005-07-30 17:35:35Z chromatic $

=head1 NAME
@@ -176,6 +176,29 @@

Define a named constant of style I and value I.

+=item .namespace 
+
+Open a new scope block. This "namespace" is not the same as the 
+.namespace [  ] syntax, which is used for storing subroutines

+in a particular namespace in the global symboltable.
+This directive is useful in cases such as (pseudocode):
+
+   local x = 1;
+   print(x);   # prints 1
+   do  # open a new 
namespace/scope block
+   local x = 2;# this x hides the previous x
+   print(x);   # prints 2
+   end # close the 
current namespace
+   print(x);   # prints 1 again
+   
+All types of common language constructs such as if, for, while, repeat and such
+that have nested scopes, can use this directive.
+
+=item .endnamespace 
+
+Closes the scope block that was opened with .namespace .
+
+
=item .namespace [  ]

=item .namespace [  ;  ]
 



--- syntax.pod  2005-08-25 16:13:16.0 +0200
+++ syntax_patched.pod  2005-08-25 16:13:59.0 +0200
@@ -176,6 +176,29 @@
 
 Define a named constant of style I and value I.
 
+=item .namespace 
+
+Open a new scope block. This "namespace" is not the same as the 
+.namespace [  ] syntax, which is used for storing subroutines
+in a particular namespace in the global symboltable.
+This directive is useful in cases such as (pseudocode):
+
+  local x = 1; 
+  print(x);   # prints 1
+  do  # open a new namespace/scope block
+local x = 2;  # this x hides the previous x
+print(x); # prints 2
+  end # close the current namespace
+  print(x);   # prints 1 again
+   
+All types of common language constructs such as if, for, while, repeat and such
+that have nested scopes, can use this directive.
+
+=item .endnamespace 
+
+Closes the scope block that was opened with .namespace .
+
+
 =item .namespace [  ]
 
 =item .namespace [  ;  ]


Re: [PATCH] PIR Syntax: (end)namespace

2005-08-25 Thread Klaas-Jan Stol



thanks, applied. in the future, please provide diffs relative to the
parrot base directory, it makes it easier to find the files to patch.
 


that is, I should do (for instance)

   $ diff -u imcc/docs/file.pod imcc/docs/newfile.pod > patchfile

?


also, this patch brings up an interesting point.

 .namespace 
means something totally different than
 .namespace [  ]
or
 .namespace [ ,  ]
this is a Bad Thing.
 

I think this is confusing for new people yes. (well, I would have been 
confused, if I had not known about this)


i propose we rename 
 .namespace 

to something more appropriate like
 .scope 
and change the matching
 .endnamespace 
to
 .endscope 
to better describe their function, and to prevent developer confusion. thoughts?
 


sounds good to me!


~jerry

 


klaas-jan




Re: Variable registers

2005-10-01 Thread Klaas-Jan Stol

Leopold Toetsch wrote:



On Oct 1, 2005, at 8:46, <[EMAIL PROTECTED]> wrote:



hi,

I read that with the new calling conventions, there are a variable 
number of registers. So, if I understand correctly, if a function 
call takes 2 parameters, then there are only 2, and if there are 30 
parameters, there will be a frame holding 30 registers. Is this about 
right?



Yes. The argument passing opcodes take a variable amount of registers

How does this stand WRT the 32 registers in Parrot. Is this still the 
case, or will this change as well?



This will change. Register frame size and thus the amount of registers 
will be adapted to the actual usage of a subroutine.


ah I thought so. just making sure. Then another question WRT this; will 
there be a register allocator? In other words, an attempt to minimize 
the number of needed registers? (in my simple code generator 
implementations, any time I need a new register, I just increment a 
counter, and use that, so in that case there is  No register allocation 
scheme)


regards,
klaas-jan





Re: Variable registers

2005-10-03 Thread Klaas-Jan Stol

Leopold Toetsch wrote:



On Oct 1, 2005, at 18:11, Klaas-Jan Stol wrote:

ah I thought so. just making sure. Then another question WRT this; 
will there be a register allocator? In other words, an attempt to 
minimize the number of needed registers? (in my simple code generator 
implementations, any time I need a new register, I just increment a 
counter, and use that, so in that case there is  No register 
allocation scheme)



Sure, the register allocator will remain. The "increment the counter" 
strategy is fine. The only difference will be that all lexicals and 
persistent variables, which are used around a function call, will be 
assigned to distinct Parrot registers. This strategy will solve the 
still lurking continuation bug that was discussed excessively here. 
Temps, not used around a function call, will have their registers 
reused as now.


maybe I misunderstand, but does the above mean that lexicals are stored 
in registers, instead of storing them in  scratchpads? (with lexicals 
being local variables in a function, with the addition of being also 
accessible from nested functions)


klaas-jan




Software Architecture of Parrot

2005-10-04 Thread Klaas-Jan Stol

Hi,

Currently I'm doing a course 'Software Architecture' for my Master 
Computer Science. For this course, I have to write a paper on some 
subject that has to do with software architecture. Therefore, I proposed 
to write a paper on the architecture of Parrot, and today I got approval 
of this subject from my Professor :-).


The idea of the paper is to describe the architecture of the current 
state of Parrot, and maybe some future plans. It should be about 5 to 10 
pages long, but I expect to write about 15-20. I'd like to start with 
the reasons for writing Parrot (why not an existing VM), and continue 
with design decisions for all the main components (so for instance, why 
not ref.counting-GC, but a DOD/GC.)


Maybe, if the document is ready, it may be a good introduction for new 
people interested in Parrot. I'm looking forward to writing it, 
especially I can finally do something in return for all the help I 
already got (I wrote my Bachelor thesis on Lua/Parrot).


Of course, it may turn out that some information I collect is outdated 
or I misinterpreted it. I hope some of you are willing to proof-read it, 
as it develops, to prevent incorrect information in the paper.


Kind regards,

Klaas-Jan







Paper Software Architecture 1: started writing

2005-10-18 Thread Klaas-Jan Stol

Hi all,

Some weeks ago, I announced my plans for writing a paper on the 
archtecture of Parrot. In the mean time, I made a start, and more or 
less defined the structure of the article. It's an initial draft, so 
nothing definite yet. Also, as it's a really early draft, not much too 
read. However, it gives an overview of the paper as I 'm planning it, 
and if you're interested, you can find it at:


http://members.home.nl/joeijoei/parrot/paper.pdf

(next 'releases' will be more complete, and less cluttered with 'notes 
to self')


If you read it, and you think: what is he talking about, please give me 
an email and I can change things. As it is kinda hard to describe 
something that (1) isn't finished (in other words, I don't know exactly 
*what* the design is), and (2) didn't design myself, I may draw wrong 
conclusions, or give false information. I hope to write something that 
may be of use, also in the future.


Thanks for your attention,
klaas-jan


Paper Software Architecture 1: started writing

2005-10-18 Thread Klaas-Jan Stol

Hi all,

Some weeks ago, I announced my plans for writing a paper on the 
archtecture of Parrot. In the mean time, I made a start, and more or 
less defined the structure of the article. It's an initial draft, so 
nothing definite yet. Also, as it's a really early draft, not much too 
read. However, it gives an overview of the paper as I 'm planning it, 
and if you're interested, you can find it at:


http://members.home.nl/joeijoei/parrot/paper.pdf

(next 'releases' will be more complete, and less cluttered with 'notes 
to self')


If you read it, and you think: what is he talking about, please give me 
an email and I can change things. As it is kinda hard to describe 
something that (1) isn't finished (in other words, I don't know exactly 
*what* the design is), and (2) didn't design myself, I may draw wrong 
conclusions, or give false information. I hope to write something that 
may be of use, also in the future.


Thanks for your attention,
klaas-jan


Re: Paper Software Architecture 1: started writing

2005-10-19 Thread Klaas-Jan Stol

Hi,
first of all, thanks for reading! :-)
Most things I wrote so far, I got from several sources, like the Parrot 
FAQ.


Joshua Hoblitt wrote:


   This is because Parrot is implemented in C,
   while developing a large program such as this could well
   have been done in C++. This is for three reasons:

 1. C is available everywhere
 2. there is a large pool of C programmers
 3. other languages are not fast enough

I think you've missed the most important reason as to why any project
would be implemented in C and not C++.  C++ is still not as portable
between implementations as C (but it's gotten a lot better).  I'm sure
Chip has some strong feelings on this point. ;)
 

These reasons are on the Parrot FAQ. But I think it's an important point 
you mentioned.



  3 For instance, C is not suitable for creating an object oriented
design.

I partially disagree with that. As examples: The first C++ 'compliers'
emitted C code, Linux kernel Kobjects, and Glib objects.  Sure
polymorphism is hard in C (by definition, an OO language supports
polymorphism) but many simpler OO techniques are easily accessible in
C.
 

Yes, I think you're right a bit. However, if polymorphism and 
inheritence are available, I think one would actually use it too in the 
design (I'm not *that* familiar with the run-core, but I believe there 
is at least an switch/case implementation (I think it's the "slow" 
core), and this just _asks_ for a polymorphic implementation (on first 
sight, anyway))



   Intensive CPU users; these users care most about
   performance, and not about Parrot internals or space
   usage. Compatibility is important, as these users are
   likely to use a particular (favorite) feature set.

I disagree with that too.  Most HPC users don't really care about
compatibility (there are exceptions, like users that are dependent on
Fujitsu's compiler extensions so Fujitsu continues to it's niche
compiler series).  An example of this is that the Itanic manages to sell
into this market space.
 

I got this point from the "model_users.pod" by Chip (got it from planet 
parrot). I think his point is that power users use a particular feature 
set, and so they are interested that this feature set is still available 
in new versions. But I think I can rewrite that part (I think I should 
rewrite most of it anyway, it's only a first draft)



Cheers,

-J
 

Thanks for reading! Next versions will be more complete, not as hacky as 
this one.

klaas-jan



Components of Parrot

2005-11-30 Thread Klaas-Jan Stol

Hello,

Some time ago, I announced I would be writing a paper on the 
architecture of Parrot. The paper will be about 10 pages (I think, at 
this point), so there will be quite a high level of abstraction in order 
to be able to fit all important info. (so no "class" diagrams, if one 
could even speak of classes, but more "components", or (black) boxes 
that have some functionality).


Anyway, the structure will be more or less as follows (very global, for 
details, the interested reader can refer to the paper, which is at
http://members.home.nl/joeijoei/parrot/paper.pdf , only 4 pages 
currently, including references, and section headers):


the sections are:

-introduction *
-motives for Parrot *
-stakeholders *
-requirements *
-architecture overview
-main components -> some sections, each one on a different important 
component, for example, a section on the Garbage Collector
-other features (things that I can't fit or are architecturally speaking 
not very significant/interesting)

-summary

The *'ed items are more or less complete, but will be subject to 
reviewing later on.


Now, I'm at the "architecture overview". In this section, I'd like to 
give a picture of what Parrot looks like from 10 miles in the sky.
So, what main components are there, and, very important, what are the 
mutual relations between those components.


As said, in the sections after that, I'll talk about a number of these 
components that have interesting design decisions, such as the Parrot 
core (i.e. why registers, and not stack oriented, data types, why not 
PMC and Strings unified?, that kind of stuff), the garbage collector 
(why not ref.counting, etc.), threads (how implemented, OS, or some library)
Luckily, a lot of that stuff is documented *somewhere* in the docs or 
can be retrieved in the mailing list.


Now, my question is, are there any docs describing, or containing 
pictures, of these main components of Parrot? (I'm talking about a 
picture containing boxes, with lines of interaction between them). For 
example, the part of Parrot running the actual opcodes would be a box, 
(this is the engine), and it would have interaction with the registers 
(themselves being represented by a box "registers" or something like 
that). Then there is a box "heap" memory or something (would there 
be??), and a box called Garbage collector having interaction with that 
memory.


I vaguely remember a dependency graph which was generated, and could be 
found on the Parrot Wiki (IIRC). Maybe something like that could be of 
help too (the wiki is down, last time I checked). Of course, I would 
very much like to include some graphics, which helps the reader to see 
how Parrot is constructed of "components" with certain functionality.


Anyway, help of any kind (pointers to docs, or whatever) would be 
greatly appreciated :-),


kind regards,

klaas-jan




Re: [perl #37815] Tcl: implement [flush]

2005-12-02 Thread Klaas-Jan Stol

Hi, attached a patch with a start on the implementation of flush.pir

Note that ParrotIO.pmc doesn't seem to have a method to find out what 
mode it is opened in, so that check cannot be done.


regards,
kj

Will Coleda (via RT) wrote:

# New Ticket Created by  Will Coleda 
# Please include the string:  [perl #37815]
# in the subject line of all future correspondence about this issue. 
# https://rt.perl.org/rt3/Ticket/Display.html?id=37815 >




File:
  languages/tcl/lib/builtins/flush.pir (exists, stub)
Spec:
  http://www.tcl.tk/man/tcl8.5/TclCmd/flush.htm
Tests:
  languages/tcl/t/cmd_flush.t (doesn't exist)
Implementation:
 lookup the named channel in _Tcl::channels and use the flush method  
on the ParrotIO pmc.

See Also:
 languages/tcl/lib/builtins/howto.pod


 



--- flush.pir   2005-12-02 19:44:27.0 +0100
+++ flushpatch.pir  2005-12-02 19:33:39.0 +0100
@@ -7,6 +7,93 @@
   .param int register_num
   .param pmc argv
 
-  .return(register_num,'')
+  .local string pir_code, temp_code
+  pir_code = ""
+  temp_code = ""
+  
+  # get number of arguments and check
+  .local int argc
+   argc = argv
+  if argc != 1 goto args_miscount
+
+  # number of args is ok
+
+  # generate code that checks for the specified channel:
+  # get the channel specified to be flushed
+
+  .local pmc compiler, value
+  compiler = find_global "_Tcl", "compile_dispatch"
+  .local int value_num
+  value = argv[0]
+  (value_num, temp_code) = compiler(value, register_num)
+  pir_code .= temp_code
+  register_num = value_num + 1
+  $S0 = register_num
+  pir_code .= "$P"
+  pir_code .= $S0
+  pir_code .= "=$P"
+  $S0 = value_num
+  pir_code .= $S0
+  pir_code .= "\n"
+  temp_code = ".local string channel_id\n"
+  temp_code .= "channel_id = $P"
+  $S0 = register_num
+  temp_code .= $S0
+  pir_code .= temp_code
+
+  
+  pir_code .= <<"END_PIR"
+  # keep this comment, we need a newline!
+  # generate code for accessing the "channels" variable in ParTcl 
+  .local pmc channels, channel
+  channels = find_global "_Tcl", "channels"
+
+  # find the specified channel
+  channel = channels[channel_id]
+
+  # check whether the channel is found
+  unless_null channel, do_flush
+  #
+  # channel is not found;
+  # throw an exception
+  .local string msg
+  msg = "can not find channel named \\\""
+  msg .= channel_id
+  msg .= "\\\""
+  .throw(msg)
+END_PIR
+
+  pir_code .=<<"END_PIR"  
+do_flush:
+  # check whether it was opened for writing
+  # XXX TODO -- Seems like ParrotIO.pmc doesn't have support for this
+
+  # everything ok, flush it
+  channel."flush"()
+
+  # return an empty string
+  .local pmc retval
+  retval = new .TclString
+  retval = ""
+  .return(retval)
+END_PIR
+
+  .return(register_num, pir_code)
+
+channel_not_write_mode:
+  pir_code=<<"END_PIR"
+  .local string msg
+  msg = "channel \""
+  msg .= channel_id
+  msg .= "\" wasn't opened for writing"
+  .throw(msg)
+END_PIR
+
+.return(register_num, pir_code)
+
+args_miscount:
+  pir_code = ".throw(\"wrong # args: should be flush \\\"channelId\\\"\")\n"
+  .return(register_num, pir_code)
+
 .end
 


[PATCH] .lex syntax in PIR docs (imcc)

2005-12-05 Thread Klaas-Jan Stol

hi,

attached is a patch that adds the new ".lex" syntax. The description is 
copy/paste from PDD20.


regards,
klaas-jan
--- imcc/docs/syntax.pod2005-12-05 19:49:30.0 +0100
+++ imcc/docs/syntax2.pod   2005-12-05 20:15:53.0 +0100
@@ -207,6 +207,25 @@
 them with commas:
   .sym int i, j
 
+=item .lex , 
+
+Declare a lexical variable that is an alias for a PMC register. The 
+PIR compiler calls this method in response to a .lex STRING, PREG 
+directive. For example, given this preamble:
+
+.lex "$a", $P0
+$P1 = new Integer
+
+These two opcodes have an identical effect:
+
+$P0 = $P1
+store_lex "$a", $P1
+
+And these two opcodes also have an identical effect:
+
+$P1 = $P0
+$P1 = find_lex "$a"
+
 =item .const   = 
 
 Define a named constant of style I and value I.


Global storage access

2005-12-05 Thread Klaas-Jan Stol

hi,

if I understood correctly, the global storage is implemented as a hash 
table.

If so, will it be possible to load this global hash table in a P register?

So, for example, are there any plans to support this:

   $P0 = get_globals # put a reference to the global storage into 
register $P0


and
  
   set_globals $P0 # set the hash table referenced by $P0 as the global 
storage.


regards,

klaas-jan


Re: Global storage access

2005-12-06 Thread Klaas-Jan Stol

Leopold Toetsch wrote:



On Dec 5, 2005, at 21:58, Klaas-Jan Stol wrote:


hi,

if I understood correctly, the global storage is implemented as a 
hash table.
If so, will it be possible to load this global hash table in a P 
register?



It is possible right now. See the introspection interface of the 
interpreter:

 perldoc classes/parrotinterpreter.pmc

interp = getinterp
glob_hash = interp['globals']


great! thanks, seems I didn't look in the right place then.

You can't replace the globals hash but all manipulations of the hash 
are currently allowed.


kjs


Strange behaviour of PIR register $P0 vs others

2005-12-18 Thread Klaas-Jan Stol

Hi,

I get some strange behaviour in the attached code snippet.
The problem is with the lines marked with a '*'. If the global 'r' is 
stored into $P0,
and in the second marked line it is called, the output of the print 
statements furhter below

is:

Lua_Proto_2_0
2

instead of the expected

1
2

Now, if I change the register from $P0 to, say, $P10 (in both marked 
lines), I do get

the expected results. (the code is generated, so somewhat inefficient)

I don't understand really the difference between $P0 and $P10, this 
shouldn't make any difference, should it?

I just got a fresh Parrot, shouldn't be the problem here)

thanks,

klaas-jan



.sub _LuaMain :main
   LuaProto_1_0()
   end
.end


.sub LuaProto_1_0
   .lex 'p', $P0
   .lex 'q', $P1
   $P0 = new .Float
   $P0 = 1
   $P1 = new .Float
   $P1 = 2
   $P2 = find_name 'LuaProto_2_0'
   $P2 = newclosure $P2
   global 'r' = $P2
*$P0 = global 'r'
*($P10,$P11) = $P0()
   global 'b' = $P11
   global 'a' = $P10
   $P1 = global 'a'
   $P2 = global 'b'
   print $P1
   print "\n"
   print $P2
   print "\n"
.end

.sub LuaProto_2_0 :outer(LuaProto_1_0) :lex
   find_lex $P0, 'p'
   find_lex $P1, 'q'
   .return($P0,$P1)
.end


Threading PDD?

2005-12-23 Thread Klaas-Jan Stol

Hi,

I'm wondering, is there a PDD about Thread implementation in Parrot? I 
searched the list archive, and found a lot of info. Dan even mentioned 
writing a PDD on the subject, but I havent' been able to find it.


Thanks,
klaas-jan


Event system implementation

2006-01-04 Thread Klaas-Jan Stol

Hi,
As you know, I'm currently busy writing a paper on the architecture of 
Parrot, and during my attempt to describe the exception sub-system, 
something came to mind. I'm not sure if the event system is fully 
operational (I thought it was already implemented), but I do know the 
plan was to check at a regular base if there were any events generated. 
So, instead of checking after each opcode if an event is pending, this 
is done every few opcodes in order to safe

time.

So, this brings the danger of introducing delays between sending an 
event, and their handling (I'm sure this delay is not that bad, but still).
Then, I remembered, if an exception is thrown, this is handled 
immediately by the exception handler (the one the user should have 
pushed onto the control stack). So, exceptions are handled immediately, 
while events are not.


Of course, I'm no expert in these things, so please correct me if I'm 
wrong. But I'm wondering, why the event system hasn't been implemented 
this way, as an event also has an event handler (just like an exception 
has an exception handler). (I'm sure there are a lot of implementation 
details involved, but I'm talking about the big picture here; making 
sure events are handled immediately).


Thanks in advance for reading this,

klaas-jan


Event sub-system implementation

2006-01-04 Thread Klaas-Jan Stol

Hi,
As you know, I'm currently busy writing a paper on the architecture of 
Parrot, and during my attempt to describe the exception sub-system, 
something came to mind. I'm not sure if the event system is fully 
operational (I thought it was already implemented), but I do know the 
plan was to check at a regular base if there were any events generated. 
So, instead of checking after each opcode if an event is pending, this 
is done every few opcodes in order to safe

time.

So, this brings the danger of introducing delays between sending an 
event, and their handling (I'm sure this delay is not that bad, but still).
Then, I remembered, if an exception is thrown, this is handled 
immediately by the exception handler (the one the user should have 
pushed onto the control stack). So, exceptions are handled immediately, 
while events are not.


Of course, I'm no expert in these things, so please correct me if I'm 
wrong. But I'm wondering, why the event system hasn't been implemented 
this way, as an event also has an event handler (just like an exception 
has an exception handler). (I'm sure there are a lot of implementation 
details involved, but I'm talking about the big picture here; making 
sure events are handled immediately).


Thanks in advance for reading this,

klaas-jan


Paper on Parrot [2]

2006-01-06 Thread Klaas-Jan Stol

Hello,

Some time ago I announced to be writing a paper on the architecture of 
Parrot. It's not completely finished, but most things are in. If you are 
interested, you can read it at


http://members.home.nl/joeijoei/parrot/paper.pdf

It proved a bit harder than I had expected, and a bit more work.
I hope it's worthwhile to read. I'll be finishing it this weekend. If 
you read it and think to see incorrect information, please inform me. 
(most information is from mailing lists, docs and Perl6 essentials 2nd 
ed., so some info could be out-of-date)


Kind regards,

Klaas-Jan Stol


Lua2PIR translator

2006-01-10 Thread Klaas-Jan Stol

Hi,

As you know, I've been playing with Lua for some time now, and my 
attempt to write a Lua compiler targetting Parrot has not been 
completely unsuccessful, but it was quite some work.


Anyway, at some point I realized that PIR looks very much like Lua 
bytecodes (which I had inspected at that time already). So, I thought it 
may be a nice project to write a Lua2PIR translator, which takes a 
binary Lua file (compiled with the Lua compiler, so you'll need to get 
Lua (to be found at www.lua.org))


If you are interested, it can be found at

   http://members.home.nl/joeijoei/lua2pir/

It works pretty good. It needs still many tests, in order to check if 
all special cases are covered, but quite complex examples do work 
already. Furthermore, the Lua PMCs have to be integrated, as it just 
uses the Parrot basic types (Float, String, Hash, etc). It's also nice 
to see what kind of code the Lua compiler should more or less be generating.


Kind regards,

Klaas-Jan Stol





declaration of 'clone'

2006-01-12 Thread Klaas-Jan Stol

Hi,

I'm trying to implement some functions into the Lua PMCs, but I'm having 
trouble to compile them.


I want to add a clone method to the LuaNil PMC (which should extend 
Null.pmc, not None.pmc, as it does currently; changed that already)


However, I get the following error:

luanil.c:343: error: conflicting types for `clone'
/usr/include/bits/sched.h:72: error: previous declaration of `clone'
compile luanil.c failed (256)
make: *** [pmcs] Error 2

It seems the compiler finds another function called "clone", which has 
nothing to do with Parrot:


   /* Definitions of constants and data structure for POSIX 1003.1b-1993
  scheduling interface.
  Copyright (C) 1996-1999,2001,2002,2003 Free Software Foundation, Inc.
  This file is part of the GNU C Library.

regards,
klaas-jan


Re: declaration of 'clone'

2006-01-13 Thread Klaas-Jan Stol

Joshua Hoblitt wrote:


On Thu, Jan 12, 2006 at 04:53:26PM +0100, Leopold Toetsch wrote:
 


Klaas-Jan Stol wrote:
   


Hi,

I'm trying to implement some functions into the Lua PMCs, but I'm having 
trouble to compile them.


I want to add a clone method to the LuaNil PMC (which should extend 
Null.pmc, not None.pmc, as it does currently; changed that already)


However, I get the following error:

luanil.c:343: error: conflicting types for `clone'
/usr/include/bits/sched.h:72: error: previous declaration of `clone'
compile luanil.c failed (256)
 

clone is a standardized vtable function. But it's name is never a bare 
'clone', it's always prefixed by 'Parrot__. This is also true 
for


 METHOD PMC* clone()  # dunno if that works, if vtable exists

You must have some bug in your PMC code.
   



On Linux clone() is a syscall with a wraper function in the the standard
library that is defined in sched.h.  On my laptop types.h includes
pthreadtypes.h which includes sched.h.  You should *probably* use a
different function name. ;)

-J

 

I got the bug already, thank! (stupid error in PMC file) Works perfectly 
now.

-kj


[PATCH] Add new_from_string() to LuaNumber (was: Re: .const & HLL improvement)

2006-01-13 Thread Klaas-Jan Stol






.const .LuaNumber n = "12.34"



I presume LuaNumber doesn't have new_from_string (Float hasn't either).


Attached is a patch that implements new_from_string() for LuaNumber.
In my opinion it's handy to say:

.const .LuaNumber n = "12.34"

kind regards,

klaas-jan



--- languages/lua/classes/luanumber.pmc 2006-01-13 13:58:04.0 +0100
+++ languages/lua/classes/newluanumber.pmc  2006-01-13 14:02:49.0 
+0100
@@ -67,6 +67,31 @@
 return 1;
 }
 
+/*
+
+=item C
+
+Return a LuaNumber PMC created from a string. Implementation
+is based on new_from_string() from Integer PMC.
+
+=cut
+
+*/
+
+PMC* new_from_string(STRING *rep, INTVAL flags) {
+INTVAL type;
+PMC *res;
+
+type = SELF->vtable->base_type;
+if (flags & PObj_constant_FLAG)
+res = constant_pmc_new(INTERP, type);
+else
+res = pmc_new(INTERP, type);
+
+PMC_num_val(res) = string_to_num(INTERP, rep);
+return res;
+}
+
 }
 
 /*


[PATCH] changes for LuaNil

2006-01-13 Thread Klaas-Jan Stol
This patch changes LuaNil PMC, it used to be a singleton, this patch 
makes it a normal PMC.
some other methods are implemented for morphing into other Lua types 
(LuaString, LuaNumber, LuaBoolean).


regards,
klaas-jan
--- languages/lua/classes/luanil.pmc2006-01-13 16:34:42.0 +0100
+++ languages/lua/classes/newluanil.pmc 2006-01-13 16:37:36.0 +0100
@@ -1,130 +1,184 @@
-/*
-Copyright: 2005 The Perl Foundation.  All Rights Reserved.
-$Id: luanil.pmc 10933 2006-01-06 01:43:24Z particle $
-
-=head1 NAME
-
-classes/luanil.pmc - Lua Nil
-
-=head1 DESCRIPTION
-
-C extends C to provide a class with the behaviour of
-the Lua C value.
-
-=head2 Overloaded Methods
-
-=over 4
-
-=cut
-
-*/
-
-#include "parrot/parrot.h"
-
-static STRING *string_representation;
-static PMC *Lua_Nil;
-
-pmclass LuaNil
-singleton
-extends None
-dynpmc
-group lua_group
-hll Lua {
-
-/* Class initialization. Caches constant strings that will be used later.
-*/
-void class_init() {
-if (pass) {
-string_representation = const_string(INTERP, "nil");
-}
-}
-
-/*
-
-=item C
-
-Return the string "nil".
-
-=cut
-
-*/
-STRING* name () {
-return string_representation;
-}
-
-/*
-
-=item C
-
-Return the string "nil".
-
-=cut
-
-*/
-STRING* get_string () {
-return string_representation;
-}
-
-/*
-
-=item C
-
-Return the string "nil".
-
-=cut
-
-*/
-STRING* get_repr () {
-return string_representation;
-}
-
-/*
-
-=item C
-
-=item C
-
-These two functions are part of the singleton creation interface. For more
-information see F.
-
-=cut
-
-*/
-void* get_pointer() {
-return Lua_Nil;
-}
-
-void set_pointer(void* ptr) {
-Lua_Nil = (PMC*)ptr;
-}
-
-/*
-
-=item C
-
-Return always true.
-
-=cut
-
-*/
-PMC* logical_not (PMC* dest) {
-if (!dest)
-dest = pmc_new(INTERP, Parrot_PMC_typenum(INTERP, "LuaBoolean"));
-VTABLE_set_integer_native(INTERP, dest, 1);
-return dest;
-}
-
-}
-
-/*
-
-=back
-
-=head1 AUTHORS
-
-Original code by Klaas-Jan Stol.
-
-=cut
-
-*/
-
+/*
+Copyright: 2005 The Perl Foundation.  All Rights Reserved.
+$Id: luanil.pmc 10933 2006-01-06 01:43:24Z particle $
+
+=head1 NAME
+
+classes/luanil.pmc - Lua Nil
+
+=head1 DESCRIPTION
+
+C provides a class with the behaviour of the Lua C value.
+Implementation is based on the Undef PMC. LuaNil is no longer a singleton;
+this would be a problem, as all uninitialized values in Lua are LuaNil.
+If some value is assigned, the LuaNil should morph into the correct type,
+and so a new PMC is constructed anyway. Therefore, we may as well create
+a new PMC right away. Also, creating a new PMC from a singleton class is
+troublesome (if not possible?).
+
+
+
+=head2 Overloaded Methods
+
+=over 4
+
+=cut
+
+*/
+
+#include "parrot/parrot.h"
+
+static STRING *string_representation;
+static INTVAL dynclass_LuaNumber;
+static INTVAL dynclass_LuaString;
+static INTVAL dynclass_LuaBoolean;
+
+pmclass LuaNil   
+dynpmc
+group lua_group
+hll Lua {
+
+/* 
+* Class initialization. Caches constant strings that will be used later.
+*/
+void class_init() {
+if (pass) {
+string_representation = const_string(INTERP, "nil");
+   dynclass_LuaNumber = Parrot_PMC_typenum(INTERP, "LuaNumber");
+   dynclass_LuaString = Parrot_PMC_typenum(INTERP, "LuaString");
+   dynclass_LuaBoolean = Parrot_PMC_typenum(INTERP, "LuaBoolean");
+}
+}
+
+/*
+
+=item C
+
+Return the string "nil".
+
+=cut
+
+*/
+STRING* name () {
+return string_representation;
+}
+
+/*
+
+=item C
+
+Return the string "nil".
+
+=cut
+
+*/
+STRING* get_string () {
+return string_representation;
+}
+
+
+
+   
+
+
+/*
+
+=item C
+
+Return the string "nil".
+
+=cut
+
+*/
+STRING* get_repr () {
+return string_representation;
+}
+
+
+PMC* clone () {
+PMC* dest = pmc_new(INTERP, SELF->vtable->base_type);
+memcpy(&PMC_union(dest), &PMC_union(SELF), sizeof(UnionVal));
+return dest;
+}
+
+
+
+/*
+
+=item C
+
+Return always true.
+
+=cut
+
+*/
+PMC* logical_not (PMC* dest) {
+if (!dest)
+dest = pmc_new(INTERP, dynclass_LuaBoolean);
+VTABLE_set_integer_native(INTERP, dest, 1);
+return dest;
+}
+
+/*
+
+=item C
+
+"nil" in Lua is always undefined.
+
+=cut
+
+*/
+INTVAL defined() {
+return 0;
+}
+
+/*
+
+=item C
+
+=item C
+
+=item C
+
+Methods to set a new value to this LuaNil PMC. First,
+this PMC is morph'ed into the correct Lua type.
+
+=item C
+
+Morph to another Lua type.
+
+=cut
+
+*/
+void set_number_native(FLOATVAL value) {
+VTABLE_morph(INTERP, SELF, dynclass_LuaNumb

[PATCH] Changes for LuaTable

2006-01-13 Thread Klaas-Jan Stol

this patch changes the behaviour of the LuaTable PMC.
changes have to do with the reference semantics that PMCs have, and 
LuaTables should not have.


Setting and getting a value now will set (and get) a copy of the value.

Clone() returns a reference to itself, as clone() should be used for 
register to register copying (due to the by-value semantics of Lua values)


regards,
klaas-jan
--- languages/lua/classes/luatable.pmc  2006-01-13 16:34:42.0 +0100
+++ languages/lua/classes/newluatable.pmc   2006-01-13 16:37:42.0 
+0100
@@ -68,6 +68,31 @@
 return Parrot_sprintf_c(INTERP, "table: %08X", SELF);
 }
 
+
+/*
+
+=item C
+
+PMCs are always handled by-reference in Parrot. So, copying register contents 
only copies 
+the reference to the PMC. For LuaString, LuaNumber, LuaBoolean, this is not 
correct,
+as Lua has by-value semantics for these types. In order to be able to handle 
register
+"move" instructions, this should be implemented using clone(). However, 
LuaTable and LuaFunction
+do have by-reference semantics. As you don't know the type during compile-time 
of an object,
+just always use clone() to copy register contents. LuaTable and LuaFunction 
should therefore
+only clone the reference to themselves, not make a deep copy.
+
+=cut
+
+*/
+
+ PMC* clone() {
+ return SELF;
+ }
+
+
+
+
+
 /*
 
 =item C
@@ -90,6 +115,13 @@
 
 C accessor.
 
+A copy of the value is retrieved, otherwise, this could happen:
+
+   temp = table[key]
+   temp = 
+   temp2 = table[key]
+   # temp2 is now  due to the by-reference semantics of 
PMCs
+
 =cut
 
 */
@@ -97,9 +129,10 @@
 PMC *retval = SUPER(key);
 
 if (enum_class_None == retval->vtable->base_type) {
-return Lua_Nil;
+return Lua_Nil; /* should we create a New LuaNil object every 
time? Or is returning the same LuaNil over and over again ok? */
 }
-return retval;
+   PMC *newcopy = retval->vtable->clone(INTERP, retval);
+return newcopy;
 }
 
 /*
@@ -108,22 +141,36 @@
 
 C mutator.
 
+A copy of the value is stored, otherwise, this could happen:
+ 
+   table[key] = value
+   value = 
+   temp = table[key]
+   # temp is now  due to the by-reference semantics of 
PMCs
+
 =cut
 
 */
 void set_pmc_keyed (PMC* key, PMC* value) {
-if (key == Lua_Nil) {
+
+   /* XXX should check for "isa", not equality with "==", since LuaNil is 
no singular anymore */
+
+   if (key == Lua_Nil) {
 real_exception(INTERP, NULL, 1, "table index is nil");
 }
+   
 if (value == Lua_Nil) {
 Hash.SELF.delete_keyed(key);
-} else {
-SUPER(key, value);
+} 
+   else {
+ 
+ PMC *newcopy = value->vtable->clone(INTERP, value);
+  SUPER(key, newcopy);
 }
 }
 
 /*
-
+0
 =item C
 
 Return always false.
@@ -150,6 +197,8 @@
 return (PMC*)0;
 }
 
+/* TODO: Implement the Metamethod mechanism, see the Lua ref.man. */
+
 PMC* subtract (PMC* value, PMC* dest) {
 return (PMC*)0;
 }


Qs WRT params: flags using get_params and .param notation

2006-01-15 Thread Klaas-Jan Stol

hi,

I have 2 questions wrt PIR parameter notation and usage.

I'm not quite sure how I should specifiy the flags when using 
get_params, instead of the .param notation.
according to PDD03, flag "3" is for specifiying slurpy parameters. 
Should I type:


   get_params "(3)", $P0

to say $P0 is a slurpy array?
(this doesn't work).

Also, according to the syntax docs of PIR, it should be possible to write:
(taken from: http://www.parrotcode.org/docs/imcc/syntax.html)

   .param $P0 

so, using registers, not names. This does not work currently, but it's 
in the docs. Should it be working?


regards,
klaas-jan






Parrot link failure imc_yyin_set/get

2006-01-16 Thread Klaas-Jan Stol

Hi,
since yesterday, Parrot breaks during compiling, with the following output:

c++ -o miniparrot -L/usr/local/lib -Wl,-E   compilers/imcc/main.o \
-Wl,-rpath=/home/klaas/parrot/blib/lib -L/home/klaas/parrot/blib/lib 
-lparrot  -lnsl -ldl -lm -lcrypt -lutil -lpthread -lrt -lgmp 
src/null_config.o

compilers/imcc/main.o(.text+0xd85): In function `main':
compilers/imcc/main.c:494: undefined reference to `imc_yyin_set'
compilers/imcc/main.o(.text+0xe03):compilers/imcc/main.c:504: undefined 
reference to `imc_yyin_set'
compilers/imcc/main.o(.text+0xfcf):compilers/imcc/main.c:551: undefined 
reference to `imc_yyin_get'
compilers/imcc/main.o(.text+0x1125):compilers/imcc/main.c:580: undefined 
reference to `imc_yyin_get'
compilers/imcc/main.o(.text+0x118b):compilers/imcc/main.c:591: undefined 
reference to `imc_yyin_get'

collect2: ld returned 1 exit status
gmake: *** [miniparrot] Error 1
[EMAIL PROTECTED]:~/parrot$

imc.c is compiled, and the Makefile looks ok too.
regards,
klaas-jan



Re: Parrot link failure imc_yyin_set/get

2006-01-16 Thread Klaas-Jan Stol

Klaas-Jan Stol wrote:


Hi,
since yesterday, Parrot breaks during compiling, with the following 
output:


c++ -o miniparrot -L/usr/local/lib -Wl,-E   compilers/imcc/main.o \
-Wl,-rpath=/home/klaas/parrot/blib/lib -L/home/klaas/parrot/blib/lib 
-lparrot  -lnsl -ldl -lm -lcrypt -lutil -lpthread -lrt -lgmp 
src/null_config.o

compilers/imcc/main.o(.text+0xd85): In function `main':
compilers/imcc/main.c:494: undefined reference to `imc_yyin_set'
compilers/imcc/main.o(.text+0xe03):compilers/imcc/main.c:504: 
undefined reference to `imc_yyin_set'
compilers/imcc/main.o(.text+0xfcf):compilers/imcc/main.c:551: 
undefined reference to `imc_yyin_get'
compilers/imcc/main.o(.text+0x1125):compilers/imcc/main.c:580: 
undefined reference to `imc_yyin_get'
compilers/imcc/main.o(.text+0x118b):compilers/imcc/main.c:591: 
undefined reference to `imc_yyin_get'

collect2: ld returned 1 exit status
gmake: *** [miniparrot] Error 1
[EMAIL PROTECTED]:~/parrot$

imc.c is compiled, and the Makefile looks ok too


correction: it seems the file "imc.o" is not linked at the Parrot and 
Miniparrot targets in the Makefile

(line ~800).

regards,
klaas-jan



Q: Keys can be strings/ints only?

2006-01-20 Thread Klaas-Jan Stol

Hi,

I tried to index aggregates using several types of keys (that is, 
several types of values), and it seems only string and integer values 
can be used as keys. A quick look at the source in 
compilers/imcc/symreg.c confirms this, there is no case for 'N' values 
(and a test makes Parrot say build_key: unknown set).


Will it be possible to use floating points as keys for arrays? It's up 
to the PMC to implement the indexing correctly, so support for this by 
IMCC should be no problem, I think.


(I vaguely remember myself asking this sort of question before, quite 
some time ago, but I couldn't find it anywhere in the mail archives -- 
sorry about that)


The reason for this question is LuaTable PMC, which can be used as both 
an array as well as a Hashtable. I'd like to implement proper Lua Table 
behaviour into the LuaTable PMC, but it should be able to cope with code 
like this:
  
   $P0 = new .LuaTable

   $P1 = new .LuaNumber
   $P1 = 42
   $P0[1.234] =  $P1

And this currently doesn't work, as mentioned above. (According to the 
PDD on keys, it should be possible to do this:


op arg, P1[12.34] # Constant number key - handled as constant key   

Kind regards,
klaas-jan


Re: Q: Keys can be strings/ints only?

2006-01-20 Thread Klaas-Jan Stol

Matt Fowles wrote:


Klaas-Jan~

On 1/20/06, Klaas-Jan Stol <[EMAIL PROTECTED]> wrote:
 


Hi,

I tried to index aggregates using several types of keys (that is,
several types of values), and it seems only string and integer values
can be used as keys. A quick look at the source in
compilers/imcc/symreg.c confirms this, there is no case for 'N' values
(and a test makes Parrot say build_key: unknown set).

Will it be possible to use floating points as keys for arrays? It's up
to the PMC to implement the indexing correctly, so support for this by
IMCC should be no problem, I think.

(I vaguely remember myself asking this sort of question before, quite
some time ago, but I couldn't find it anywhere in the mail archives --
sorry about that)

The reason for this question is LuaTable PMC, which can be used as both
an array as well as a Hashtable. I'd like to implement proper Lua Table
behaviour into the LuaTable PMC, but it should be able to cope with code
like this:

   $P0 = new .LuaTable
   $P1 = new .LuaNumber
   $P1 = 42
   $P0[1.234] =  $P1

And this currently doesn't work, as mentioned above. (According to the
PDD on keys, it should be possible to do this:

   op arg, P1[12.34] # Constant number key - handled as constant key
   



I am not sure how wise an idea this is given the difficult of
comparing floating point numbers for equality.
 

You may be right, but nevertheless, that's the problem of the 
language/pmc implementer (me, in this case). And, if Lua can do it, it 
should be possible for me to do it as well.


klaas-jan


Re: Perl 6 Summary for 2006-01-10 though 2006-01-24

2006-01-25 Thread Klaas-Jan Stol

Matt Fowles wrote:


  LuaNil Morphing
   Klaas-Jan Stol proffered a patch which changed LuaNil from a singleton
   and made it morph to other Lua types when asked. Warnock applies.

 

Actually, François Perrad applied this patch, but I think he only sent a 
reply to me.



   <http://xrl.us/jpww>

  LuaTable Loving
   Klaas-Jan Stol also provided a patch making LuaTable more correct.
   Warnock applies.
 


Same here.

kjs


Re: What version of perl is required?

2006-04-24 Thread Klaas-Jan Stol

Bernhard Schmalhofer wrote:


Will Coleda schrieb:

There was an agreement on 5.6.1 a few weeks back on IRC, if I recall  
correctly, I haven't heard anything about 5.8.


This change was made here:

r11744 | bernhard | 2006-02-26 05:55:39 -0500 (Sun, 26 Feb 2006) | 7  
lines


Configuration:
- Sprinkle a few 'use warnings;'
- Some code beautification
- Explicit use of Parrot::BuildUtil::parrot_version()
- Use the 'our' syntax in Configure.pl
- $description in the steps, needs no trailing '...'


Bernhard, was the upgrade to 5.8 intentional and necessary?



In February I was fairly sure that Perl 5.8.0 was already required. 
But I must have mixed that up

as I can't find that mentioned on p6i.

The reason for making an explicit check was that I didn't recall whether
'our' was introduced in 5.6.0 or 5.8.0.  As 'our' was introduced in 
5.6.0,

I have lowered the requirements for Configure.pl to 5.006.

CU, Bernhard


I'm not sure if this has anything to do with this, but I know that perl 
5.6 on OS X had troubles with parsing pmc files. (in my case at least, 
then after an upgrade to 5.8, the problems were gone)

Maybe this is it?

klaas-jan



:immediate behaviour

2006-05-18 Thread Klaas-Jan Stol

hi,

if I understand correctly, the :immediate pragma makes the sub which has 
this pragma run immediately after parsing (well, at least before running 
the program)


Suppose I have this code:

   .sub loadstuff :immediate
  # load stuff
   .end

   .sub main
   dostuff( )
   end
   .end

Then, running this code will start running the loadstuff( ) again 
(because main doesn't have the :main pragma, and loadstuff() is at the 
top of the file).
My concern is, is this the desired effect? Shouldn't the :immediate subs 
only be run once? So, in effect shouldn't they be skipped (if they're at 
the top of the file, where execution starts when :main is missing) when 
running the program?


regards,
klaas-jan




Coroutine reset functionality?

2006-05-29 Thread Klaas-Jan Stol

Hi,
I couldn't find any functionality to reset a coroutine. Sometimes you want
to reset a coroutine, so it starts at the beginning of the sub body, but
there doesn't seem to be any method to do that. Am I overlooking something?

Thanks,
klaas-jan


Re: Coroutine reset functionality?

2006-05-29 Thread Klaas-Jan Stol

I was thinking of just a method on the Coroutine PMC so you could do

.sub some_global_coroutine
 .yield(1)
 .yield(2)
 .yield(3)
 .yield(4)
 .yield(5)
.end

.local pmc mycoro
# create the coroutine
mycoro = global 'some_global_coroutine'
mycoro = clonoe mycoro

.local pmc corresult
# call it a few times
corresult = mycoro() # 1
corresult = mycoro() # 2
corresult = mycoro() # 3
mycoro."reset"() # reset the coroutine
corresult = mycoro() # 1 again (not 4)

But maybe this was already possible, I don't know. I'm not familiar with the
implementation specifics of a Coroutine, but it seems to me it shouldn't be
too hard.

Kind regards,
klaas-jan

On 5/29/06, Elizabeth Mattijsen <[EMAIL PROTECTED]> wrote:


At 11:04 PM +0200 5/29/06, Klaas-Jan Stol wrote:
>I couldn't find any functionality to reset a coroutine. Sometimes you
want
>to reset a coroutine, so it starts at the beginning of the sub body, but
>there doesn't seem to be any method to do that. Am I overlooking
something?

Good point.

Essentially you would be removing the continuation context of that
subroutine / method.

A method on a method maybe?

   foo.reset( bar => 1 );

comes to mind?


Suggestions?  Comments?


Liz



coroutine segfaults

2006-05-30 Thread Klaas-Jan Stol

hi,

I was investigating a possible implementation of the "reset" method for 
coroutine.pmc, but I encountered the following:
if the coroutine is called more times than the coroutine ".yield()s", it 
segfaults


example:

.sub main :main
   .local int result
   .local pmc cor
   cor = global "_foo"

   result = cor()
   print result # prints 1
   print "\n"
  
   result = cor()

   print result # prints 2
   print "\n"
  
   result = cor()

   print result # prints 3
   print "\n"
  
   result = cor()

   print result # prints 4
   print "\n"
  
   result = cor()

   print result #prints 5
   print "\n"
  
   result = cor()

   print result # what should this do? start over again?
   print "\n"
   end
.end

.sub _foo
   .yield(1)
   .yield(2)
   .yield(3)
   .yield(4)
   .yield(5)
   #.yield(6)
.end

If the last .yield() is uncommented, it works, but otherwise, the last 
result (5, in this case), is printed twice. Can this be a bug?


regards,
klaas-jan


Re: [perl #39313] [TODO] or [BUG] improve PMC compiler

2006-06-07 Thread Klaas-Jan Stol

Hi,

I had a look at this, but I'm not that good at Perl, and regular 
expressions. However, I found where things go wrong, so someone who 
really groks REs may fix it.


THe problem is (well, at least I think it is) at about line 440 in pmc2c.pl

sub parse_pmc {
   my $code = shift;

   my $signature_re = qr{
   ^
   (?: #blank spaces and comments and spurious semicolons
 [;\n\s]*
 (?:/\*.*?\*/)?# C-like comments
   )*

   (METHOD\s+)?#method flag

   (\w+\**)#type   <<<==I'd say this 
should be (\w+\s*\**) so it matches a word (the return type), optional 
spaces, and then optial *'s to indicate a pointer

 \s+
   (\w+)   #method name
 \s*
   \( ([^\(]*) \)  #parameters
   }sx;

If the fix as I noted above is done, things don't compile anymore.
I'm sorry I can't provide a real fix, but at least it's easier to fix 
now, hopefully.


A more kludgy fix may be to check whether $type equals "METHOD", if so, 
then there is something wrong. And it may be that not everything is 
handled by this.


kind regards,

klaas-jan



Leopold Toetsch (via RT) wrote:

# New Ticket Created by  Leopold Toetsch 
# Please include the string:  [perl #39313]
# in the subject line of all future correspondence about this issue. 
# https://rt.perl.org/rt3/Ticket/Display.html?id=39313 >



It's easy to add 'invalide' code to .pmc files. E.g. I had defined:

   METHOD parent() {
   return PMC_pmc_val(SELF) ? PMC_pmc_val(SELF) : PMCNULL;
   }

Due to the absence of a return value, the PMC compiler just ignores this 
'method' without further notice.


This also is happening, if there's just a whitespace before the '*':

   METHOD PMC *parent() {
   return PMC_pmc_val(SELF) ? PMC_pmc_val(SELF) : PMCNULL;
   }

This totally valid C type declaration is just ignored.

Fixes welcome,
leo

 





Re: Readonly PMCs and types

2006-06-16 Thread Klaas-Jan Stol

Leopold Toetsch wrote:


Recently on IRC:

 @woggle> leo: So, for read-only PMC variants, I'm presuming that it's okay  
to have the read-only
variants have their own type number and type name (like was 
done for ConstSArray)...


My 2 c:
A distinct type number would cause e.g. different MMD behavior and I'm not 
sure, if we want to duplicate MMD function code. Letting r/o types subclass 
the r/w types would change relative distances and also looks suboptimal.


But I don't know yet, how to do it right.

leo

 

Wouldn't it be an idea to have a property 'is_read_only' or something 
like that? Then, when attempting to do a write action on a r/o PMC, an 
exception is thrown. It would seem to me that this is a typical case for 
using a property.


The disadvantage of course of this approach is that for every 
write-operation, this check would have to be done, although this is done 
in fast C code, it *is* yet another check to be done.


My 2c,
klaas-jan


Tcl windows make problems

2007-01-12 Thread Klaas-Jan Stol

hello,
yesterday I had a look at why tcl does not build on windows. Although I 
haven't been able to fix it, I'd like to share the issues I found, so 
you don't have to look for it yourself.


there were several problems with the makefile

line 123:
   ops: src\binary.o , should be binary$(O)
this is fixed by particle.

line 126:
   @cd $(OPSDIR) && $(OPSBUILD) linklibs tcl ..\binary$(O)

makes that the system will look for binary.obj_ops_switch.obj
changing it into ..\ops\tcl will fix that problem

Furthermore, the next problem is that the ops file won't link correctly 
because binary.obj is not linked. To solve the problem, I added 
binary.obj to the tools/build/dynoplibs.pl script, but of course that is 
not a good solution. I haven't been able to solve it. Maybe it's an idea 
to just put the source from binary.c into the ops file itself, if that's 
possible.


If that's corrected, you'll find 1 more problem: if binary.obj is 
linked, it can't resolve the symbol _PMCNULL. As a quick hack, I 
#define'd PMCNULL as NULL. After these fixes, it worked.


Hope this helps you further.
regards,
klaas-jan


Adjust copyright notice

2007-01-13 Thread Klaas-Jan Stol

Hi,

I tried to write a little script that checks for the copyright notice 
and updates it if necessary.
THere are some comments on what should be done (SVN date comparing and 
stuff.


hope this helps,
kjs
#
# Start of a script to recursively process all files in a directory to change 
the copyright notice.
#
use File::Find;
use strict;
use warnings;

sub process_file {
my $oldValue = 2006; #the minimal value for a year to be 
replaced
my $newValue = 2007; #the new year!
my $startYear = 2000; # Parrot start year
my $shouldChange = 0;  # flag only set when file was changed in a year 
later than it's copyright notice year.

my $file = $_;

# only handle files, not directories
return unless -f $file;

# only handle text files
return unless -T $file;

# only handle file if it is writable
return unless -w $file;

# open file for reading and writing
open(FILE, "+< $file") or die "can't open file $File::Find::name: $!";

# get last date the file was changed according to svn:
#
# TODO:
# Get SVN info on the file, get its "Last Changed Date" year ("LCD")
# Then, compare this year with the file's current copyright date.
# If LCD > CURRENT, adjust the file.
# 
# can't get it to work right now, on windows. probably the "/" vs "\" thing.
print "Getting SVN info from $File::Find::name...\n";
my $str = "svn info $File::Find::name"; 
print "Executing:\n$str";
# Maybe use 
# kjs: may make sense to just use 'capture_output' from 
lib/Parrot/Configure/Step.pm
# (instead of system)
system($str);
#
#
# set a flag if necessary "$shouldChange"
#

# buffer to store file contents
my $filebuffer = '';   

# read file line by line
while() {

# flag indicating whether the file has been changed yet
my $changed = 0;

# store the year to be replaced in a temp, it'll be decremented if it's 
not found 
# so, if 2006 is not found, it'll look for 2005, 2004 etc.  
my $old = $oldValue;

# look in the file as long as it's not changed, and the year to be 
changed $startYear
while($changed == 0 && $old >= $startYear) {

# check for copyright lines containing only 1 year
if ($_ =~ m/.*[cC]opyright.*\ $old.*/ ) { # check for match
print "Changing: '$_' \ninto: \n";

# change a notice like '2006' into '2006-2007'
$_ =~ s/$old/$old\-$newValue/;

print $_;
print "\n";

# add line to file buffer
$filebuffer .= $_;  

# set changed flag
$changed = 1;
}
# check for copyright lines like X-Y
elsif ($_ =~ m/.*[cC]opyright.*\-$old.*/ ) {
print "Changing: '$_' \ninto: \n";

# make sure only the 'Y', not 'X', in 'X-Y' is changed
$_ =~ s/\-$old/\-$newValue/;

print $_;
print "\n";
$filebuffer .= $_;
$changed = 1;   
}
# try a lower value of $oldvalue, so an earlier year

$old--; 
}

# if the line was not changed, it was not a copyright notice.
# add it to the buffer.
if($changed == 0) {
$filebuffer .= $_;
}
}

# end of file reached, now write the buffer back to file again.
# this code is taken from the Perl Cookbook.
seek(FILE, 0, 0)   or die "can't seek to start of $file: 
$!";
print FILE $filebuffer or die "can't print to $file: 
$!";
truncate(FILE, tell(FILE)) or die "can't truncate $file: 
$!";
close(FILE)or die "can't close $file: $!";  
 

print "Handled file $file\n";


}

if (@ARGV < 1) {
print <<'USAGE' 

Usage: perl changeCopyright 

Updates the copyright notice to 2007 for all files in .

USAGE

}
else {
my @DIRLIST = ();
push @DIRLIST, $ARGV[0];
find(\&process_file, @DIRLIST);
}


# TODO: compile a list of files that has been changed by this script. 

Re: [perl #41237] [TODO] PMC Class name IDs will require a dot in front

2007-01-15 Thread Klaas-Jan Stol

Matt Diephouse wrote:

Allison Randal via RT <[EMAIL PROTECTED]> wrote:

> PMC Class name IDs ... will require a dot in front

My preference is to eliminate the dot in classname IDs. Lodge your
objections now, before it's made fact in 0.4.9.

Allison


I actually prefer the dot. I don't like the possible ambiguity between
types and local variables:

   .local string MyClass
   MyClass = '...'
   $P0 = new MyClass # is this a type or a string?

Capitalized variable names may be rare and/or bad practice, but it's
bound to happen. There was talk on #parrot about how this still
conflicts with macros, but those are rarer than variables.

Also, if we decide that anything starting with a dot that doesn't have
parens is a type, I could write:

   $I0 = typeof $P0
   if $I0 == .Foo goto bar

I know we're not optimizing PIR for human readability, but I've
written a lot of it, so I appreciate the little things. :)

A dot also indicates that this is not pure PASM, but rather PIR. The dot 
implies the token is pre-processed by IMCC (the type is looked up during 
parsing, IIRC), which is, IMHO, more consistent with the other 
dot-prefixed tokens from PIR. One could also think about it like this: 
the dot indicates the difference between a variable having a value 
during compile time or runtime, or, in other words, a dot-prefixed name 
is a variable during compile-time, and no-dot-prefixed name is a runtime 
variable. So:


compile time:
.local pmc p
p = new .Hash # dot indicates ".Hash" is looked up during compile time 
by IMCC


runtime:
.local pmc p
.local int hash_type
hash_type = find_type "Hash"
p = new hash_type  # no dot means "hash_type" gets a value during 
runtime (the previous statement in this case, but usually it may not be 
as clear as this simple example)



Just a thought,
klaas-jan


Re: Tcl, trace, profiling...

2007-01-20 Thread Klaas-Jan Stol




I like the idea. Write up a more complete proposal and we'll all 
review it. A few thoughts:


- The same mechanism could be used to implement Perl 6 sub wrapping, 
so keep that in mind as you're thinking through the implementation 
options. Names like "trace_sub" may be too specific to one particular 
use.


- Runtime addition of traces/wrappers will be more important than 
adding them at compile-time, considering that they're likely to be 
mostly used for layering debugging/profiling/etc checks over existing 
code, and in the debugger. So much more important, that I'd consider 
skipping the compile-time syntax.


- I like the Perl 6 way of specifying the point in the wrapping sub 
where the wrapped sub should be called better than setting up 
conditionals based on an argument for the operation type. So, 
something like:


.sub joe
  .param pmc wrapped_sub
  .param pmc orig_args

  .local string proc_name
  proc_name = wrapped_sub.name()

  print "entering "
  say proc_name

  invoke_wrapped wrapped_sub, orig_args

  print "leaving "
  say proc_name
.end

.sub bob :wrap joe
  say "whoa."
.end

(That also means you can monkey around with the args before passing 
them on to the wrapped sub.)



- It should be possible both to put multiple wrappers/traces on a 
subroutine, and to put wrappers around other wrappers. So these are 
all possible:


.sub joe
  #...
.end

.sub bob :wrap joe
  #...
.end

.sub phil :wrap joe
  #...
.end

.sub dave :wrap phil
  #...
.end


Allison
FWIW, it might be easier to put the :wrap flag onto the wrapping sub, 
IMHO. If there is some sub you want to wrap, according to the syntax 
above you would need to change that sub, which might not be desirable or 
even possible. The wrapped sub could be only available as a library, for 
instance.


so, the idea would then be:

.sub joe :wrap('bob')
   .param pmc args
   say "calling bob..."
   invoke_wrapped args
   say "returned from bob"
.end

.sub bob
   say "this is bob"
.end

which outputs:

calling bob
this is bob
returned from bob

This way, the original sub is not touched, and you just 'add' the 
wrapper function.

my 2c.


Language Testing

2007-01-30 Thread Klaas-Jan Stol

hello,

I'm trying to set up a test harness for languages/PIR

I did the following:
1. added a file lib\Parrot\Test\PIR.pm
   (there are others, like Punie.pm).
   I changed this file a bit, so it uses pir.pbc as compiler (I copied 
the file from Punie.pm, and changed the compiler from punie.pbc to pir.pbc)


2. I added a file languages\PIR\t\harness containing:
  
   #! perl -w


   use Parrot::Test::Harness language => 'PIR';

3. I added 1 test file "sub.t"

Now, if I run it with a deliberate error in the test file, I see that:
[...]
# '.\parrot.exe   "C:\parrot\languages\PIR\t\sub_1.pir"' failed with 
exit code 1

[...]

which obviously means that languages\pir.pbc is not even used.
In other words, it seems that this module PIR.pm is not used.

I could not find docs on how to set this up. Help would greatly be 
appreciated.
(and I could provide a patch after that for compiler FAQ, right below 
"Languages" explaining this)


Thanks,
Klaas-Jan








Re: Language Testing

2007-01-30 Thread Klaas-Jan Stol

Thanks a bunch!
It's working :-)

kjs

Will Coleda wrote:

I just tried this setup in my sandbox as well.

Turns out you have an unfortunately named language, as language=>"PIR" 
forces the usage of output_is(), as the author assumed PIR was 
reserved for internal testing.


This will require either an update to lib/Parrot/Test.pm, or that you 
use a different language name for the language arg and module. I 
recommend the latter, e.g. "PIR_PGE". You won't need to change the 
language DIR or the compiled .pbc you're using.


Regards.

On Jan 30, 2007, at 5:03 AM, Klaas-Jan Stol wrote:


hello,

I'm trying to set up a test harness for languages/PIR

I did the following:
1. added a file lib\Parrot\Test\PIR.pm
   (there are others, like Punie.pm).
   I changed this file a bit, so it uses pir.pbc as compiler (I 
copied the file from Punie.pm, and changed the compiler from 
punie.pbc to pir.pbc)


2. I added a file languages\PIR\t\harness containing:
 #! perl -w

   use Parrot::Test::Harness language => 'PIR';

3. I added 1 test file "sub.t"

Now, if I run it with a deliberate error in the test file, I see that:
[...]
# '.\parrot.exe   "C:\parrot\languages\PIR\t\sub_1.pir"' failed with 
exit code 1

[...]

which obviously means that languages\pir.pbc is not even used.
In other words, it seems that this module PIR.pm is not used.

I could not find docs on how to set this up. Help would greatly be 
appreciated.
(and I could provide a patch after that for compiler FAQ, right below 
"Languages" explaining this)


Thanks,
Klaas-Jan









--
Will "Coke" Coleda
[EMAIL PROTECTED]







On PASM and PIR registers

2007-01-31 Thread Klaas-Jan Stol

hello,

Parrot has 2 categories of registers: PASM registers, which are of the 
form [S|N|I|P] (which is kinda odd, if only regs 0-31 are 
available) and PIR registers, which are formed like: $[S|N|I|P]+


In the old days, this distinction was necessary for the register 
allocator to translate PIR registers to PASM registers, because there 
were only 32 regs of each type (S/N/I/P).


IIUC, the number of registers is now equal to "the necessary number of 
registers"; that is, each sub has as many registers as it needs to do 
its job.


So, my question is now, why do we still need the PASM registers (except 
for backward compatibility) if we have PIR registers (which, after a 
possible "we don't need them", brings the question, why we need the "$", 
but that's a different topic). In other words, why not stick to 1 category:
either $[SNIP]+ (or maybe skip the $ altogether, but again, 
that's not the point here)?


regards,
klaas-jan


Q on PIR vs PASM

2007-02-02 Thread Klaas-Jan Stol

hi,

IIRC, IMCC started as a kind of pre-processor for PASM, in other words, 
it allowed more readable shortcuts for several constructs. Eventually, 
everything was translated to pure PASM, that is, 1 long list of real 
Parrot instructions (no .sub/.end blocks etc).


At some point, IMCC was merged with Parrot as its parser. Since then, a 
lot of additions have been done, like the .sub pragmas like :load 
,:main, :init, :outer etc. (When Perl6 and Parrot essentials was 
written, these flags were not there)


Now, my question, is it still true that every PIR construct has a PASM 
form as well, can every PIR construct be translated directly to PASM? 
That is, can one still get the same behaviour that is achieved by all 
those high-level PIR constructs like :outer(...), in PASM as well?


thanks in advance,
klaas-jan


[PATCH] Update copyright for Parrot --version

2007-02-02 Thread Klaas-Jan Stol
attached a patch that makes ./parrot --version respond copyright 
2001-2007, instead of 2001-2006.


regards,
kjs
Index: compilers/imcc/main.c
===
--- compilers/imcc/main.c	(revision 16864)
+++ compilers/imcc/main.c	(working copy)
@@ -127,7 +127,7 @@
 if (PARROT_REVISION != rev) {
 printf( "Warning: used Configure.pl revision %d!\n", rev);
 }
-printf("Copyright (C) 2001-2006, The Perl Foundation.\n\
+printf("Copyright (C) 2001-2007, The Perl Foundation.\n\
 \n\
 Parrot may be copied only under the terms of either the Artistic License or the\
 \n\


Copyright chang script and test

2007-02-02 Thread Klaas-Jan Stol

hi,

attached are 2 files: a script that checks all files for the Last 
Changed Date according to SVN, and updates the file if its year > 
copyright notice in the file. I'm not very good with Perl, so it might 
be badly programmed... However, it only needs running once.


The 2nd file is a test, and again, this only needs to run once a year.

Issues with the test file:
* I redirect stderr to stdout, maybe it needs to be restored later, but 
I can imagine each test is a new invocation of perl, so in that case 
it's not necessary.
* if it finds a file that is literally out of date (it needs copyright 
notice update), it will only give an error message, not the file name 
(which should really be the case, otherwise, you don't know what file to 
fix)


* on ctrl-c it won't stop (well, for 1 second after which it 
continues...) I guess it has to do with me using File::Find...


The test file can just be put in the parrot/t/configure directory, that 
one will be run first when doing make test (so you don't have to wait 
for it to run)


hope this helps,
klaas-jan


#! perl
# Copyright (C) 2007, The Perl Foundation.

=head1 NAME

adjustcopyright.t - check copyright for all files in the parrot distr.

=head1 SYNOPSIS



=head1 DESCRIPTION

This test checks the "Last Changed Date" according to SVN for the year
it was changed. Then it looks in the file being processed for a copyright
notice, and extracts the year. Then, if $SVNYear > $fileYear, fail test
(and the copyright should be updated).

=head1 ISSUES

=over 4

=item *

C^C won't stop the testing...

=item *

How to restore stderr after having it redirected to stdout?






=cut

use strict;
use warnings;
use lib qw( . lib ../lib ../../lib );

use File::Find;
use Parrot::Test;
use Parrot::Config;
use Test::More;


# don't know how many files will be tested:
plan tests => 1;

sub vdiag(@) { &diag if $ENV{TEST_VERBOSE} }


sub checkCopyright {

my $file = $_;

# only handle files, not directories
return unless -f $file;

# only handle text files
return unless -T $file;

# if there's '.svn' in the filename, it's the directory 
(probably?) 
return if $File::Find::name =~ m/.*\.svn.*/;
  
my $cmd = "svn info $File::Find::name";

#
# FIXME: restore stderr->stdout after we're done.
#
my $output = `$cmd 2>&1`;

my $SVNYear = undef;# to 
store the year according to SVN

if ($output =~ m/.*Last Changed Date:\s+(\d\d\d\d).*/) {

$SVNYear = $1;  
}
else {
return;
}

open(FILE, "< $File::Find::name") or die "cannot open file 
$File::Find::name";
   
while() {

# on failure, it should emit the failing file's name so 
we can fix it!  

# check for copyright lines containing only 1 year; note the matching 
space here.
if ($_ =~ m/.*[cC]opyright[^[\d\d\d\d\-]]*(\d\d\d\d).*/ ) { # check for 
match

# ok found it, now compare with $SVNYear
# only change when SVN Year > current
is($1, $SVNYear);
}
# check for copyright lines like X-Y
elsif ($_ =~ m/.*[cC]opyright[^\d]*\d\d\d\d\-(\d\d\d\d).*/ ) {  

is($1, $SVNYear);
}
   } 
   
   close(FILE);

}


{

# set $parrotRootDir to parrot build directory: 
my $parrotRootDir = $PConfig{'build_dir'};

# find takes an array containing directories to 
# be processed, we only have 1 directory: parrot
my @dirlist = ();   
push @dirlist, $parrotRootDir;

# check copyright for each file.
find(\&checkCopyright, @dirlist);
}
#
# Start of a script to recursively process all files in a directory to change 
the copyright notice.
#
use File::Find;
use strict;
use warnings;

my @unhandled_files = ();
my @handled_files = ();

sub process_file {
my $oldValue = 2006;# the minimal value for a year 
to be replaced   

my $shouldChange = 0;   # flag only set when file was changed in a year 
later than it's copyright notice year.

my $file = $_;

# only handle files, not directories
return unless -f $file;

# only handle text files
return unless -T $file;

# only handle file if it is writable
return unless -w $file;

# open file for 

[PATCH] PIR updates

2007-02-03 Thread Klaas-Jan Stol
t;.return" parenthesized_args
+
+  long_yield_stat:
+".pcc_begin_yield" nl
+return_directive*
+".pcc_end_yield"
+
+  return_directive:
+".return" simple_expr set_flags? nl
+
+  short_yield_stat:
+".yield" parenthesized_args
+
+  tail_call:
+".return" short_sub_call
+
+  open_namespace:
+".namespace" identifier
+
+  close_namespace:
+".endnamespace" identifier
+
+
+NOTE: an emit block only allows PASM instructions,
+not PIR instructions.
+
+
+  emit:
+".emit" nl
+labeled_pasm_instr*
+".eom"
+
+NOTE: the macro definition is not complete, and untested.
+This should be fixed. For now, all characters up to but not
+including ".endm" are 'matched'.
+
+
+  macro_def:
+".macro" identifier macro_parameters? nl
+macro_body
+
+  macro_parameters:
+"(" id_list? ")"
+
+  macro_body:
+.*?
+".endm" nl
+
+  pragma:
+  include
+| new_operators
+| loadlib
+| namespace
+| hll_mapping
+| hll_specifier
+| source_info
+
+
+  include:
+".include" string_constant
+
+  new_operators:
+".pragma" "n_operators" int_constant
+
+  loadlib:
+".loadlib" string_constant
+
+  namespace:
+".namespace" [ "[" namespace_id "]" ]?
+
+  hll_specifier:
+".HLL" string_constant "," string_constant
+
+  hll_mapping:
+".HLL_map" int_constant "," int_constant
+
+  namespace_id:
+string_constant [ ";" string_constant ]*
+
+
+NOTE: currently, the line directive is implemented in IMCC as #line.
+See the PROPOSALS document for more information on this.
+
+  source_info:
+".line" int_constant [ "," string_constant ]?
+
+  id_list:
+identifier [ "," identifier ]*
+
+  string_constant:
+charset_specifier?  quoted_string
+
+  charset_specifier:
+  "ascii:"
+| "binary:"
+| "unicode:"
+| "iso-8859-1:"
+
+
+  type:
+  "int"
+| "num"
+| "pmc"
+| "object"
+| "string"
+| "Array"
+| "Hash"
+
+  target:
+identifier | register
+
+
+
+=head1 AUTHOR
+
+
+Klaas-Jan Stol [EMAIL PROTECTED]
+
+
+=head1 KNOWN ISSUES AND BUGS
+
+Some work should be done on:
+
+=over 4
+
+=item *
+
+Macro parsing
+
+=item *
+
+Heredoc parsing
+
+=item *
+
+The rule 'type' does currently not include custom types (user defined).
+Probably it needs an alternative "identifier". Not sure yet at this point.
+
+=item *
+
+Clean up grammar, remove never-used features.
+
+=item *
+
+Test. A lot.
+
+Bugs or improvements may be sent to the author, and of course greatly
+appreciated. Moreover, if you find any missing constructs that are in
+IMCC, indications of these would be appreciated as well.
+
+=back
+
+=cut
+
Index: languages/PIR/docs/pirgrammar.html
===
--- languages/PIR/docs/pirgrammar.html	(revision 0)
+++ languages/PIR/docs/pirgrammar.html	(revision 0)
@@ -0,0 +1,662 @@
+
+http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";>
+http://www.w3.org/1999/xhtml";>
+
+PIR.pod	- The Grammar of languages/PIR
+
+
+
+
+
+
+
+
+
+
+
+	NAME
+	DESCRIPTION
+	STATUS
+	VERSION
+	LEXICAL CONVENTIONS
+	
+
+		PIR Directives
+		Registers
+		Constants
+		Identifiers
+		Labels
+	
+
+	GRAMMAR RULES
+	AUTHOR
+	KNOWN ISSUES AND BUGS
+
+
+
+
+
+
+NAME
+PIR.pod	- The Grammar of languages/PIR
+
+
+
+DESCRIPTION
+This document provides a more readable grammar of languages/PIR. The actual input
+for PGE is a bit more complex. This grammar for humans does not contain error
+handling and some other issues unimportant for the PIR reference.
+
+
+
+STATUS
+For a bugs and issues, see the section KNOWN ISSUES AND BUGS.
+The grammar includes some constructs that *are* in the IMCC parser,
+but are not implemented. An example of this is the ".global" directive.
+
+
+
+VERSION
+Version: Saturday Feb. 3rd 2007.
+(not a version number yet, as many improvements are to be expected at this point).
+
+
+
+LEXICAL CONVENTIONS
+
+
+PIR Directives
+PIR has a number of directives. All directives start with a dot. Macro identifiers
+(when using a macro, on expansion) also start with a dot (see below). Therefore,
+it is important not to use any of the PIR directives as a macro identifier. The
+PIR directives are:
+
+  .arg.invocant  .pcc_call 
+  .const  .lex   .pcc_end_return   
+  .emit   .line  .pcc_end_yield 
+  .end.loadlib   .pcc_end   
+  .endnamespace   .local .pcc_sub   
+  .eom.meth_call .pragma 

Q on Calling conventions; parameter order

2007-02-05 Thread Klaas-Jan Stol

hello,

Some details of the Parrot calling conventions are a bit unclear. For 
the languages/PIR parser implementation, I'd like to check on this 
order, instead of postponing the check this in a later phase. My guess 
is that the actual checking for mismatches is done in Parrot during 
runtime, but I'm not sure about that(i.e. throwing exceptions on 
mismatches)
After experimenting a bit and some common sense, I came up with the 
following order, which I'd like to check with experienced PIR programmers.


1. (Positional, non-optional parameters)*
2. (optional positional parameters)*
3. (slurpy parameter)? # need not be optional, it just takes whatever is 
left up till the named parameters

4. (named parameters, either optional or not)*
5. (slurpy named parameter, may be optional)? # :optional flag makes 
sense here, it may not be passed.


If people see cases that are not listed here, comments are most 
certainly welcome!


Furthermore, I found that using the :named flag without identifier (like 
:named('x') ) does not work, or better, is undefined. Shouldn't the 
identifier be obligatory?


This weekend, I added docs/pirgrammar.pod to languages/PIR. This 
document describes the PIR grammar according to languages/PIR in a more 
readable format than the PGE input file (some rules are simplified and 
the error handling is removed). It now also contains example code to 
explain the formal rules, because reading a formal grammar description 
may be too hard for newcomers. In order to explain the calling 
conventions, I think being very clear on this point is important to get 
new users started easily. IMHO, PDD03 has some gaps here and there.


kind regards,
klaas-jan


[PATCH] update docs/imcc/calling_conventions.pod

2007-02-05 Thread Klaas-Jan Stol

hi,

I noticed the file calling_conventions.pod misses the sub pragmas 
:postcomp (and I understood this is the same as :immediate) and  
:outer(sub).


This patch adds these pragmas.

regards,
kjs
Index: docs/imcc/calling_conventions.pod
===
--- docs/imcc/calling_conventions.pod	(revision 16890)
+++ docs/imcc/calling_conventions.pod	(working copy)
@@ -132,7 +132,7 @@
 
 Engage in multiple dispatch with the listed types.
 
-=item :immediate
+=item :immediate or :postcomp
 
 This subroutine is executed immediately after being compiled. (Analagous to
 C in perl5.)
@@ -152,6 +152,10 @@
 the method B also be the v-table method B), use
 B<:vtable("get_string")>.
 
+=item :outer(subname)
+
+The marked C<.sub> is lexically nested within the sub known by B.
+
 =back
 
 Notes:


PIR syntax (was: Re: What Skills Do We Need to Finish Parrot?)

2007-02-06 Thread Klaas-Jan Stol

Allison Randal wrote:

James Keenan wrote:


Which leads to my next questions:

Given a knowledge of a dynamic language (I believe there's one called 
Perl 5), what is the trajectory for learning PIR?


Is there any tutorial in the docs?


There's docs/imcc/syntax.pod. Not a tutorial, but a decent introduction.


Is the "Parrot Essentials" book (still) of any use in this regard?


It's still a good starting point, but the content needs to be updated. 
I haven't yet been successful in getting O'Reilly to release those 
chapters to the Parrot project for inclusion in the repository.


Failing that, a PIR tutorial is a good project for someone to take on. 
You interested in working on it?
It's not a tutorial, but I'm working on 
languages/PIR/docs/pirgrammar.pod (and a html version). As languages/PIR 
aims to be a kind of reference PIR implementation (well, that's my goal 
:-), it should come *very* close to the language that IMCC accepts. 
Anyway, pirgrammar.pod is a human-readable, cleaned-up version of the 
languages/PIR PGE implementation (no error handling). I also sent a 
patch that embeds examples into it.




Allison

klaas-jan



Re: [PATCH] Updates for languages/PIR/docs/pirgrammar.pod

2007-02-07 Thread Klaas-Jan Stol

chromatic wrote:

On Wednesday 07 February 2007 08:33, Klaas-Jan Stol wrote:

  

attached a patch for pirgrammar.pod and its html variant.



Keeping this HTML in the repository sucks.  Is there a possibilty that we 
could generate it automatically?  What's preventing us from doing so?


I understand the rationale for some generated files, such as those that 
require flex and bison, but this one seems different.


-- c
  
absolutely true. I'm not sure; is pod2html present on any platform where 
perl is? If so, then it can be incorporated into step.pm, (that makes 
the Makefiles), so it can done when running make.


(likewise, make test could run podchecker on the pod files)

kjs


[PATCH] Update ASTGrammar for lang/PIR

2007-02-08 Thread Klaas-Jan Stol

hi,

attached an update for ASTGrammar.tg for languages/PIR

In order to print the past tree to screen, set 'target' to 'past' in 
pirc.pir. Currently, it is set to 'parse' in order to pass the tests.


regards,
klaas-jan
Index: languages/PIR/lib/ASTGrammar.tg
===
--- languages/PIR/lib/ASTGrammar.tg	(revision 16922)
+++ languages/PIR/lib/ASTGrammar.tg	(working copy)
@@ -1,506 +1,330 @@
 
 grammar ASTGrammar is TGE::Grammar;
 
-transform past (ROOT) :language('PIR') {
-# Ask the child node for its result
-.local pmc child
-.local pmc result
-
-
-result = new 'PAST::Block'
-result.'init'('node'=>node, 'name'=>'anon')
 
-
-#.return(result)
-
-$I0 = defined node["program"]
-unless $I0 goto err_no_tree
-$P0 = node["program"]
-print "\nSuccess!\n"
-#printerr "SOURCE:\n"
-#$S0 = node["source"]
-#printerr $S0
-#printerr "\n\n"
-child = tree.get('past', $P0, 'PIRGrammar::program')
-		print "Back from tree\n\n"
-result.'push'(child)
-.return (result)
-
-  err_no_tree:
-print "The top-level node doesn't contain a 'program' match.\n"
-end
+# past (ROOT)
+#
+# Transform the 'program' rule into a PAST::Block.
+#
+transform past (ROOT) :language('PIR') { 
+.local pmc past
+		past = new 'PAST::Block'
+		past.'init'('node'=>node, 'name'=>'anon')
+
+.local pmc childnode, childpast
+childnode = node['program']
+childpast = tree.'get'('past', childnode, 'PIRGrammar::program')
+		past.'push'(childpast)
+.return (past)  
 }
 
-
+# past (PIRGrammar::program)
+#
+# Store each of the compilation units into a PAST::Stmts node.
+#
 transform past (PIRGrammar::program) :language('PIR') {
-.local pmc result
-result = new 'PAST::Stmts'
-result.'init'('node'=>node)
+.local pmc past
+past = new 'PAST::Stmts'
+past.'init'('node'=>node)
 
-$S0 = node["source"]
-printerr "SOURCE:\n"
-printerr $S0
-printerr "\n\n"
-
-# Ask the child node for its result
-.local pmc child
-$I0 = defined node["compilation_unit"]
-unless $I0 goto err_no_tree
-$P0 = node["compilation_unit"]
-print $P0		
 .local pmc iter
-iter = new Iterator, $P0# setup iterator for node
-iter = 0
-
-  iter_loop:  	
-unless iter, iter_end # while (entries) ...
-  shift $P2, iter  
-  $P3 = tree.get('past', $P2, 'PIRGrammar::compilation_unit')
-  result.'push'($P3)
-  goto iter_loop
+$P0 = node['compilation_unit']
+if null $P0 goto iter_end
+iter = new .Iterator, $P0
+  iter_loop:
+unless iter goto iter_end
+.local pmc cnode, cpast
+cnode = shift iter
+cpast = tree.'get'('past', cnode, 'PIRGrammar::compilation_unit')
+past.'push'(cpast)
+goto iter_loop
   iter_end:
-	
-.return (result)
-  err_no_tree:
-print "The 'program' node doesn't contain a 'compilation_unit' match.\n"
-.return (result)
+.return (past)
 }
 
+# past (PIRGrammar::compilation_unit)
+#
+# Call the appropiate transform rule depending on the type of compilation unit.
+#
 transform past (PIRGrammar::compilation_unit) :language('PIR') {
-.local pmc result
-result = new .ResizablePMCArray
+  global_def:
+$P0 = node['global_def']
+if null $P0 goto sub_def
+.return tree.'get'('past', $P0, 'PIRGrammar::global_def')
+  sub_def:
+$P0 = node['sub_def']
+if null $P0 goto const_def
+.return tree.'get'('past', $P0, 'PIRGrammar::sub_def')
+  const_def:
+$P0 = node['const_def']
+if null $P0 goto macro_def
+.return tree.'get'('past', $P0, 'PIRGrammar::const_def')
+  macro_def:
+$P0 = node['macro_def']
+if null $P0 goto pragma
+.return tree.'get'('past', $P0, 'PIRGrammar::macro_def')
+  pragma:
+  	$P0 = node['pragma']
+if null $P0 goto emit
+.return tree.'get'('past', $P0, 'PIRGrammar::pragma')
+  emit:  
+$P0 = node['emit']
+if null $P0 goto const_def
+.return tree.'get'('past', $P0, 'PIRGrammar::emit') 
+}
 
-.local pmc iter
-iter = new Iterator, node# setup iterator for node
-iter = 0
-  iter_loop:
-unless iter, iter_end # while (entries) ...
-  shift $S1, iter   # get the key of the iterator
-  $P2 = iter[$S1]
-  $S1 = concat 'PIRGrammar::', $S1
-  $P3 = tree.get('past', $P2, $S1)
-  if null $P3 goto iter_loop
-  push result, $P3
-  goto iter_loop
-  iter_end:
-$I0 = elements result
-if $I0 != 1 goto err_too_many
-$P4 = result[0]
-  
-.return ($P4)
-  err_too_many:
-print "A 'line' node can only have one child.\n"
-end
- 	.return(result)
+transform past (PIRGrammar::global_def) :language('PIR') {
+
 }
 
-transform past (PIRGrammar::class_def) :language('PIR') {
+# past (PIRGrammar::sub_def)
+#
+# Transform a sub_def into a PAST::Block node.
+#
+transfor

[PATCH] Updates and fixes for docs/imcc/syntax.pod

2007-02-08 Thread Klaas-Jan Stol

hi,

attached a patch for docs/imcc/syntax.pod

fixing:
* typo, changing eamples in examples
* added ", respectively" to description of binary/hex numbers
* added syntax description for slices:
 =  [  ]
where  is one of:
 .. 
.. 
 ..

Also, I added references to 2 files to the slicing part. Please note 
that there is not a clear description of what slicing should do. (or I 
overlooked).

My guess is that
   $P0 = $P1[ 1 .. 3 ]
should return an array with values from $P1[1], $P1[2] and $P[3].

Any confirmations or error marking would be appreciated.

regards,
klaas-jan

Index: docs/imcc/syntax.pod
===
--- docs/imcc/syntax.pod	(revision 16922)
+++ docs/imcc/syntax.pod	(working copy)
@@ -128,7 +128,7 @@
 
 =item encoding:charset:"string constant"
 
-Like above with an extra encoding attached to the string. For eample:
+Like above with an extra encoding attached to the string. For example:
 
   set S0, utf8:unicode:"«"
 
@@ -137,7 +137,7 @@
 
 =item numeric constants
 
-B<0x> and B<0b> denote hex and binary constants.
+B<0x> and B<0b> denote hex and binary constants respectively.
 
 =back
 
@@ -435,6 +435,26 @@
 This generates either a keyed B operation or B for string arguments and an integer key.
 
+=item  =  [  ]
+
+where C is:
+
+  .. 
+
+returns a slice defined starting at C and ending at C.
+
+ .. 
+
+returns a slice starting at the first element, and ending at C.
+
+  ..
+
+returns a slice starting at C to the end of the array.
+
+see src/pmc/slice.pmc
+and t/pmc/slice.t.
+
+
 =item  [  ] = 
 
 A keyed B operation or the assign B op with a length of


[PATCH] languages/PIR fix string encoding, hex and binary numbers

2007-02-08 Thread Klaas-Jan Stol

hi

attached a patch for languages/PIR fixing:

* added optional "utf8:" encoding specifier (according to 
docs/imcc/syntax.pod)

* fixed support for binary and hex. numbers
* added test for these changes.

regards,
klaas-jan
Index: languages/PIR/lib/pir.pg
===
--- languages/PIR/lib/pir.pg	(revision 16923)
+++ languages/PIR/lib/pir.pg	(working copy)
@@ -703,19 +703,17 @@
 #
 
 token int_constant {
-[-]? \d+
-  | 
+
   | 
+  | [-]? \d+
 }
 
-# FIXTHIS
-regex hex_constant {
-  \d+
+token hex_constant {
+  0x\d+
 }
 
-# FIXTHIS
-regex binary_constant {
-  \d+
+token binary_constant {
+  0b\d+
 }
 
 token float_constant {
@@ -724,10 +722,13 @@
 
 
 rule string_constant {
-  ? 
+	[ ?  ]?
   [  |  ]
 }
 
+rule encoding_specifier {
+	<'utf8:'>
+}
 
 rule charset_specifier {
   [ <'ascii:'> | <'binary:'> | <'unicode:'> | <'iso-8859-1:'> ]  
Index: languages/PIR/t/assign.t
===
--- languages/PIR/t/assign.t	(revision 16923)
+++ languages/PIR/t/assign.t	(working copy)
@@ -3,7 +3,7 @@
 use strict;
 use warnings;
 use lib qw(t . lib ../lib ../../lib ../../../lib);
-use Parrot::Test tests => 6;
+use Parrot::Test tests => 7;
 use Test::More;
 
 language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'simple assignments' );
@@ -18,6 +18,16 @@
 Parse successful!
 OUT
 
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'int/hex/bin' );
+.sub main			
+	a = 10
+	b = 0b10
+	c = 0x10	
+.end
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
 
 language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'get keyed assignments' );
 .sub main			
@@ -93,6 +103,7 @@
 	s = binary:"Hello WOrld"
 	s = unicode:"Hello world"
 	s = iso-8859-1:"Hello world"		 
+	s = utf8:unicode:"Hello World"
 .end
 CODE
 "parse" => PMC 'PIRGrammar' { ... }


[PATCH] languages/PIR add command line options for output of pirc.pir (Parse/PAST/PIR)

2007-02-12 Thread Klaas-Jan Stol

hi,

attached a patch for lang/PIR fixing:

* add command line options to specify the kind of output:
   - parse only (used for tests currently)
   - PAST
   - PIR
   - parse and dump parse tree.
   (I stole the code from tge.pir)

regards,
kjs
Index: languages/PIR/pirc.pir
===
--- languages/PIR/pirc.pir	(revision 16932)
+++ languages/PIR/pirc.pir	(working copy)
@@ -1,17 +1,21 @@
-.namespace [ 'PIR' ]
+#
+# specify a different namespace than "PIR", as "PIR" is a built-in language
+#
+.namespace [ 'PIR-lang' ]
 
 .include "errors.pasm"
 
-.sub '__onload' :load, :init
+.sub '__onload' :load :init
 load_bytecode 'PGE.pbc'
-load_bytecode 'Parrot/HLLCompiler.pir'
+load_bytecode 'Parrot/HLLCompiler.pbc'
 load_bytecode 'PAST-pm.pbc'
 load_bytecode 'PGE/Util.pbc'
-
+load_bytecode 'PGE/Text.pbc'
+
 load_bytecode 'languages/PIR/lib/ASTGrammar.pbc'
 
 $P0 = new [ 'HLLCompiler' ]
-$P0.'language'('PIR')
+$P0.'language'('languages-PIR')
 $P0.'parsegrammar'('PIRGrammar')
 $P0.'astgrammar'('ASTGrammar')
 
@@ -19,57 +23,116 @@
 
 .sub 'main' :main
 .param pmc args
-
-## prevent printing of ASTs to the screen
-#load_bytecode 'PGE/Dumper.pbc'
-#load_bytecode 'dumper.pbc'
-
-$P0 = compreg 'PIR'
-
+   
+   	# get program name for error reporting		
+		.local string prog
+		prog = shift args
+		
+		# Sanity check parameters
+$I0 = args
+unless $I0 >= 1 goto ERR_TOO_FEW_ARGS
+		
+		# Register the PIR compiler		
+$P0 = compreg 'languages-PIR'
+
 # set up a global variable to keep track of syntax errors
 .local pmc errs
 errs = new .Integer
 set_root_global 'errors', errs
 
-push_eh unexpected_exc
+		
+		# Process command line options
+		load_bytecode "Getopt/Obj.pir"
+		
+.local pmc getopts
+getopts = new "Getopt::Obj"
+getopts."notOptStop"(1)
+push getopts, "output|o=s"
+push getopts, "help|h"
+.local pmc opts
+opts = getopts."get_options"( args )
+
+# put back the program name
+unshift args, prog
+
+# handle help option
+.local string help
+help = opts['help']
+if help goto USAGE
+
+# handle target option
+  	.local string output
+output = opts['output']
+unless output goto OPTIONS_DONE
+if output == "PARSE" goto TARGET_PARSE 
+if output == "PAST" goto TARGET_PAST
+if output == "PIRTIDY" goto TARGET_PIR
+if output == "PARSETREE" goto TARGET_PARSETREE
+goto ERR_UNKNOWN_TARGET
+
+  OPTIONS_DONE:  	  			
+
+  TARGET_PARSE:
 $P1 = $P0.'command_line'(args, 'target' => 'parse')
-#$P1 = $P0.'command_line'(args, 'target' => 'past')
-#$P1 = $P0.'command_line'(args)
-if errs > 0 goto err_msg
-print "Parse successful!\n"
-
-clear_eh
+goto DONE
+
+  TARGET_PARSETREE:
+  	load_bytecode 'PGE/Dumper.pbc'
+load_bytecode 'dumper.pbc'  
+$P1 = $P0.'command_line'(args, 'target' => 'parse')
+goto DONE
+
+  TARGET_PAST:
+$P1 = $P0.'command_line'(args, 'target' => 'past')
+goto DONE
+
+  TARGET_PIR:   
+$P1 = $P0.'command_line'(args, 'target' => 'PIR')
+goto DONE
+
+  ##COMPILE_AND_RUN:   
+  ##  $P1 = $P0.'command_line'(args)
+ 		
+  DONE:
+if errs > 0 goto ERR_MSG
+print "Parse successful!\n"
 .return($P1)
 
- err_msg:
-printerr "There "
-if errs == 1 goto one_error
-printerr "were "
+  ERR_MSG: 		
+if errs == 1 goto ONE_ERROR
+printerr "There were"   
 printerr errs
-printerr " errors.\n"
+printerr " errors.\n"
 end
 
- one_error:
-printerr "was 1 error.\n"
+  ONE_ERROR: 		
+printerr "There was 1 error.\n"
 end
+
+  USAGE:
+ 		printerr "Usage: "
+printerr prog
+printerr " [OPTIONS] FILE\n"
+printerr <<"OPTIONS"
+ 	Options:  	
+  	--help-- print this message
+  	--output=TARGET   -- specify target 
+  	  possible targets are:
+  	 PARSE -- parse only (default)
+  	 PAST  -- print Parrot AST
+  	 PIRTIDY   -- print generated PIR code
+  	 PARSETREE -- parse and print parse tree 
+OPTIONS
+exit 1
 
- unexpected_exc:
-.local pmc exception, message
-.get_results (exception, message)
-printerr "Unexpected exception: "
-if null message goto no_msg
-if null exception goto no_exc
-
-printerr message
-printerr "\n"
-end
-
- no_msg:
-printerr "No message"
-end
- no_exc:
-printerr "No exception\n"
-end
+	ERR_TOO_FEW_ARGS:
+		printerr "Error: too few arguments\n"
+		goto USAGE
+	ERR_UNKNOWN_TARGET:
+		printerr "Error: "
+		printerr output
+		printerr " is an unknown target\n"		
+		exit 1		
 .end
 
 
@@ -97,54 +160,56 @@
 
 
 .sub warning
-  .param pmc self
-  .param string message
-
-
-  if null self goto no_self
-  if null message goto no_msg
-
-  printerr "Warning: "
-  $P0 = 

[PATCH] languages/PIR more Tree Transformations

2007-02-12 Thread Klaas-Jan Stol

hi

attached a patch for lang/PIR fixing:

* extended TGE, but far from complete
* minor changes in .pg file

regards,
kjs
Index: languages/PIR/lib/ASTGrammar.tg
===
--- languages/PIR/lib/ASTGrammar.tg	(revision 16957)
+++ languages/PIR/lib/ASTGrammar.tg	(working copy)
@@ -9,6 +9,7 @@
 transform past (ROOT) :language('PIR') { 
 .local pmc past
 		past = new 'PAST::Block'
+		#past.'init'('node'=>node)
 		past.'init'('node'=>node, 'name'=>'anon')
 
 .local pmc childnode, childpast
@@ -16,6 +17,7 @@
 childpast = tree.'get'('past', childnode, 'PIRGrammar::program')
 		past.'push'(childpast)
 .return (past)  
+#.return (childpast)
 }
 
 # past (PIRGrammar::program)
@@ -82,27 +84,46 @@
 # Transform a sub_def into a PAST::Block node.
 #
 transform past (PIRGrammar::sub_def) :language('PIR') {		
-		printerr "subdef\n"
-		.local pmc result
-  	result = new 'PAST::Block'
+		
+		.local pmc past
+  	past = new 'PAST::Block'
+  	
   	.local string name
 name = node['sub_id']
-result.'init'('node'=>node, 'name'=> name, 'blocktype'=>'sub')
-.local pmc child
+past.'init'('node'=>node, 'name'=> name, 'blocktype'=>'sub')
 
-# TODO: parameters
+.local pmc pnode, pragma
+pnode = node['sub_pragmas']
+if null pnode goto skip_pragma
+ 		pragma = tree.'get'('past', pnode, 'PIRGrammar::sub_pragma') 		
+past.'pragma'(pragma)
+  skip_pragma:
 
+.local pmc child   
 $P1 = node['body']
 child = tree.'get'('past', $P1, 'PIRGrammar::body')
-result.'push'(child)
-.return(result)
+past.'push'(child)
+.return (past)
 }
 
+#transform past (PIRGrammar::sub_pragmas) {
+#		
+#}
+
+transform past (PIRGrammar::sub_pragma) {
+		.local pmc past		
+		past = node[':main'] ### mmm why does *this* work for all pragmas??
+		if null past goto skip
+		.return (past)		
+	skip:
+		.return ()
+}
+
 transform past (PIRGrammar::const_def) :language('PIR') {
 	.local pmc past
 	past = new 'PASM::Op'
 	# FIX:
-	past.'init'('node'=>node, 'pasttype'=>'pirop', 'pirop'=>'const')	
+	past.'init'('node'=>node, 'pasttype'=>'pirop', 'pirop'=>'.const')	
 	.return (past)
 }
 
@@ -110,83 +131,206 @@
 
 }
 
-transform past (PIRGrammar::pragma_def) :language('PIR') {
-	.local pmc past
-	past = new 'PASM::Op'	
-	past.'init'('node'=>node, 'pasttype'=>'pirop', 'pirop'=>'.pragma')	
-	.return (past)
+transform past (PIRGrammar::pragma) :language('PIR') {
+		.local pmc past
+		
+	include_pragma:
+		$P0 = node['.include']
+		if null $P0 goto n_op_pragma
+		past = new 'PASM::Op'	
+		past.'init'('node'=>node, 'pasttype'=>'pirop', 'pirop'=>'.include')	
+		.return (past)
+	n_op_pragma:
+		if null $P0 goto loadlib_pragma
+		past = new 'PASM::Op'	
+		past.'init'('node'=>node, 'pasttype'=>'pirop', 'pirop'=>'.include')	
+		.return (past)
+	loadlib_pragma:
+		if null $P0 goto namespace_pragma
+		past = new 'PASM::Op'	
+		past.'init'('node'=>node, 'pasttype'=>'pirop', 'pirop'=>'.include')	
+		.return (past)
+	namespace_pragma:
+		if null $P0 goto hll_map_pragma
+		past = new 'PASM::Op'	
+		past.'init'('node'=>node, 'pasttype'=>'pirop', 'pirop'=>'.include')	
+		.return (past)
+	hll_map_pragma:
+		if null $P0 goto hll_spec_pragma
+		past = new 'PASM::Op'	
+		past.'init'('node'=>node, 'pasttype'=>'pirop', 'pirop'=>'.include')	
+		.return (past)
+	hll_spec_pragma:
+		if null $P0 goto source_pragma
+		past = new 'PASM::Op'	
+		past.'init'('node'=>node, 'pasttype'=>'pirop', 'pirop'=>'.include')	
+		.return (past)
+	source_pragma:
+		if null $P0 goto unknown
+		past = new 'PASM::Op'	
+		past.'init'('node'=>node, 'pasttype'=>'pirop', 'pirop'=>'.include')	
+		.return (past)
+	unknown:
+		printerr "unknown pragma in tree transformation\n"
+		end
+	
 }
 
 transform past (PIRGrammar::emit) :language('PIR') {
-	
+		.local pmc past, startop, endop
+		past = new 'PAST::Block'
+		past.'init'('node'=>node)
+		
+		#startop = new 'PAST::Op'
+		#startop.'init'('node'=>node, 'pasttype'=>'inline', 'inline'=>'.emit')
+		#past.'push'(startop)
+		
+		#endop = new 'PAST::Op'
+		#endop.'init'('node'=>node, 'pasttype'=>'inline', 'inline'=>'.eom')
+		#past.'push'(endop)
+		
+		.return (past)	
 }
 
-#transform past (PIRGrammar::param) :language('PIR') {
-#	
-#}
 
 # past (PIRGrammar::body)
 #
 # Store each of the instructions in a body node in a PAST::Stmts node.
 #
-transform past (PIRGrammar::body) :language('PIR') {
-		printerr "body\n"
+transform past (PIRGrammar::body) :language('PIR') {		
 .local pmc past
 past = new 'PAST::Stmts'
 past.'init'('node'=>node)		
-		
+
 .local pmc iter
+.local pmc cnode, cpast
+
+# process the parameter declarations
+$P0 = node['param_decl']
+if null $P0 goto iter_param_end
+iter = new .Iterator, $P0
+  iter_param_loop:
+  	unless iter goto iter_param_end
+  	cnode = shift iter
+cpast = tree.'get'('past', cnode, 'PIRGrammar::param_decl')
+past.'

PAST-pm: only PAST::Block allowed at root of PAST

2007-02-14 Thread Klaas-Jan Stol

hello,

It was discussed before, but I'm not sure what was the result; PAST-pm 
only allows a PAST::Block node to be returned from transform (ROOT). 
However, in languages/PIR, the top level construct is a compilation 
unit, which may be an include statement. An include statement should not 
be enclosed by a subroutine.


Will PAST-pm be able to handle this?

regards,
klaas-jan


[PATCH] languages/PIR updates

2007-02-15 Thread Klaas-Jan Stol

hi,

attached a patch for languages/PIR, fixing:

* changed PIRGrammar into PIR::Grammar (changes many files)
* updated pirgrammar.pod
* updates to ASTGrammar.tg

regards,
kjs
Index: languages/PIR/docs/pirgrammar.pod
===
--- languages/PIR/docs/pirgrammar.pod	(revision 17008)
+++ languages/PIR/docs/pirgrammar.pod	(working copy)
@@ -308,7 +308,7 @@
 	  .param num nParam
 	  .param pmc argv :slurpy
 	  .param string sParam :named('foo')
-	  .param $P0 :named('bar')
+	  .param $P0 :named('bar')	  
 	  # body
 	.end
 
@@ -327,8 +327,16 @@
 
  :named('x')
 
-The parameter is known in the called sub by name C<'x'>.
+The parameter is known in the called sub by name C<'x'>. The C<:named> flag can also be used B an 
+identifier, in combination with the C<:flat> or C<:slurpy> flag, i.e. on a container holding several values:
 
+	.param pmc args :slurpy :named
+
+and
+
+	.arg args :flat :named
+	
+
 =item *
 
  :optional
@@ -453,6 +461,15 @@
 	.local pmc p
 	.lex 'i', p
 
+The same is true when a parameter should be stored as a lexical:
+
+	.param pmc p
+	.lex 'i', p
+	
+So, now it is also clear why C<.lex 'i', p> is B a declaration of p:
+it needs a separate declaration, because it may either be a C<.local> or a C<.param>.
+The C<.lex> directive merely is a shortcut for saving and retrieving lexical variables.
+
 =head2 Global definitions
 
   global_def:
@@ -795,8 +812,14 @@
 
 Pass the denoted argument into the named parameter that is denoted by 'x', like so:
 
- .param   :named('x')
+ .param int myX :named('x')   # the type 'int' is just an example
 
+As was mentioned at the parameter declaration section, the C<:named> section can be used
+on an aggregate value in combination with the C<:flat> flag.
+
+ .arg pmc myArgs :flat :named
+ 
+
 =back
 
 	.local pmc arr
@@ -840,6 +863,7 @@
 	obj.'toString'() # call the method 'toString'
 	obj.x() # call the method whose name is stored in 'x'.
 
+Note that no spaces are allowed between the invocant and the dot; "obj . 'toString'" is not valid.
 IMCC also allows the "->" instead of a dot, to make it readable for C++ programmers:
 
 	obj->'toString'()
@@ -929,7 +953,14 @@
 	foo() # returns 42
 	foo() # returns 43
 
+NOTE: IMCC allows for writing:
 
+	.pcc_begin_yield
+	...
+	.pcc_end_return
+
+which is of course not consistent; languages/PIR does B allow this.
+
 =head2 Short yield statements
 
   short_yield_stat:
@@ -956,8 +987,11 @@
 	.return(results)
 
 The call to C can be considered a normal function call with respect to parameters: it can take the exact
-same format using argument flags.
+same format using argument flags. The tail call can also be a method call, like so:
 
+	.return obj.'foo'()
+	
+
 =head2 Symbol namespaces
 
   open_namespace:
@@ -1132,8 +1166,11 @@
 =head2 Tokens, types and targets
 
   string_constant:
-charset_specifier?  quoted_string
+[ encoding_specifier? charset_specifier ]?  quoted_string
 
+  encoding_specifier:
+"utf8:"
+
   charset_specifier:
   "ascii:"
 | "binary:"
@@ -1161,7 +1198,11 @@
 but if desirable, the character set can be specified:
 
 	unicode:"Hello world"
+	
+When using the "unicode" character set, one can also specify an encoding specifier; currently only C is allowed:
 
+	utf8:unicode:"hello world"
+
 IMCC currently allows identifiers to be used as types. During the parse, the identifier
 is checked whether it is a defined class. The built-in types int, num, pmc and string are
 always available.
Index: languages/PIR/examples/test.pir
===
--- languages/PIR/examples/test.pir	(revision 17008)
+++ languages/PIR/examples/test.pir	(working copy)
@@ -1,3 +1,4 @@
+.include 'HELLO'
 
 
 .sub 'main' :main
Index: languages/PIR/lib/ASTGrammar.tg
===
--- languages/PIR/lib/ASTGrammar.tg	(revision 17008)
+++ languages/PIR/lib/ASTGrammar.tg	(working copy)
@@ -10,21 +10,21 @@
 .local pmc past
 		past = new 'PAST::Block'
 		#past.'init'('node'=>node)
-		past.'init'('node'=>node, 'name'=>'anon')
+		past.'init'('node'=>node, 'blocktype'=>'immediate', 'name'=>'anon')
 
 .local pmc childnode, childpast
 childnode = node['program']
-childpast = tree.'get'('past', childnode, 'PIRGrammar::program')
+childpast = tree.'get'('past', childnode, 'PIR::Grammar::program')
 		past.'push'(childpast)
 .return (past)  
 #.return (childpast)
 }
 
-# past (PIRGrammar::program)
+# past (PIR::Grammar::program)
 #
 # Store each of the compilation units into a PAST::Stmts node.
 #
-transform past (PIRGrammar::program) :language('PIR') {
+transform past (PIR::Grammar::program) :language('PIR') {
 .local pmc past
 past = new 'PAST::Stmts'
 past.'init'('node'=>node)
@@ -37,53 +37,53 @@
 unless iter goto iter_end
 .local pmc cnode, cpast
 cnode = shift iter
-cpast 

[PATCH] lang/PIR macros!

2007-02-16 Thread Klaas-Jan Stol

hi,

* attached a patch that implements better macro parsing
* begin of better heredoc parsing,but not finished yet.
* added test for macro parsing

regards,
klaas-jan

Index: languages/PIR/examples/macro2.pir
===
--- languages/PIR/examples/macro2.pir	(revision 0)
+++ languages/PIR/examples/macro2.pir	(revision 0)
@@ -0,0 +1,49 @@
+.sub main
+	.local int i
+	#.a = 1
+	a = a
+	.X(a,b)
+.end
+
+
+.macro X(a,b)
+	.local $x: doit()
+	
+	
+	loop: doit()
+	.a = .b
+	.sym int i
+.endm
+
+.sub main
+	.local int i
+	#.a = 1
+	a = a
+	.X(a,b)
+.end
+
+
+.macro X(a,b)
+	.local $x: doit()
+	
+	
+	loop: doit()
+	.a = .b
+	.sym int i
+.endm
+
+.macro X(a,b)
+	.local $x: doit()
+	
+	
+	loop: doit()
+	.a = .b
+	.sym int i
+.endm
+
+.sub main
+	.local int i
+	#.a = 1
+	a = a
+	.X(a,b)
+.end
Index: languages/PIR/lib/pir.pg
===
--- languages/PIR/lib/pir.pg	(revision 17016)
+++ languages/PIR/lib/pir.pg	(working copy)
@@ -2,8 +2,7 @@
 
 # TO DO:
 # 1. fix Heredocs parsing
-# 2. fix macro parsing
-# 3. Test and fix things
+# 2. Test and fix things
 
 token TOP {
   ^  [ $ |  ]
@@ -151,14 +150,11 @@
   
 }
 
-# this is a token, because no spaces are allowed between
-# the id and the colon.
-token label {
-   <':'>
-}
 
+
 rule pir_instr {
 
+  | 
   | 
   | 
   | 
@@ -181,12 +177,28 @@
 ## Locals and Lexicals
 ## 
 
+
+=head2 Local declarations
+
+Local declarations can be done using C<.sym> or C<.local> in normal context.
+In macro context however, only C<.sym> is allowed, and the C<.local> keyword
+indicates a label declaration. 
+
+=cut
+
 rule local_decl {
-  [ <'.local'> | <'.sym'> ]
+  <'.local'>
   [  |  ]
   
 }
 
+rule sym_decl {
+	<'.sym'>
+	[  |  ]
+  
+}
+
+
 rule local_id_list {
[ <','>  ]*
 }
@@ -261,8 +273,8 @@
 }
 
 rule conditional_expr {
-		[ <'null'>  ]
-  | [  [   ]? ]
+		<'null'>  
+  |  [   ]?
 }
 
 ## Jump statements
@@ -461,7 +473,9 @@
   | [  <'->'> ]
   ]?   # optional invocant
   [  |  ] # method or sub name/id
-   # sub args
+   # sub args  
+  
+  
 }
 
 rule sub_invocation {
@@ -500,11 +514,20 @@
   [  |  ]
 ]?
   | 
+  | 
   ] ?
 }
 
+token heredoc_id {
+	<'<<'>  
+}
 
+rule heredoc_label {
+	.* ^^  $$
+}
 
+
+
 ## Argument passing
 ##
 rule arguments {
@@ -633,10 +656,15 @@
   [ <')'>   |  ]
 }
 
- TODO: FIX
+# In order to be able to parse macro identifiers, before 
+# the macro body is parsed, some rules are redefined. 
+# After parsing the macro body, they are restored.
+#
 regex macro_body {
-  .*?
-  <'.endm'> \h* \n
+	
+  *  
+  <'.endm'>
+  
 }
 
 
@@ -713,6 +741,22 @@
 # Tokens
 #
 
+# this is a token, because no spaces are allowed between
+# the id and the colon.
+token normal_label {
+ 	 <':'>
+}
+
+
+token macro_label {
+	<'$'>  <':'>
+}
+
+rule macro_label_decl {
+		<'.local'> [  |  ]
+	|	
+}
+
 token int_constant {
 
   | 
@@ -762,10 +806,17 @@
   
 }
 
-token target {
-  [  |  ]
+token normal_target {
+	 |  
 }
 
+# in a macro, a target can also be a 
+# macro_id
+#
+token macro_target {
+	 |  | 
+}
+
 token id {
\w+
 }
Index: languages/PIR/pirc.pir
===
--- languages/PIR/pirc.pir	(revision 17016)
+++ languages/PIR/pirc.pir	(working copy)
@@ -40,6 +40,9 @@
 errs = new .Integer
 set_root_global 'errors', errs
 
+		.local pmc labels
+		labels = new .ResizablePMCArray		
+		set_root_global 'heredoc', labels
 		
 		# Process command line options
 		load_bytecode "Getopt/Obj.pir"
@@ -100,7 +103,7 @@
 
   ERR_MSG: 		
 if errs == 1 goto ONE_ERROR
-printerr "There were"   
+printerr "There were "   
 printerr errs
 printerr " errors.\n"
 end
@@ -158,37 +161,86 @@
 load_bytecode 'languages/PIR/lib/pasm_core_gen.pbc'
 .end
 
-.sub parenthesized_args_2
-	.param pmc mob	
-	.param pmc adverbs :slurpy :named
-	.local pmc match
-	.local string target
-	.local int cpos, mfrom, mpos	
+
+
+
+.sub process_heredocs
+		.param pmc mob
+		
 	
-	(mob, target, mfrom, mpos) = mob.'newfrom'(mob)
-	printerr "Target: ["
-	printerr target
-	printerr "]"
+		.local pmc labels
+		labels = get_root_global "heredoc"
+		.local pmc id
+		.local int count, i
+		
+		count = labels
+		i = 0
+	
+	loop:	
+		if i >= count goto endloop
+		id = shift labels		
+		i += 1
+		
+		printerr id
+		#mob = heredoc_label(mob)
+		#heredoc_label()
+
+		goto loop
+	endloop:
+
+.end
+
+
+
+.sub store_heredoc_label
+	.param pmc mob
+	.param pmc heredocid
+	
+	printerr heredocid
 	printerr "\n"
-	$S0 = mob.'text'()
-	printerr $S0
-	mob.'next'()
-	$S0 = mob.'text'()
-	printerr $S0  
- 
-	#
-	#printerr match
-	#printerr "\n"
-	#
-	#printerr cpos
-	#printerr "\n"
-	#printerr target
-	#printerr "\n"
-	.return(mob)
+		
+	.local pmc labels
+	labels = get_root_global "heredoc"
+	push labels, heredocid
+	
+#

[PATCH] languages/lua PGE grammar fix

2007-02-16 Thread Klaas-Jan Stol

hi,

attached a patch for the PGE implementation of the Lua parser (lua.pg).

fixing:

* make  rule match longest identifiers, not keyword-prefixed 
identifiers (like "for" in "format")

* fix parameter list rule
* all examples in the lua distribution (in the test directory) can be 
parsed correctly now.


regards,
klaas-jan
Index: languages/lua/src/lua.pg
===
--- languages/lua/src/lua.pg	(revision 17016)
+++ languages/lua/src/lua.pg	(working copy)
@@ -128,14 +128,13 @@
   [  |  ]*
 }
 
-
 rule parlist {
-[  [ <','> <'...'> ]? ]?
+ [ <','> <'...'> ]? 
   | <'...'>
 }
 
 rule body {
-  <'('>
+  <'('> ?   
 }
 
 rule explist1 {
@@ -147,7 +146,7 @@
 }
 
 rule funcargs {
-<'('> ? 
+<'('> ?  
   | 
   | 
 }
@@ -282,7 +281,7 @@
 =cut
 
 token name {
-   \b 
+   \b  
 }
 
 
@@ -317,12 +316,20 @@
 ]*
 }
 
+=head2 Keywords
 
+Lua keywords may B be used as identifiers. To make sure the longest
+identifier is matched, so that identifiers that B with a keyword
+is still an identifier, a keyword should end at a word boundary.
+This way, for instance, the identifier C is not read as C.
+
+=cut
+
 token keyword {
-<'and'>  |  <'break'> | <'do'>| <'elseif'>
+  [  <'and'> | <'break'>  | <'do'>| <'elseif'>
   | <'else'> | <'end'>| <'false'> | <'for'>
   | <'function'> | <'if'> | <'in'>| <'local'>
   | <'nil'>  | <'not'>| <'or'>| <'repeat'>
   | <'return'>   | <'then'>   | <'true'>  | <'until'>
-  | <'while'>
+  | <'while'> 	 ] \b
 }


[PATCH] languages/PIR

2007-02-17 Thread Klaas-Jan Stol

attached a patch for fixing
* some things for parsing PASM instructions correctly
* minor updates to pir.pg

regards,
kjs
Index: languages/PIR/lib/pasm_args.pg
===
--- languages/PIR/lib/pasm_args.pg	(revision 17016)
+++ languages/PIR/lib/pasm_args.pg	(working copy)
@@ -1,4 +1,4 @@
-grammar PIRGrammar;
+grammar PIR::Grammar;
 
 # This file contains helper rules to handle
 # the PASM instruction arguments. Many instructions
Index: languages/PIR/lib/pasm_core.pg
===
--- languages/PIR/lib/pasm_core.pg	(revision 17016)
+++ languages/PIR/lib/pasm_core.pg	(working copy)
@@ -7,59 +7,59 @@
   #
   end
 | noop
-| reserved 
-| load_bytecode   
+| reserved # 
+| load_bytecode#
   #
   # control flow
   #
-| branch  
-| branch_cs   
-| bsr 
+| branch   #
+| branch_cs#
+| bsr  #
 | ret
 | jsr 
 | enternative
   # conditional branch
-| if   \, 
-| unless   \, 
-  # subroutine ops
-| invokecc 
-| invoke   \, 
-| yield
-| tailcall
-| returncc
-| newclosure   \, 
+| if   # \, 
+| unless   # \, 
+  # subroutine ops  #
+| invokecc  # 
+| invoke# \, 
+| yield #
+| tailcall  #
+| returncc  #
+| newclosure# \, 
   # function args ops
-| set_args
-| get_results  
-| get_params  
-| set_returns 
+| set_args # 
+| get_results  #  
+| get_params   # 
+| set_returns  # 
 | result_info 
   # address manipulation  
-| set_addr # \, 
-| get_addr # \,  
+| set_addr # \, 
+| get_addr # \,  
   # exception handling
 | push_eh  #
 | clear_eh #
-| throw#
-| rethrow  #
+| throw#
+| rethrow  #
 | die  # \, 
 | exit # 
 | pushmark #
 | popmark  #
-| pushaction   #
+| pushaction   #
   # interpreter ops
 | debug#
 | bounds   #
 | profile  #
 | trace#
 | gc_debug #
-| interpinfo   # \, 
+| interpinfo   # \, 
 | warningson   #
 | warningsoff  #
 | errorson #
 | errorsoff#
-| runinterp# \, 
-| getinterp# 
+| runinterp# \, 
+| getinterp# 
   # DOD/GC
 | sweep#
 | collect 
@@ -67,11 +67,11 @@
 | sweepon 
 | collectoff  
 | collecton   
-| needs_destroy#
+| needs_destroy#
   # NCI   
-| loadlib  # \, 
-| dlfunc   # \,  \,  \, 
-| dlvar# \,  \, 
-| compreg  # \, 
-| new_callback # \,  \,  \, 
+| loadlib  # \, 
+| dlfunc   # \,  \,  \, 
+| dltarget# \,  \, 
+| compreg  # \, 
+| new_callback # \,  \,  \, 
 }
Index: languages/PIR/lib/pasm_instr.pg
===
--- languages/PIR/lib/pasm_instr.pg	(revision 17016)
+++ languages/PIR/lib/pasm_instr.pg	(working copy)
@@ -7,320 +7,322 @@
 # PGE implements this.
 
 token pasm_instruction {
-  end 
-| noop
-| reserved
-| load_bytecode 
-| branch  
-| branch_cs   
-| bsr 
-| ret 
-| jsr
-| enternative 
-| if  
+[ yield 
+| xor   
+| warningson
+| warningsoff  
+| valid_type
+| upcase
+| unshift   
+| unregister
+| unpin 
+| unless_null   
 | unless
-| invokecc
-| invoke  
-| yield   
-| tailcall
-| returncc
+| typeof
+| trans_encoding
+| trans_charset 
+| trace 
+| titlecase 
+| time  
+| throw 
+| thaw  
+| tell  
+| tanh  
+| tan   
+| tailcallmethod
+| tailcall  
+| sysinfo   
+| sweepon   
+| sweepoff  
+| sweep 
+| substr
+| subclass  
+| sub   
+| stringinfo
+| store_lex 
+| stat  
+| sqrt  
+| sprintf   
+| split 
+| spawnw
+| socket
+| sockaddr  
+| sleep 
+| sizeof
+| sinh  
+| singleton 
+| sin   
+| shr   
+| shl   
+| shift 
+| setstdout 
+| setstderr 
+| sets_ind  
+| setref
+| setprop
+| setp_ind  
+| setn_ind

[PATCH] #39615: [TODO] get_outer op not defined in PDDs

2007-02-18 Thread Klaas-Jan Stol

hi,

I was browsing the TODO list for some low hanging fruit, and saw a 
request for updating PDD20.


Attached a patch that adds a description of get_outer() according to 
t/op/lexicals.t to PDD20.


regards,
klaas-jan
Index: docs/pdds/pdd20_lexical_vars.pod
===
--- docs/pdds/pdd20_lexical_vars.pod	(revision 17016)
+++ docs/pdds/pdd20_lexical_vars.pod	(working copy)
@@ -80,7 +80,7 @@
 Parrot runtime stores and fetches lexical variables.
 
 At run time, each call frame for a Subroutine (or Subroutine derivative) that
-uses lexical variables will be populated with a PMC of HLL-mapped 
+uses lexical variables will be populated with a PMC of HLL-mapped
 type LexPad.  Note that call frames for subroutines without lexical
 variables will omit the LexPad.
 
@@ -341,11 +341,41 @@
 $P0 = getinterp
 $P1 = $P0["lexpad"; 1]
 
+To access a sub's C<:outer> subroutine, use the C method:
+
+.include "interpinfo.pasm"
+interpinfo $P1, .INTERPINFO_CURRENT_SUB
+$P2 = $P1."get_outer"()
+
+Here, C<$P1> contains information on the current subroutine. C<$P2> will
+contain C<$P1>'s outer subroutine.
+
+To get C<$P2>'s outer subroutine (if any), the same method can be used on C<$P2>
+itself:
+
+$P3 = $P2."get_outer"()
+
+
+Using the C instruction is one way to do it. Another way is this:
+
+$P0 = getinterp
+$P1 = $P0["outer"; "sub"]
+$P2 = $P0["outer"; "sub"; 2] # get the outer sub of the current's outer subroutine
+
+It is also possible to get the C<:outer> sub's LexPad, as above:
+
+$P0 = getinterp
+$P1 = $P0["outer"; "lexpad"]
+
+See [1] for an example.
+
 It's likely that this interface will continue to be available even once call
 frames become visible as PMCs.
 
+
 TODO: Full interpreter introspection interface.
 
+
 =head1 ATTACHMENTS
 
 None.
@@ -356,8 +386,14 @@
 
 =head1 REFERENCES
 
-None.
+=over 4
 
+=item [1]
+
+t/op/lexicals.t
+
+=back
+
 =cut
 
 __END__


[PATCH] updates for docs/faq.pod

2007-02-18 Thread Klaas-Jan Stol

hi,

I made some small updates to faq.pod, regarding TODO ticket  #41312: 
[TODO] - Docs - update FAQ.


updating:

* updated languages section
* updated PASM to PIR usage
* removed VERSION section as suggested in the ticket.

It does NOT fix:
* I left Parrot/Perl6 in, I'm not sure if it should be moved to perl 6 faq.
* updating Pugs.
* reduce humor to provide facts/refs.

Hope this helps,
klaas-jan



Index: docs/faq.pod
===
--- docs/faq.pod	(revision 17016)
+++ docs/faq.pod	(working copy)
@@ -37,14 +37,19 @@
 
 Yes.
 
-Parrot is in the early phases of its implementation.  The primary way to use
-Parrot is to write Parrot assembly code, described in L.
+Although Parrot is currently still under development, Parrot has been usable for 
+a long time. The primary way to use Parrot is to write Parrot Intermediate 
+Representation (PIR), described in L. PIR is a high-level 
+assembly language. PIR maps to the more low-level Parrot Assembly language (PASM),
+which is harder to write and read. Although you could write PASM instead of PIR,
+PIR is the recommended way to program your Parrot. See the examples to see what
+both PIR and PASM looks like.
 
 You can also create dynamic content within Apache using Ask Bjorn Hansen's
 mod_parrot module.  You are strongly advised that mod_parrot is a toy, and
 should not be used with any production code.
 
-=head2 Why should I program in Parrot Assembly language?
+=head2 Why should I program in PIR?
 
 Lots of reasons, actually.  :^)
 
@@ -56,60 +61,58 @@
 
 =item *
 
-It's a neat hack.
+It's easy to write and read.
 
 =item *
 
-You get all the pleasure of programming in assembly language without any of the
-requisite system crashes.
+You get all the pleasure of programming in assembly language (albeit a high-level
+assembly language) without any of the requisite system crashes.
 
 =back
 
-Seriously, though, programming in Parrot assembly language is an interesting
+Seriously, though, programming in PIR is an effective way to write
 challenge.  It's also one of the best ways to write test cases for Parrot.
 
 =head2 When can I expect to use Parrot with a I programming language?
 
-It depends on what you mean by I.  :^)
+You can already today! There are quite some high level languages being targeted
+to Parrot. Since the introduction of the Parrot Compiler Tools (the Parrot
+Grammar Engine (PGE) and the Tree Grammar Engine (TGE)), targeting a 
+language to Parrot has become a snap! Please note that, although some languages
+have come a long way, due to the fact that Parrot is still under active development,
+it's most safe to program in PIR. 
 
+Below is a list of some languages that are actively worked on.
+
 =over 4
 
 =item *
 
-Leon Brocard has released a proof-of-concept L compiler.
+Will Coleda and Matt Diephouse are working hard on their Tcl port to Parrot
+(called ParTcl). Will also created an APL implementation.
 
 =item *
 
-Gregor Purdy is working on a little language called Jako that targets Parrot
-bytecode directly.  (Available with the Parrot distribution.)
+Patrick R. Michaud is working on a Perl 6 implementation using the Parrot Compiler 
+Tools. (although the Perl 6 specification is not finished yet).
 
 =item *
 
-Dan Sugalski and Jeff Goff have started work on compiling Scheme down to Parrot
-bytecode.  (Available with the Parrot distribution.)
+François Perrad is working on a Lua implementation for Parrot.
 
 =item *
 
-Clint Pierce wrote an Integer Basic implementation in parrot assembly, which is
-shipped with the parrot distribution, as are a few example programs. (Including
-Hunt the Wumpus and Eliza)
+Allison Randal has been working on a Perl 1 port to Parrot, called Punie.
 
 =item *
 
-There's a Befunge interpreter in the languages directory
+Jonathan Worthington has been working on a .NET to Parrot translator.
 
 =item *
 
-There's an (ahem)BF interpreter in the languages directory. Be aware that BF is
-not, strictly speaking, the language's name, merely its initials.
+Many other languages are worked on, some more actively than others. See 
+C for a complete list.
 
-=item *
-
-There is a prototype Perl 6 implementation in the languages directory as well,
-though it's only as complete as the Perl 6 spec. (Which, at this writing, isn't
-sufficiently complete)
-
 =back
 
 =head2 What language is Parrot written in?
@@ -546,33 +549,4 @@
 
 =cut
 
-=head1 VERSION
 
-The FAQ is now in version control and "Revision" isn't really being tracked.
-The most recent SVN ID is C<$Id$>
-
-=over 4
-
-=item Revision 0.5 - 04 September 2002
-
-=item Revision 0.4 - 26 August 2002
-
-Fixed up the licensing bits
-
-=item Revision 0.3 - 13 March 2002
-
-Translated to POD and added "Why aren't we using external tool or library
-I?"
-
-=item Revision 0.2 - 03 December 2001
-
-Added the "Parrot and Perl" section and "Why Re-implement Perl".  Incorporated
-Dan's Q&A i

:anon flag bug?

2007-02-18 Thread Klaas-Jan Stol

hi,

I was working on a test for addmethod op (ticket #39196: [TODO] tests - 
need to test addmethod) and

tried this:

.sub main :main

# this works:
 hello()

# while this does not:   
 $P0 = find_name "hello"

 $P0()
.end


.sub hello :anon
   print "Hello world!\n"
.end

My question is, should the call "hello()" not fail as well? hello is an 
anonymous sub, so it should not be found when calling hello().


Is this a bug?

regards,
kjs



[PATCH] retry pir/pasm updates for lang/pir

2007-02-18 Thread Klaas-Jan Stol

hi,
attached a new patch, replacing the other one from 2/17.

kjs
Index: languages/PIR/lib/pasm_args.pg
===
--- languages/PIR/lib/pasm_args.pg	(revision 17016)
+++ languages/PIR/lib/pasm_args.pg	(working copy)
@@ -1,4 +1,4 @@
-grammar PIRGrammar;
+grammar PIR::Grammar;
 
 # This file contains helper rules to handle
 # the PASM instruction arguments. Many instructions
Index: languages/PIR/lib/pasm_core.pg
===
--- languages/PIR/lib/pasm_core.pg	(revision 17016)
+++ languages/PIR/lib/pasm_core.pg	(working copy)
@@ -7,59 +7,59 @@
   #
   end
 | noop
-| reserved 
-| load_bytecode   
+| reserved # 
+| load_bytecode#
   #
   # control flow
   #
-| branch  
-| branch_cs   
-| bsr 
+| branch   #
+| branch_cs#
+| bsr  #
 | ret
 | jsr 
 | enternative
   # conditional branch
-| if   \, 
-| unless   \, 
-  # subroutine ops
-| invokecc 
-| invoke   \, 
-| yield
-| tailcall
-| returncc
-| newclosure   \, 
+| if   # \, 
+| unless   # \, 
+  # subroutine ops  #
+| invokecc  # 
+| invoke# \, 
+| yield #
+| tailcall  #
+| returncc  #
+| newclosure# \, 
   # function args ops
-| set_args
-| get_results  
-| get_params  
-| set_returns 
+| set_args # 
+| get_results  #  
+| get_params   # 
+| set_returns  # 
 | result_info 
   # address manipulation  
-| set_addr # \, 
-| get_addr # \,  
+| set_addr # \, 
+| get_addr # \,  
   # exception handling
 | push_eh  #
 | clear_eh #
-| throw#
-| rethrow  #
+| throw#
+| rethrow  #
 | die  # \, 
 | exit # 
 | pushmark #
 | popmark  #
-| pushaction   #
+| pushaction   #
   # interpreter ops
 | debug#
 | bounds   #
 | profile  #
 | trace#
 | gc_debug #
-| interpinfo   # \, 
+| interpinfo   # \, 
 | warningson   #
 | warningsoff  #
 | errorson #
 | errorsoff#
-| runinterp# \, 
-| getinterp# 
+| runinterp# \, 
+| getinterp# 
   # DOD/GC
 | sweep#
 | collect 
@@ -67,11 +67,11 @@
 | sweepon 
 | collectoff  
 | collecton   
-| needs_destroy#
+| needs_destroy#
   # NCI   
-| loadlib  # \, 
-| dlfunc   # \,  \,  \, 
-| dlvar# \,  \, 
-| compreg  # \, 
-| new_callback # \,  \,  \, 
+| loadlib  # \, 
+| dlfunc   # \,  \,  \, 
+| dltarget# \,  \, 
+| compreg  # \, 
+| new_callback # \,  \,  \, 
 }
Index: languages/PIR/lib/pasm_instr.pg
===
--- languages/PIR/lib/pasm_instr.pg	(revision 17016)
+++ languages/PIR/lib/pasm_instr.pg	(working copy)
@@ -7,320 +7,322 @@
 # PGE implements this.
 
 token pasm_instruction {
-  end 
-| noop
-| reserved
-| load_bytecode 
-| branch  
-| branch_cs   
-| bsr 
-| ret 
-| jsr
-| enternative 
-| if  
+[ yield 
+| xor   
+| warningson
+| warningsoff  
+| valid_type
+| upcase
+| unshift   
+| unregister
+| unpin 
+| unless_null   
 | unless
-| invokecc
-| invoke  
-| yield   
-| tailcall
-| returncc
+| typeof
+| trans_encoding
+| trans_charset 
+| trace 
+| titlecase 
+| time  
+| throw 
+| thaw  
+| tell  
+| tanh  
+| tan   
+| tailcallmethod
+| tailcall  
+| sysinfo   
+| sweepon   
+| sweepoff  
+| sweep 
+| substr
+| subclass  
+| sub   
+| stringinfo
+| store_lex 
+| stat  
+| sqrt  
+| sprintf   
+| split 
+| spawnw
+| socket
+| sockaddr  
+| sleep 
+| sizeof
+| sinh  
+| singleton 
+| sin   
+| shr   
+| shl   
+| shift 
+| setstdout 
+| setstderr 
+| sets_ind  
+| setref
+| setprop
+| setp_ind  
+| setn_ind  
+| seti_ind  
+| setattribute  
+| set_ro

[PATCH] lang/PIR updates

2007-02-19 Thread Klaas-Jan Stol

hi
attached a patch for languages/PIR, fixing:

* added unique_reg to allowed flags for parameters
* updated pirgrammar.pod
* removed pirgrammar.html (can be generated)
* minor fixes for pir.pg (both syntax and comments, now in POD format)

regards,
kjs
Index: languages/PIR/docs/pirgrammar.pod
===
--- languages/PIR/docs/pirgrammar.pod	(revision 17047)
+++ languages/PIR/docs/pirgrammar.pod	(working copy)
@@ -1,6 +1,6 @@
 =head1 NAME
 
-PIR.pod - The Grammar of languages/PIR
+pirgrammar.pod - The Grammar of languages/PIR
 
 =head1 DESCRIPTION
 
@@ -19,7 +19,7 @@
 
 =head1 VERSION
 
-0.1.1
+0.1.2
 
 =head1 LEXICAL CONVENTIONS
 
@@ -39,9 +39,9 @@
   .eom.meth_call .pragma
   .get_results.namespace .return
   .global .nci_call  .result
-  .HLL_map.param .sub
-  .HLL.pcc_begin_return  .sym
-  .immediate  .pcc_begin_yield   .yield
+  .globalconst.param .sub
+  .HLL_map.pcc_begin_return  .sym
+  .HLL.pcc_begin_yield   .yield
   .include.pcc_begin
 
 
@@ -178,7 +178,7 @@
 ".end"
 
   param_decl:
-".param"  [ [ type identifier ] | register ] get_flags? nl
+".param"  [ [ type identifier ] | register ] [ get_flags | ":unique_reg" ]* nl
 
   get_flags:
 [ ":slurpy"
@@ -194,13 +194,14 @@
 
 The simplest example for a subroutine definition looks like:
 
-	.sub foo
-	# PIR instructions go here
-	.end
+  .sub foo
+  # PIR instructions go here
+  .end
 
 The body of the subroutine can contain PIR instructions. The subroutine can be given
 one or more flags, indicating the sub should behave in a special way. Below is a list of these
-flags and their meaning:
+flags and their meaning. The flag C<:unique_reg> is discussed in the section defining
+local declarations.
 
 =over 4
 
@@ -290,27 +291,28 @@
 that when "bar" is invoked, this sub is called I and I. It is undecided yet whether this flag will
 be implemented. If so, its syntax may change.
 
+
 =back
 
 The sub flags are listed after the sub name. They may be separated by a comma, but this is
 not necessary. The subroutine name can also be a string instead of a bareword, as is shown in this
 example:
 
-	.sub 'foo' :load, :init :anon
-	# PIR body
-	.end
+  .sub 'foo' :load, :init :anon
+  # PIR body
+  .end
 
 Parameter definitions have the following syntax:
 
-	.sub main
-	  .param int argc :optional
-	  .param int has_argc :optional
-	  .param num nParam
-	  .param pmc argv :slurpy
-	  .param string sParam :named('foo')
-	  .param $P0 :named('bar')	  
-	  # body
-	.end
+  .sub main
+.param int argc :optional
+.param int has_argc :optional
+.param num nParam
+.param pmc argv :slurpy
+.param string sParam :named('foo')
+.param $P0 :named('bar')
+# body
+  .end
 
 As shown, parameter definitions may take flags as well. These flags are listed here:
 
@@ -327,16 +329,16 @@
 
  :named('x')
 
-The parameter is known in the called sub by name C<'x'>. The C<:named> flag can also be used B an 
+The parameter is known in the called sub by name C<'x'>. The C<:named> flag can also be used B an
 identifier, in combination with the C<:flat> or C<:slurpy> flag, i.e. on a container holding several values:
 
-	.param pmc args :slurpy :named
+  .param pmc args :slurpy :named
 
 and
 
-	.arg args :flat :named
-	
+  .arg args :flat :named
 
+
 =item *
 
  :optional
@@ -402,15 +404,15 @@
 Local temporary variables can be declared by the directives C<.local> or C<.sym>. There is no
 difference between these directives, except within macro definitions. (See Macros).
 
-	.local int i
-	.local num a, b, c
-	.sym string s1, s2
-	.sym pmc obj
+  .local int i
+  .local num a, b, c
+  .sym string s1, s2
+  .sym pmc obj
 
 The optional C<:unique_reg> modifier will force the register allocator to associate the identifier
 with a unique register for the duration of the compilation unit.
 
-	.local int j :unique_reg
+  .local int j :unique_reg
 
 =head2 Lexical declarations
 
@@ -421,12 +423,12 @@
 
 The declaration
 
-	.lex 'i', $P0
+  .lex 'i', $P0
 
 indicates that the value in $P0 is stored as a lexical variable, named by 'i'.
 Once the above lexical declaration is written, and given the following statement:
 
-	$P1 = new .Integer
+  $P1 = new .Integer
 
 then the following two statements have an identical effect:
 
@@ -458,14 +460,14 @@
 
 Instead of a register, one can also specify a local variable, like so:
 
-	.local pmc p
-	.lex 'i', p
+  .local pmc p
+  .lex 'i', p
 
 The same is true when a parameter should be stored as a lexical:
 
-	.param pmc p
-	.lex 'i', p
-	
+  .param pmc p
+  .lex 'i', p
+
 So, now it is also clear why C<.lex 'i', p> is B a declaration of p:
 it needs a separate declaration, because it may either be a C<.local> or a C<.param>.
 The C<.lex> directive merely is a shortcut for saving and retrieving lexical variables.
@@ -483,7 +485,7 @@
 

Re: [perl #41237] [TODO] PMC Class name IDs will require a dot in front

2007-02-19 Thread Klaas-Jan Stol
This issue was not decided on, and in an attempt to fix this issue, so 
this TODO can be closed, a proposition below.


Allison Randal wrote:

Matt Diephouse wrote:

I actually prefer the dot. I don't like the possible ambiguity between
types and local variables:

   .local string MyClass
   MyClass = '...'
   $P0 = new MyClass # is this a type or a string?


At that point, what we're really talking about is sigils. So, why put 
sigils on types instead of putting them on variables? And is dot 
really the best sigil for types?



Capitalized variable names may be rare and/or bad practice, but it's
bound to happen. There was talk on #parrot about how this still
conflicts with macros, but those are rarer than variables.


If we're setting up a system to remove ambiguity, better to remove 
ambiguity entirely than move to a slightly less common ambiguity.



Also, if we decide that anything starting with a dot that doesn't have
parens is a type, I could write:

   $I0 = typeof $P0
   if $I0 == .Foo goto bar


You can do that already.


Klaas-Jan Stol wrote:
A dot also indicates that this is not pure PASM, but rather PIR. 


Except that the dot is required in PASM. Removing the dot was an added 
bit of PIR syntatic sugar, intended to make it more human-readable 
(and human-writable).


The dot implies the token is pre-processed by IMCC (the type is 
looked up during parsing, IIRC), which is, IMHO, more consistent with 
the other dot-prefixed tokens from PIR. 


Except it's not consistent. To a certain extent type IDs act like 
constants. You can:


  print .String

Or, you can create your own constant and print it (PASM here):

  .constant Foo 2
  print .Foo

But if you try to create a constant with the same name as a type ID, 
it is simply ignored:


  .constant String 1
  print .String

Prints "33" instead of the constant value "1".

It's an unfortunate conflict. (Not quite as unfortunate as the 
variablename/methodname conflict, but still pretty awful.)

The proposal with respect to the dot-prefix is this:
   * we keep the dot in front of Class IDs. (according to replies 
above, more people are in favor)
   * in order to get consistency, the ".constant  " 
construct from PASM should be removed. It makes me think a bit of 
#define's in C, and both in C and in PIR we have a better alternative:

   ".const"   "=" .

Not only is the ambiguity removed, it's also "type safe", it removes 
duplication of syntax (why have 2 ways to define constants?).


klaas-jan


Q on: #37542: [TODO] core - document behavior of multiple :load subpragmas in same compilation unit

2007-02-19 Thread Klaas-Jan Stol
I'm not sure how to respond on TODO tickets, any pointers would be 
appreciated.

Meanwhile, I'll just compose an email, like this one.

Ticket:
#37542: [TODO] core - document behavior of multiple :load subpragmas in 
same compilation unit


states:

the behavior of multiple subroutines marked with the ':load' subpragma
in the same compilation unit is currently undefined. PGE currently
uses a workaround for this limitation, as seen in
compilers/pge/PGE.pir.

However, this behavior *is* defined, according to 
http://www.parrotcode.org/docs/imcc/calling_conventions.html:


:load
   Run this subroutine during the load_library opcode. :load is 
ignored, if another subroutine in that file is marked with :main. If 
multiple subs have the :load pragma, the subs are run in source code order.


Does this mean this ticket can be closed?
kjs


Deprecated ops: emit warning?

2007-02-20 Thread Klaas-Jan Stol

hi,

currently there are some deprecated ops, as listed in:
http://www.parrotcode.org/docs/ops/var.html

they are not listed in DEPRECATED.pod

This is not the first time some ops are deprecated, and will probably 
not be the last time before the 1.0 release.
Is it a good idea to add a check to the parser that checks whether a 
certain op is deprecated, so it can emit a warning?


As Parrot will be more stable from a 1.0 release, this code can be 
removed, so the overhead of checking is gone.


Doing this check, tests using those ops will fail (because there is more 
output), and there is more "pressure" to start using the new ops.

Then, after a deprecation cycle, they can be removed completely.

If this is desirable, I'd be happy to provide a patch.

Regards,
klaas-jan




[PATCH] languages/lua lua.pg Grammar fixes

2007-02-20 Thread Klaas-Jan Stol

hi,
attached a patch for the Lua grammar file for PGE (lua.pg).
fixing:

* reorganized some rules w.r.t. "do  end"
*  rule instead of "..."
* fixed table constructor rules (they now work correctly) -- stolen from 
lua51.pg



regards,
kjs

Index: languages/lua/src/lua.pg
===
--- languages/lua/src/lua.pg	(revision 17078)
+++ languages/lua/src/lua.pg	(working copy)
@@ -22,7 +22,7 @@
 rule statement {
 
   | 
-  | 
+  | 
   | 
   | 
   | 
@@ -35,11 +35,11 @@
 }
 
 rule laststat {
-  	<'return'> ?
+<'return'> ?
   | <'break'>
 }
 
-rule doblock {
+rule dostat {
   <'do'>  
 }
 
@@ -57,14 +57,14 @@
 }
 
 rule whilestat {
-  <'while'>
+  <'while'>   
 }
 
 rule repeatstat {
   <'repeat'>   
 }
 
-rule forbody {
+rule doblock {
 
 }
 
@@ -77,7 +77,7 @@
 }
 
 rule forstat {
-  <'for'> [  |  ] 
+  <'for'> [  |  ]  
 }
 
 rule ifstat {
@@ -93,7 +93,7 @@
 }
 
 rule localdecl {
-  <'local'>  [ <','>  ]* [ <'='>  ]?
+  <'local'>  [ <'='>  ]?
 }
 
 rule localfunc {
@@ -101,17 +101,18 @@
 }
 
 rule funcname {
-   [ <'.'>  ]* [ <':'>  ]?
+   [ <'.'>  ]* ?
 }
 
+rule method {
+  <':'> 
+}
+
+
 rule index {
   <'['>  
 }
 
-rule recfield {
-  [  |  ]  
-}
-
 rule constructor {
   <'{'> ? 
 }
@@ -125,14 +126,20 @@
 }
 
 rule tablefield {
-  [  |  ]*
+  <'='> 
+   |  <'='> 
+   | 
 }
 
 rule parlist {
- [ <','> <'...'> ]?
-  | <'...'>
+ [ <','>  ]? 
+  | 
 }
 
+token varargs {
+  <'...'>
+}
+
 rule body {
   <'('> ?   
 }
@@ -146,14 +153,14 @@
 }
 
 rule funcargs {
-<'('> ? 
+<'('> ?  
   | 
   | 
 }
 
 rule prefixexp {
 
-  | <'('>  
+  | <'('>   
 }
 
 rule primaryexp {
@@ -163,16 +170,16 @@
   | <':'>  
   | 
   ]*
-
 }
 
+
 rule simpleexpr {
 
   | 
   | <'nil'>
   | <'true'>
   | <'false'>
-  | <'...'>
+  | 
   | 
   | <'function'> 
   | 
@@ -281,7 +288,7 @@
 =cut
 
 token name {
-   \b 
+   \b  
 }
 
 
@@ -331,5 +338,5 @@
   | <'function'> | <'if'> | <'in'>| <'local'>
   | <'nil'>  | <'not'>| <'or'>| <'repeat'>
   | <'return'>   | <'then'>   | <'true'>  | <'until'>
-  | <'while'> 	] \b
+  | <'while'>] \b
 }


[PATCH] PDD16 NCI update with simple example

2007-02-23 Thread Klaas-Jan Stol

hi,

I've been playing with NCI calls and more fun (embedding a Parrot, that 
runs a PIR program, which invokes a C function, that then invokes a PIR 
callback function).


As a result, I added a simple example to PDD16. I didnt' put too much 
work in it (there are many more places that could be improved), because 
I didn't know if updating this doc is desirable at this moment (any big 
changes pending?).


If desired, I'd be happy to do more updates. Please let me know.
At least there's full working code to do a simple NCI invocation.

regards,
klaas-jan

Index: docs/pdds/draft/pdd16_native_call.pod
===
--- docs/pdds/draft/pdd16_native_call.pod	(revision 17146)
+++ docs/pdds/draft/pdd16_native_call.pod	(working copy)
@@ -126,8 +126,48 @@
 =head2 Examples
 
 Most of the function parameters are reasonably self-evident. Some, however,
-merit additional explanation. The {{ ??? }}
+merit additional explanation.
 
+This section describes the simplest example for NCI possible. To every NCI
+invocation, there are two parts: the native function to be invoked, and the
+PIR code to do the invocation.
+
+First the native function, to be written in C.
+On Windows, it is necessary to do a DLL export specification of the NCI function:
+
+  /* foo.c */
+
+  /* specify the function prototype */
+
+	void foo(void);
+
+  /* or on Windows using Microsoft Visual Studio: */
+
+  __declspec(dllexport) void foo(void);
+
+  void foo(void) {
+printf("Hello Parrot!\n");
+  }
+
+Then, after having compiled the file as a shared library, the PIR code looks
+like this:
+
+  .sub main :main
+ .local pmc lib, func
+
+ # load the shared library
+ lib = loadlib "hello" # no extension, .so or .dll is assumed
+
+ # get a reference to the function from the library just
+ # loaded, called "foo", and signature "void" (and no arguments)
+ func = dlfunc lib, "foo", "v"
+
+ # invoke
+ func()
+
+  .end
+
+
 =head2 Callbacks
 
 Some libraries, particularly ones implementing more complex functionality such
@@ -224,9 +264,9 @@
 Maintainer: Dan Sugalski
 Class: Internals
 PDD Number: 16
-Version: 1.1
+Version: 1.2
 Status: Developing
-Last Modified: Oct 12, 2004
+Last Modified: Feb 23, 2007
 PDD Format: 1
 Language: English
 
@@ -234,6 +274,10 @@
 
 =over 4
 
+=item version 1.2
+
+Updated with basic example.
+
 =item version 1.1
 
 Changed callback section to reflect current status.
@@ -248,6 +292,10 @@
 
 =over 4
 
+=item version 1.2
+
+Updated with basic example.
+
 =item version 1.1
 
 Changed callback section to reflect current status.


[PATCH] languages/PIR update pirgrammar.pod

2007-02-23 Thread Klaas-Jan Stol

hi,

attached an update for languages/PIR/docs/pirgrammar.pod

fixing:

0.1.3

   *

 Updated short sub invocation for NCI invocations.

   *

 Added an example for |.globalconst|.

   *

 Added some remarks at section for Macros.

   *

 Added some remarks here and there, and fixed some style issues.


The document languages/PIR/docs/pirgrammar.html should be removed from 
the repository -- don't know how to do this. Then later, we can 
generated it via the make file.


regards,
klaas-jan

Index: languages/PIR/docs/pirgrammar.pod
===
--- languages/PIR/docs/pirgrammar.pod	(revision 17146)
+++ languages/PIR/docs/pirgrammar.pod	(working copy)
@@ -16,10 +16,16 @@
 The grammar includes some constructs that B in the IMCC parser,
 but are not implemented. An example of this is the C<.global> directive.
 
+Please note that languages/PIR is B the official definition of the
+PIR language. The reference implementation of PIR is IMCC, located
+in C. However, languages/PIR tries to be as close
+to IMCC as possible. IMCC's grammar could use some cleaning up;
+languages/PIR might be a basis to start with a clean reimplementation of
+PIR in C (using Lex/Yacc).
 
 =head1 VERSION
 
-0.1.2
+0.1.3
 
 =head1 LEXICAL CONVENTIONS
 
@@ -375,6 +381,7 @@
   local_decl
 | lexical_decl
 | const_def
+| globalconst_def
 | conditional_stat
 | assignment_stat
 | open_namespace
@@ -502,6 +509,27 @@
 assign a floating point number to an integer constant. The PIR parser will
 check for this.
 
+
+=head2 Global constant definitions
+
+  globalconst_def:
+".globalconst" type identifier "=" constant_expr
+
+=head3 Example global constant definitions
+
+This directive is similar to C, except that once a C
+has been defined, it is accessible from B subroutines.
+
+  .sub main :main
+.global const int answer = 42
+foo()
+  .end
+
+  .sub foo
+print answer # prints 42
+  .end
+
+
 =head2 Conditional statements
 
   conditional_stat:
@@ -518,7 +546,7 @@
 
   if null $P0 goto L1
 
-Checks whether $P0 is C, if it is, flow of control jumps to label L1
+Checks whether C<$P0> is C, if it is, flow of control jumps to label C
 
   unless $P0 goto L2
   unless x   goto L2
@@ -725,6 +753,26 @@
 are  stored as well.
 
 
+In IMCC, a heredoc identifier can be specified as an argument, like this:
+
+foo(42, "hello", <<'EOS')
+
+This is a heredoc text argument.
+
+  EOS
+
+In IMCC, only B such argument can be specified. The languages/PIR implementation
+aims to allow for B number of heredoc arguments, like this:
+
+foo(<<'STR1', <<'STR2')
+
+  	argument 1
+  STR1
+argument 2
+  STR2
+
+B
+
 =head2 Invoking subroutines and methods
 
   sub_invocation:
@@ -880,8 +928,27 @@
   arr[1] = 43
   foo(arr :flat, $I0 :named('intArg'))
 
-Please note that the short subroutine call does B allow for C calls.
+In order to do a Native Call Interface invocation, the subroutine to be invoked needs to be in referenced
+from a PMC register, as its name is B visible from Parrot. A NCI call looks like this:
 
+  .local pmc nci_sub, nci_lib
+  .local string c_function, signature
+
+  nci_lib = loadlib "myLib"
+
+  # name of the C function to be called
+  c_function = "sayHello"
+
+  # set signature to "void" (no arguments)
+  signature  = "v"
+
+  # get a PMC representing the C function
+  nci_sub = dlfunc nci_lib, c_function, signature
+
+  # and invoke
+  nci_sub()
+
+
 =head2 Return values from subroutines
 
 
@@ -1056,12 +1123,21 @@
 "(" id_list? ")"
 
   macro_body:
-.*?
+*
 ".endm" nl
 
   macro_invocation:
 macro_id parenthesized_args?
 
+
+Note that before a macro body will be parsed, some grammar rules
+will be changed. In a macro body, local variable declaration can
+B be done using the C<.sym> directive. The C<.local> directive
+is only available for declaring labels.
+
+  macro_label:
+".local" "$"identifier":"
+
 =head3 Example Macros
 
 When the following macro is defined:
@@ -1079,7 +1155,7 @@
 .add2(myNum)
 print myNum  # prints 44
   .end
-
+
 =head2 PIR Pragmas
 
   pragma:
@@ -1256,6 +1332,9 @@
 appreciated. Moreover, if you find any missing constructs that are in
 IMCC, indications of these would be appreciated as well.
 
+Please see the PROPOSALS document for some proposals of the author to
+clean up the official grammar of PIR (as defined by the IMCC compiler).
+
 =back
 
 =head1 REFERENCES
@@ -1286,6 +1365,29 @@
 
 =head1 CHANGES
 
+0.1.3
+
+=over 4
+
+=item *
+
+Updated short sub invocation for NCI invocations.
+
+=item *
+
+Added an example for C<.globalconst>.
+
+=item *
+
+Added some remarks at section for Macros.
+
+=item *
+
+Added some remarks here and there, and fixed some style issues.
+
+=back
+
+
 0.1.2
 
 =over 4
@@ -1295,7 +1397,7 @@
 Removed C<.immediate>, it is C<:immediate>, and thus not a PIR directive, but a flag.
 This was a mistake.
 
-=item * 
+=

[PATCH] Update DEPRECATED.pod

2007-02-23 Thread Klaas-Jan Stol

hi,

attached a patch updating DEPRECATED.pod.
it adds the deprecated ops from http://www.parrotcode.org/docs/ops/var.html

(ops: store_global and friends)

regards,
kjs
Index: DEPRECATED.pod
===
--- DEPRECATED.pod	(revision 17165)
+++ DEPRECATED.pod	(working copy)
@@ -29,6 +29,25 @@
 
 =back
 
+=head1 Deprecated ops
+
+From http://www.parrotcode.org/docs/ops/var.html, the following ops are 
+deprecated:
+
+=over 4
+
+=item store_global
+
+=item find_global
+
+=item find_name
+
+=back
+
+There are several variants of some of the above ops; all are deprecated,
+and are replaced by the ops {set,get}_[hll,root]_global. See also
+http://www.parrotcode.org/docs/ops/var.html.
+
 =head1 FUTURE changes
 
 Not yet deprecated, but it's recommended to use the new syntax and


Re: [perl #41604] [BUG] pbc_output_is doesn't work?

2007-02-24 Thread Klaas-Jan Stol

James Keenan via RT wrote:

On Fri Feb 23 13:44:22 2007, [EMAIL PROTECTED] wrote:
  
I couldn't find any other tests that run pbc_output_is() (but 
admittedly, I didnt' look for too long), so it might be this function is 
never used. 



[parrot] 577 $ find t -name '*.t' | xargs grep -n pbc_output_is
t/native_pbc/integer.t:58:pbc_output_is( undef, '270544960', "i386 32 bit opcode_t, 32 bit 
intval" );
t/native_pbc/number.t:88:pbc_output_is( undef, $output, "i386 double float 32 bit opcode_t" 
);
t/native_pbc/number.t:91:# pbc_output_is(undef, 

Re: [perl #41604] [BUG] pbc_output_is doesn't work?

2007-02-25 Thread Klaas-Jan Stol

Leopold Toetsch wrote:

Am Samstag, 24. Februar 2007 17:05 schrieb Klaas-Jan Stol:
  

it seems the .pbc files are stored in the repository is that
desirable? 



Yes for these files.

  
IMO, it would be enough to store the PIR only, and have that 
compiled to PBC



If you have a closer look at these .pbcs, you'll see that they are generated 
on machines of very different flavours (LE, BE, 32, 64bit). The tests are 
checking that one parrot can read all these .pbcs.
  

ok, I didn't look that close.

Can you tell whether pbc_output_is() can take PIR code and compile it 
during running the test? Or does is always expect the pbc file to be 
present?


kjs


[PATCH] Pynie updates

2007-02-25 Thread Klaas-Jan Stol

hi,

attached a patch for languages/Pynie, adding:

* more grammar rules
* statement.t  for testing statements -- kinda simple, should be extended
* keyword rule, so that id's are not recognized as identifiers

regards,
kjs
Index: languages/pynie/src/parser/Grammar.pg
===
--- languages/pynie/src/parser/Grammar.pg	(revision 17174)
+++ languages/pynie/src/parser/Grammar.pg	(working copy)
@@ -37,6 +37,11 @@
 token compound_stmt {
 | 
 | 
+| 
+| 
+| 
+| 
+| 
 }
 
 rule if_stmt {
@@ -50,25 +55,174 @@
 [ <'else'> <':'>  ]?
 }
 
+rule for_stmt {
+<'for'>  <'in'>  <':'> 
+[ <'else'> <':'>  ]?
+}
+
+rule try_stmt {
+ | 
+}
+
+rule try1_stmt {
+<'try'> <':'> 
+[ <'except'> [  [ <','>  ]? ]? <':'>  ]+
+[ <'else'> <':'>  ]?
+[ <'finally'> <':'>  ]?
+}
+
+rule try2_stmt {
+<'try'> <':'> 
+<'finally'> <':'> 
+}
+
+rule with_stmt {
+<'with'>  [ <'as'>  ]? <':'> 
+}
+
+rule funcdef {
+? <'def'>  <'('> ? <')'>
+[ <':'> |  ] 
+}
+
+
+rule decorators {
++
+}
+
+rule decorator {
+<'@'>  [ <'('> [  <','>? ]? <')'> ]? 
+}
+
+rule dotted_name {
+ [ <'.'>  ]*
+}
+
+rule funcname {
+
+}
+
+rule parameter_list {
+[  <','> ]*
+[
+  <'*'>  [ <','> <'**'>  ]?
+| <'**'> 
+|  <','>?
+]
+}
+
+rule defparameter {
+ [ <'='>  ]?
+}
+
+rule sublist {
+ [ <','>  ]* <','>?
+}
+
+rule parameter {
+ | <'('>  <')'>
+}
+
+
+rule classdef {
+<'class'>  ? <':'> 
+}
+
+rule classname {
+
+}
+
+rule inheritance {
+<'('>  <')'>
+}
+
 token simple_stmt {
+| 
+| 
+| 
+| 
+| 
 | 
-| 
+| 
+| 
+| 
+| 
+| 
+| 
+| 
 | 
 }
 
+rule assert_stmt {
+<'assert'>  [ <','>  ]?
+}
+
 rule assignment_stmt { [  <'='> ]+  }
 
+rule augmented_assignment_stmt {}
+
 rule target_list {  [ <','>  ]* (<','>)? }
 
 token target {  }
 
-token identifier { [  | <'_'> ] \w* }
+token identifier {  [  | <'_'> ] \w* }
 
+token name {  <[a..z]> [  | <'_'> ]* }
+
 rule print_stmt {
 <'print'> [  [ <','>  ]* (<','>?) ]?
 }
 
+rule pass_stmt {
+<'pass'>
+}
 
+rule del_stmt {
+<'del'> 
+}
+
+rule return_stmt {
+<'return'> ?
+}
+
+rule yield_stmt {
+<'yield'> 
+}
+
+rule break_stmt {
+<'break'>
+}
+
+rule continue_stmt {
+<'continue'>
+}
+
+rule raise_stmt {
+<'raise'> [  [ <','>  [ <','>  ]? ]? ]?
+}
+
+rule global_stmt {
+<'global'>  [ <','>  ]*
+}
+
+rule import_stmt {
+| <'import'>  ?
+  [ <','>  ? ]*
+| <'from'>  <'import'>  ?
+  [ <','>  ? ]*
+| <'from'>  <'import'> <'('>  ?
+  [ <','>  ? ]* <','>? <')'>
+| <'from'>  <'import'> <'*'>
+}
+
+rule import_alias {
+<'as'> 
+}
+
+rule module {
+[  <'.'> ]* 
+}
+
 token literal {
 | 
 | 
@@ -93,6 +247,9 @@
 
 rule listmaker {  [ <','>  ]* (<','>)? }
 
+token augop {
+<'+='> | <'-='> | <'*='> | <'/='> | <'\%='> | <'**='>
+}
 
 ##  This identifies operators for the bottom-up parser
 
@@ -137,4 +294,19 @@
 proto 'infix:<'is equiv('infix:==')  { ... }
 proto 'infix:>'is equiv('infix:==')  { ... }
 
+
+## Python reserved words and keywords
+
+token reserved {
+ | <'None'>
+}
+
+token keyword {
+[ <'and'>   | <'assert'> | <'break'>  | <'class'>  | <'continue'> | <'def'>
+| <'del'>   | <'elif'>   | <'else'>   | <'except'> | <'exec'> | <'finally'>
+| <'for'>   | <'from'>   | <'global'> | <'if'> | <'import'>   | <'in'>
+| <'is'>| <'lambda'> | <'not'>| <'or'> | <'pass'> | <'print'>
+| <'raise'> | <'return'> | <'try'>| <'while'>  | <'with'> | <'yield'> ] \b
+}
+
 ## vim: expandtab sw=4
Index: languages/pynie/src/PAST/Grammar.tg
===
--- languages/pynie/src/PAST/Grammar.tg	(revision 17174)
+++ languages/pynie/src/PAST/Grammar.tg	(working copy)
@@ -28,12 +28,33 @@
 
   compound_stmt:
 $P0 = node['compound_stmt']
+  if_stmt:
 $P1 = $P0['if_stmt']
 if null $P1 goto while_stmt
 .return tree.'get'('past', $P1, 'Pynie::Grammar::if_stmt')
   while_stmt:
 $P1 = $P0['while_stmt']
+if null $P1 goto for_stmt
 .return tree.'get'('past', $P1, 'Pynie::Grammar::while_stmt')
+  for_stmt:
+$P1 = $P0['for_stmt']
+if null $P1 goto try_stmt
+.return tree.'get'('past', $P1, 'Pynie::Grammar::for_stmt')
+  try_stmt:
+$P1 = $P0['try_stmt']
+if null $P1 goto with_stmt
+.return tree.'get'('past', $P1, 'Pynie::Grammar::try_stmt')
+  with_stmt:
+$P1 = $P0['with_stmt']
+if null $P1 goto funcdef
+.return tree.'get'('past', $P1, 'Pynie::Grammar::with_stmt')
+  funcdef:
+$P1 = $P0['funcdef']
+if null $P1 goto classdef
+.return tree.'get'('past', $P1, 'Pynie::Grammar::funcdef')
+  classdef:
+$P1 = $P0['classdef']
+.return tree.'get'('past', $P1, 'Pynie::Grammar::classdef')
 }
 
 
@@ -68,7 +89,98 @@
 .return tree.'get'('p

[PATCH] welcome message and prompt for HLLCompiler

2007-02-25 Thread Klaas-Jan Stol

hi,

most languages that can run in interactive mode have some kind of 
welcome message and prompt that is printed before the user can give any 
input.


For example, Python prints:

Python 2.5 (r25:51908, Sep 19 2006, 09:52:17) [MSC v.1310 32 bit 
(Intel)] on win

32
Type "help", "copyright", "credits" or "license" for more information.
>>>

and another well-known language being implemented for Parrot, Lua:

Lua 5.1.1  Copyright (C) 1994-2006 Lua.org, PUC-Rio
>

Attached is a patch that extends HLLCompiler with 2 attributes: 
commandline_message, and commandline_prompt


The first can be set to set the message to be shown when the interactive 
mode is entered. The second one is the prompt to be printed before the 
user can give input.  (a possible improvement would be to have an array 
of prompts; many languages have 2 prompts, when a "\" or whatever is 
given. In Python, if one gives "\" at the end of the line, the next 
prompt is "...". In lua it is ">>" instead of the normal prompt ">".)


As an example, I used this in Pynie.pir, which prints nicely:

C:\parrot\languages\pynie>..\..\parrot pynie.pbc
Python 2.5 for Parrot
Type "help", "copyright", "credits" or "license" for more information.
>>>

(although the "help" etc. commands are not implemented).

I don't know if this feature is desired, but it was not too much work, 
and it makes languages look more like the real thing.


regards,
klaas-jan
Index: languages/pynie/pynie.pir
===
--- languages/pynie/pynie.pir	(revision 17174)
+++ languages/pynie/pynie.pir	(working copy)
@@ -35,7 +35,13 @@
 $P0.'language'('Pynie')
 $P0.'parsegrammar'('Pynie::Grammar')
 $P0.'astgrammar'('Pynie::PAST::Grammar')
-
+		
+		.local string welcomestring		
+		welcomestring = "Python 2.5 for Parrot\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n"
+		
+		$P0.'commandline_message'(welcomestring)
+		$P0.'commandline_prompt'('>>> ')
+		
 $P0 = get_hll_global ['PGE::Util'], 'die'
 set_hll_global ['Pynie::Grammar'], 'die', $P0
 .end
Index: runtime/parrot/library/Parrot/HLLCompiler.pir
===
--- runtime/parrot/library/Parrot/HLLCompiler.pir	(revision 17174)
+++ runtime/parrot/library/Parrot/HLLCompiler.pir	(working copy)
@@ -20,6 +20,11 @@
 addattribute $P0, '$ostgrammar'
 addattribute $P0, '@stages'
 addattribute $P0, '$!compsub'
+
+# the commandline_message is the welcome message for interactive mode
+addattribute $P0, '$commandline_message'
+# the commandline_prompt is the prompt to show for input
+addattribute $P0, '$commandline_prompt'
 .end
 
 =head2 Methods
@@ -105,6 +110,18 @@
 .return self.'attr'('$ostgrammar', value, has_value)
 .end
 
+.sub 'commandline_message' :method
+.param string value:optional
+.param int has_value   :opt_flag
+.return self.'attr'('$commandline_message', value, has_value)
+.end
+
+.sub 'commandline_prompt' :method
+.param string value:optional
+.param int has_value   :opt_flag
+.return self.'attr'('$commandline_prompt', value, has_value)
+.end
+
 =item removestage(string stagename)
 
 Delete a stage from the compilation process queue.
@@ -346,7 +363,11 @@
 .local string target, encoding
 target = adverbs['target']
 target = downcase target
-
+
+# on startup show the welcome message
+		$P0 = self.'commandline_message'()
+printerr $P0
+
 .local pmc stdin
 .local int has_readline
 stdin = getstdin
@@ -359,6 +380,11 @@
 unless stdin goto interactive_end
 ##  FIXME:  we have to avoid stdin.'readline'() when readline
 ##  libraries aren't present (RT #41103)
+
+# for each input line, print the prompt
+$P0 = self.'commandline_prompt'()
+printerr $P0
+
 if has_readline < 0 goto no_readline
 code = stdin.'readline'('> ')
 if null code goto interactive_end


Re: [PATCH] welcome message and prompt for HLLCompiler

2007-02-25 Thread Klaas-Jan Stol

Patrick R. Michaud wrote:

On Sun, Feb 25, 2007 at 04:39:17PM +0100, Klaas-Jan Stol wrote:
  
most languages that can run in interactive mode have some kind of 
welcome message and prompt that is printed before the user can give any 
input.



Yes, this is helpful.  But also one of the things we need is a way
so that we can have "additional input" -- i.e., when entering
constructs that span multiple lines, for the language to be able
to signal HLLCompiler to obtain additional lines of input.  

  
(a possible improvement would be to have an array 
of prompts; many languages have 2 prompts, when a "\" or whatever is 
given. In Python, if one gives "\" at the end of the line, the next 
prompt is "...". In lua it is ">>" instead of the normal prompt ">".)

The escape character to continue on the next line should also be handled 
by HLLCompiler?

something like

   $P0.'joinlinechar'('\')

sets the "\" character to be the signal to HLLCompiler to keep reading 
from the next line.

($P0 holds the compiler object).



I think we need to go ahead and have it possible to use an
array of prompts.
  
ok. I've added it, but it only uses prompts[0] right now... (the main 
prompt). It also needs an attribute that keeps track of what prompt 
needs to be used (an index).


kjs

  

As an example, I used this in Pynie.pir, which prints nicely:

C:\parrot\languages\pynie>..\..\parrot pynie.pbc
Python 2.5 for Parrot
Type "help", "copyright", "credits" or "license" for more information.



I'm generally in favor of not making false promises.  So,
don't offer options that aren't available.  :-)

Similarly, Pynie was modeled on Python 2.3, not 2.5... but if
someone has a copy of Python's 2.5 specification (or can point me
to it on the web), we can do 2.5.

Pm

  




Re: [PATCH] welcome message and prompt for HLLCompiler

2007-02-25 Thread Klaas-Jan Stol

Will Coleda wrote:

Nifty.

FYI, in tcl, the two prompts can be overridden via a user defined 
procedure. See http://www.tcl.tk/man/tcl8.5/UserCmd/tclsh.htm#M11


Be nice if this was also possible with the default tool.
yup that should be possible as long as the language can access its own 
compiler object. Just call


   $P0.'set_prompt'(0, ">>>")
   $P0.'set_prompt'(1, "...")

(in case of Python/Pynie)
It should overwrite the prompt in that slot.

kjs


On Feb 25, 2007, at 11:24 AM, Klaas-Jan Stol wrote:


Patrick R. Michaud wrote:

On Sun, Feb 25, 2007 at 04:39:17PM +0100, Klaas-Jan Stol wrote:

most languages that can run in interactive mode have some kind of 
welcome message and prompt that is printed before the user can give 
any input.




Yes, this is helpful.  But also one of the things we need is a way
so that we can have "additional input" -- i.e., when entering
constructs that span multiple lines, for the language to be able
to signal HLLCompiler to obtain additional lines of input.

(a possible improvement would be to have an array of prompts; many 
languages have 2 prompts, when a "\" or whatever is given. In 
Python, if one gives "\" at the end of the line, the next prompt is 
"...". In lua it is ">>" instead of the normal prompt ">".)


The escape character to continue on the next line should also be 
handled by HLLCompiler?

something like

   $P0.'joinlinechar'('\')

sets the "\" character to be the signal to HLLCompiler to keep 
reading from the next line.

($P0 holds the compiler object).



I think we need to go ahead and have it possible to use an
array of prompts.

ok. I've added it, but it only uses prompts[0] right now... (the main 
prompt). It also needs an attribute that keeps track of what prompt 
needs to be used (an index).


kjs




As an example, I used this in Pynie.pir, which prints nicely:

C:\parrot\languages\pynie>..\..\parrot pynie.pbc
Python 2.5 for Parrot
Type "help", "copyright", "credits" or "license" for more information.



I'm generally in favor of not making false promises.  So,
don't offer options that aren't available.  :-)

Similarly, Pynie was modeled on Python 2.3, not 2.5... but if
someone has a copy of Python's 2.5 specification (or can point me
to it on the web), we can do 2.5.

Pm







--
Will "Coke" Coleda
[EMAIL PROTECTED]







  1   2   3   4   >