Any kv() question

2009-03-12 Thread Cory Spencer


In the spectest suite (specifically in:  t/spec/S32-array/kv.t), the last 
several tests seem to be testing for named arguments to kv:


# check the non-invocant form with named arguments
my @array = a b c d;
my @kv = kv(:array(@array));
#?rakudo skip 'named args'
is(+...@kv, 8, 'kv(:array(@array)) returns the correct number of elems');
#?rakudo skip 'named args'
is(~...@kv, 0 a 1 b 2 c 3 d, 'kv(:array(@array)) has no inner list');

I've found no mention of named arguments to kv in the spec, so I'm 
wondering if these tests are out of date and should be removed...


-c


Re: Rakudo repository -- svn or git?

2009-02-02 Thread Cory Spencer


Subversion's OK, but I would definitely prefer git.  I've only used it 
for a few small projects, but already it's impressed the heck out of me 
for its behavior in both big things (branching) and small things (git 
diff automatically pages).


Perhaps a response to this thread is a little late, but I stumbled across 
git-svn today which allows interaction between git and a Subversion 
repository:


  http://www.kernel.org/pub/software/scm/git/docs/git-svn.html

I've not used it, so I can't speak to its effectiveness, but I thought of 
this thread when I came across it. :)


Cory


Question regarding Ranges

2008-12-22 Thread cory . spencer

I've got a question regarding Ranges and in particular, infinite
Ranges.  How should a range such as:

  (0..Inf)

or

  (-Inf..0)

be represented when it is converted to a string?  I believe that Pugs
currently attempts to create a range of infinite length and provides
no stringified value.  I'm unable to find a definitive answer in the
Apocalypses and would appreciate any clarification!

Best regards,

Cory



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-30 Thread Cory Spencer
On Fri, 22 Apr 2005, Matt Diephouse wrote:
- (defun (square x) (* x x))
T
- (square 2)
*** ERROR: SQUARE is not a function name
A quick follow-up - I've just checked in code implementing some primitive 
macros, so if you wanted to give (defun ...) a go again, you should find
that it works now.  (Note that Lisp is now included in the languages 
subdirectory of the latest Parrot SVN tree.)

Also, while playing I around I found this happening:
- (* 2 3)
9
- (* 4 3)
9
I've noticed this is also happening for floating point numbers:
  - (* 2 3.2)
  9.6
  - (+ 1.2 3)
I'm not sure what kind of magic you worked last time with Integers, 
Leo, but would you mind working it again?  (Or pointing me in the right 
direction so that I can fix it myself. :)

-c


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


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