Re: [perl #25265] [PATCH] peek opcode
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
- (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...
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
(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
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
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
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
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
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?
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
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
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
'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
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
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...
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
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
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
I've been hard pressed to find any examples of proper exception-raising with Parrot t/pmc/exception.t Excellent, thank you.
Raising exceptions
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?
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
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
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
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
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
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
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