Author: jonathan
Date: Tue Nov 11 11:44:51 2008
New Revision: 32554

Modified:
   trunk/languages/perl6/perl6.pir
   trunk/languages/perl6/src/builtins/guts.pir
   trunk/languages/perl6/src/parser/actions.pm

Log:
[rakudo] Some very basic support for MAIN entry point sub. Just passes all 
command line arguments as positionals.

Modified: trunk/languages/perl6/perl6.pir
==============================================================================
--- trunk/languages/perl6/perl6.pir     (original)
+++ trunk/languages/perl6/perl6.pir     Tue Nov 11 11:44:51 2008
@@ -160,24 +160,21 @@
 .sub 'main' :main
     .param pmc args_str
 
-    ##  create @ARGS global.  We could possibly use the args pmc
-    ##  coming directly from Parrot, but currently Parrot provides
-    ##  it as a ResizableStringArray and we need Undefs for
-    ##  non-existent elements (RSA gives empty strings).
-    .local pmc args, iter
-    args = new 'List'
-    iter = new 'Iterator', args_str
-  args_loop:
-    unless iter goto args_end
-    $P0 = shift iter
-    push args, $P0
-    goto args_loop
-  args_end:
-    set_hll_global '@ARGS', args
+    ## Set up @*ARGS.
+    .local pmc args
+    args = '!SETUP_ARGS'(args_str, 0)
 
     $P0 = compreg 'Perl6'
     $P1 = $P0.'command_line'(args, 'encoding'=>'utf8', 
'transcode'=>'iso-8859-1')
 
+    ## Now execute any MAIN sub.
+    .local pmc main_sub, args
+    main_sub = get_hll_global 'MAIN'
+    if null main_sub goto no_main
+    args = get_hll_global '@ARGS'
+    main_sub(args :flat)
+  no_main:
+
     .include 'iterator.pasm'
     .local pmc iter
     $P0 = get_hll_global ['Perl6'], '@?END_BLOCKS'

Modified: trunk/languages/perl6/src/builtins/guts.pir
==============================================================================
--- trunk/languages/perl6/src/builtins/guts.pir (original)
+++ trunk/languages/perl6/src/builtins/guts.pir Tue Nov 11 11:44:51 2008
@@ -251,6 +251,34 @@
 .end
 
 
+=item !SETUP_ARGS
+
+Sets up the @*ARGS global. We could possibly use the args pmc coming directly
+from Parrot, but currently Parrot provides it as a ResizableStringArray and we
+need Undefs for non-existent elements (RSA gives empty strings).
+
+=cut
+
+.sub '!SETUP_ARGS'
+    .param pmc args_str
+    .param int strip_program_name
+    .local pmc args, iter
+    args = new 'List'
+    iter = new 'Iterator', args_str
+  args_loop:
+    unless iter goto args_end
+    $P0 = shift iter
+    push args, $P0
+    goto args_loop
+  args_end:
+    unless strip_program_name goto done
+    $P0 = shift args
+  done:
+    set_hll_global '@ARGS', args
+    .return (args)
+.end
+
+
 =item !keyword_class(name)
 
 Internal helper method to create a class.

Modified: trunk/languages/perl6/src/parser/actions.pm
==============================================================================
--- trunk/languages/perl6/src/parser/actions.pm (original)
+++ trunk/languages/perl6/src/parser/actions.pm Tue Nov 11 11:44:51 2008
@@ -56,6 +56,64 @@
         )
     );
 
+    #  emit a :main block that acts as the entry point in pre-compiled scripts
+    $past.push(
+        PAST::Block.new(
+            :pirflags(':main'),
+            PAST::Op.new(
+                :pasttype('call'),
+                :name('!SETUP_ARGS'),
+                PAST::Var.new(
+                 :name('args_str'),
+                 :scope('parameter')
+                ),
+                PAST::Val.new( :value(1) )
+            ),
+            PAST::Op.new(
+                :inline(
+                    '$P0 = interpinfo .INTERPINFO_CURRENT_SUB',
+                    '$P0 = $P0."get_outer"()',
+                    '$P0()'
+                )
+            ),
+            PAST::Op.new(
+                :pasttype('bind'),
+                PAST::Var.new(
+                    :name('main_sub'),
+                    :scope('register'),
+                    :isdecl(1)
+                ),
+                PAST::Var.new(
+                    :name('MAIN'),
+                    :scope('package')
+                )
+            ),
+            PAST::Op.new(
+                :pasttype('unless'),
+                PAST::Op.new(
+                    :pirop('isnull'),
+                    PAST::Var.new(
+                        :name('main_sub'),
+                        :scope('register')
+                    )
+                ),
+                PAST::Op.new(
+                    :pasttype('call'),
+                    PAST::Var.new(
+                        :name('main_sub'),
+                        :scope('register')
+                    ),
+                    PAST::Var.new(
+                        :name('@ARGS'),
+                        :scope('package'),
+                        :namespace(''),
+                        :flat(1)
+                    )
+                )
+            )
+        )
+    );
+
     make $past;
 }
 

Reply via email to