Author: bernhard
Date: Wed Jan 31 13:30:57 2007
New Revision: 16856

Added:
   trunk/languages/PIR/PROPOSALS
   trunk/languages/PIR/examples/hllmap.pir
   trunk/languages/PIR/t/branch.t
   trunk/languages/PIR/t/call.t
   trunk/languages/PIR/t/compunit.t
   trunk/languages/PIR/t/sym.t
Modified:
   trunk/MANIFEST
   trunk/MANIFEST.SKIP
   trunk/languages/PIR/lib/pasm.pg
   trunk/languages/PIR/lib/pir.pg
   trunk/languages/PIR/t/assign.t
   trunk/languages/PIR/t/sub.t
   trunk/languages/PIR/t/whitespace.t

Log:
fixes for language/PIR grammar on several points, amongst which are:

   * support for .invocant + .meth_call
   * support for .local decls before .result directives
   * added assignment operators like +=
   * minor other fixes
   * added more tests
   * added a PROPOSALS file, containing some ideas on
     how to improve/clean up PIR grammar,
     which might be interesting to discuss in the future. 

Thanks to Klaas Jan Stol


Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST      (original)
+++ trunk/MANIFEST      Wed Jan 31 13:30:57 2007
@@ -1,7 +1,7 @@
 # ex: set ro:
 # $Id$
 #
-# generated by tools/dev/mk_manifest_and_skip.pl Wed Jan 31 20:18:40 2007 UT
+# generated by tools/dev/mk_manifest_and_skip.pl Wed Jan 31 20:29:02 2007 UT
 #
 # See tools/dev/install_files.pl for documentation on the
 # format of this file.

Modified: trunk/MANIFEST.SKIP
==============================================================================
--- trunk/MANIFEST.SKIP (original)
+++ trunk/MANIFEST.SKIP Wed Jan 31 13:30:57 2007
@@ -1,6 +1,6 @@
 # ex: set ro: 
 # $Id$
-# generated by tools/dev/mk_manifest_and_skip.pl Wed Jan 31 20:18:40 2007 UT
+# generated by tools/dev/mk_manifest_and_skip.pl Wed Jan 31 20:29:02 2007 UT
 #
 # This file should contain a transcript of the svn:ignore properties
 # of the directories in the Parrot subversion repository. (Needed for

Added: trunk/languages/PIR/PROPOSALS
==============================================================================
--- (empty file)
+++ trunk/languages/PIR/PROPOSALS       Wed Jan 31 13:30:57 2007
@@ -0,0 +1,224 @@
+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. PIR vs PASM registers
+               
+        Since the new calling conventions/register allocation scheme (don't
+        know when exactly), subs have as many registers as they need; no 
+        spilling is needed anymore (IIUC). Therefore, the difference between
+        PIR and PASM registers is not necessary anymore.
+        
+        Proposal: stick to 1 category of registers, either PIR or PASM.
+        My preference is to stick with PIR registers, to make a difference
+        with .local's or .sym's (which may not start with a '$').
+        
+        
+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.
\ No newline at end of file

Added: trunk/languages/PIR/examples/hllmap.pir
==============================================================================
--- (empty file)
+++ trunk/languages/PIR/examples/hllmap.pir     Wed Jan 31 13:30:57 2007
@@ -0,0 +1,2 @@
+
+.HLL_map 22 , 22

Modified: trunk/languages/PIR/lib/pasm.pg
==============================================================================
--- trunk/languages/PIR/lib/pasm.pg     (original)
+++ trunk/languages/PIR/lib/pasm.pg     Wed Jan 31 13:30:57 2007
@@ -41,20 +41,20 @@
 
 
 rule bitwise_op {
-    band                <var> \, <simple_expr> [ \, <simple_expr> ]?
-  | bands               <var> \, <simple_expr> [ \, <simple_expr> ]?
-  | bnot                <var> [ \, <simple_expr> ]?
-  | n_bnot              <var> \, <simple_expr>
-  | bnots               <var> [ \, <simple_expr> ]?
-  | n_bnots             <var> \, <simple_expr>
-  | bor                 <var> \, <simple_expr> [ \, <simple_expr> ]?
-  | bors                <var> \, <simple_expr> [ \, <simple_expr> ]?
-  | shl                 <var> \, <simple_expr> [ \, <simple_expr> ]?
-  | shr                 <var> \, <simple_expr> [ \, <simple_expr> ]?
-  | lsr                 <var> \, <simple_expr> [ \, <simple_expr> ]?
-  | rot                 <var> \, <simple_expr>  \, <simple_expr> \, 
<simple_expr>
-  | bxor                <var> \, <simple_expr> [ \, <simple_expr> ]?
-  | bxors               <var> \, <simple_expr> [ \, <simple_expr> ]?
+    band                <target> \, <simple_expr> [ \, <simple_expr> ]?
+  | bands               <target> \, <simple_expr> [ \, <simple_expr> ]?
+  | bnot                <target> [ \, <simple_expr> ]?
+  | n_bnot              <target> \, <simple_expr>
+  | bnots               <target> [ \, <simple_expr> ]?
+  | n_bnots             <target> \, <simple_expr>
+  | bor                 <target> \, <simple_expr> [ \, <simple_expr> ]?
+  | bors                <target> \, <simple_expr> [ \, <simple_expr> ]?
+  | shl                 <target> \, <simple_expr> [ \, <simple_expr> ]?
+  | shr                 <target> \, <simple_expr> [ \, <simple_expr> ]?
+  | lsr                 <target> \, <simple_expr> [ \, <simple_expr> ]?
+  | rot                 <target> \, <simple_expr>  \, <simple_expr> \, 
<simple_expr>
+  | bxor                <target> \, <simple_expr> [ \, <simple_expr> ]?
+  | bxors               <target> \, <simple_expr> [ \, <simple_expr> ]?
 }
 
 rule comparison_op {
@@ -82,16 +82,16 @@
   | ge_str              <arg_exp_exp_lab>
   | ge_num              <arg_exp_exp_lab>
   | ge_addr             <arg_exp_exp_lab>
-  | if_null             <var> \, <id>
-  | unless_null         <var> \, <id>
+  | if_null             <target> \, <id>
+  | unless_null         <target> \, <id>
   | cmp                 <isXX_args>
   | cmp_str             <isXX_args>
   | cmp_num             <isXX_args>
   | issame              <isXX_args>
   | isntsame            <isXX_args>
-  | istrue              [ <int_reg> | <id> ] \, <var>
-  | isfalse             [ <int_reg> | <id> ] \, <var>
-  | isnull              [ <int_reg> | <id> ] \, <var>
+  | istrue              [ <int_reg> | <id> ] \, <target>
+  | isfalse             [ <int_reg> | <id> ] \, <target>
+  | isnull              [ <int_reg> | <id> ] \, <target>
   | isge                <isXX_args>
   | isgt                <isXX_args>
   | isle                <isXX_args>
@@ -99,27 +99,27 @@
   | iseq                <isXX_args>
   | isne                <isXX_args>
   | and                 [ <int_reg> | <id> ] \, <simple_expr> \, <simple_expr>
-  | not                 <var> [ \, <var> ]?
-  | n_not               <var> \, <var>
+  | not                 <target> [ \, <target> ]?
+  | n_not               <target> \, <target>
   | or                  [ <int_reg> | <id> ] \,<simple_expr> \, <simple_expr>
   | xor                 [ <int_reg> | <id> ] \, <simple_expr> \, <simple_expr>
 }
 
 rule debug_op {
     debug_init
-  | debug_load          <var>
+  | debug_load          <target>
   | debug_break
   | debug_print
   | backtrace
-  | getline             <var>
-  | getfile             <var>
+  | getline             <target>
+  | getfile             <target>
 }
 
 
 rule loading_op {
     clone
   | exchange
-  | set                 <var> \, <simple_expr>
+  | set                 <target> \, <simple_expr>
   | assign              <arg_hack> #
   | setref              <arg_hack> #
   | deref               <arg_hack> #
@@ -178,7 +178,7 @@
 #
 # define "argument" rules, so that not each instruction has to
 # define it's specific number and types of args.
-# for instance: args_v_i_s for matching a <var> argument,
+# for instance: args_v_i_s for matching a <target> argument,
 # <int_constant> argument and a <string_constant> argument
 #
 

Modified: trunk/languages/PIR/lib/pir.pg
==============================================================================
--- trunk/languages/PIR/lib/pir.pg      (original)
+++ trunk/languages/PIR/lib/pir.pg      Wed Jan 31 13:30:57 2007
@@ -110,7 +110,7 @@
 
 rule body {
   <param_decl>*
-  <pir_instr>*
+  <labeled_pir_instr>*
   [ <'.end'> | <syntax_error: '.end' expected to close method/sub body> ]
 }
 
@@ -132,20 +132,32 @@
 #
 
 
-rule pir_instr {
+rule labeled_pir_instr {
   [ <label> <instr>?
   | <instr>
   ] 
   [ <?nl> | <syntax_error: newline expected after instruction> ]
 }
 
+rule labeled_pasm_instr {
+       [ <label> <pasm_instr>?
+  | <pasm_instr>
+  ] 
+  [ <?nl> | <syntax_error: newline expected after instruction> ]
+}
+
+rule instr {
+       [ <pir_instr> | <pasm_instr> ]
+       
+}
+
 # this is a token, because no spaces are allowed between
 # the id and the colon.
 token label {
   <id> <':'>
 }
 
-rule instr {
+rule pir_instr {
     <local_decl>
   | <lexical_decl>
   | <const_def>
@@ -156,8 +168,7 @@
   | <return_stat>
   | <sub_invocation>
   | <macro_invocation>
-  | <jump_stat>
-  | <pasm_instr>      
+  | <jump_stat>  
   | <source_info>
 }
 
@@ -193,7 +204,7 @@
   <'.lex'>
   [ <string_constant> | <syntax_error: string constant expected> ]
   [ <','>             | <syntax_error: ',' expected> ]
-  [ <reg>             | <syntax_error: register expected> ]
+  [ <target>          | <syntax_error: register expected> ]
 }
 
 
@@ -274,14 +285,29 @@
   | <'>>>'>
   | <'>>'>  
   | <'&&'>
-  | <'!!'>
+  | <'||'>
   | <'~~'>
-  | <'!'>
+  | <'|'>
   | <'&'>
   | <'~'>
   | <'.'>
 }
 
+rule assign_operator {
+               <'+='>
+       | <'-='>
+       | <'/='>
+       | <'%='>
+       | <'*='>
+       | <'.='>
+       | <'&='>
+       | <'|='>
+       | <'~='>
+       | <'<<='>
+       | <'>>='>
+       | <'>>>='>
+}
+
 rule unary_operator {
     <'!'>  
   | <'-'>
@@ -290,7 +316,7 @@
 
 
 rule expression {
-    [ <simple_expr> [ <binary_operator> <simple_expression> ]? ]
+    [ <simple_expr> [ <binary_operator> <simple_expr> ]? ]
   | [ <unary_operator> <simple_expr> ]
 }
 
@@ -325,6 +351,7 @@
   | <target> <'='> <'find_type'> [ <string_constant> | <string_reg> | <id> ]
   | <target> <'='> <heredoc_string>
   | <target> <'='> <'global'> <string_constant> # deprecated?  
+  | <target> <assign_operator> <simple_expr>
   | <target> <keylist> <'='> <simple_expr>  
   | <'global'> <string_constant> <'='> <target> # deprecated?
   | <result_var_list> [ <'='> | <syntax_error: '=' expected> ] <short_sub_call>
@@ -399,16 +426,22 @@
   <'.pcc_begin'>
   [ <?nl>  | <syntax_error: newline after '.pcc_begin' expected> ]
   <arguments>
-  [ <'.pcc_call'> 
-  | <'.nci_call'> 
-  | <syntax_error: '.pcc_call' or '.nci_call' expected> 
+  [ [ <'.pcc_call'> | <'.nci_call'> ]
+  | [ <invocant> <'.meth_call'> ]
   ]
   [ <target> | <syntax_error: id or register expected that holds the sub 
object> ]
   [ <?nl>    | <syntax_error: newline after '.pcc_call sub' expected> ]
+       [ <local_decl> <?nl> ]*
   <result_values>
   [ <'.pcc_end'>  | <syntax_error: '.pcc_end' expected> ]  
 }
 
+rule invocant {
+       <'.invocant'> 
+       <target> 
+       <?nl>                    
+}
+
 rule short_sub_call {
   [ <target>\. ]?                  # optional object
   [ <target> | <string_constant> ] # method or sub name/id
@@ -562,7 +595,7 @@
 rule emit {
   <'.emit'>
   [ <?nl>        | <syntax_error: newline expected> ]
-  <pir_instr>*
+  <labeled_pasm_instr>*
   [ <'.eom'>     | <syntax_error: '.eom' expected> ]
 }
 
@@ -599,8 +632,8 @@
   | <new_operators>
   | <loadlib>
   | <namespace>
-  | <hll_specifier>
   | <hll_mapping>
+  | <hll_specifier>  
   | <source_info>
 }
 
@@ -618,9 +651,10 @@
 
 rule namespace {
   <'.namespace'> 
-  [ <'['>             | <syntax_error: '[' expected> ]
-  [ <namespace_id>    | <syntax_error: namespace identifier expected> ]
-  [ <']'>             | <syntax_error: ']' expected> ]
+  [ <'['>        
+       [ <namespace_id>    | <syntax_error: namespace identifier expected> ]
+       [ <']'>             | <syntax_error: ']' expected> ]
+  ]?
 }
 
 rule hll_specifier {
@@ -804,10 +838,12 @@
   | <'.HLL'>
   | <'.immediate'>
   | <'.include'>
+  | <'.invocant'>
   | <'.lex'>
   | <'.line'>
   | <'.loadlib'>
   | <'.local'>
+  | <'.meth_call'>
   | <'.namespace'>
   | <'.nci_call'>
   | <'.param'>

Modified: trunk/languages/PIR/t/assign.t
==============================================================================
--- trunk/languages/PIR/t/assign.t      (original)
+++ trunk/languages/PIR/t/assign.t      Wed Jan 31 13:30:57 2007
@@ -3,6 +3,93 @@
 use strict;
 use warnings;
 use lib qw(t . lib ../lib ../../lib ../../../lib);
+use Parrot::Test tests => 5;
+use Test::More;
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'simple assignments' );
+.sub main                      
+       a = 1
+       b = 1.1
+       c = "hello"
+       d = e
+.end
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'get keyed assignments' );
+.sub main                      
+       e = x[1]
+       f = x[1.1]
+       g = x["hello"]
+       h = x[e]        
+.end
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'set keyed assignments' );
+.sub main                      
+       x[1]                            = 1
+       x[1.1]                  = 2.222
+       x["hello"]      = "hello"
+       x[e]                            = f
+.end
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'simple expressions' );
+.sub main                      
+       .local int x,y,z,a,b,c
+       x = 1 + 2
+       x = 1 * 2
+       y = 2 / 4
+       y = 2 - 4
+       z = 2 ** 4
+       z = 2 % 1
+       a = b &  c
+       a = b && c
+       a = b |  c
+       a = b || c
+       a = b << c
+       a = b >> c
+       a = b >>> c
+       a = - x
+       a = ! x
+       a = ~ x
+.end
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'assign operators' );
+.sub main                      
+       .local int x
+       x = 0
+       x += 1
+       x *= 5
+       x /= 2
+       x -= 1
+       x %= 2
+       x <<= 1
+       x >>= 1
+       x >>>= 1
+.end
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+#!perl
+
+use strict;
+use warnings;
+use lib qw(t . lib ../lib ../../lib ../../../lib);
 use Parrot::Test tests => 3;
 use Test::More;
 

Added: trunk/languages/PIR/t/branch.t
==============================================================================
--- (empty file)
+++ trunk/languages/PIR/t/branch.t      Wed Jan 31 13:30:57 2007
@@ -0,0 +1,64 @@
+#!perl
+
+use strict;
+use warnings;
+use lib qw(t . lib ../lib ../../lib ../../../lib);
+use Parrot::Test tests => 3;
+use Test::More;
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'if statement' );
+.sub main                      
+       
+       if 1 < 2 goto L1
+L1:
+       if 2 > 3 goto L2
+L2:
+       if 1 <= 2 goto L3
+L3:
+       if 2 >= 2 goto L4
+L4:
+       if 3 == 3 goto L5
+L5:
+       if 3 != 4 goto L6
+L6:
+
+.end
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'unless statement' );
+.sub main                      
+       
+       unless 1 < 2 goto L1
+L1:
+       unless 2 > 3 goto L2
+L2:
+       unless 1 <= 2 goto L3
+L3:
+       unless 2 >= 2 goto L4
+L4:
+       unless 3 == 3 goto L5
+L5:
+       unless 3 != 4 goto L6
+L6:
+
+.end
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'goto statement' );
+.sub main                      
+       
+       goto L1
+L1:
+
+.end
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT

Added: trunk/languages/PIR/t/call.t
==============================================================================
--- (empty file)
+++ trunk/languages/PIR/t/call.t        Wed Jan 31 13:30:57 2007
@@ -0,0 +1,169 @@
+#!perl
+
+use strict;
+use warnings;
+use lib qw(t . lib ../lib ../../lib ../../../lib);
+use Parrot::Test tests => 9;
+use Test::More;
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'long sub invocation' );
+
+.sub main :main
+       .local int x, y, z
+       .pcc_begin
+       .arg 1
+       .arg 2
+       .arg 3
+       .pcc_call foo
+       .local int a, b, c      
+       .result a
+       .result b
+       .result c
+       .pcc_end
+.end
+
+.sub foo
+       .pcc_begin_return
+       .return 4
+       .return 5
+       .return 6
+       .pcc_end_return
+.end
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'long sub invocation 2' );
+
+.sub main :main
+       .pcc_begin
+       .pcc_call foo
+       .pcc_end
+.end
+
+.sub foo
+       .pcc_begin_return
+       .pcc_end_return
+.end
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'short sub invocation' );
+
+.sub main :main
+       .local int x, y, z
+       (x, y, z) = foo(1, 2, 3)
+       
+       foo(1,2,3)
+.end
+
+.sub foo
+       .return(4, 5, 6)
+.end
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'short yield' );
+
+.sub main :main
+       .yield(1,2,3)
+       .yield()
+.end
+
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'long yield' );
+
+.sub main :main
+       .pcc_begin_yield
+       .return 1
+       .return 2
+       .return 3
+       .pcc_end_yield  
+.end
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'tail call' );
+
+.sub main :main
+       .return foo()   
+.end
+
+.sub foo
+       .return bar()
+.end
+
+.sub bar
+       .return(1)
+.end
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'tail method call' );
+
+.sub main :main
+       .return obj.foo()       
+.end
+
+.sub foo
+       .return obj.bar()
+.end
+
+.sub bar
+       .return(1)
+.end
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'nci call' );
+
+.sub main :main
+       .local pmc x
+       .pcc_begin
+       .nci_call x
+       .pcc_end
+.end
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'long method call' );
+
+.sub main :main
+       .local pmc x
+       .pcc_begin
+       .invocant obj
+       .meth_call meth
+       .pcc_end
+.end
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT

Added: trunk/languages/PIR/t/compunit.t
==============================================================================
--- (empty file)
+++ trunk/languages/PIR/t/compunit.t    Wed Jan 31 13:30:57 2007
@@ -0,0 +1,167 @@
+#!perl
+
+use strict;
+use warnings;
+use lib qw(t . lib ../lib ../../lib ../../../lib);
+use Parrot::Test tests => 15;
+use Test::More;
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'global defs' );
+
+.global g_X
+
+.global g_Y
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'const defs' );
+
+.const int iConst = 42
+
+.const num nConst = 3.14
+
+.const string sConst = "Hello World"
+
+.const pmc pConst = "is a PMC const a string?"
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'simple macro, no params' );
+
+.macro myMacro
+.endm
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'simple macro, params' );
+
+.macro doIt(A,B)
+.endm
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'include directive' );
+
+.include "Hitchhikers.pir"
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'loadlib directive' );
+
+.loadlib "Hitchhikers"
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'n_operators directive' );
+
+.pragma n_operators 1
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'namespaces 1' );
+
+.namespace ['']
+.namespace [""]
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'namespaces 2' );
+
+.namespace ['PIR']
+.namespace ["PIR"]
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'namespaces 3' );
+
+.namespace ['PIR';'Grammar']
+.namespace ["PIR";"Grammar"]
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'Root namespace' );
+
+.namespace
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'HLL' );
+
+.HLL 'PIR', 'PIRlib'
+.HLL "PIR", "PIRlib"
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'HLL map' );
+
+.HLL_map 42, 10
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'source line info' );
+
+.line 42
+
+.line 42, "Hitchhikers.pir"
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'emit' );
+
+.emit
+       set P0, 1
+.eom
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+

Modified: trunk/languages/PIR/t/sub.t
==============================================================================
--- trunk/languages/PIR/t/sub.t (original)
+++ trunk/languages/PIR/t/sub.t Wed Jan 31 13:30:57 2007
@@ -3,7 +3,7 @@
 use strict;
 use warnings;
 use lib qw(t . lib ../lib ../../lib ../../../lib);
-use Parrot::Test tests => 20;
+use Parrot::Test tests => 21;
 use Test::More;
 
 language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'basic sub' );
@@ -175,3 +175,17 @@
 "parse" => PMC 'PIRGrammar' { ... }
 Parse successful!
 OUT
+
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'wrap flag -- new!' );
+
+# This test makes sure pir.pbc is running, not IMCC, as :wrap is still 
unimplemented and undecided.
+.sub x :wrap('y')
+
+.end
+
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT

Added: trunk/languages/PIR/t/sym.t
==============================================================================
--- (empty file)
+++ trunk/languages/PIR/t/sym.t Wed Jan 31 13:30:57 2007
@@ -0,0 +1,78 @@
+#!perl
+
+use strict;
+use warnings;
+use lib qw(t . lib ../lib ../../lib ../../../lib);
+use Parrot::Test tests => 5;
+use Test::More;
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'local decls 1' );
+
+.sub main
+       .local int a
+       .local string b
+       .local num c
+       .local pmc d
+.end
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'local decls 2' );
+
+.sub main
+       .local int a, k, l, m
+       .local string b, n, o, p
+       .local num c, q, r, s
+       .local pmc d, t, u
+.end
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'local decls - unique_reg' );
+
+.sub main
+       .local int a :unique_reg, b, c
+       .local num e, f :unique_reg, g
+       .local pmc h, i, j :unique_reg
+.end
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'sym decls - unique_reg' );
+
+.sub main
+       .sym int a :unique_reg, b, c
+       .sym num e, f :unique_reg, g
+       .sym pmc h, i, j :unique_reg
+.end
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'lexicals' );
+
+.sub main
+       .local pmc a
+       .lex "x", $P0
+       .lex "y", a
+.end
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+

Modified: trunk/languages/PIR/t/whitespace.t
==============================================================================
--- trunk/languages/PIR/t/whitespace.t  (original)
+++ trunk/languages/PIR/t/whitespace.t  Wed Jan 31 13:30:57 2007
@@ -522,3 +522,527 @@
 Parse successful!
 OUT
 
+#!perl
+
+use strict;
+use warnings;
+use lib qw(t . lib ../lib ../../lib ../../../lib);
+use Parrot::Test tests => 10;
+use Test::More;
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'comments before code' );
+#
+# pre-code comment
+#
+.sub main                      
+.end
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'comments after code' );
+.sub main                      
+.end
+#
+# comments after code
+#
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'comments in code' );
+.sub main                      
+#
+# in-code comment
+#
+.end
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'comments after code' );
+.sub main                      
+
+       x = 1 # this is an assignment!
+       # this is comment # this is even more comment
+       
+.end
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'pre-code whitespace' );
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+.sub main                      
+.end
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'in-code whitespace' );
+.sub main                      
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+.end
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'after-code whitespace' );
+.sub main                      
+.end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'pre-code pod comments' );
+=pod
+
+hi there
+
+documentation rocks!
+
+
+
+
+
+
+
+
+=cut
+
+
+
+.sub main                      
+.end
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'in-code pod comments' );
+.sub main                      
+
+=pod 
+
+hello!!
+
+Parrot rocks too!
+
+=cut
+.end
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+
+
+language_output_is( 'PIR_PGE', <<'CODE', <<'OUT', 'after-code pod comments' );
+.sub main                      
+.end
+
+=pod
+
+Don't forget to hit enter after typing last OUT marker in the test file!
+
+=cut
+
+CODE
+"parse" => PMC 'PIRGrammar' { ... }
+Parse successful!
+OUT
+

Reply via email to