Re: [perl #25265] [PATCH] peek opcode

2005-09-23 Thread Cory Spencer



I'm closing this bug as 'rejected' because a corrected patch was never
submitted.  If you ever get it work, please do resubmit it.


Actually, I believe it was eventually applied, although I'm not sure why 
it wasn't updated in the RT.  In any event, two peek opcodes currently 
exist in the tree...


Thanks!

Cory


Re: New language: Parrot Common Lisp

2005-04-22 Thread Cory Spencer

- (defun (square x) (* x x))
[...]
*** ERROR: SQUARE is not a function name
Is that because (a) that's not implemented yet or (b) I'm doing
something wrong? I haven't found the time to delve into the source
yet.
Oops, that wasn't supposed to have made it in there - I haven't finished 
up macros yet, and as (defun ...) is a macro construct, it doesn't work 
properly (at the moment it's just a useless stub).

To define new functions, you can use the behind-the-scenes backdoor method 
that I'm currently using:

  (sys:set-symbol-function 'square #'(lambda (x) (* x x)))
Also, while playing I around I found this happening:
- (* 2 3)
9
- (* 4 3)
9
That is probably related to an issue I'd reported last night and for which 
Leo (I think) has committed a fix.  I haven't had a chance to check out 
the new revision, but I'm fairly certain it's the case.

Looks like a bug. Maybe I'll find time to brush off my Lisp and start
writing some tests in the process. :-)
Absolutely.  I've been meaning to start up a test suite and anything you 
can do to further that end would be GREATLY appreciated. :)

-c


MMD acting up...

2005-04-21 Thread Cory Spencer
I've encountered some multimethod dispatch funnyness tonight.  The 
included code which one would expect to produce a value of 1 ends up 
printing a value of 3.

Changing a and b to be regular Integer types seems to work.  Can 
anybody shed any more light on this?

-c
.sub _main @MAIN
  .local pmc class
  .local pmc a
  .local pmc b
   subclass class, Integer, LispInteger
   a = new LispInteger
   b = new LispInteger
   a = 1
   b = 1
   print a
   print  * 
   print b
   print  = 
   a = a * b
   print a
   print \n
  end
.end


Re: New language: Parrot Common Lisp

2005-04-15 Thread Cory Spencer

 (If anyone is able to track down aforementioned DOD/GC problems,
 you'll earn my eternal gratitude.)
Can you please provide a code snippet that exhibits the error.
Just running the program gives me errors on both Linux/x86 and OS X. 
Running with GC disabled works fine.

On OS X with GC enabled:
forge:~/svn/parrot-lisp/trunk$ parrot lisp.pbc
Can't find method '__set_string_native' for object 'LispSymbol'
On OS X with GC disabled:
forge:~/svn/parrot-lisp/trunk$ parrot -G lisp.pbc
-
On Linux with GC enabled:
anvil:~/svn/parrot-lisp/trunk$ parrot lisp.pbc
Can't find method '__set_string_native' for object 'LispSymbol'
On Linux with GC disabled:
anvil:~/svn/parrot-lisp/trunk$ parrot lisp.pbc
-
This is on the Parrot checked out of Subversion this morning (revision 
7846).  Which OS/build number were you using?

-c


New language: Parrot Common Lisp

2005-04-14 Thread Cory Spencer
I'd like to announce the creation of the Parrot Common Lisp project, which 
aims to implement a significant subset of the Common Lisp language.  At 
present it's nowhere near achieving that goal, but it's progressing slowly 
as I figure out the intricacies of writing a Lisp implementation.

A brief overview of current features:
   * It currently has ~100 functions defined - some written in IMC, some
 in Lisp.  Most of them aren't all *that* interesting, but once the
 basic flow-control special forms and macros are completed, the tools
 should be in place to do more interesting things.
   * All the basic reader macros (except backquote and ,) are more or less
 in place.  Some are written in IMC, some in Lisp.
   * Support for global, dynamic and lexical scoping more or less works.
   * Support for packages more or less works.
   * Other exciting features that I'm unable to recall.
A few caveats:
  * It's not a compiler yet, although I've got plans for that down the
road.
  * Its got bugs and almost certainly won't do what you want it to do
(but will, eventually).
  * There are some outstanding issues with the Dead Object
Detection/Garbage collection systems that I've yet to track down.  If
you plan on running PCL on the current (as of April 2005) Parrot
source base you'll very likely have to run it with DOD/GC disabled.
  ie)  ~$ parrot -G lisp.pbc
Depending on the system (I develop on both x86/Linux and g4/OS X),
you'll get a Bus Error, Segmentation Fault or some other random error
if you don't disable the GC.
(If anyone is able to track down aforementioned DOD/GC problems,
you'll earn my eternal gratitude.)
For examples of what it can currently do, look in the lisp/ subdirectory 
in the files loaded at run time (bootstrap.l system.l and primitives.l).

Anyone who would like to have a peek at what I've got so far is invited to 
download the 0.1.0 release from here:

http://www.sprocket.org/pcl/pcl-0.1.0.tar.gz
Bug reports, patches and comments are most certainly welcome. :)
Enjoy!
-c


Parrot Segmentation Fault

2005-04-07 Thread Cory Spencer
The latest Parrot CVS checkout segfaults for me on the following code:
  .sub _main
.local pmc foo
 foo = new Integer
 foo = 3
 # new_pad 0
 store_lex foo, foo
end
  .end
It appears that the store_lex opcode is to blame - when no lexical pad 
has been created and you attempt to store a lexical, the SEGV is 
generated.  Uncommenting the preceding new_pad line throws an exception 
as expected.

Cory


Lexical scope pad stack

2005-04-01 Thread Cory Spencer
Just a quick question:
Is there currently any method of determining the depth of the lexical 
scope pad stack?  None of the ops in var.pod seem to be able to provide 
that information at the moment...

Cory


Re: Lexical scope pad stack

2005-04-01 Thread Cory Spencer

Is there currently any method of determining the depth of the lexical scope 
pad stack?  None of the ops in var.pod seem to be able to provide that 
information at the moment...
Actually, I suppose I should clarify what I want to get at here, which is 
when lexical pads popped off the stack.  Am I responsible for cleaning up 
any lexical pads I push on the stack? (I assume I am, but just wanted to 
be sure)  ie) If I'm in a subroutine that just pushed a lexical pad on the 
stack and an exception gets thrown, do I have to catch the exception, pop 
the pad off the stack, and then rethrow the exception?

Cory


More Garbage Collection Issues

2005-03-28 Thread Cory Spencer
I've come across another garbage collection/DOD issue that I'm trying to 
solve (without much success) and would appreciate some tips/advice on how 
to locate the source of the problem.

It appears (based on my tests) to cause strings to be marked as dead 
objects before their time.  It appears to affectthe String class (in 
my case, a subclass of String).  Oddly, it appears to only affect strings 
with a length of 1 (ie. a single character - changing the string to a 
longer length does not cause it be be marked as a dead object).  If I turn 
DOD off with the sweepoff opcode, strings are not marked and collected.

I've also noticed similar behaviour when I use a native string type (ie. 
something declared with an IMC .local string str declaration) as a key 
in a Hash table (again, it only appears to happen when the string is a 
single character in length).  Later, when I go back to retrieve the value 
stored in the hash, it can't find it.  (Running an iterator over the keys 
of the Hash shows keys that appears as garbage characters (presumably 
string types that have since been collected).)

I've as of yet been unable to produce a concise, working example.  Any 
tips as to how I can find the source of this bug?


Garbage Collection Issues?

2005-03-27 Thread Cory Spencer
I've been writing a Lisp implementation on top of Parrot for the last 
several months (and I'm just about at the point where I'm ready to unleash 
it upon the world).  I seem to have run up against some issues which 
*appear* to be related to the garbage collector collecting objects that 
aren't ready to be collected yet.  (I say appear because I'm unsure as 
to how to check when an object is being collected and the memory returned 
to the system - for all I know this could be entirely my fault.)

I've included a much pared down example IMC file which on an x86 Linux 
machine will produce a segmentation fault and on a Mac OS X 10.3 machine 
produces a bus error.  Running with the garbage collection disabled (ie. 
with the -G flag) does not produce these errors.

If anyone could point me towards what is going wrong, I would MOST 
appreciate it - it's been driving me nuts.  (I've been following Parrot 
internals only superficially for the past little while so I'm entirely 
unfamiliar with the garbage collection system.)  I have only a vague
inclination that it has to do somehow with the Hash class (based on how 
various bugs manifest themselves in my program).

The Parrot version is the latest CVS checkout as of 10 minutes ago.
Regards,
Cory

.macro PACKAGE (P,N)
  .P = new LispPackage
  .P._set_name_as_string(.N)  
.endm

.macro STRING (R,S)
  .R = new LispString
  .R = .S
.endm

.macro SYMBOL (R,N)
  .R = new LispSymbol
  .R._set_name_as_string(.N)
.endm

.sub _main @MAIN
  .local pmc package1
  .local pmc package2
  .local pmc package3
  .local pmc symbol
  .local int count

  _init_types()

  .PACKAGE(package1, COMMON-LISP)

  symbol = package1._intern_symbol(T)

  count = 0
LOOP:
  print count
  print : 
  print looking up symbol: T\n
  symbol = package1._lookup_symbol(T)

  .PACKAGE(package3, SYSTEM)

  package3._import_symbol(symbol)

  symbol = package1._lookup_symbol(T)
  package2 = symbol._get_package()

  inc count
  goto LOOP
  
  end
.end

.sub _init_types
  .local pmc class

  # Create the LispPackage class
  newclass class, LispPackage

  addattribute class, internal
  addattribute class, name

  # Create the LispString class
  subclass class, String, LispString

  # Create the LispSymbol class
  newclass class, LispSymbol

  addattribute class, function
  addattribute class, name
  addattribute class, package
.end

.namespace [LispPackage]

.sub __init method
  .local pmc value

  value = new Hash
  setattribute self, LispPackage\0internal, value
.end

.sub _lookup_symbol method
  .param string name
  .local string type
  .local pmc symbol
  .local pmc hash

  getattribute hash, self,  LispPackage\0internal
  symbol = hash[name]

  typeof type, symbol

  if type == None goto SYMBOL_NOT_FOUND
  goto DONE

SYMBOL_NOT_FOUND:
  null symbol
  goto DONE

DONE:
  .return(symbol)
.end

.sub _import_symbol method
  .param pmc symbol
  .local string symname
  .local pmc hash

  symname = symbol._get_name_as_string()

  getattribute hash, self,  LispPackage\0internal
  hash[symname] = symbol

  .return(symbol)
.end

.sub _intern_symbol method
  .param string name
  .local string type
  .local pmc symbol
  .local pmc status
  .local pmc hash

  getattribute hash, self,  LispPackage\0internal
  symbol = hash[name]

  typeof type, symbol
  if type != None goto DONE

  .SYMBOL(symbol, name)
  hash[name] = symbol

  symbol._set_package(self)

  goto DONE

DONE:
  .return(symbol)
.end

.sub _get_name_as_string method
  .local pmc name
  .local string retv

  getattribute name, self, LispPackage\0name
  retv = name

  .return(retv)
.end

.sub _set_name_as_string method
  .param string name
  .local pmc retv

  .STRING(retv, name)

  setattribute self, LispPackage\0name, retv

  .return(retv)
.end

.sub __get_string method
  .local pmc name
  .local pmc tmps
  .local pmc retv

  getattribute name, self, LispPackage\0name

  retv = new String
  tmps = new String

  tmps = #PACKAGE 

  concat retv, tmps, name

  tmps = 
  concat retv, retv, tmps

  .pcc_begin_return
  .return retv
  .pcc_end_return
.end

.namespace [LispSymbol]

.sub _get_name_as_string method
  .local pmc name
  .local string retv

  getattribute name, self, LispSymbol\0name
  retv = name

  .return(retv)
.end

.sub _set_name_as_string method
  .param string name
  .local pmc retv

  .STRING(retv, name)

  setattribute self, LispSymbol\0name, retv

  .return(retv)
.end

.sub _get_package method
  .local pmc retv

  getattribute retv, self, LispSymbol\0package

  .return(retv)
.end

.sub _set_package method
  .param pmc package

  setattribute self, LispSymbol\0package, package

  .return(package)
.end

.sub __get_string method
  .local pmc name

  getattribute name, self, LispSymbol\0name

  .pcc_begin_return
  .return name
  .pcc_end_return
.end

.namespace []


How to check an attribute's existence

2005-02-24 Thread Cory Spencer
Is is possible to check to see whether an attribute exists on a given 
object, or at least catch an exception if it doesn't?  I've tried to set 
up an exception handler, but Parrot exits without anything being caught.

A code snippet follows:
.sub _main
  .local pmc class
  .local int type
  .local pmc foo
  .local pmc val
  # The Foo class only has a bar attribute.
  newclass class, Foo
  addattribute class, bar
  # Create a Foo object
  find_type type, Foo
  new foo, type
  push_eh EXCEPTION
  # Try to access the invalid baz attribute.
  getattribute val, foo, baz
  end
EXCEPTION:
  print * caught an exception!\n
  end
.end


IO subsystem stuff

2004-01-28 Thread Cory Spencer

Perhaps someone with a bit more familiarity with the Parrot IO subsystem
could give me some guidance here.  I'm currently trying to get a new
'peek' opcode working, and I'm having difficulties getting the io_unix
layer implemented correctly.

As far as I know, I'd get a call down into the io_unix layer when the
ParrotIO object isn't buffered.  What I want to be able to do is to
read()/fread() a character off of the io-fd filedescriptor, copy it into
the buffer, then ungetc() it back onto the stream.  Unfortunately,
however, ungetc requires a (FILE *), while the ParrotIO object carries
around only a raw file descriptor (I think).

I've seen some instances where people will cast the raw descriptor to a
(FILE *), however the man page for ungetc warns ominously in its BUGS
section that:

   It  is  not advisable to mix calls to input functions from
   the stdio library with low - level calls to read() for the
   file  descriptor  associated  with  the  input stream; the
   results will be undefined and very probably not  what  you
   want.

Numerous segfaults would seem to confirm that this is indeed very probably
not what I want.

That being said, what is the best course for buffering such characters at
the io_unix layer?  I apparently am not able to use the standard library
functions to do so (additionally, they only guarantee that you can peek
and replace a single character).

-c


Re: [perl #25265] [PATCH] peek opcode

2004-01-26 Thread Cory Spencer

  'peek' implements an opcode which can look ahead at an arbitrary number of
  bytes in a IO stream, but does not remove the bytes from the stream in the
  process.
 
   [...]

 I have some question though:

 - what if peek wants to look beyond current buffered limits

Yes - at present it only looks up to the maximum size of the IO buffer
(which on my machine was 8192 byte).  If a request is made to return more
than that size, it just returns the maximum buffer size.

Since this is my first foray out of PASM and into the actual Parrot C
internals, I was still in the process of figuring out what I should be
touching, and where it was located.  In this case, I wasn't certain if it
was possible (or desirable) to be reading past the IO buffer, and if so,
where/how I should be allocating and saving further reads on the stream.

(That being said, if someone would like to give me a nudge in the right
direction, I'm more than happy to do the work of making it happen the
right way.) :)

 - what are the guarantees of peek's result (AFAIK 1 byte for the stream
   layer if ungetc() is available) - what else?
 - don't other layers need adjustment if a new layer function is
   added?

I'm assuming that these both are related to non-buffered input?  (If not,
then I'm not entirely certain what you mean...)

 - did you miss appending all the tests ;)

Ummm, most likely.   (And I'll have a patch to fix that shortly.)  :)


ParrotIO objects

2003-12-22 Thread Cory Spencer

I'd posted a similar message to this on the weekend, but it was a little
sparse on the details, so I'll rephrase it again.

The program I'm writing is passing a ParrotIO object about to various
functions (the ParrotIO object being either stdin or a file handle to a
regular file).  Each function can read as many bytes as it likes from the
descriptor.  There are times, however, where I might decide that I don't
want the byte I just read, and need to push it back onto the stream.  This
brings up (I think) two ways around the problem:

  1) I'd like to be able to peek ahead at a byte, before actually
 consuming it.  ie)

   peek DEST, ParrotIO, NBYTES
   ...
   ...
   read DEST, ParrotIO, NBYTES

 In this case peek returns NBYTES from ParrotIO into DEST, but it's
 not actually until the 'read' op that the bytes are removed.

  2) After reading in a number of bytes from the ParrotIO object, it's
 possible to push it back onto the stream for reading later.  ie)

   read DEST, ParrotIO, NBYTES
   ...
   ...
   unread ParrotIO, BYTES

 Where after the 'read' op I decide that I don't actually want to
 consume the bytes from the strea, so I am able to 'unread' them back
 onto the ParrotIO object.

A Perl 5 module has apparently been implemented with similar behaviour:

  http://search.cpan.org/~bmorrow/IO-Unread-0.03/Unread.pm

So the question remains: are either of these methods possible, planned or
even desirable for Parrot?

Regards,

Cory Spencer


Unreading characters from input streams

2003-12-20 Thread Cory Spencer

Is it possible to unread characters from an input stream in Parrot?  (ie.
if I do a read char, 1, decide later than I don't want the character so
I push it back on the stream)

Failing that, is it possible to peek ahead at a character without
necessarily taking it off the stream?


Unexpected error...

2003-12-12 Thread Cory Spencer

Can anyone tell me why the following code:

  .sub _main
.local PerlUndef val

val = new PerlUndef
_foo(bar, val)

end
  .end

  .sub _foo
.param string v1
.param pmc v2

.pcc_begin_return
.return 1
.pcc_end_return
  .end

Would produce the following output:

  cog:~/parrot test.imc
  wrong param count
  in file '(unknown file)' near line -1

It seems to be related to passing the PerlUndef as the seoncd
parameter...



Re: Determining PMC memory addresses

2003-12-03 Thread Cory Spencer

 We're already using 'eq' to perform equality testing, and in the interests
 of maintaining a consistent design I would choose to stick with something
 eq-related as opposed to changing it to 'same'.

 eqaddr/eqval?  eq_addr/eq_val?  eq_address/eq_value?

So just to follow up on this thread, was there any preference at all for
the name of the opcode performing equality testing of PMC memory
addresses?  I needed the functionality for the code I'm working on, so
I've created a patch implementing an eq_addr opcode...

Regards,

Cory


Re: Determining PMC memory addresses

2003-12-03 Thread Cory Spencer

 I don't think there was ever a consensus about opcode naming.
 It seems that we need this but can you give an example
 of where you are using it, just to give me some context to think
 with?

I've been implementing a Lisp interpretter (and hopefully at some point,
compiler) and was using the eq_addr (or whatever it's eventually destined
to be named) to test for equality between symbol types.  (I'm sure there's
another hackish way of implementing the test, but this seemed like the
cleanest way of doing it at the time...)


Re: Raising exceptions

2003-12-02 Thread Cory Spencer

  I've been hard pressed to find any examples of proper exception-raising
  with Parrot

 t/pmc/exception.t

Excellent, thank you.


Raising exceptions

2003-12-01 Thread Cory Spencer

I've been hard pressed to find any examples of proper exception-raising
with Parrot - reading back through the list in June/July I see that there
was some starts at implementing various exception related bits - has this
been at least semi-completed?


Re: Why are .sub and compilation unit one and the same thing?

2003-12-01 Thread Cory Spencer

 However, if giving up IMCC's register allocator is worth gaining
 the extra control of PASM, by all means do it,  however I'm all ears
 on suggestions for IMCC for features. *hint*

In that case, I don't suppose it would be possible for IMCC to allow
function calls in an if expr goto LABEL statement, ie:

  ...
  if _some_test() goto LABEL
  ...
  ...

I for one would find that particularly useful. ;)


Re: Determining PMC memory addresses

2003-11-28 Thread Cory Spencer

On Fri, 28 Nov 2003, Leopold Toetsch wrote:

 Op vtable   Meaning
 -  is_same  PMCs are ident
 -  is_equal PMCs are equivalent, holding the same value
 Y  cmp  cmp PMCs
 -  cmp_num  cmp PMCs numerically
 -  cmp_string   cmp PMCs as strings

 Proposals for opcode names welcome.

How does the current 'eq' opcode deal with comparissons of PMC/PMC values?


Re: Determining PMC memory addresses

2003-11-28 Thread Cory Spencer

  On Fri, 28 Nov 2003, Leopold Toetsch wrote:
 
   Op vtable   Meaning
   -  is_same  PMCs are ident
   -  is_equal PMCs are equivalent, holding the same value
   Y  cmp  cmp PMCs
   -  cmp_num  cmp PMCs numerically
   -  cmp_string   cmp PMCs as strings
  
   Proposals for opcode names welcome.
 
  [snip]

Well, a page could be stolen from the Lisp book by defining eq/eql/equal
opcodes (though in ths case, differing from the Lisp counterparts in the
meaning of the tests) where

  - eq is true if both arguments have the same value (that is, both are
numerically equal or both are equivalent strings)
  - eql is true if both arguments are the same, identical object
  - equal does a comparison to test if the two objects are structurally
similar (ie. in the case of a PerlArray, an element-by-element
comparrison would be performed to determine the similarity of the
structure.)

Cory


Re: Determining PMC memory addresses

2003-11-28 Thread Cory Spencer

 I think this is definitely something we should do if we want to confuse
 people as much as possible :-)

This is likely true, seeing as I *still* have troubles keeping the various
Lisp eq/eql/equal/equalp's straight. ;)

 I would therefore vote that we keep these opcodes as verbose as
 possible. So no eq/eql/equal, but rather
 same_address/same_content/compare/compare_as_num/compare_as_string.

Some of those are probably a little too verbose for my tastes. ;)

We're already using 'eq' to perform equality testing, and in the interests
of maintaining a consistent design I would choose to stick with something
eq-related as opposed to changing it to 'same'.

eqaddr/eqval?  eq_addr/eq_val?  eq_address/eq_value?

With respects to the compare_as_num/compare_as_string opcodes, there's
also already a 'cmp' opcode and there already seems to be the established
naming scheme of opcodeX, where X is one of n/i/s/p, depending on the type
being dealt with (ie. cleari, clearn, clears, clearp).

cmpi/cmpn/cmps/cmpp?  cmpasi/cmpasn/cmpass/cmpasp?
cmp_as_i/cmp_as_n/cmp_as_s/cmp_as_p?

Personally, I'd probably pick the first option in each of the above sets,
though that is just my preference... :)

Cory


Re: Determining PMC memory addresses

2003-11-28 Thread Cory Spencer

 We're already using 'eq' to perform equality testing, and in the interests
 of maintaining a consistent design I would choose to stick with something
 eq-related as opposed to changing it to 'same'.

 eqaddr/eqval?  eq_addr/eq_val?  eq_address/eq_value?

Oops, correction there - I'd forgotten an earlier post that pointed out
the proposed functionality of eqval/eq_val/eq_value had already been
implemented.


Determining PMC memory addresses

2003-11-27 Thread Cory Spencer

Is there any way in PASM to determine whether or not two PMC's share the
same memory address?

That is, for example, given the following IMC snippet:

  .sub _eq
.param pmc arg1
.param pmc arg2
.local int retv

...
...

.pcc_begin_return
.return retv
.pcc_end_return
  .end

what I'd like to do is to determine whether arg1 and arg2 are the SAME pmc
object (not in value, but whether or not they reside at the same location
in memory).

Regards,

Cory


Parrot compilers

2003-01-17 Thread Cory Spencer

Hey folks -

In my wanders through the parrot/languages subdirectories, it appears that
most example languages implement a complete compiler (ie lexxer - parser
- optimizer - code emitter), which seems to be somewhat of a
duplication of labour.  Has or is anyone worked on a framework a la gcc
which would only require that new languages have a lexxer/parser written
that coerced data into a standardized AST which could be passed off to other
compilation stages?  (Similarly, other end targets (such as Java bytecode
or native code would only require the implementation of a new code
emission module.)

-c