PROPOSALS FOR PIR GRAMMAR
-------------------------

This document lists peculiarities of the current PIR implementation
in IMCC while implementing it using PGE. 
IMHO, it'd be nice to clean up some of these before the 1.0 release 
of Parrot, in order to prevend 'backward compatibilty' features.

Also, I propose some extensions to PIR, which may or may not
be accepted. These new features are prefixed with "NEW:".
The rationale for them is included. The proposals for the extensions
have an ID starting at 100, so they can be listed together, separate
from the clean-up proposals.

This document is intended to start discussion of the listed
features. That way, the grammar of PIR can be cleaned up and
made more user-friendly.

Please note that these are just *proposals*, not an attempt to
extend PIR with non-features.



1. ".emit/.eom" directives to put PASM instructions in PIR files.
	 Do we still need these? What use-case do they have? If any,
	 can't they use .sub <id> :anon :load or whatever?
	 
	 Proposal: remove them.
	 
2. The optional comma between sub pragmas.
	 Sub definitions allow for pragmas after the sub id, like so:
	 	
	 	.sub main :main :load :init
	 	.end
	 	
	 However, the pragmas *may* be separated by a comma, like so:
	 
	 	.sub main :main, :load, :init
	 	.end
	 	
	 Proposal: remove the optional comma from the grammar. Parameter
	 flags are not separated by commas neither, so it would look more
	 consistent. An optional comma is kinda strange; either demand it,
	 or not.
	 
3. :postcomp and :immediate
	 
	 According to the documentation, both flags indicate the same
	 behaviour. This is both unnecessary and unclear to new users.
	 
	 Proposal: deprecate one of these flags and remove it afterwards.
	 
4. Macro parameter list.

	 Macro definitions may have parameters. However, if they don't take
	 parameters, the parentheses are optional. So either of these examples
	 are allowed:
	 
	 # 1
	 .macro doIt
	 .endm
	 
	 # 2
	 .macro doIt()
	 .endm
	 
	 Currently, IMCC differentiates between these 2: if the macro was 
	 declared like #1, then it needs to be called *without* parentheses
	 (which is, arguably, consistent). However, if it's defined like #2,
	 then the empty parentheses are needed in the macro 'invocation' (i.e.
	 expansion).
	 
	 Proposal: Always demand parentheses. This way, macro expansions always
	 have parentheses, even if there are no parameters. This looks more
	 uniform than having both forms in the PIR source code.
		 
		 
5. .pcc_sub vs .sub
		
	 What's the difference? Are both directives needed? Are there clear
	 advantages to have both?
	 
	 Proposal: remove '.pcc_sub', and stick to '.sub'
	 
6. Disallow .pcc_begin_yield + .pcc_end_return

	 Currently, IMCC allows:
	 	
	 	.pcc_begin_yield
	 	.return 1
	 	.pcc_end_return
	 	
	 It would be more consistent to demand '.pcc_begin_yield' to match '.pcc_end_yield'.
	 
7. Change #line into .line
	
	 IMHO, it would be nicer to have the #line directive spelled as ".line". This way,
	 it's more clear it's not a comment but rather a directive saying to the assembler
	 which line is being parsed/assembled. It'd be more consistent with respect to
	 other PIR directives ('.include' etc.). The current spelling seems rather arbitrary.




NEW FEATURE PROPOSALS GO HERE:	 
	 
	 
100. NEW: Allow nested subs.
	
	 With the reimplementation of PIR in PGE it'd be *very* easy to allow
	 for nested subs. This would prevent the need for the :outer() flag,
	 and would make code generation for *many* languages targeting Parrot
	 much easier.
	 
	 So, instead of:
	 
	 	sub foo {
	 		sub bar {
	 		}
	 	}
	 
	 to translate to:
	 
	 	.sub foo	 
	 	.end
	 
	 	.sub bar :outer('foo')	 
	 	.end
	 
	 have it translate to:
	 
	 	.sub foo
	 		.sub bar
	 		.end
	 	.end
	 
101. NEW: Allow for ".class" directive.

	 Sometimes, you just want to have some class defined in the HLL source
	 to be just there, when the code starts running. Currently, this can be
	 solved like:
	 
	 	.sub _create_classes :anon :load :init
	 		$P0 = newclass "MyClass"
	 		addattribute $P0, "x"
	 	.end
	 	
	 	.namespace ["MyClass"]
	 	
	 	.sub sayHello :method
	 		print "Hello"
	 	.end
	 	
	 This feature is so common, why not have a .class/.end pair for this? It would
	 make code generation for languages a bit easier, I think.
	 
	 This would allow for writing:
	 
	 	.class MyClass
	 		.attribute x
	 		
	 		# .sub could be used to specify a "Class method" (i.e. static method in Java)
	 		# or, maybe, allow for ".method sayHello :static" or ":class" to
	 		# indicate class methods. Or, just use the ".sub <id> :method" syntax.
	 		.method sayHello 
	 			print "Hello"
	 		.end
	 		
	 	.end
	 	
	 	Of course, as classes may be nested in several namespaces, the use of the .namespace
	 	directive may still be needed, like:
	 	
	 		.namespace ['PIR';'Grammar'] 
	 	
	 	could become:
	 	
	 		.namespace ['PIR']
	 		
	 		.class Grammar
	 		.end
	 	
	 	This feature could easily be built "on top" of PIR, i.e. just have it translated to the
	 	current scheme. (using an anonymous :load/:init sub creating the class).
	 	
	 	
	
102. NEW: Allow for .try/.catch blocks

	 Instead of writing:
	 	
	 	...
	 	push_eh on_error
	 	# do some scary stuff
	 	clear_eh
	 	goto after_handler
on_error:
		# exception handling
		.local pmc Exc 
		.get_results "()", Exc # get the exception object.
after_handler:			 		 
		...
		
		One could have the labels stuff generated by PIR:
		
		.try # no need for some label, it's done for you!
			# do some scary stuff
		.catch Exc # some id for the exception object
			# exception handling
		.end
		
	 Not only is the programmer freed of handling the labels, it
	 just looks neater and cleaner!
	 
	 
103. NEW: '.yield' instead of '.return' in '.pcc_begin_yield/.pcc_end_yield'
	
		Currently, IMCC demands '.return' directives in a .pcc_begin_yield/.pcc_end_yield
		block. It might be more clear to introduce a '.yield' directive, to make it
		very clear that it's a yield, not a plain return.