[svn:parrot] r42889 - in trunk: . lib/Parrot tools/dev

pmichaud at svn.parrot.org pmichaud at svn.parrot.org
Fri Dec 4 17:26:20 UTC 2009


Author: pmichaud
Date: Fri Dec  4 17:26:19 2009
New Revision: 42889
URL: https://trac.parrot.org/parrot/changeset/42889

Log:
[tools]  Update create_language.pl to build for nqp-based toolchain.
Add create_language.pl to files in installed Parrot.

Modified:
   trunk/MANIFEST
   trunk/lib/Parrot/Manifest.pm
   trunk/tools/dev/create_language.pl

Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST	Fri Dec  4 16:49:04 2009	(r42888)
+++ trunk/MANIFEST	Fri Dec  4 17:26:19 2009	(r42889)
@@ -2154,7 +2154,7 @@
 tools/dev/branch_status.pl                                  []
 tools/dev/cc_flags.pl                                       []
 tools/dev/checkdepend.pl                                    []
-tools/dev/create_language.pl                                []
+tools/dev/create_language.pl                                [devel]
 tools/dev/debian_docs.sh                                    []
 tools/dev/fetch_languages.pl                                []
 tools/dev/gen_charset_tables.pl                             []

Modified: trunk/lib/Parrot/Manifest.pm
==============================================================================
--- trunk/lib/Parrot/Manifest.pm	Fri Dec  4 16:49:04 2009	(r42888)
+++ trunk/lib/Parrot/Manifest.pm	Fri Dec  4 17:26:19 2009	(r42889)
@@ -284,6 +284,7 @@
         tools/build/ops2c.pl                            [devel]
         tools/build/pmc2c.pl                            [devel]
         tools/dev/mk_language_shell.pl                  [devel]
+        tools/dev/create_language.pl                    [devel]
         tools/dev/pbc_to_exe.pir                        [devel]
         tools/dev/gen_makefile.pl                       [devel]
         tools/dev/reconfigure.pl                        [devel]

Modified: trunk/tools/dev/create_language.pl
==============================================================================
--- trunk/tools/dev/create_language.pl	Fri Dec  4 16:49:04 2009	(r42888)
+++ trunk/tools/dev/create_language.pl	Fri Dec  4 17:26:19 2009	(r42889)
@@ -23,14 +23,14 @@
 
     README
     Configure.pl
-    xyz.pir
     build/Makefile.in
-    build/gen_builtins_pir.pl
     build/gen_parrot.pl
-    src/pct/grammar.pg
-    src/pct/grammar-oper.pg
-    src/pct/actions.pm
-    src/builtins/say.pir
+    src/Xyz.pir
+    src/Xyz/Grammar.pm
+    src/Xyz/Actions.pm
+    src/Xyz/Compiler.pm
+    src/Xyz/Runtime.pm
+    src/gen/.gitignore
     t/harness
     t/00-sanity.t
 
@@ -40,6 +40,8 @@
 If all goes well, after creating the language shell one can simply
 change to the language directory and type
 
+    $ perl Configure.pl [--gen-parrot]
+    $ make
     $ make test
 
 to verify that the new language compiles and configures properly.
@@ -61,15 +63,48 @@
 my $lclang = lc $lang;
 my $uclang = uc $lang;
 
-## the name and revision of the script, for use in the generated README
+## the name of the script, for use in the generated README and "reverse"
 my $script = $0;
-my $rev = '$Revision$';
-$rev =~ s/^\D*(\d+)\D*$/r$1/;
 
 ##  get the path from the command line, or if not supplied then
 ##  use languages/$lclang.
 my $path = $ARGV[1] || $lclang;
 
+my $option = $ARGV[2] || '';
+
+if ($option eq 'reverse') {
+    ## instead of using this script to generate the files into $path,
+    ## use the files in $path to generate a new version of this script.
+    open my $fh0, '<', $script or die "Unable to read $script";
+    while (<$fh0>) {
+        print $_;
+        last if /^__DATA__/;
+    }
+    while (<$fh0>) {
+        last if /^__DATA__$/;
+        if (/^__(.*?)__$/) {
+            print;
+            $_ = $1;
+            s{\@lang\@}   {$lang}g;
+            s{\@lclang\@} {$lclang}ig;
+            s{\@UCLANG\@} {$uclang}ig;
+            open my $fh, '<', "$path/$_" or die "Unable to read $path/$_";
+            while (<$fh>) {
+                s{$lang}   {\@lang\@}g;
+                s{$lclang} {\@lclang\@}g;
+                s{$uclang} {\@UCLANG\@}g;
+                s{$script} {\@script\@}g;
+                print;
+            }
+            close $fh;
+        }
+    }
+    print;
+    while (<$fh0>) { print; }
+    close $fh0;
+    exit 0;
+}
+
 ##  now loop through the file information (see below), substituting
 ##  any instances of @lang@, @lclang@, @UCLANG@, and @Id@ with
 ##  the language name or the svn id tag.  If the line has the form
@@ -80,13 +115,16 @@
     s{\@lang\@}   {$lang}g;
     s{\@lclang\@} {$lclang}ig;
     s{\@UCLANG\@} {$uclang}ig;
-    s{\@Id\@}     {\$Id\$}ig;
     s{\@script\@} {$script}ig;
-    s{\@rev\@}    {$rev}ig;
     if (/^__(.*)__$/) { start_new_file("$path/$1"); }
     elsif ($fh) { print $fh $_; }
 }
-##  close the last file
+
+## generate build/PARROT_REVISION
+start_new_file("$path/build/PARROT_REVISION");
+my $rev = '$Revision$';
+$rev =~ s/^\D*(\d+)\D*$/$1/;
+print $fh "$rev\n";
 close($fh) if $fh;
 
 print <<"END";
@@ -95,7 +133,7 @@
 To do an initial build and test of the language:
 
     cd $path
-    perl Configure.pl
+    perl Configure.pl [--gen-parrot]
     make
     make test
 
@@ -132,19 +170,104 @@
 
 __DATA__
 __README__
-Language '@lang@' was created with @script@, @rev at .
+=head1 @lang@
+
+This is @lang@, a compiler for the Parrot virtual machine.
+
+=head2 Build requirements (installing from source)
+
+For building @lang@ you need at least a C compiler, a C<make> utility,
+and Perl 5.8 or newer.  To automatically obtain and build Parrot
+you may also need a subversion (svn) client.
+
+=head2 Building and invoking @lang@
+
+We generally recommend downloading @lang@ directly from 
+[XXX: fill in this information for @lang@].
+
+Once you have a copy of @lang@, build it as follows:
+
+    $ cd @lclang@
+    $ perl Configure.pl --gen-parrot
+    $ make
+
+This will create a "@lclang@" or "@lclang at .exe" executable in the
+current directory.  Programs can then be run from the build 
+directory using a command like:
+
+    $ ./@lclang@ <source>
+
+The C<--gen-parrot> option above tells Configure.pl to automatically
+download and build the most appropriate version of Parrot into
+a local "parrot/" subdirectory, install that Parrot into
+the "parrot_install/" subdirectory, and use that for building
+ at lang@.  It's okay to use the C<--gen-parrot> option on later
+invocations of Configure.pl; the configure system will re-build
+Parrot only if a newer version is needed for whatever version
+of @lang@ you're working with.
+
+You can use C<--parrot-config=/path/to/parrot_config> instead
+of C<--gen-parrot> to use an already installed Parrot for building
+ at lang@.  This installed Parrot must include its development
+environment; typically this is done via Parrot's C<make install>
+target or by installing prebuilt C<parrot-devel> and/or C<libparrot-dev>
+packages.  The version of the already installed Parrot must satisfy a
+minimum specified by @lang@ -- Configure.pl will verify this for you.  
+
+Once built, @lang@'s C<make install> target will install @lang@
+and its libraries into the Parrot installation that was used to
+create it.  Until this step is performed, the "@lclang@" executable
+created by C<make> above can only be reliably run from the root of
+ at lang@'s build directory.  After C<make install> is performed,
+the installed executable can be run from any directory (as long as
+the Parrot installation that was used to create it remains intact).
 
+If the @lang@ compiler is invoked without an explicit script to
+run, it enters a small interactive mode that allows statements
+to be executed from the command line.  Each line entered is treated
+as a separate compilation unit, however (which means that subroutines
+are preserved after they are defined, but variables are not).
+
+=head2 Running the test suite
+
+Entering C<make test> will run a test suite that comes bundled 
+with @lang at .  This is a simple suite of tests, designed to make sure 
+that the compiler is basically working and that it's capable of 
+running a simple test harness.
+
+If you want to run the tests in parallel, you need to install a
+fairly recent version of the Perl 5 module L<Test::Harness> (3.16
+works for sure).
+
+=head2 Where to get help or answers to questions
+
+=head2 Reporting bugs
+
+=head2 Submitting patches
+
+=head2 How the compiler works
+
+See F<docs/compiler_overview.pod>.
+
+=head1 AUTHOR
+
+=cut
+
+## vim: expandtab sw=4 ft=pod tw=70:
 __Configure.pl__
 #! perl
+# Copyright (C) 2009 The Perl Foundation
+
 use 5.008;
 use strict;
 use warnings;
 use Getopt::Long;
+use Cwd;
 
 MAIN: {
     my %options;
     GetOptions(\%options, 'help!', 'parrot-config=s',
-               'gen-parrot!', 'gen-parrot-option=s@');
+               'gen-parrot!', 'gen-parrot-prefix=s', 'gen-parrot-option=s@');
 
     # Print help if it's requested
     if ($options{'help'}) {
@@ -152,10 +275,20 @@
         exit(0);
     }
 
+    # Determine the revision of Parrot we require
+    open my $REQ, "build/PARROT_REVISION"
+      || die "cannot open build/PARROT_REVISION\n";
+    my ($reqsvn, $reqpar) = split(' ', <$REQ>);
+    $reqsvn += 0;
+    close $REQ;
+
     # Update/generate parrot build if needed
     if ($options{'gen-parrot'}) {
         my @opts    = @{ $options{'gen-parrot-option'} || [] };
-        my @command = ($^X, "build/gen_parrot.pl", @opts);
+        my $prefix  = $options{'gen-parrot-prefix'} || cwd()."/parrot_install";
+        # parrot's Configure.pl mishandles win32 backslashes in --prefix
+        $prefix =~ s{\\}{/}g;
+        my @command = ($^X, "build/gen_parrot.pl", "--prefix=$prefix", ($^O !~ /win32/i ? "--optimize" : ()), @opts);
 
         print "Generating Parrot ...\n";
         print "@command\n\n";
@@ -164,31 +297,59 @@
 
     # Get a list of parrot-configs to invoke.
     my @parrot_config_exe = qw(
-        parrot/parrot_config
+        parrot_install/bin/parrot_config
         ../../parrot_config
         parrot_config
     );
+    if (exists $options{'gen-parrot-prefix'}) {
+        unshift @parrot_config_exe,
+                $options{'gen-parrot-prefix'} . '/bin/parrot_config';
+    }
 
     if ($options{'parrot-config'} && $options{'parrot-config'} ne '1') {
         @parrot_config_exe = ($options{'parrot-config'});
     }
 
-    #  Get configuration information from parrot_config
+    # Get configuration information from parrot_config
     my %config = read_parrot_config(@parrot_config_exe);
-    unless (%config) {
-        die <<'END';
-Unable to locate parrot_config.
-To automatically checkout (svn) and build a copy of parrot,
+
+    my $parrot_errors = '';
+    if (!%config) {
+        $parrot_errors .= "Unable to locate parrot_config\n";
+    }
+    elsif ($reqsvn > $config{'revision'} &&
+            ($reqpar eq '' || version_int($reqpar) > version_int($config{'VERSION'}))) {
+        $parrot_errors .= "Parrot revision r$reqsvn required (currently r$config{'revision'})\n";
+    }
+
+    if ($parrot_errors) {
+        die <<"END";
+===SORRY!===
+$parrot_errors
+To automatically checkout (svn) and build a copy of parrot r$reqsvn,
 try re-running Configure.pl with the '--gen-parrot' option.
 Or, use the '--parrot-config' option to explicitly specify
-the location of parrot_config.
+the location of parrot_config to be used to build @lang at .
+
 END
     }
 
-#  Create the Makefile using the information we just got
-    create_makefile(%config);
+    # Verify the Parrot installation is sufficient for building @lang@
+    verify_parrot(%config);
 
+    # Create the Makefile using the information we just got
+    create_makefile(%config);
     my $make = $config{'make'};
+
+    {
+        no warnings;
+        print "Cleaning up ...\n";
+        if (open my $CLEAN, '-|', "$make clean") {
+            my @slurp = <$CLEAN>;
+            close $CLEAN;
+        }
+    }
+
     print <<"END";
 
 You can now use '$make' to build @lang at .
@@ -210,7 +371,7 @@
             while (<$PARROT_CONFIG>) {
                 if (/(\w+) => '(.*)'/) { $config{$1} = $2 }
             }
-            close $PARROT_CONFIG;
+            close $PARROT_CONFIG or die $!;
             last if %config;
         }
     }
@@ -218,21 +379,47 @@
 }
 
 
+sub verify_parrot {
+    print "Verifying Parrot installation...\n";
+    my %config = @_;
+    my $PARROT_VERSION = $config{'versiondir'};
+    my $PARROT_BIN_DIR = $config{'bindir'};
+    my $PARROT_LIB_DIR = $config{'libdir'}.$PARROT_VERSION;
+    my $PARROT_SRC_DIR = $config{'srcdir'}.$PARROT_VERSION;
+    my $PARROT_INCLUDE_DIR = $config{'includedir'}.$PARROT_VERSION;
+    my $PARROT_TOOLS_DIR = "$PARROT_LIB_DIR/tools";
+    my @required_files = (
+        "$PARROT_BIN_DIR/parrot-nqp"
+    );
+    my @missing;
+    for my $reqfile (@required_files) {
+        push @missing, "    $reqfile" unless -e $reqfile;
+    }
+    if (@missing) {
+        my $missing = join("\n", @missing);
+        die <<"END";
+
+===SORRY!===
+I'm missing some needed files from the Parrot installation:
+$missing
+(Perhaps you need to use Parrot's "make install" or
+install the "parrot-devel" package for your system?)
+
+END
+    }
+}
+
 #  Generate a Makefile from a configuration
 sub create_makefile {
     my %config = @_;
 
     my $maketext = slurp( 'build/Makefile.in' );
 
-    $config{'win32_libparrot_copy'} = $^O eq 'MSWin32' ? 'copy $(BUILD_DIR)\libparrot.dll .' : '';
+    $config{'win32_libparrot_copy'} = $^O eq 'MSWin32' ? 'copy $(PARROT_BIN_DIR)\libparrot.dll .' : '';
     $maketext =~ s/@(\w+)@/$config{$1}/g;
     if ($^O eq 'MSWin32') {
-        # use backslashes.
         $maketext =~ s{/}{\\}g;
-        # wildcards (for clean rules) need an additional backslash,
-        # see Rakudo http://rt.perl.org/rt3/Ticket/Display.html?id=65006
         $maketext =~ s{\\\*}{\\\\*}g;
-        # use forward slashes again for HTTP URLs
         $maketext =~ s{http:\S+}{ do {my $t = $&; $t =~ s'\\'/'g; $t} }eg;
     }
 
@@ -257,6 +444,10 @@
     return $maketext;
 }
 
+sub version_int {
+    sprintf('%d%03d%03d', split(/\./, $_[0]))
+}
+
 
 #  Print some help text.
 sub print_help {
@@ -265,11 +456,11 @@
 
 General Options:
     --help             Show this text
-    --parrot-config=(config)
-                       Use configuration information from config
     --gen-parrot       Download and build a copy of Parrot to use
     --gen-parrot-option='--option=value'
                        Set parrot config option when using --gen-parrot
+    --parrot-config=(config)
+                       Use configuration information from config
 END
 
     return;
@@ -281,161 +472,124 @@
 #   fill-column: 100
 # End:
 # vim: expandtab shiftwidth=4:
-
-__build/PARROT_REVISION__
- at rev@
 __build/Makefile.in__
+# Copyright (C) 2006-2009, The Perl Foundation.
 # $Id$
 
-# arguments we want to run parrot with
-PARROT_ARGS =
+PARROT_ARGS      =
 
 # values from parrot_config
-BUILD_DIR     = @build_dir@
-LOAD_EXT      = @load_ext@
-O             = @o@
+PARROT_BIN_DIR     = @bindir@
+PARROT_VERSION     = @versiondir@
+PARROT_INCLUDE_DIR = @includedir@$(PARROT_VERSION)
+PARROT_LIB_DIR     = @libdir@$(PARROT_VERSION)
+PARROT_SRC_DIR     = @srcdir@$(PARROT_VERSION)
+PARROT_LIBRARY_DIR = $(PARROT_LIB_DIR)/library
+HAS_ICU            = @has_icu@
+
+CC            = @cc@
+CFLAGS        = @ccflags@ @cc_shared@ @cc_debug@ @ccwarn@ @cc_hasjit@ @cg_flag@ @gc_flag@
 EXE           = @exe@
-MAKE          = @make_c@
+LD            = @ld@
+LDFLAGS       = @ldflags@ @ld_debug@
+LD_LOAD_FLAGS = @ld_load_flags@
+LIBPARROT     = @inst_libparrot_ldflags@
+O             = @o@
+LOAD_EXT      = @load_ext@
 PERL          = @perl@
+CP            = @cp@
+MV            = @mv@
 RM_F          = @rm_f@
-HAS_ICU       = @has_icu@
+MKPATH        = $(PERL) -MExtUtils::Command -e mkpath
+CHMOD         = $(PERL) -MExtUtils::Command -e chmod
 
-# Various paths
-PARROT_DYNEXT = $(BUILD_DIR)/runtime/parrot/dynext
-PERL6GRAMMAR  = $(BUILD_DIR)/runtime/parrot/library/PGE/Perl6Grammar.pbc
-NQP           = $(BUILD_DIR)/compilers/nqp/nqp.pbc
-PCT           = $(BUILD_DIR)/runtime/parrot/library/PCT.pbc
-PMC_DIR       = src/pmc
-OPSDIR        = src/ops
-OPSLIB        = @lclang@
-OPS_FILE      = src/ops/@lclang at .ops
-
-# Setup some commands
-PARROT        = $(BUILD_DIR)/parrot$(EXE)
-CAT           = $(PERL) -MExtUtils::Command -e cat
-BUILD_DYNPMC  = $(PERL) $(BUILD_DIR)/tools/build/dynpmc.pl
-BUILD_DYNOPS  = $(PERL) $(BUILD_DIR)/tools/build/dynoplibs.pl
-PBC_TO_EXE    = $(BUILD_DIR)/pbc_to_exe$(EXE)
-
-SOURCES = @lclang at .pir \
-  src/gen_grammar.pir \
-  src/gen_actions.pir \
-  src/gen_builtins.pir \
-  $(@uclang at _GROUP)
-
-BUILTINS_PIR = \
-  src/builtins/say.pir \
-
-# PMCS        = @lclang@
-# PMC_SOURCES = $(PMC_DIR)/@lclang at .pmc
-# @uclang at _GROUP  = $(PMC_DIR)/@lclang at _group$(LOAD_EXT)
+# locations of parrot resources
+PARROT           = $(PARROT_BIN_DIR)/parrot$(EXE)
+PARROT_NQP       = $(PARROT_BIN_DIR)/parrot-nqp$(EXE)
+PBC_TO_EXE       = $(PARROT_BIN_DIR)/pbc_to_exe$(EXE)
+PARROT_TOOLS_DIR = $(PARROT_LIB_DIR)/tools
+PARROT_PERL_LIB  = $(PARROT_TOOLS_DIR)/lib
+
+ at UCLANG@_LANG_DIR     = $(PARROT_LIB_DIR)/languages/@lclang@
+
+ at UCLANG@_EXE     = @lclang@$(EXE)
+ at UCLANG@_PBC     = @lclang at .pbc
+ at UCLANG@_G_PIR   = src/gen/@lclang at -grammar.pir
+ at UCLANG@_A_PIR   = src/gen/@lclang at -actions.pir
+ at UCLANG@_C_PIR   = src/gen/@lclang at -compiler.pir
+ at UCLANG@_R_PIR   = src/gen/@lclang at -runtime.pir
+
+ at UCLANG@_SOURCES = \
+    src/@lang at .pir \
+    $(@UCLANG at _G_PIR) \
+    $(@UCLANG at _A_PIR) \
+    $(@UCLANG at _C_PIR) \
+    $(@UCLANG at _R_PIR) \
 
 CLEANUPS = \
-  @lclang at .pbc \
-  @lclang at .c \
   *.manifest \
   *.pdb \
-  @lclang@$(O) \
-  @lclang@$(EXE) \
-  src/gen_*.pir \
-  src/gen_*.pm \
-  $(PMC_DIR)/*.h \
-  $(PMC_DIR)/*.c \
-  $(PMC_DIR)/*.dump \
-  $(PMC_DIR)/*$(O) \
-  $(PMC_DIR)/*$(LOAD_EXT) \
-  $(PMC_DIR)/*.exp \
-  $(PMC_DIR)/*.ilk \
-  $(PMC_DIR)/*.manifest \
-  $(PMC_DIR)/*.pdb \
-  $(PMC_DIR)/*.lib \
-  $(PMC_DIR)/objectref.pmc \
-  $(OPSDIR)/*.h \
-  $(OPSDIR)/*.c \
-  $(OPSDIR)/*$(O) \
-  $(OPSDIR)/*$(LOAD_EXT) \
-
-HARNESS = $(PERL) t/harness --keep-exit-code --icu=$(HAS_ICU)
-HARNESS_JOBS = $(HARNESS) --jobs
-
-# the default target
-all: @lclang@$(EXE)
-
-installable: installable_ at lclang@$(EXE)
-
-##  targets for building a standalone executable
- at lclang@$(EXE): @lclang at .pbc
-	$(PBC_TO_EXE) @lclang at .pbc
-	@win32_libparrot_copy@
-
-installable_ at lclang@$(EXE): @lclang at .pbc
-	$(PBC_TO_EXE) @lclang at .pbc --install
-
-# the compiler .pbc
- at lclang@.pbc: Makefile $(PARROT) $(SOURCES) $(BUILTINS_PIR)
-	$(PARROT) $(PARROT_ARGS) -o @lclang at .pbc @lclang at .pir
-
-src/gen_grammar.pir: $(PARROT) $(PERL6GRAMMAR) src/pct/grammar.pg src/pct/grammar-oper.pg
-	$(PARROT) $(PARROT_ARGS) $(PERL6GRAMMAR) \
-	    --output=src/gen_grammar.pir \
-	    src/pct/grammar.pg src/pct/grammar-oper.pg
-
-src/gen_actions.pir: $(PARROT) $(NQP) $(PCT) src/pct/actions.pm
-	$(PARROT) $(PARROT_ARGS) $(NQP) --output=src/gen_actions.pir \
-	    --encoding=fixed_8 --target=pir src/pct/actions.pm
-
-src/gen_builtins.pir: Makefile build/gen_builtins_pir.pl
-	$(PERL) build/gen_builtins_pir.pl $(BUILTINS_PIR) > src/gen_builtins.pir
-
-$(@uclang at _GROUP): Makefile $(PARROT) $(PMC_SOURCES)
-	cd $(PMC_DIR) && $(BUILD_DYNPMC) generate $(PMCS)
-	cd $(PMC_DIR) && $(BUILD_DYNPMC) compile $(PMCS)
-	cd $(PMC_DIR) && $(BUILD_DYNPMC) linklibs $(PMCS)
-	cd $(PMC_DIR) && $(BUILD_DYNPMC) copy --destination=$(PARROT_DYNEXT) $(PMCS)
-
-src/ops/@lclang at _ops$(LOAD_EXT) : $(PARROT) $(OPS_FILE)
-	@cd $(OPSDIR) && $(BUILD_DYNOPS) generate $(OPSLIB)
-	@cd $(OPSDIR) && $(BUILD_DYNOPS) compile $(OPSLIB)
-	@cd $(OPSDIR) && $(BUILD_DYNOPS) linklibs $(OPSLIB)
-	@cd $(OPSDIR) && $(BUILD_DYNOPS) copy "--destination=$(PARROT_DYNEXT)" $(OPSLIB)
-
-##  local copy of Parrot
-parrot: parrot/parrot_config build/PARROT_REVISION
-	$(PERL) build/gen_parrot.pl
-
-parrot/parrot_config:
-	@echo "Don't see parrot/parrot_config."
-
-test: @lclang@$(EXE)
-	$(PERL) t/harness t/
-
-# Run a single test
-t/*.t t/*/*.t t/*/*/*.t: all Test.pir
-	@$(HARNESS_WITH_FUDGE) --verbosity=1 $@
+  *.c\
+  *.o\
+  $(@UCLANG at _EXE) \
+  $(@UCLANG at _PBC) \
+  src/gen/*.pir \
+
+default: $(@UCLANG at _EXE)
+
+all: $(@UCLANG at _EXE)
+
+$(@UCLANG at _EXE) : $(@UCLANG at _SOURCES)
+	$(PARROT) -o $(@UCLANG at _PBC) src/@lang at .pir
+	$(PBC_TO_EXE) $(@UCLANG at _PBC)
+
+$(@UCLANG at _G_PIR): src/@lang@/Grammar.pm
+	$(PARROT_NQP) --target=pir -o $(@UCLANG at _G_PIR) src/@lang@/Grammar.pm
+$(@UCLANG at _A_PIR): src/@lang@/Actions.pm
+	$(PARROT_NQP) --target=pir -o $(@UCLANG at _A_PIR) src/@lang@/Actions.pm
+$(@UCLANG at _C_PIR): src/@lang@/Compiler.pm
+	$(PARROT_NQP) --target=pir -o $(@UCLANG at _C_PIR) src/@lang@/Compiler.pm
+$(@UCLANG at _R_PIR): src/@lang@/Runtime.pm
+	$(PARROT_NQP) --target=pir -o $(@UCLANG at _R_PIR) src/@lang@/Runtime.pm
+
+## testing
+
+test: $(@UCLANG at _EXE)
+	$(PERL) t/harness t
+
+## installation
+
+install: all
+	$(MKPATH)        $(DESTDIR)$(@UCLANG at _LANG_DIR)
+	$(CP) $(@UCLANG at _PBC) $(DESTDIR)$(@UCLANG at _LANG_DIR)
+	$(CP) $(@UCLANG at _EXE) $(DESTDIR)$(PARROT_BIN_DIR)
+	$(CHMOD) 755     $(DESTDIR)$(PARROT_BIN_DIR)/$(@UCLANG at _EXE)
+
+## cleaning
 
-##  cleaning
 clean:
 	$(RM_F) $(CLEANUPS)
 
 distclean: realclean
 
 realclean: clean
-	$(RM_F) src/utils/Makefile Makefile
+	$(RM_F) Makefile
 
 testclean:
 
-
 ##  miscellaneous targets
 # a listing of all targets meant to be called by users
 help:
 	@echo ""
 	@echo "Following targets are available for the user:"
 	@echo ""
-	@echo "  all:               @lclang at .exe"
+	@echo "  all:               $(@UCLANG at _EXE)"
 	@echo "                     This is the default."
+	@echo "  $(@UCLANG at _EXE):        The @lang@ compiler."
+	@echo "  install:           Install compiler into Parrot."
 	@echo ""
 	@echo "Testing:"
-	@echo "  test:              Run Rakudo's sanity tests."
+	@echo "  test:              Run tests."
 	@echo ""
 	@echo "Cleaning:"
 	@echo "  clean:             Basic cleaning up."
@@ -447,47 +601,13 @@
 	@echo "  help:              Print this help message."
 	@echo ""
 
-Makefile: build/Makefile.in
-	@echo ""
-	@echo "warning: Makefile is out of date... re-run Configure.pl"
-	@echo ""
-
-manifest:
-	echo MANIFEST >MANIFEST
-	git ls-files | $(PERL) -ne '/^\./ || print' >>MANIFEST
-
-release: manifest
-	[ -n "$(VERSION)" ] || ( echo "\nTry 'make release VERSION=yyyymm'\n\n"; exit 1 )
-	[ -d @lclang at -$(VERSION) ] || ln -s . @lclang at -$(VERSION)
-	$(PERL) -ne 'print "@lclang at -$(VERSION)/$$_"' MANIFEST | \
-	    tar -zcv -T - -f @lclang at -$(VERSION).tar.gz
-	rm @lclang at -$(VERSION)
-
-__build/gen_builtins_pir.pl__
-#!/usr/bin/perl
-# $Id$
-
-use strict;
-use warnings;
-
-my @files = @ARGV;
-
-print <<"END_PRELUDE";
-# This file automatically generated by $0.
-
-END_PRELUDE
-
-foreach my $file (@files) {
-    print ".include '$file'\n";
-}
-
-
 __build/gen_parrot.pl__
 #! perl
+# Copyright (C) 2009 The Perl Foundation
 
 =head1 TITLE
 
-gen_parrot.pl - script to obtain and build Parrot
+gen_parrot.pl - script to obtain and build Parrot for Rakudo
 
 =head2 SYNOPSIS
 
@@ -511,23 +631,24 @@
 ##  determine what revision of Parrot we require
 open my $REQ, "build/PARROT_REVISION"
   || die "cannot open build/PARROT_REVISION\n";
-my $required = 0+<$REQ>;
+my ($reqsvn, $reqpar) = split(' ', <$REQ>);
+$reqsvn += 0;
 close $REQ;
 
 {
     no warnings;
-    if (open my $REV, '-|', "parrot${slash}parrot_config revision") {
+    if (open my $REV, '-|', "parrot_install${slash}bin${slash}parrot_config revision") {
         my $revision = 0+<$REV>;
         close $REV;
-        if ($revision >= $required) {
-            print "Parrot r$revision already available (r$required required)\n";
+        if ($revision >= $reqsvn) {
+            print "Parrot r$revision already available (r$reqsvn required)\n";
             exit(0);
         }
     }
 }
 
-print "Checking out Parrot r$required via svn...\n";
-system(qw(svn checkout -r),  $required , qw(https://svn.parrot.org/parrot/trunk parrot));
+print "Checking out Parrot r$reqsvn via svn...\n";
+system(qw(svn checkout -r),  $reqsvn , qw(https://svn.parrot.org/parrot/trunk parrot));
 
 chdir('parrot');
 
@@ -550,7 +671,11 @@
 print "\nBuilding Parrot ...\n";
 my %config = read_parrot_config();
 my $make = $config{'make'} or exit(1);
-system($make);
+my @make_opts;
+if ($ENV{GNU_MAKE_JOBS}) {
+    push @make_opts, '-j', $ENV{GNU_MAKE_JOBS}
+}
+system($make, 'install-dev', @make_opts);
 
 sub read_parrot_config {
     my %config = ();
@@ -563,278 +688,155 @@
     %config;
 }
 
-__ at lclang@.pir__
-=head1 TITLE
-
- at lclang@.pir - A @lang@ compiler.
-
-=head2 Description
-
-This is the base file for the @lang@ compiler.
-
-This file includes the parsing and grammar rules from
-the src/ directory, loads the relevant PGE libraries,
-and registers the compiler under the name '@lang@'.
-
-=head2 Functions
-
-=over 4
-
-=item onload()
-
-Creates the @lang@ compiler using a C<PCT::HLLCompiler>
-object.
-
-=cut
-
+__src/@lang at .pir__
 .HLL '@lclang@'
 
-.namespace [ '@lang@';'Compiler' ]
-
-.loadlib '@lclang at _group'
+.namespace []
 
 .sub '' :anon :load :init
-    load_bytecode 'PCT.pbc'
-    .local pmc parrotns, hllns, exports
-    parrotns = get_root_namespace ['parrot']
-    hllns = get_hll_namespace
-    exports = split ' ', 'PAST PCT PGE'
-    parrotns.'export_to'(hllns, exports)
-.end
-
-.include 'src/gen_grammar.pir'
-.include 'src/gen_actions.pir'
+    load_bytecode 'HLL.pbc'
 
-.sub 'onload' :anon :load :init
-    $P0 = get_hll_global ['PCT'], 'HLLCompiler'
-    $P1 = $P0.'new'()
-    $P1.'language'('@lclang@')
-    $P0 = get_hll_namespace ['@lang@';'Grammar']
-    $P1.'parsegrammar'($P0)
-    $P0 = get_hll_namespace ['@lang@';'Grammar';'Actions']
-    $P1.'parseactions'($P0)
+    .local pmc hllns, parrotns, imports
+    hllns = get_hll_namespace
+    parrotns = get_root_namespace ['parrot']
+    imports = split ' ', 'PAST PCT HLL Regex Hash'
+    parrotns.'export_to'(hllns, imports)
 .end
 
-=item main(args :slurpy)  :main
-
-Start compilation by passing any command line C<args>
-to the @lang@ compiler.
-
-=cut
+.include 'src/gen/@lclang at -grammar.pir'
+.include 'src/gen/@lclang at -actions.pir'
+.include 'src/gen/@lclang at -compiler.pir'
+.include 'src/gen/@lclang at -runtime.pir'
 
+.namespace []
 .sub 'main' :main
     .param pmc args
 
-    $P0 = compreg '@lclang@'
+    $P0 = compreg '@lang@'
+    # Cannot tailcall here. (TT #1029)
     $P1 = $P0.'command_line'(args)
+    .return ($P1)
 .end
-
-.include 'src/gen_builtins.pir'
-
-=back
-
-=cut
-
-# Local Variables:
-#   mode: pir
-#   fill-column: 100
-# End:
-# vim: expandtab shiftwidth=4 ft=pir:
-
-__src/pct/grammar.pg__
-# @Id@
-
+__src/@lang@/Grammar.pm__
 =begin overview
 
-This is the grammar for @lang@ written as a sequence of Perl 6 rules.
+This is the grammar for @lang@ in Perl 6 rules.
 
 =end overview
 
-grammar @lang@::Grammar is PCT::Grammar;
+grammar @lang@::Grammar is HLL::Grammar;
 
-rule TOP {
-    <statement>*
-    [ $ || <panic: 'Syntax error'> ]
-    {*}
+token TOP {
+    <statementlist>
+    [ $ || <.panic: "Syntax error"> ]
 }
 
-##  this <ws> rule treats # as "comment to eol"
-##  you may want to replace it with something appropriate
+## Lexer items
+
+# This <ws> rule treats # as "comment to eol".
 token ws {
     <!ww>
     [ '#' \N* \n? | \s+ ]*
 }
 
-rule statement {
-    'say' <expression> [ ',' <expression> ]* ';'
-    {*}
-}
-
-rule value {
-    | <integer> {*}                              #= integer
-    | <quote> {*}                                #= quote
-}
-
-token integer { \d+ {*} }
+## Statements
 
-token quote {
-    [ \' <string_literal: '\'' > \' | \" <string_literal: '"' > \" ]
-    {*}
-}
+rule statementlist { [ <statement> | <?> ] ** ';' }
 
-##  terms
-token term {
-    | <value> {*}                                #= value
+rule statement {
+    | <statement_control>
+    | <EXPR>
 }
 
-rule expression is optable { ... }
-
-__src/pct/grammar-oper.pg__
-# @Id@
-
-##  expressions and operators
-proto 'term:'     is precedence('=')     is parsed(&term)      { ... }
+proto token statement_control { <...> }
+rule statement_control:sym<say>   { <sym> [ <EXPR> ] ** ','  }
+rule statement_control:sym<print> { <sym> [ <EXPR> ] ** ','  }
 
-## multiplicative operators
-proto infix:<*>   is looser(term:)       is pirop('mul')     { ... }
-proto infix:</>   is equiv(infix:<*>)    is pirop('div')     { ... }
+## Terms
 
-## additive operators
-proto infix:<+>   is looser(infix:<*>)   is pirop('add')     { ... }
-proto infix:<->   is equiv(infix:<+>)    is pirop('sub')     { ... }
+token term:sym<integer> { <integer> }
+token term:sym<quote> { <quote> }
 
-__src/pct/actions.pm__
-# @Id@
+proto token quote { <...> }
+token quote:sym<'> { <?[']> <quote_EXPR: ':q'> }
+token quote:sym<"> { <?["]> <quote_EXPR: ':qq'> }
 
-=begin comments
+## Operators
 
- at lang@::Grammar::Actions - ast transformations for @lang@
+INIT {
+    @lang@::Grammar.O(':prec<u>, :assoc<left>',  '%multiplicative');
+    @lang@::Grammar.O(':prec<t>, :assoc<left>',  '%additive');
+}
 
-This file contains the methods that are used by the parse grammar
-to build the PAST representation of an @lang@ program.
-Each method below corresponds to a rule in F<src/parser/grammar.pg>,
-and is invoked at the point where C<{*}> appears in the rule,
-with the current match object as the first argument.  If the
-line containing C<{*}> also has a C<#= key> comment, then the
-value of the comment is passed as the second argument to the method.
+token circumfix:sym<( )> { '(' <.ws> <EXPR> ')' }
 
-=end comments
+token infix:sym<*>  { <sym> <O('%multiplicative, :pirop<mul>')> }
+token infix:sym</>  { <sym> <O('%multiplicative, :pirop<div>')> }
 
-class @lang@::Grammar::Actions;
+token infix:sym<+>  { <sym> <O('%additive, :pirop<add>')> }
+token infix:sym<->  { <sym> <O('%additive, :pirop<sub>')> }
+__src/@lang@/Actions.pm__
+class @lang@::Actions is HLL::Actions;
 
 method TOP($/) {
-    my $past := PAST::Block.new( :blocktype('declaration'), :node( $/ ), :hll('@lang@') );
-    for $<statement> {
-        $past.push( $_.ast );
-    }
-    make $past;
+    make PAST::Block.new( $<statementlist>.ast , :hll<@lclang@>, :node($/) );
 }
 
-
-method statement($/) {
-    my $past := PAST::Op.new( :name('say'), :pasttype('call'), :node( $/ ) );
-    for $<expression> {
-        $past.push( $_.ast );
-    }
+method statementlist($/) {
+    my $past := PAST::Stmts.new( :node($/) );
+    for $<statement> { $past.push( $_.ast ); }
     make $past;
 }
 
-##  expression:
-##    This is one of the more complex transformations, because
-##    our grammar is using the operator precedence parser here.
-##    As each node in the expression tree is reduced by the
-##    parser, it invokes this method with the operator node as
-##    the match object and a $key of 'reduce'.  We then build
-##    a PAST::Op node using the information provided by the
-##    operator node.  (Any traits for the node are held in $<top>.)
-##    Finally, when the entire expression is parsed, this method
-##    is invoked with the expression in $<expr> and a $key of 'end'.
-method expression($/, $key) {
-    if ($key eq 'end') {
-        make $<expr>.ast;
-    }
-    else {
-        my $past := PAST::Op.new( :name($<type>),
-                                  :pasttype($<top><pasttype>),
-                                  :pirop($<top><pirop>),
-                                  :lvalue($<top><lvalue>),
-                                  :node($/)
-                                );
-        for @($/) {
-            $past.push( $_.ast );
-        }
-        make $past;
-    }
+method statement($/) {
+    make $<statement_control> ?? $<statement_control>.ast !! $<EXPR>.ast;
 }
 
-
-##  term:
-##    Like 'statement' above, the $key has been set to let us know
-##    which term subrule was matched.
-method term($/, $key) {
-    make $/{$key}.ast;
+method statement_control:sym<say>($/) {
+    my $past := PAST::Op.new( :name<say>, :pasttype<call>, :node($/) );
+    for $<EXPR> { $past.push( $_.ast ); }
+    make $past;
 }
 
-
-method value($/, $key) {
-    make $/{$key}.ast;
+method statement_control:sym<print>($/) {
+    my $past := PAST::Op.new( :name<print>, :pasttype<call>, :node($/) );
+    for $<EXPR> { $past.push( $_.ast ); }
+    make $past;
 }
 
+method term:sym<integer>($/) { make $<integer>.ast; }
+method term:sym<quote>($/) { make $<quote>.ast; }
 
-method integer($/) {
-    make PAST::Val.new( :value( ~$/ ), :returns('Integer'), :node($/) );
-}
+method quote:sym<'>($/) { make $<quote_EXPR>.ast; }
+method quote:sym<">($/) { make $<quote_EXPR>.ast; }
 
+method circumfix:sym<( )>($/) { make $<EXPR>.ast; }
 
-method quote($/) {
-    make PAST::Val.new( :value( $<string_literal>.ast ), :node($/) );
-}
-
-
-# Local Variables:
-#   mode: cperl
-#   cperl-indent-level: 4
-#   fill-column: 100
-# End:
-# vim: expandtab shiftwidth=4:
-
-__src/builtins/say.pir__
-# @Id@
-
-=head1
-
-say.pir -- simple implementation of a say function
-
-=cut
-
-.namespace []
-
-.sub 'say'
-    .param pmc args            :slurpy
-    .local pmc it
-    it = iter args
-  iter_loop:
-    unless it goto iter_end
-    $P0 = shift it
-    print $P0
-    goto iter_loop
-  iter_end:
-    print "\n"
-    .return ()
-.end
+__src/@lang@/Compiler.pm__
+class @lang@::Compiler is HLL::Compiler;
 
+INIT {
+    @lang@::Compiler.language('@lang@');
+    @lang@::Compiler.parsegrammar(@lang@::Grammar);
+    @lang@::Compiler.parseactions(@lang@::Actions);
+}
+__src/@lang@/Runtime.pm__
+# language-specific runtime functions go here
 
-# Local Variables:
-#   mode: pir
-#   fill-column: 100
-# End:
-# vim: expandtab shiftwidth=4 ft=pir:
+sub print(*@args) {
+    pir::print(pir::join('', @args));
+    1;
+}
 
+sub say(*@args) {
+    pir::say(pir::join('', @args));
+    1;
+}
+__src/gen/.gitignore__
+*
 __t/harness__
 #! perl
 
-# $Id$
-
 use strict;
 use warnings;
 
@@ -933,7 +935,6 @@
 say 'ok ', 2;
 say 'ok ', 2 + 1;
 say 'ok', ' ', 4;
-
 __DATA__
 
 


More information about the parrot-commits mailing list