[svn:languages] r20 - in c99: . branches tags trunk trunk/config trunk/config/makefiles trunk/lib trunk/lib/Parrot trunk/lib/Parrot/Test trunk/src trunk/src/builtins trunk/src/cpp trunk/src/cpp/src trunk/src/cpp/src/builtins trunk/src/cpp/src/parser trunk/src/cpp/t trunk/src/parser trunk/t
allison at svn.parrot.org
allison at svn.parrot.org
Tue Mar 10 23:43:33 UTC 2009
Author: allison
Date: Tue Mar 10 23:43:32 2009
New Revision: 20
URL: https://trac.parrot.org/languages/changeset/20
Log:
[c99] Relocating c99 language to languages repository from
https://svn.parrot.org/parrot/trunk/languages/c99/.
Added:
c99/
c99/branches/
c99/tags/
c99/trunk/
c99/trunk/MAINTAINER
c99/trunk/c99.pir
c99/trunk/config/
c99/trunk/config/makefiles/
c99/trunk/config/makefiles/cpp.in
c99/trunk/config/makefiles/root.in
c99/trunk/lib/
c99/trunk/lib/Parrot/
c99/trunk/lib/Parrot/Test/
c99/trunk/lib/Parrot/Test/C99.pm
c99/trunk/src/
c99/trunk/src/CPP_AST2Constants.tg
c99/trunk/src/CPP_ASTGrammar.tg
c99/trunk/src/CPP_PASTNodes.pir
c99/trunk/src/CPP_PGE2AST.pir
c99/trunk/src/builtins/
c99/trunk/src/builtins/say.pir
c99/trunk/src/c99.pg
c99/trunk/src/c99_PGE.pir
c99/trunk/src/cpp/
c99/trunk/src/cpp/Makefile
c99/trunk/src/cpp/cpp.pir
c99/trunk/src/cpp/src/
c99/trunk/src/cpp/src/builtins/
c99/trunk/src/cpp/src/builtins/say.pir
c99/trunk/src/cpp/src/parser/
c99/trunk/src/cpp/src/parser/actions.pm
c99/trunk/src/cpp/src/parser/grammar.pg
c99/trunk/src/cpp/t/
c99/trunk/src/cpp/t/comment_01.t
c99/trunk/src/cpp/t/cpp_0.t
c99/trunk/src/cpp/t/harness (contents, props changed)
c99/trunk/src/cpp/t/spi.t
c99/trunk/src/parser/
c99/trunk/src/parser/actions.pm
c99/trunk/src/parser/grammar.pg
c99/trunk/src/preamble
c99/trunk/t/
c99/trunk/t/harness (contents, props changed)
c99/trunk/t/spi.t
Added: c99/trunk/MAINTAINER
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/MAINTAINER Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1,7 @@
+# $Id: MAINTAINER 25984 2008-02-22 12:18:20Z kjs $
+
+N: Kevin Tew
+E: kevintew at tewk.com
+
+N: Klaas-Jan Stol (kjs)
+E: parrotcode at gmail.com
Added: c99/trunk/c99.pir
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/c99.pir Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1,80 @@
+# $Id: c99.pir 36833 2009-02-17 20:09:26Z allison $
+# Copyright (C) 2008, Parrot Foundation.
+
+=head1 TITLE
+
+c99.pir - A C99 compiler.
+
+=head2 Description
+
+This is the base file for the C99 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 'C99'.
+
+=head2 Functions
+
+=over 4
+
+=item onload()
+
+Creates the C compiler using a C<PCT::HLLCompiler>
+object.
+
+=cut
+
+.namespace [ 'C99';'Compiler' ]
+
+.loadlib 'c99_group'
+
+.sub 'onload' :anon :load :init
+ load_bytecode 'PCT.pbc'
+
+ $P0 = get_hll_global ['PCT'], 'HLLCompiler'
+ $P1 = $P0.'new'()
+ $P1.'language'('C99')
+ $P1.'parsegrammar'('C99::Grammar')
+ $P1.'parseactions'('C99::Grammar::Actions')
+.end
+
+=item main(args :slurpy) :main
+
+Start compilation by passing any command line C<args>
+to the C compiler.
+
+=cut
+
+.sub 'main' :main
+ .param pmc args
+
+ $P0 = compreg 'C99'
+ $P1 = $P0.'command_line'(args)
+.end
+
+
+.include 'src/gen_builtins.pir'
+.include 'src/gen_grammar.pir'
+.include 'src/gen_actions.pir'
+
+
+.namespace [ 'C99';'Grammar' ]
+
+.sub 'debug'
+ .param pmc match
+ .param pmc arg
+ .param pmc attrs :slurpy
+ printerr arg
+ printerr "\n"
+.end
+
+=back
+
+=cut
+
+# Local Variables:
+# mode: pir
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:
+
Added: c99/trunk/config/makefiles/cpp.in
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/config/makefiles/cpp.in Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1,102 @@
+# Copyright (C) 2008-2009, Parrot Foundation.
+## $Id: cpp.in 36833 2009-02-17 20:09:26Z allison $
+
+## arguments we want to run parrot with
+PARROT_ARGS =
+
+## configuration settings
+BUILD_DIR = @build_dir@
+LOAD_EXT = @load_ext@
+O = @o@
+
+## Setup some commands
+PERL = @perl@
+RM_F = @rm_f@
+CP = @cp@
+CAT = @cat@
+PARROT = ../../../../parrot at exe@
+BUILD_DYNPMC = $(PERL) $(BUILD_DIR)/tools/build/dynpmc.pl
+RECONFIGURE = $(PERL) $(BUILD_DIR)/tools/dev/reconfigure.pl
+
+## places to look for things
+PARROT_DYNEXT = $(BUILD_DIR)/runtime/parrot/dynext
+PGE_LIBRARY = $(BUILD_DIR)/runtime/parrot/library/PGE
+PERL6GRAMMAR = $(PGE_LIBRARY)/Perl6Grammar.pbc
+NQP = $(BUILD_DIR)/compilers/nqp/nqp.pbc
+PCT = $(BUILD_DIR)/runtime/parrot/library/PCT.pbc
+
+PMC_DIR = src/pmc
+
+all: cpp.pbc
+
+SOURCES = cpp.pir \
+ src/gen_grammar.pir \
+ src/gen_actions.pir \
+ src/gen_builtins.pir
+
+BUILTINS_PIR = \
+ src/builtins/say.pir
+
+# the default target
+cpp.pbc: $(PARROT) $(SOURCES)
+ $(PARROT) $(PARROT_ARGS) -o cpp.pbc cpp.pir
+ $(CP) cpp.pbc ../../cpp.pbc
+
+src/gen_grammar.pir: $(PERL6GRAMMAR) src/parser/grammar.pg
+ $(PARROT) $(PARROT_ARGS) $(PERL6GRAMMAR) \
+ --output=src/gen_grammar.pir \
+ src/parser/grammar.pg
+
+src/gen_actions.pir: $(NQP) $(PCT) src/parser/actions.pm
+ $(PARROT) $(PARROT_ARGS) $(NQP) --output=src/gen_actions.pir \
+ --target=pir src/parser/actions.pm
+
+src/gen_builtins.pir: $(BUILTINS_PIR)
+ $(CAT) $(BUILTINS_PIR) >src/gen_builtins.pir
+
+# regenerate the Makefile
+Makefile: ../../config/makefiles/cpp.in
+ cd $(BUILD_DIR) && $(RECONFIGURE) --step=gen::languages --languages=c99
+
+# This is a listing of all targets, that are meant to be called by users
+help:
+ @echo ""
+ @echo "Following targets are available for the user:"
+ @echo ""
+ @echo " all: c.pbc"
+ @echo " This is the default."
+ @echo "Testing:"
+ @echo " test: Run the test suite."
+ @echo " testclean: Clean up test results."
+ @echo ""
+ @echo "Cleaning:"
+ @echo " clean: Basic cleaning up."
+ @echo " realclean: Removes also files generated by 'Configure.pl'"
+ @echo " distclean: Removes also anything built, in theory"
+ @echo ""
+ @echo "Misc:"
+ @echo " help: Print this help message."
+ @echo ""
+
+test: all
+ $(PERL) t/harness
+
+# this target has nothing to do
+testclean:
+
+CLEANUPS = \
+ cpp.pbc \
+ "src/gen_*.pir"
+
+clean:
+ $(RM_F) $(CLEANUPS)
+
+realclean: clean
+ $(RM_F) Makefile
+
+distclean: realclean
+
+# Local variables:
+# mode: makefile
+# End:
+# vim: ft=make:
Added: c99/trunk/config/makefiles/root.in
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/config/makefiles/root.in Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1,113 @@
+# Copyright (C) 2006-2009, Parrot Foundation.
+## $Id: root.in 36833 2009-02-17 20:09:26Z allison $
+
+## arguments we want to run parrot with
+PARROT_ARGS =
+
+## configuration settings
+BUILD_DIR = @build_dir@
+LOAD_EXT = @load_ext@
+O = @o@
+
+## Setup some commands
+PERL = @perl@
+RM_RF = @rm_rf@
+CP = @cp@
+CAT = @cat@
+MAKE = @make_c@
+PARROT = ../../parrot at exe@
+BUILD_DYNPMC = $(PERL) $(BUILD_DIR)/tools/build/dynpmc.pl
+RECONFIGURE = $(PERL) $(BUILD_DIR)/tools/dev/reconfigure.pl
+#IF(darwin):
+#IF(darwin):# MACOSX_DEPLOYMENT_TARGET must be defined for OS X compilation/linking
+#IF(darwin):export MACOSX_DEPLOYMENT_TARGET := @osx_version@
+
+## places to look for things
+PARROT_DYNEXT = $(BUILD_DIR)/runtime/parrot/dynext
+PGE_LIBRARY = $(BUILD_DIR)/runtime/parrot/library/PGE
+PERL6GRAMMAR = $(PGE_LIBRARY)/Perl6Grammar.pbc
+NQP = $(BUILD_DIR)/compilers/nqp/nqp.pbc
+PCT = $(BUILD_DIR)/runtime/parrot/library/PCT.pbc
+
+PMC_DIR = src/pmc
+
+all: c99.pbc cpp
+
+C_GROUP = $(PMC_DIR)/c_group$(LOAD_EXT)
+
+SOURCES = c99.pir \
+ src/gen_grammar.pir \
+ src/gen_actions.pir \
+ src/gen_builtins.pir
+
+BUILTINS_PIR = \
+ src/builtins/say.pir
+
+c99.pbc: $(PARROT) $(SOURCES)
+ $(PARROT) $(PARROT_ARGS) -o c99.pbc c99.pir
+
+src/gen_grammar.pir: $(PERL6GRAMMAR) src/parser/grammar.pg
+ $(PARROT) $(PARROT_ARGS) $(PERL6GRAMMAR) \
+ --output=src/gen_grammar.pir \
+ src/parser/grammar.pg
+
+src/gen_actions.pir: $(NQP) $(PCT) src/parser/actions.pm
+ $(PARROT) $(PARROT_ARGS) $(NQP) --output=src/gen_actions.pir \
+ --target=pir src/parser/actions.pm
+
+src/gen_builtins.pir: $(BUILTINS_PIR)
+ $(CAT) $(BUILTINS_PIR) >src/gen_builtins.pir
+
+cpp:
+ $(MAKE) src/cpp
+
+# regenerate the Makefile
+Makefile: config/makefiles/root.in
+ cd $(BUILD_DIR) && $(RECONFIGURE) --step=gen::languages --languages=c99
+
+# This is a listing of all targets, that are meant to be called by users
+help:
+ @echo ""
+ @echo "Following targets are available for the user:"
+ @echo ""
+ @echo " all: c.pbc"
+ @echo " This is the default."
+ @echo "Testing:"
+ @echo " test: Run the test suite."
+ @echo " testclean: Clean up test results."
+ @echo ""
+ @echo "Cleaning:"
+ @echo " clean: Basic cleaning up."
+ @echo " realclean: Removes also files generated by 'Configure.pl'"
+ @echo " distclean: Removes also anything built, in theory"
+ @echo ""
+ @echo "Misc:"
+ @echo " help: Print this help message."
+ @echo ""
+
+test: all
+ $(PERL) t/harness
+ $(MAKE) src/cpp test
+
+# this target has nothing to do
+testclean:
+
+CLEANUPS = \
+ c99.pbc \
+ "src/gen_*.pir"
+
+clean:
+ $(RM_RF) $(CLEANUPS)
+ $(MAKE) src/cpp clean
+
+realclean: clean
+ $(RM_RF) Makefile
+ $(MAKE) src/cpp realclean
+
+distclean: realclean
+ $(MAKE) src/cpp distclean
+
+# Local variables:
+# mode: makefile
+# End:
+# vim: ft=make:
Added: c99/trunk/lib/Parrot/Test/C99.pm
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/lib/Parrot/Test/C99.pm Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1,90 @@
+# $Id: C99.pm 36833 2009-02-17 20:09:26Z allison $
+# Copyright (C) 2006, Parrot Foundation.
+
+
+package Parrot::Test::C99;
+
+use strict;
+use warnings;
+
+use File::Basename;
+
+=head1 Parrot::Test::C99
+
+Provide language specific testing routines here...
+
+This is currently alarmingly similar to the generated subs in Parrot::Test.
+Perhaps someone can do a better job of delegation here.
+
+=cut
+
+sub new {
+ return bless {};
+}
+
+sub output_is() {
+ my ( $self, $code, $output, $desc ) = @_;
+
+ #print "@_\n";
+
+ my $count = $self->{builder}->current_test + 1;
+ $desc = 'C99 Test' unless $desc;
+
+ my $lang_f = File::Spec->rel2abs( Parrot::Test::per_test( '.c', $count ) );
+ my $out_f = File::Spec->rel2abs( Parrot::Test::per_test( '.out', $count ) );
+ my $c99_out_f = File::Spec->rel2abs( Parrot::Test::per_test( '.c99.out', $count ) );
+ my $c99_out_debug_f = File::Spec->rel2abs( Parrot::Test::per_test( '.c99.debug.out', $count ) );
+ my $parrotdir = dirname $self->{parrot};
+
+ Parrot::Test::write_code_to_file( $code, $lang_f );
+
+ my $args = $ENV{TEST_PROG_ARGS} || '';
+
+#my $gcc_cmd = "gcc $lang_f";
+#my $gcc_exit_code = Parrot::Test::run_command($gcc_cmd, CD => $self->{relpath}, STDOUT => $out_f, STDERR => $out_f );
+#my $gcc_output = Parrot::Test::slurp_file($out_f);
+
+ my $c99_cmd = "$self->{parrot} $args languages/c99/c99.pbc $lang_f";
+ my $c99_exit_code = Parrot::Test::run_command(
+ $c99_cmd,
+ CD => $self->{relpath},
+ STDOUT => $c99_out_f,
+ STDERR => $c99_out_f
+ );
+ my $c99_output = Parrot::Test::slurp_file($c99_out_f);
+
+ my $pass = $self->{builder}->is_eq( $c99_output, "1" );
+
+#my $pass = $self->{builder}->is_eq( $c99_output, $gcc_output, $desc );
+#$self->{builder}->diag("'$gcc_cmd' failed with exit code $gcc_exit_code") if $gcc_exit_code and not $pass;
+ $self->{builder}->diag("'$c99_cmd' failed with exit code $c99_exit_code")
+ if $c99_exit_code and not $pass;
+
+ if ( not $pass ) {
+ my $c99_debug_cmd = "$self->{parrot} $args languages/c99/c99.pbc -d $lang_f";
+ my $c99_debug_exit_code = Parrot::Test::run_command(
+ $c99_debug_cmd,
+ CD => $self->{relpath},
+ STDOUT => $c99_out_debug_f,
+ STDERR => $c99_out_debug_f
+ );
+ my $c99_debug_output = Parrot::Test::slurp_file($c99_out_debug_f);
+ }
+
+ unless ( $ENV{POSTMORTEM} ) {
+
+ #unlink $lang_f;
+ unlink $out_f;
+ unlink $c99_out_f;
+ }
+ return $pass;
+}
+
+1;
+
+# Local Variables:
+# mode: cperl
+# cperl-indent-level: 4
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4:
Added: c99/trunk/src/CPP_AST2Constants.tg
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/src/CPP_AST2Constants.tg Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1,190 @@
+=head1 NAME
+
+C99::CPPConstants Grammar -- A grammar for transforming an CPP AST to a Parrot constants file
+
+=head1 SYNOPSYS
+
+=head1 DESCRIPTION
+
+=cut
+
+#code = new 'CodeString'
+#code.'emit'(" %0 = find_name '%1'", value, name)
+
+grammar C99::CPP::Constants::ConstantsGrammar is TGE::Grammar;
+
+transform root (C99::CPP::PAST::Node) :language('PIR') {
+ .local pmc code
+ code = new 'CodeString'
+ code .= "# DO NOT EDIT THIS FILE.\n"
+ code .= "#\n"
+ code .= "# This file is generated automatically from\n"
+ code .= "# ?? by c99 --constants \n"
+ code .= "#\n"
+ code .= "# Any changes made here will be lost.\n"
+ code .= "#\n"
+ $P0 = tree.get('pir', node)
+ $S0 = $P0
+ code .= $S0
+ .return (code)
+}
+
+transform pir (C99::CPP::PAST::Node) :language('PIR') {
+ .local pmc code
+ .local pmc iter
+ code = new 'CodeString'
+ iter = node.'child_iter'()
+ iter_loop:
+ unless iter, iter_end
+ $P0 = shift iter
+ $P1 = tree.get('pir', $P0)
+ code .= $P1
+ goto iter_loop
+ iter_end:
+ .return (code)
+}
+
+transform pir (C99::CPP::PAST::IF_SECTION) :language('PIR') {
+ .local pmc code
+ .local pmc iter
+ code = new 'CodeString'
+ iter = node.'child_iter'()
+ iter_loop:
+ unless iter, iter_end
+ $P0 = shift iter
+ $P1 = tree.get('pir', $P0)
+ code .= $P1
+ goto iter_loop
+ iter_end:
+ .return (code)
+}
+
+transform pir(C99::CPP::PAST::IFNDEF) :language('PIR') {
+ .local pmc code
+ .local pmc iter
+ code = new 'CodeString'
+ iter = node.'child_iter'()
+ iter_loop:
+ unless iter, iter_end
+ $P0 = shift iter
+ $P1 = tree.get('pir', $P0)
+ code .= $P1
+ goto iter_loop
+ iter_end:
+ .return (code)
+}
+
+transform pir(C99::CPP::PAST::IFDEF) :language('PIR') {
+ .local pmc code
+ .local pmc iter
+ code = new 'CodeString'
+ iter = node.'child_iter'()
+ iter_loop:
+ unless iter, iter_end
+ $P0 = shift iter
+ $P1 = tree.get('pir', $P0)
+ code .= $P1
+ goto iter_loop
+ iter_end:
+ .return (code)
+}
+
+transform pir(C99::CPP::PAST::IF) :language('PIR') {
+ .local pmc code
+ .local pmc iter
+ code = new 'CodeString'
+ iter = node.'child_iter'()
+ iter_loop:
+ unless iter, iter_end
+ $P0 = shift iter
+ $P1 = tree.get('pir', $P0)
+ code .= $P1
+ goto iter_loop
+ iter_end:
+ .return (code)
+}
+
+transform pir(C99::CPP::PAST::ELIF) :language('PIR') {
+ .local pmc code
+ .local pmc iter
+ code = new 'CodeString'
+ iter = node.'child_iter'()
+ iter_loop:
+ unless iter, iter_end
+ $P0 = shift iter
+ $P1 = tree.get('pir', $P0)
+ code .= $P1
+ goto iter_loop
+ iter_end:
+ .return (code)
+}
+
+transform pir(C99::CPP::PAST::ELSE) :language('PIR') {
+ .local pmc code
+ .local pmc iter
+ code = new 'CodeString'
+ iter = node.'child_iter'()
+ iter_loop:
+ unless iter, iter_end
+ $P0 = shift iter
+ $P1 = tree.get('pir', $P0)
+ code .= $P1
+ goto iter_loop
+ iter_end:
+ .return (code)
+}
+
+
+transform pir(C99::CPP::PAST::DEFINE) :language('PIR') {
+ .local pmc code
+ code = new 'CodeString'
+ $S0 = node.'name'()
+ $S1 = node.'line'()
+ code.'emit'(" .macro_const %0 %1", $S0, $S1)
+ .return (code)
+}
+transform pir(C99::CPP::PAST::DEFINE_FUNCTION) :language('PIR') {
+ .local pmc code
+ code = new 'CodeString'
+ $S0 = node.'name'()
+ $S1 = node.'line'()
+ code.'emit'(" .macro_const %0 = %1", $S0, $S1)
+ .return (code)
+}
+transform pir(C99::CPP::PAST::INCLUDE) :language('PIR') {
+ .local pmc code
+ .return ("")
+}
+transform pir(C99::CPP::PAST::ERROR) :language('PIR') {
+ .local pmc code
+ .return ("")
+}
+transform pir(C99::CPP::PAST::LINE) :language('PIR') {
+ .local pmc code
+ .return ("")
+}
+transform pir(C99::CPP::PAST::PRAGMA) :language('PIR') {
+ .local pmc code
+ .return ("")
+}
+transform pir(C99::CPP::PAST::SOURCE_LINE) :language('PIR') {
+ .local pmc code
+ .return ("")
+}
+transform pir(C99::CPP::PAST::WSNWS) :language('PIR') {
+ .local pmc code
+ .return ("")
+}
+
+=head1 LICENSE
+
+Copyright (C) 2006, Parrot Foundation.
+
+This is free software; you may redistribute it and/or modify
+it under the same terms as Parrot.
+
+=head1 AUTHOR
+
+Kevin Tew <tewk at tewk.com>
+
+=cut
Added: c99/trunk/src/CPP_ASTGrammar.tg
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/src/CPP_ASTGrammar.tg Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1,336 @@
+grammar C99::CPP::ASTGrammar is TGE::Grammar;
+
+transform result (ROOT) :language('PIR') {
+ debug_init
+
+ .local pmc child
+ $I0 = defined node['group']
+ unless $I0 goto err_no_tree
+ $P0 = node['group']
+ child = tree.get('result', $P0, 'C99::CPP::ASTGrammar::group')
+ .return (child)
+
+ err_no_tree:
+ print "The top-level node doesn't contain an 'group' match.\n"
+ end
+}
+
+transform result (C99::CPP::ASTGrammar::group) :language('PIR') {
+ .local pmc child
+ .local pmc result
+ result = new 'C99::CPP::PAST::Node'
+ result.'init'()
+
+ $I0 = defined node['group_line']
+ unless $I0 goto err_no_tree
+ $P0 = node['group_line']
+
+ .local pmc iter
+ iter = new Iterator, $P0
+ iter_loop:
+ unless iter, iter_end
+ $P1 = shift iter
+ child = tree.get('result', $P1, 'C99::CPP::ASTGrammar::group_line')
+ result.add_child(child)
+ goto iter_loop
+ iter_end:
+ .return (result)
+
+ err_no_tree:
+ $S0 = "The group node doesn't contain an 'group_line' match.\n"
+ print $S0
+ .kdump(node)
+ print $S0
+ end
+}
+
+transform result (C99::CPP::ASTGrammar::group_line) :language('PIR') {
+ .local pmc child
+
+ $I0 = defined node['if_section']
+ unless $I0 goto control_line
+ $P1 = node['if_section']
+ child = tree.get('result', $P1, 'C99::CPP::ASTGrammar::if_section')
+ .return (child)
+
+ control_line:
+ $I0 = defined node['control_line']
+ unless $I0 goto source_line
+ $P1 = node['control_line']
+ child = tree.get('result', $P1, 'C99::CPP::ASTGrammar::control_line')
+ .return (child)
+
+ source_line:
+ $I0 = defined node['source_line']
+ unless $I0 goto wsnws
+ $S0 = node
+ child = new 'C99::CPP::PAST::SOURCE_LINE'
+ child .'init'('line'=>$S0)
+ .return (child)
+
+ wsnws:
+ $I0 = defined node['wsnws']
+ unless $I0 goto err_no_tree
+ $S0 = node
+ child = new 'C99::CPP::PAST::WSNWS'
+ child .'init'('line'=>$S0)
+ .return (child)
+
+ err_no_tree:
+ $S0 = "The group_line node doesn't contain an 'if_section' match.\n"
+ print $S0
+ .kdump(node)
+ print $S0
+ end
+}
+
+transform result (C99::CPP::ASTGrammar::if_section) :language('PIR') {
+ .local pmc child
+ .local pmc result
+ result = new 'C99::CPP::PAST::IF_SECTION'
+ result.'init'('node'=>node)
+
+ $I0 = defined node['if_group']
+ unless $I0 goto err_no_tree
+ $P0 = node['if_group']
+ child = tree.get('result', $P0, 'C99::CPP::ASTGrammar::if_group')
+ result.add_child(child)
+
+ .local pmc iter
+ $I0 = defined node['elif_group']
+ unless $I0 goto else_group
+ $P0 = node['elif_group']
+ iter = new Iterator, $P0
+ iter_loop:
+ unless iter, iter_end
+ $P1 = shift iter
+ child = tree.get('result', $P1, 'C99::CPP::ASTGrammar::elif_group')
+ result.add_child(child)
+ goto iter_loop
+
+ else_group:
+ $I0 = defined node['else_group']
+ unless $I0 goto return
+ $P0 = node['else_group']
+ child = tree.get('result', $P0, 'C99::CPP::ASTGrammar::else_group')
+ result.add_child(child)
+ iter_end:
+
+ return:
+ .return (result)
+
+ err_no_tree:
+ $S0 = "The if_section node doesn't contain an 'if*_group' match.\n"
+ print $S0
+ .kdump(node)
+ print $S0
+ end
+}
+
+transform result (C99::CPP::ASTGrammar::if_group) :language('PIR') {
+ .local pmc result
+
+ $I0 = defined node['ifndef']
+ unless $I0 goto ifdef_lbl
+ result = new 'C99::CPP::PAST::IFNDEF'
+ result.'init'('node'=>node)
+ goto parts
+
+ ifdef_lbl:
+ $I0 = defined node['ifdef']
+ unless $I0 goto if_lbl
+ $P0 = node['ifdef']
+ result = new 'C99::CPP::PAST::IFDEF'
+ result.'init'('node'=>node)
+ goto parts
+
+ if_lbl:
+ $I0 = defined node['if']
+ unless $I0 goto err_no_tree
+ $P0 = node['if']
+ result = new 'C99::CPP::PAST::IF'
+ result.'init'('node'=>node)
+ goto parts
+
+ parts:
+ $I0 = defined node['identifier']
+ unless $I0 goto constant_expression
+ $P0 = node['identifier']
+ $S0 = $P0
+ result.'line'($S0)
+ constant_expression:
+ $I0 = defined node['constant_expression']
+ unless $I0 goto group
+ $P0 = node['constant_expression']
+ $S0 = $P0
+ result.'line'($S0)
+ group:
+ $I0 = defined node['group']
+ unless $I0 goto err_no_tree
+ $P0 = node['group' ; 0]
+ $P1= tree.get('result', $P0, 'C99::CPP::ASTGrammar::group')
+ $P2 = $P1.'children'()
+ result.'append_children'($P2)
+ .return (result)
+
+
+ err_no_tree:
+ $S0 = "The if_group node doesn't contain an 'if*' match.\n"
+ print $S0
+ .kdump(node)
+ print $S0
+ end
+}
+
+transform result (C99::CPP::ASTGrammar::elif_group) :language('PIR') {
+ .local pmc result
+
+ $I0 = defined node['elif']
+ unless $I0 goto err_no_tree
+ result = new 'C99::CPP::PAST::ELIF'
+ result.'init'('node'=>node)
+
+ $I0 = defined node['constant_expression']
+ unless $I0 goto err_no_tree
+ $P0 = node['constant_expression']
+ $S0 = $P0
+ result.'line'($S0)
+ group:
+ $I0 = defined node['group']
+ unless $I0 goto err_no_tree
+ $P0 = node['group' ; 0]
+ $P1= tree.get('result', $P0, 'C99::CPP::ASTGrammar::group')
+ $P2 = $P1.'children'()
+ result.'append_children'($P2)
+ .return (result)
+
+
+ err_no_tree:
+ $S0 = "The elif_group node doesn't contain an 'if*' match.\n"
+ print $S0
+ .kdump(node)
+ print $S0
+ end
+}
+
+transform result (C99::CPP::ASTGrammar::elif_group) :language('PIR') {
+ .local pmc result
+
+ $I0 = defined node['elif']
+ unless $I0 goto err_no_tree
+ result = new 'C99::CPP::PAST::ELIF'
+ result.'init'('node'=>node)
+
+ $I0 = defined node['group']
+ unless $I0 goto err_no_tree
+ $P0 = node['group' ; 0]
+ $P1= tree.get('result', $P0, 'C99::CPP::ASTGrammar::group')
+ $P2 = $P1.'children'()
+ result.'append_children'($P2)
+ .return (result)
+
+
+ err_no_tree:
+ $S0 = "The elif_group node doesn't contain an 'if*' match.\n"
+ print $S0
+ .kdump(node)
+ print $S0
+ end
+}
+
+transform result (C99::CPP::ASTGrammar::control_line) :language('PIR') {
+ .local pmc child
+ .local pmc result
+
+ $I0 = defined node['include']
+ unless $I0 goto define_function_lbl
+ result = new 'C99::CPP::PAST::INCLUDE'
+ result.'init'('node'=>node)
+ bsr pp_tokens
+ .return (result)
+
+ define_function_lbl:
+ $I0 = defined node['define_function']
+ unless $I0 goto define_lbl
+ result = new 'C99::CPP::PAST::DEFINE_FUNCTION'
+ result.'init'('node'=>node)
+ $P0 = node['define_function']
+ $S0 = $P0
+ result.'name'($S0)
+ bsr pp_tokens
+ .return (result)
+
+ define_lbl:
+ $I0 = defined node['define']
+ unless $I0 goto undefine_lbl
+ result = new 'C99::CPP::PAST::DEFINE'
+ result.'init'('node'=>node)
+ $I0 = defined node['define_name']
+ unless $I0 goto no_id
+ $P0 = node['define_name']
+ $S0 = $P0
+ result.'name'($S0)
+ no_id:
+ bsr pp_tokens
+ .return (result)
+
+ undefine_lbl:
+ $I0 = defined node['undefine']
+ unless $I0 goto line_lbl
+ result = new 'C99::CPP::PAST::UNDEFINE'
+ bsr pp_tokens
+ .return (result)
+
+ line_lbl:
+ $I0 = defined node['line']
+ unless $I0 goto error_lbl
+ result = new 'C99::CPP::PAST::LINE'
+ result.'init'('node'=>node)
+ bsr pp_tokens
+ .return (result)
+
+ error_lbl:
+ $I0 = defined node['error']
+ unless $I0 goto pragma_lbl
+ result = new 'C99::CPP::PAST::ERROR'
+ result.'init'('node'=>node)
+ bsr pp_tokens
+ .return (result)
+
+ pragma_lbl:
+ $I0 = defined node['pragma']
+ unless $I0 goto err_no_tree
+ result = new 'C99::CPP::PAST::PRAGMA'
+ result.'init'('node'=>node)
+ bsr pp_tokens
+ .return (result)
+
+ pp_tokens:
+ $I0 = defined node['value']
+ unless $I0 goto notoks1
+ $P0 = node['value']
+ $S0 = $P0
+ result.'line'($S0)
+ notoks1:
+ ret
+
+ err_no_tree:
+ print "The control_line node doesn't contain an appropriate match.\n"
+ print $S0
+ .kdump(node)
+ print $S0
+ end
+}
+
+=head1 LICENSE
+
+Copyright (C) 2006, Parrot Foundation.
+
+This is free software; you may redistribute it and/or modify
+it under the same terms as Parrot.
+
+=head1 AUTHOR
+
+Kevin Tew <tewk at tewk.com>
+
+=cut
Added: c99/trunk/src/CPP_PASTNodes.pir
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/src/CPP_PASTNodes.pir Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1,300 @@
+## $Id: CPP_PASTNodes.pir 31862 2008-10-10 18:23:45Z tene $
+
+=head1 NAME
+
+C99::CPP::PAST - Abstract syntax tree nodes for C99
+
+=head1 DESCRIPTION
+
+This file implements the various abstract syntax tree nodes
+needed for C99. The currently defined ast nodes:
+
+ C99::CPP::PAST::Node - base class for all ast nodes
+
+=head1 METHODS
+
+=over 4
+
+=cut
+
+.include 'languages/c99/src/preamble'
+
+.HLL 'C99', 'c99_group'
+.namespace [ 'C99';'CPP';'PAST' ]
+
+.sub '__onload' :load
+ .local pmc base, p6meta
+ p6meta = get_hll_global 'P6metaclass'
+ base = p6meta.'new_class'('C99::CPP::PAST::Node','attr'=>'children source pos name line')
+
+ $P0 = p6meta.'new_class'('C99::CPP::PAST::IF_SECTION','parent'=>'C99::CPP::PAST::Node')
+ $P0 = p6meta.'new_class'('C99::CPP::PAST::IFNDEF','parent'=>'C99::CPP::PAST::Node')
+ $P0 = p6meta.'new_class'('C99::CPP::PAST::IFDEF','parent'=>'C99::CPP::PAST::Node')
+ $P0 = p6meta.'new_class'('C99::CPP::PAST::IF','parent'=>'C99::CPP::PAST::Node')
+ $P0 = p6meta.'new_class'('C99::CPP::PAST::ELIF','parent'=>'C99::CPP::PAST::Node')
+ $P0 = p6meta.'new_class'('C99::CPP::PAST::ELSE','parent'=>'C99::CPP::PAST::Node')
+ $P0 = p6meta.'new_class'('C99::CPP::PAST::DEFINE','parent'=>'C99::CPP::PAST::Node')
+ $P0 = p6meta.'new_class'('C99::CPP::PAST::DEFINE_FUNCTION','parent'=>'C99::CPP::PAST::Node')
+ $P0 = p6meta.'new_class'('C99::CPP::PAST::INCLUDE','parent'=>'C99::CPP::PAST::Node')
+ $P0 = p6meta.'new_class'('C99::CPP::PAST::ERROR','parent'=>'C99::CPP::PAST::Node')
+ $P0 = p6meta.'new_class'('C99::CPP::PAST::LINE','parent'=>'C99::CPP::PAST::Node')
+ $P0 = p6meta.'new_class'('C99::CPP::PAST::PRAGMA','parent'=>'C99::CPP::PAST::Node')
+ $P0 = p6meta.'new_class'('C99::CPP::PAST::SOURCE_LINE','parent'=>'C99::CPP::PAST::Node')
+ $P0 = p6meta.'new_class'('C99::CPP::PAST::WSNWS','parent'=>'C99::CPP::PAST::Node')
+
+
+ $P0 = new 'Integer'
+ $P0 = 10
+ set_hll_global ['C99';'CPP';'PAST'], 'serial_number', $P0
+ .return ()
+.end
+
+
+.namespace [ 'C99';'CPP';'PAST';'Node' ]
+
+.sub 'attr' :method
+ .param string attrname
+ .param pmc value
+ .param int setvalue
+ if setvalue goto set
+ value = getattribute self, attrname
+ unless null value goto end
+ value = new .Undef
+ set:
+ setattribute self, attrname, value
+ end:
+ .return (value)
+.end
+
+
+.sub 'init' :method
+ .param pmc children :slurpy
+ .param pmc adverbs :slurpy :named
+
+ unless null children goto set_children
+ children = new .ResizablePMCArray
+ set_children:
+ setattribute self, 'children', children
+
+ if null adverbs goto end
+ .local pmc iter
+ iter = new .Iterator, adverbs
+ iter_loop:
+ unless iter goto iter_end
+ $S0 = shift iter
+ if $S0 == 'XXX' goto iter_loop
+ $P0 = iter[$S0]
+ $P1 = find_method self, $S0
+ self.$P1($P0)
+ goto iter_loop
+ iter_end:
+ end:
+ .return ()
+.end
+
+
+.sub 'new' :method
+ .param string class
+ .param pmc children :slurpy
+ .param pmc adverbs :slurpy :named
+
+ $P0 = new class
+ $P0.'init'(children :flat, 'node'=>self, 'XXX'=>1, adverbs :flat :named)
+ .return ($P0)
+.end
+
+
+.sub 'add_child' :method
+ .param pmc child
+ .local pmc array
+ array = getattribute self, 'children'
+ push array, child
+ .return ()
+ .end
+
+.sub 'append_children' :method
+ .param pmc children
+ .local pmc array
+ array = getattribute self, 'children'
+ array.'append'(children)
+ .return ()
+.end
+
+
+.sub 'add_child_new' :method
+ .param string class
+ .param pmc children :slurpy
+ .param pmc adverbs :slurpy :named
+ $P0 = self.'new'(class, children :flat, 'XXX'=>0, adverbs :flat :named)
+ self.'add_child'($P0)
+ .return ($P0)
+.end
+
+.gen_accessor('source')
+.gen_accessor('pos')
+.gen_accessor('name')
+.gen_accessor('line')
+.gen_get_accessor('children')
+
+.sub 'children' :method
+# .param pmc value :optional
+# .param int has_value :opt_flag
+ null $P0
+ .return self.'attr'('children', $P0, 0)
+.end
+
+.sub 'node' :method
+ .param pmc node
+ $I0 = isa node, ['C99';'CPP';'PAST';'Node']
+ if $I0 goto clone_past
+ clone_pge:
+ $S0 = node
+ self.'source'($S0)
+ $I0 = node.'from'()
+ self.'pos'($I0)
+ .return ()
+ clone_past:
+ $S0 = node.'source'()
+ self.'source'($S0)
+ $I0 = node.'pos'()
+ self.'pos'($I0)
+ .return ()
+.end
+
+
+.sub 'child_iter' :method
+ $P0 = getattribute self, 'children'
+ $P1 = new .Iterator, $P0
+ $P1 = 0
+ .return ($P1)
+.end
+
+
+=item C<C99::CPP::PAST::Node::unique([string fmt])>
+
+Each call to C<unique> returns a unique number, or if a C<fmt>
+parameter is given it returns a unique string beginning with
+C<fmt>. (This may eventually be generalized to allow
+uniqueness anywhere in the string.) The function starts
+counting at 10 (so that the values 0..9 can be considered "safe").
+
+=cut
+
+.sub 'unique' :method
+ .param string fmt :optional
+ .param int has_fmt :opt_flag
+
+ if has_fmt goto unique_1
+ fmt = ''
+ unique_1:
+ $P0 = get_hll_global ['C99';'CPP';'PAST'], 'serial_number'
+ $S0 = $P0
+ $S0 = concat fmt, $S0
+ inc $P0
+ .return ($S0)
+.end
+
+
+.sub '__elements' :method
+ $P0 = getattribute self, 'children'
+ $I0 = elements $P0
+ .return ($I0)
+.end
+
+
+.sub '__get_pmc_keyed_int' :method
+ .param int key
+ $P0 = getattribute self, 'children'
+ $P0 = $P0[key]
+ .return ($P0)
+.end
+
+
+.sub '__set_pmc_keyed_int' :method
+ .param int key
+ .param pmc val
+ $P0 = getattribute self, 'children'
+ $P0[key] = val
+ .return ()
+.end
+
+.sub '__get_string' :method
+ $P0 = getattribute self, 'name'
+ $S0 = $P0
+ .return ($S0)
+.end
+
+
+.sub '__dumplist' :method
+ .return ('pos name children')
+.end
+
+
+.sub '__dump' :method
+ .param pmc dumper
+ .param string label
+ .local string indent, subindent
+
+ (subindent, indent) = dumper.'newIndent'()
+ print '=> { '
+.local pmc attrlist, iter
+ $S0 = self.'__dumplist'()
+ attrlist = split ' ', $S0
+ iter = new .Iterator, attrlist
+ iter_loop:
+ unless iter goto iter_end
+ .local string attrname
+ .local pmc val
+ attrname = shift iter
+ val = getattribute self, attrname
+ print "\n"
+ print subindent
+ print attrname
+ print ' => '
+ dumper.'dump'(label, val)
+ goto iter_loop
+ iter_end:
+ print "\n"
+ print indent
+ print '}'
+ dumper.'deleteIndent'()
+ .return ()
+.end
+
+
+.namespace [ 'C99';'CPP';'PAST';'Node' ]
+.gen_dumplist('children')
+.namespace [ 'C99';'CPP';'PAST';'IF_SECTION' ]
+.gen_dumplist('children')
+.namespace [ 'C99';'CPP';'PAST';'IFNDEF' ]
+.gen_dumplist('line children')
+.namespace [ 'C99';'CPP';'PAST';'IFDEF' ]
+.gen_dumplist('line children')
+.namespace [ 'C99';'CPP';'PAST';'IF' ]
+.gen_dumplist('line children')
+.namespace [ 'C99';'CPP';'PAST';'ELIF' ]
+.gen_dumplist('line children')
+.namespace [ 'C99';'CPP';'PAST';'ELSE' ]
+.gen_dumplist('children')
+.namespace [ 'C99';'CPP';'PAST';'DEFINE' ]
+.gen_dumplist('name line')
+.namespace [ 'C99';'CPP';'PAST';'DEFINE_FUNCTION' ]
+.gen_dumplist('name line')
+.namespace [ 'C99';'CPP';'PAST';'INCLUDE' ]
+.gen_dumplist('line')
+.namespace [ 'C99';'CPP';'PAST';'ERROR' ]
+.gen_dumplist('line')
+.namespace [ 'C99';'CPP';'PAST';'LINE' ]
+.gen_dumplist('line')
+.namespace [ 'C99';'CPP';'PAST';'PRAGMA' ]
+.gen_dumplist('line')
+.namespace [ 'C99';'CPP';'PAST';'SOURCE_LINE' ]
+.gen_dumplist('line')
+.namespace [ 'C99';'CPP';'PAST';'WSNWS' ]
+.gen_dumplist('line')
+
+# Local Variables:
+# mode: pir
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:
Added: c99/trunk/src/CPP_PGE2AST.pir
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/src/CPP_PGE2AST.pir Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1,92 @@
+.namespace [ 'C99';'CPP';'ASTGrammar' ]
+
+.include 'languages/c99/src/preamble'
+.include 'languages/c99/src/CPP_ASTGrammar.pir'
+.include "iterator.pasm"
+
+.sub '__onload' :load
+ $P0 = get_class ['C99';'CPP';'ASTGrammar']
+ if null $P0 goto error
+ addattribute $P0, 'scope_stack'
+ .return ()
+error:
+ print "C99::CPP::ASTGrammar class not found\n"
+ end
+.end
+
+.sub 'attr' :method
+ .param string attrname
+ .param pmc value
+ .param int setvalue
+ if setvalue goto set
+ value = getattribute self, attrname
+ unless null value goto end
+ value = new .Undef
+ set:
+ setattribute self, attrname, value
+ end:
+ .return (value)
+.end
+
+.sub 'scope_stack' :method
+ .param pmc attr :optional
+ .param int has_attr :opt_flag
+ .local pmc value
+ value = self.'attr'('scope_stack', attr, has_attr)
+ $I0 = defined value
+ if $I0 goto end
+ value = new .ResizablePMCArray
+ value = self.'attr'('scope_stack', value, 1)
+ end:
+ .return (value)
+.end
+
+.sub 'push_scope_stack' :method
+ .param pmc value
+ .local pmc stack
+ stack = self.'scope_stack'()
+ push stack, value
+ .return (value)
+.end
+
+.sub 'pop_scope_stack' :method
+ .local pmc value
+ .local pmc stack
+ stack = self.'scope_stack'()
+ value = pop stack
+ .return (value)
+.end
+
+.sub 'top_scope_stack' :method
+ .local pmc value
+ .local pmc stack
+ stack = self.'scope_stack'()
+ $I0 = elements stack
+ unless $I0 goto end
+ $I0 -= 1
+ value = stack[$I0]
+ .return (value)
+ end:
+ print "Error: top_scope_stack is empty"
+ end
+.end
+
+.sub 'add_to_current_block' :method
+ .param string key
+ .param pmc value
+ .local pmc scope
+ scope = self.'top_scope_stack'()
+ $I0 = isa scope, ['Cardinal';'PAST';'Block']
+ unless $I0 goto end
+ scope.'vardecl'(key, value)
+ .return ()
+ end:
+ print "Error: top_scope_stack is empty"
+ end
+.end
+
+# Local Variables:
+# mode: pir
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:
Added: c99/trunk/src/builtins/say.pir
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/src/builtins/say.pir Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1,82 @@
+# $Id: say.pir 27878 2008-05-28 14:44:03Z Whiteknight $
+
+=head1
+
+say.pir -- simple implementation of a say function
+
+=cut
+
+.namespace []
+
+.sub 'say'
+ .param pmc args :slurpy
+ .local pmc iter
+ iter = new 'Iterator', args
+ iter_loop:
+ unless iter goto iter_end
+ $P0 = shift iter
+ print $P0
+ goto iter_loop
+ iter_end:
+ print "\n"
+ .return ()
+.end
+
+.sub 'printf'
+ .param pmc format
+ .param pmc args :slurpy
+ .local pmc iter
+ iter = new 'Iterator', args
+ iter_loop:
+ unless iter goto iter_end
+ goto iter_loop
+ iter_end:
+.end
+
+.sub 'puts'
+ .param pmc str
+ print str
+ print "\n"
+.end
+
+.sub 'infix:<'
+ .param pmc a
+ .param pmc b
+ islt $I0, a, b
+ .return ($I0)
+.end
+
+.sub 'postfix:++'
+ .param pmc arg
+ $P0 = clone arg
+ inc $P0
+ .return (arg)
+.end
+
+.sub 'postfix:--'
+ .param pmc arg
+ $P0 = clone arg
+ dec $P0
+ .return (arg)
+.end
+
+.sub 'prefix:++'
+ .param pmc arg
+ inc arg
+ .return (arg)
+.end
+
+.sub 'prefix:--'
+ .param pmc arg
+ dec arg
+ .return (arg)
+.end
+
+
+
+# Local Variables:
+# mode: pir
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:
+
Added: c99/trunk/src/c99.pg
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/src/c99.pg Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1,581 @@
+#taken from n869.pdf
+#google for n869.pdf
+
+## A.1 Lexical grammar
+grammar C99::Grammar;
+
+## A.1.1 Lexical elements
+token ws {
+ [
+ | <'//'> \N* \n
+ | <'/*'> .*? <'*/'>
+ | \s+
+ ]*
+}
+
+rule c99_token {
+ | <keyword>
+ | <identifier>
+ | <constant>
+ | <string_literal>
+ | <punctuator>
+}
+
+token pound { <'\#'> }
+
+regex preprocessing_token {
+ | <header_name>
+ | <identifier>
+ | <pp_number>
+ | <character_constant>
+ | <string_literal>
+ | <!pound> <punctuator>
+ | <universal_character_name>
+ | <-[# \r\n\t]>\S* ## <-[#]-\S>\S* ##non-whitespace
+}
+
+## A.1.2 Keywords
+token keyword {
+ | auto | enum | restrict | unsigned
+ | break | extern | return | void
+ | case | float | short | volatile
+ | char | for | signed | while
+ | const | goto | sizeof | _Bool
+ | continue | if | static | _Complex
+ | default | inline | struct | _Imaginary
+ | do | int | switch
+ | double | long | typedef
+ | else | register | union
+
+}
+
+## A.1.3 Identifiers
+#token identifier { <identifier_nondigit> [ <identifier_nondigit> | \d ]* }
+token identifier { <?identifier_nondigit> [ <?identifier_nondigit> | <?digit> ]* }
+
+token identifier_nondigit { <alpha> | <[_]> | <universal_character_name> }
+
+## A.1.4 Universal character names
+token universal_character_name {
+ | <'\u'> <xdigit>**{4}
+ | <'\U'> <xdigit>**{8}
+}
+
+## A.1.5 Constants
+token constant {
+ | <integer_constant>
+ | <floating_constant>
+ | <enumeration_constant>
+ | <character_constant>
+}
+
+token integer_constant {
+ [ <decimal_constant>
+ | <octal_constant>
+ | <hexadecimal_constant>
+ ] <integer_sufffix>?
+}
+
+token decimal_constant { <[1..9]> <digit> }
+#token decimal_constant { <[1..9]> \d* }
+token octal_constant { 0 <[0..7]>+ }
+token hexadecimal_constant { 0 <[xX]> <xdigit>+ }
+
+token integer_suffix {
+ | <[uU]> [ll?|LL?]?
+ | [ll?|LL?] <[uU]>?
+}
+
+token floating_constant {
+ | <decimal_floating_constant>
+ | <hexadecimal_floating_constant>
+}
+
+token decimal_floating_constant {
+ [ <fractional_constant> <exponent_part>?
+ | <digit_sequence> <exponent_part>
+ ] <floating_suffix>?
+}
+
+token hexadecimal_prefix
+{
+ 0 <[xX]>
+}
+
+token hexadecimal_floating_constant {
+ <hexadecimal_prefix>
+ [ <hexadecimal_fractional_constant>
+ | <hexadecimal_digit_constant>
+ ] <binary_exponent_part> <floating_suffix>?
+}
+
+token fractional_constant {
+ | <digit_sequence>? \. <digit_sequence>
+ | <digit_sequence> \.
+}
+
+token exponent_part {
+ <[eE]> <[\+\-]>? <digit_sequence>
+}
+
+#token digit_sequence { \d+ }
+token digit_sequence { <digit>+ }
+
+token hexadecimal_fractional_constant {
+ | <hexadecimal_digit_sequence>? \. <hexadecimal_digit_sequence>
+ | <hexadecimal_digit_sequence> \.
+}
+
+token binary_exponent_part {
+ <[pP]> <[\+\-]>? <digit_sequence>
+}
+
+token hexadecimal_digit_sequence { <xdigit>+ }
+
+token floating_suffix { <[fFlL]> }
+
+token enumeration_constant { <identifier> }
+
+token character_constant { <[L]>? \' <c_char>+ \' }
+
+token <c_char> { <-['\\\n]> | <escape_sequence> }
+
+token escape_sequence {
+ \\
+ [ <['"?\\abfnrtv]>
+ | <octal_digit>**{1..3}
+ | x <xdigit>+
+ | <universal_character_name>
+ ]
+}
+
+## A.1.6 String literals
+token string_literal { <[L]>? " <s_char>* " }
+
+token s_char { <-["\\\n]> | <escape_sequence> }
+
+## A.1.7 Punctuators
+token punctuator {
+ | \[ | \] | <[(){}.]> | <'->'>
+ | <'++'> | <'--'> | <[&*+\-~!/%]>
+ | <'<<'> | <'>>'> | <[<>]>
+ | <'<='> | <'>='> | <'=='> | <'!='>
+ | <[^|]> | <'&&'> | <'||'>
+ | <[?:;]> | <'...'>
+ | [ <[*/%+\-&^|]> | <'<<'> | <'>>'> ] <'='>
+ | <[,#]> | <'##'>
+ | <'<:'> | <':>'> | <'<%'> | <'%>'> | <'%:'> | <'%:%:'>
+}
+
+## A.1.8 Header names
+token header_name {
+ | \< $<name:>=<?h_char>+ \>
+ | " $<name>:=<?q_char>+ "
+}
+
+token h_char { <-[\n>]> }
+token q_char { <-[\n"]> }
+
+## A.1.9 Preprocessing numbers
+token pp_number { \.? \d [ \d | <identifier_nondigit> | <[eEpP]> <[\+\-]> | \. ]* }
+
+## A.2 Phrase structure grammar
+## XXX: see below
+
+## A.2.2 Declarations
+rule declaration { <declaration_specifier>+ <init_declarator_list>? ; }
+
+rule declaration_specifier {
+ | <storage_class_specifier>
+ | <type_specifier>
+ | <type_qualifier>
+ | <function_specifier>
+}
+
+rule init_declarator_list { init_declarator [ , <init_declarator> ]* }
+
+rule init_declarator { <declarator> [ = <initializer> ]? }
+
+token storage_class_specifier { typedef | extern | static | auto | register }
+
+rule type_specifier {
+ | void | char | short | int
+ | long | float | double | signed
+ | unsigned | _Bool | _Complex | _Imaginary
+ | <struct_or_union_specifier>
+ | <enum_specifier>
+ | <typedef_name>
+}
+
+rule struct_or_union_specifier {
+ [ $<struct>:=<'struct'> | $<union>:=<'union'> ] [ <identifier> | <identifier>? \{ <struct_declaration>+ \} ]
+}
+
+rule struct_declaration { [<type_specifier>|<type_qualifier>]+ <struct_declarator>+ ; }
+
+rule struct_declarator { <declarator> | <declarator>? : <constant_expression> }
+
+rule enum_specifier { enum [ <identifier>? \{ <enumerator> [ , <enumerator> ]+ [,]? \}| <identifier> ] }
+
+rule enumerator { <enumeration_constant> [ = <constant_expression> ]? }
+
+token type_qualifier { const | restrict | volatile }
+
+token function_specifier { inline }
+
+rule declarator { <pointer>? <direct_declarator> }
+
+rule direct_declarator {
+ [ <identifier> | \( <declarator> \) ]
+ [
+ | \[ <assignment_expression>? \]
+ | \[ \* \]
+ | \( <parameter_type_list> \)
+ | \( <identifier_list>? \)
+ ]*
+}
+
+rule pointer { [\* <type_qualifier>* ]+ }
+
+rule parameter_type_list { <parameter_declaration> [ , <parameter_declaration> ]* [ , <'...'>]? }
+
+rule parameter_declaration { <declaration_specifier>+ [ <declarator> | <abstract_declatator> ]? }
+
+rule identifier_list { <identifier> [ , <identifier> ]* }
+
+rule type_name { <specifier_qualifier_list> <abstract_declatator>? }
+
+rule abstract_declatator {
+ <pointer>? <direct_abstract_declarator>
+ |<pointer>
+}
+
+rule direct_abstract_declarator {
+ [
+ | \( <abstract_declatator> \)
+ | \[ <assignment_expression>? \]
+ | \( <parameter_type_list> \)
+ ]
+ <direct_abstract_declarator_1>*
+}
+
+rule direct_abstract_declarator_1 {
+ | \[ <assignment_expression>? \]
+ | \[ * \]
+ | \( <parameter_type_list> \)
+}
+
+rule typedef_name { <identifier> }
+
+rule initializer { <assignment_expression> | \{ <initializer_list> [,]? \} }
+
+rule initializer_list { <designation>? <initializer> [, <designation>? <initializer> ]* }
+
+rule designation { <designator>+ = }
+
+rule designator {
+ | \[ <constant_expression> \]
+ | \. <identifier>
+}
+
+## A.2.3 Statements
+rule statement {
+ | <labeled_statement>
+ | <compound_statement>
+ | <expression_statement>
+ | <selection_statement>
+ | <iteration_statement>
+ | <jump_statement>
+}
+
+rule labeled_statement {
+ [ <identifier> \:
+ | case <constant_expression> \:
+ | default \:
+ ] <statement>
+}
+
+rule compound_statement { \{ [ <declaration> | <statement> ]* \} }
+
+rule expression_statement { <expression>? ; }
+
+rule selection_statement {
+ | if \( <expresssion> \) <statement> [else <statement>]?
+ | switch \( <expression> \) <statement>
+}
+
+rule iteration_statement {
+ | while \( <expression> \) <statement>
+ | do <statement> while \( <expression> \) ;
+ | for \( [ <expression>? ; <expression>? ; <expression>? | <declaration> <expression>? ; <expression>? ] \) <statement>
+}
+
+rule jump_statement {
+ | goto <identifier> ;
+ | continue ;
+ | break ;
+ | return <expression>? ;
+}
+
+
+## A.2.4 External definitions
+rule translation_unit { [ <function_definition> | <declaration> ]+ }
+
+rule function_definition { <declaration_specifier>+ <declarator> <declaration>* <compound_statement> }
+
+
+## A.3 preprocessing directives
+token wsnws {
+ <?ws_minus_n>? \n <?ws>?
+}
+
+regex prereprocessing_file { <group> }
+
+regex group { <group_line>+ }
+
+regex group_line {
+ | <if_section>
+ | <control_line>
+ | <source_line>? $<wsnws>:=<?wsnws>
+}
+
+regex source_line {
+ <?pp_tokens>
+}
+
+
+rule if_section { <if_group> <elif_group>* <else_group>? <endif_line> }
+
+token ws_minus_n
+{
+ [
+ | <'//'> \N* \n
+ | <'/*'> .*? <'*/'>
+ | \t
+ | <' '>
+ ## | <\s-<[\n]>
+ ]*
+}
+
+regex if_group {
+ [
+ | \# <?ws>? $<ifndef>:=<'ifndef'> <?ws> <identifier>
+ | \# <?ws>? $<ifdef>:=<'ifdef'> <?ws> <identifier>
+ | \# <?ws>? $<if>:=<'if'> <?ws> <constant_expression>
+ ] <?wsnws> <group>?
+}
+
+regex elif_group { \# <?ws> $<elif>:=<'elif'> <?ws> <constant_expression> <?wsnws> <group>? }
+regex else_group { \# <?ws> $<else>:=<'else'> <?wsnws> <group>? }
+regex endif_line { \# <?ws> $<endif>:=<'endif'> <?wsnws> }
+regex control_line {
+ | \# <?ws>? $<include>:=<'include'> <?ws_minus_n> $<value>:=<pp_tokens> <?wsnws>
+ | \# <?ws>? $<define>:=<'define'> <?ws>
+ [
+ | $<define_name>:=<identifier>
+ | $<define_function>:=(<identifier_p> [ <identifier_list> [, \.\.\.]? | [ \.\.\.] ]? \))
+ ] <?ws_minus_n>? $<value>:=<pp_tokens>?
+ | \# ?<ws>? $<undefine>:=<'undefine'> <?ws_minus_n> <identifier> <?wsnws>
+ | \# ?<ws>? $<line>:=<'line'> <?ws_minus_n> $<value>:=<pp_tokens> <?wsnws>
+ | \# ?<ws>? $<error>:=<'error'> <?ws_minus_n> $<value>:=<pp_tokens>? <?wsnws>
+ | \# ?<ws>? $<pragma>:=<'pragma'> <?ws_minus_n> $<value>:=<pp_tokens>? <?wsnws>
+ | \# <?wsnws>
+
+}
+
+token identifier_p { <identifier> \( }
+regex pp_tokens { <preprocessing_token> [<?ws_minus_n> <preprocessing_token>]* }
+
+
+## A.2.1 Expressions
+rule primary_expression {
+ | <identifier>
+ | <constant>
+ | <string_literal>
+ | \( <expression> \)
+}
+
+rule postfix_expression {
+ [ <primary_expression>
+ | \( <type_name> \) \{ <initializer_list> [\,]? \} ]
+
+ [ <'++'>
+ | <'--'>
+ | \[ <expression> \]
+ | \( [ <assignment_expression> [ \, <assignment_expression> ]* ]? \)
+ | \. <identifier>
+ | <'->'> <identifier>
+ | \( <type_name> \) \{ <initializer_list> [\,]? \}
+ ]*
+}
+
+rule unary_expression {
+ [<'++'>|<'--'>|<'sizeof'>]?
+
+ [ <postfix_expression>
+ | $<unary_op>:=<[&*+\-~!]> <cast_expression>
+ | <'sizeof'> \( <type_name> \)
+ ]
+}
+
+rule cast_expression { [ \( <type_name> \) ]* <unary_expression> }
+
+#proto 'term:' is precedence('22=')
+# is parsed(primary_expression)
+# is pastrule('past_term') { ... }
+
+## postfix expressions
+#proto 'postfix:++' is precedence('20=') { ... }
+#proto 'postcircumfix:[]' is equiv('postfix:++') { ... }
+#rule postfix_expression { <postfix_expression> \[ <expression> \] }
+#proto 'postcircumfix:()' is equiv('postfix:++') { ... }
+#rule postfix_expression { <postfix_expression> \( [ <assignment_expression> [\, <assignment_expression>]* ]? \) }
+#proto 'infix:.' is equiv('postfix:++') { ... }
+#rule postfix_expression { <postfix_expression> . <identifier> }
+#proto 'infix:->' is equiv('postfix:++') { ... }
+#rule postfix_expression { <postfix_expression> \-\> <identifier> }
+#proto 'postfix:--' is equiv('postfix:++') { ... }
+#rule postfix_expression { \( <type_name> \) \{ <initializer_list> [,]? \} }
+
+## unary-expression
+#proto 'prefix:++' is precedenc('18=') { ... }
+#proto 'prefix:--' is equiv('prefix:++') { ... }
+#proto 'prefix:&' is equiv('prefix:++') { ... }
+#proto 'prefix:*' is equiv('prefix:++') { ... }
+#proto 'prefix:+' is equiv('prefix:++') { ... }
+#proto 'prefix:-' is equiv('prefix:++') { ... }
+#proto 'prefix:~' is equiv('prefix:++') { ... }
+#proto 'prefix:!' is equiv('prefix:++') { ... }
+#proto 'prefix:sizeof' is equiv('prefix:++') { ... }
+#proto 'prefix:sizeof' is equiv('prefix:++') { ... }
+#rule unary_expression { sizeof <unary_expression> }
+#rule unary_expression { sizeof [\( <type_name> \) ] }
+
+## cast-expression
+## XXX: PGE doesn't have a precircumfix:() function (yet?)
+#proto 'precircumfix:()' is precedence('17=') {...}
+#rule cast_expression { [\( <type_name> \) ]* <unary_expression> }
+
+proto 'term:' is precedence('22=')
+ is parsed(cast_expression)
+ is pastrule('cast_expression') { ... }
+
+## multiplicative
+proto 'infix:*' is precedence('16=')
+ is post('mul')
+ { ... }
+
+proto 'infix:/' is equiv('infix:*')
+ is post('div')
+ { ... }
+
+proto 'infix:%' is equiv('infix:*')
+ is post('mod')
+ { ... }
+
+## additive
+proto 'infix:+' is precedence('16=')
+ is post('add')
+ { ... }
+
+proto 'infix:-' is equiv('infix:+')
+ is post('sub')
+ { ... }
+
+
+## shift-expression
+proto 'infix:<<' is precedence('15=') { ... }
+proto 'infix:>>' is precedence('15=') { ... }
+
+
+## relational-expression
+## chaining binary
+proto 'infix:<' is equiv('14=') is assoc('chain')
+ is pasttype('chain')
+ { ... }
+
+proto 'infix:<=' is equiv('infix:<')
+ is pasttype('chain')
+ { ... }
+
+proto 'infix:>' is equiv('infix:<')
+ is pasttype('chain')
+ { ... }
+
+proto 'infix:>=' is equiv('infix:<')
+ is pasttype('chain')
+ { ... }
+
+# equality-expression
+proto 'infix:==' is precedence('13=') is assoc('chain')
+ is pasttype('chain')
+ { ... }
+
+proto 'infix:!=' is equiv('infix:==')
+ is pasttype('chain')
+ { ... }
+
+
+proto 'infix:&' is precedence('12=') { ... }
+proto 'infix:^' is precedence('11=') { ... }
+proto 'infix:|' is precedence('10=') { ... }
+
+proto 'infix:&&' is precedence('09=')
+ is pasttype('cond')
+ { ... }
+
+proto 'infix:||' is precedence('08=')
+ is pasttype('cond')
+ { ... }
+
+## ternary
+#proto 'ternary:? :' is precedence('07=') is assoc('right')
+# is pasttype('cond')
+# is parsed('conditional_expression')
+# { ... }
+
+rule operator_precedence_parser { {{
+ .local pmc optable
+ .local pmc match_result
+ #optable = get_hll_namespace ['Cardinal'; 'Grammar']
+ optable = get_root_global [ 'parrot'; 'C99'], '$optable'
+ match_result = optable."parse"(match)
+ .return (match_result)
+}} }
+
+rule conditional_expression { <operator_precedence_parser> [ \? <expression> : <operator_precedence_parser> ]* }
+
+rule assignment_expression { [ <unary_expression> <assignment_operator> ]* <constant_expression> }
+
+token assignment_operator {
+ | <'*='>
+ | <'/='>
+ | <'%='>
+ | <'+='>
+ | <'-='>
+ | <'<<='>
+ | <'>>='>
+ | <'&='>
+ | <'^='>
+ | <'|='>
+}
+
+rule expression { <assignment_expression> [, <assignment_expression> ] }
+rule constant_expression { <conditional_expression> }
+
+## assignment
+#proto 'infix:=' is precedence('06=') is assoc('right')
+# is parsed('assignment_expression')
+# is pasttype('assign')
+# { ... }
+
+#proto 'infix:*=' is equiv('infix:=') is parsed('assignment_expression') { ... }
+#proto 'infix:/=' is equiv('infix:=') is parsed('assignment_expression') { ... }
+#proto 'infix:%=' is equiv('infix:=') is parsed('assignment_expression') { ... }
+#proto 'infix:+=' is equiv('infix:=') is parsed('assignment_expression') { ... }
+#proto 'infix:-=' is equiv('infix:=') is parsed('assignment_expression') { ... }
+#proto 'infix:<<=' is equiv('infix:=') is parsed('assignment_expression') { ... }
+#proto 'infix:>>=' is equiv('infix:=') is parsed('assignment_expression') { ... }
+#proto 'infix:&=' is equiv('infix:=') is parsed('assignment_expression') { ... }
+#proto 'infix:^=' is equiv('infix:=') is parsed('assignment_expression') { ... }
+#proto 'infix:|=' is equiv('infix:=') is parsed('assignment_expression') { ... }
Added: c99/trunk/src/c99_PGE.pir
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/src/c99_PGE.pir Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1,60 @@
+=head1 NAME
+
+C99::Grammar -- A grammar for parsing C99
+
+=head1 SYNOPSYS
+
+=head1 DESCRIPTION
+
+This is a grammar to parse c99 programs. It inherits the behavior
+of the PGE::Grammar class. It parses a string of source code according to
+its hierarchy of rules and returns a PGE::Match object (a parse tree).
+
+=cut
+
+#.HLL 'C99', 'c99y_group'
+#.namespace [ 'C99'; 'Grammar' ]
+.namespace [ 'C99';'Grammar' ]
+
+.sub _load :load
+ load_bytecode 'PGE.pbc'
+ load_bytecode 'PGE/Text.pbc'
+.end
+
+# Pull in the compiled grammar
+.include "languages/c99/src/c99_grammar_gen.pir"
+.sub '__onload' :load
+ $P0 = get_hll_global ['C99';'Grammar'], '$optable'
+ $P1 = get_hll_global ['C99';'Grammar'], 'ws'
+ setattribute $P0, '&!ws', $P1
+ $P0 = new .Hash
+.end
+
+# Operator precedence parsing rule
+.sub "operator_precedence_parser"
+ .param pmc match_object
+ .local pmc optable
+ #optable = get_hll_namespace ['C99'; 'Grammar']
+ optable = get_root_global [ 'parrot'; 'C99';'Grammar'], '$optable'
+ $P0 = optable."parse"(match_object)
+ .return ($P0)
+.end
+
+=head1 LICENSE
+
+Copyright (C) 2005-2008, Parrot Foundation.
+
+This is free software; you may redistribute it and/or modify
+it under the same terms as Parrot.
+
+=head1 AUTHOR
+
+Kevin Tew <kevintew at tewk.com>
+
+=cut
+
+# Local Variables:
+# mode: pir
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:
Added: c99/trunk/src/cpp/Makefile
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/src/cpp/Makefile Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1,106 @@
+# ex: set ro:
+# DO NOT EDIT THIS FILE
+# Generated by Parrot::Configure::Compiler from languages/c99/config/makefiles/cpp.in
+
+# Copyright (C) 2008-2009, Parrot Foundation.
+## $Id: cpp.in 36833 2009-02-17 20:09:26Z allison $
+
+## arguments we want to run parrot with
+PARROT_ARGS =
+
+## configuration settings
+BUILD_DIR = /home/allison/projects/svn/parrot
+LOAD_EXT = .so
+O = .o
+
+## Setup some commands
+PERL = /usr/bin/perl
+RM_F = $(PERL) -MExtUtils::Command -e rm_f
+CP = $(PERL) -MExtUtils::Command -e cp
+CAT = $(PERL) -MExtUtils::Command -e cat
+PARROT = ../../../../parrot
+BUILD_DYNPMC = $(PERL) $(BUILD_DIR)/tools/build/dynpmc.pl
+RECONFIGURE = $(PERL) $(BUILD_DIR)/tools/dev/reconfigure.pl
+
+## places to look for things
+PARROT_DYNEXT = $(BUILD_DIR)/runtime/parrot/dynext
+PGE_LIBRARY = $(BUILD_DIR)/runtime/parrot/library/PGE
+PERL6GRAMMAR = $(PGE_LIBRARY)/Perl6Grammar.pbc
+NQP = $(BUILD_DIR)/compilers/nqp/nqp.pbc
+PCT = $(BUILD_DIR)/runtime/parrot/library/PCT.pbc
+
+PMC_DIR = src/pmc
+
+all: cpp.pbc
+
+SOURCES = cpp.pir \
+ src/gen_grammar.pir \
+ src/gen_actions.pir \
+ src/gen_builtins.pir
+
+BUILTINS_PIR = \
+ src/builtins/say.pir
+
+# the default target
+cpp.pbc: $(PARROT) $(SOURCES)
+ $(PARROT) $(PARROT_ARGS) -o cpp.pbc cpp.pir
+ $(CP) cpp.pbc ../../cpp.pbc
+
+src/gen_grammar.pir: $(PERL6GRAMMAR) src/parser/grammar.pg
+ $(PARROT) $(PARROT_ARGS) $(PERL6GRAMMAR) \
+ --output=src/gen_grammar.pir \
+ src/parser/grammar.pg
+
+src/gen_actions.pir: $(NQP) $(PCT) src/parser/actions.pm
+ $(PARROT) $(PARROT_ARGS) $(NQP) --output=src/gen_actions.pir \
+ --target=pir src/parser/actions.pm
+
+src/gen_builtins.pir: $(BUILTINS_PIR)
+ $(CAT) $(BUILTINS_PIR) >src/gen_builtins.pir
+
+# regenerate the Makefile
+Makefile: ../../config/makefiles/cpp.in
+ cd $(BUILD_DIR) && $(RECONFIGURE) --step=gen::languages --languages=c99
+
+# This is a listing of all targets, that are meant to be called by users
+help:
+ @echo ""
+ @echo "Following targets are available for the user:"
+ @echo ""
+ @echo " all: c.pbc"
+ @echo " This is the default."
+ @echo "Testing:"
+ @echo " test: Run the test suite."
+ @echo " testclean: Clean up test results."
+ @echo ""
+ @echo "Cleaning:"
+ @echo " clean: Basic cleaning up."
+ @echo " realclean: Removes also files generated by 'Configure.pl'"
+ @echo " distclean: Removes also anything built, in theory"
+ @echo ""
+ @echo "Misc:"
+ @echo " help: Print this help message."
+ @echo ""
+
+test: all
+ $(PERL) t/harness
+
+# this target has nothing to do
+testclean:
+
+CLEANUPS = \
+ cpp.pbc \
+ "src/gen_*.pir"
+
+clean:
+ $(RM_F) $(CLEANUPS)
+
+realclean: clean
+ $(RM_F) Makefile
+
+distclean: realclean
+
+# Local variables:
+# mode: makefile
+# End:
+# vim: ft=make:
Added: c99/trunk/src/cpp/cpp.pir
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/src/cpp/cpp.pir Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1,80 @@
+# $Id: cpp.pir 36833 2009-02-17 20:09:26Z allison $
+# Copyright (C) 2008, Parrot Foundation.
+
+=head1 TITLE
+
+cpp.pir - A C pre processor.
+
+=head2 Description
+
+This is the base file for the C99 C pre processor.
+
+This file includes the parsing and grammar rules from
+the src/ directory, loads the relevant PGE libraries,
+and registers the compiler under the name 'C99::CPP'.
+
+=head2 Functions
+
+=over 4
+
+=item onload()
+
+Creates the C compiler using a C<PCT::HLLCompiler>
+object.
+
+=cut
+
+.namespace [ 'C99';'CPP';'Compiler' ]
+
+.loadlib 'c99_group'
+
+.sub 'onload' :anon :load :init
+ load_bytecode 'PCT.pbc'
+
+ $P0 = get_hll_global ['PCT'], 'HLLCompiler'
+ $P1 = $P0.'new'()
+ $P1.'language'('C99::CPP')
+ $P1.'parsegrammar'('C99::CPP::Grammar')
+ $P1.'parseactions'('C99::CPP::Grammar::Actions')
+.end
+
+=item main(args :slurpy) :main
+
+Start compilation by passing any command line C<args>
+to the C compiler.
+
+=cut
+
+.sub 'main' :main
+ .param pmc args
+
+ $P0 = compreg 'C99::CPP'
+ $P1 = $P0.'command_line'(args)
+.end
+
+
+.include 'src/gen_builtins.pir'
+.include 'src/gen_grammar.pir'
+.include 'src/gen_actions.pir'
+
+
+.namespace [ 'C99';'CPP';'Grammar' ]
+
+.sub 'debug'
+ .param pmc match
+ .param pmc arg
+ .param pmc attrs :slurpy
+ printerr arg
+ printerr "\n"
+.end
+
+=back
+
+=cut
+
+# Local Variables:
+# mode: pir
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:
+
Added: c99/trunk/src/cpp/src/builtins/say.pir
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/src/cpp/src/builtins/say.pir Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1,82 @@
+# $Id: say.pir 27878 2008-05-28 14:44:03Z Whiteknight $
+
+=head1
+
+say.pir -- simple implementation of a say function
+
+=cut
+
+.namespace []
+
+.sub 'say'
+ .param pmc args :slurpy
+ .local pmc iter
+ iter = new 'Iterator', args
+ iter_loop:
+ unless iter goto iter_end
+ $P0 = shift iter
+ print $P0
+ goto iter_loop
+ iter_end:
+ print "\n"
+ .return ()
+.end
+
+.sub 'printf'
+ .param pmc format
+ .param pmc args :slurpy
+ .local pmc iter
+ iter = new 'Iterator', args
+ iter_loop:
+ unless iter goto iter_end
+ goto iter_loop
+ iter_end:
+.end
+
+.sub 'puts'
+ .param pmc str
+ print str
+ print "\n"
+.end
+
+.sub 'infix:<'
+ .param pmc a
+ .param pmc b
+ islt $I0, a, b
+ .return ($I0)
+.end
+
+.sub 'postfix:++'
+ .param pmc arg
+ $P0 = clone arg
+ inc $P0
+ .return (arg)
+.end
+
+.sub 'postfix:--'
+ .param pmc arg
+ $P0 = clone arg
+ dec $P0
+ .return (arg)
+.end
+
+.sub 'prefix:++'
+ .param pmc arg
+ inc arg
+ .return (arg)
+.end
+
+.sub 'prefix:--'
+ .param pmc arg
+ dec arg
+ .return (arg)
+.end
+
+
+
+# Local Variables:
+# mode: pir
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:
+
Added: c99/trunk/src/cpp/src/parser/actions.pm
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/src/cpp/src/parser/actions.pm Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1,31 @@
+# $Id: actions.pm 36833 2009-02-17 20:09:26Z allison $
+# Copyright (C) 2008, Parrot Foundation.
+
+=begin comments
+
+C99::Grammar::Actions - ast transformations for C99
+
+This file contains the methods that are used by the parse grammar
+to build the PAST representation of an C 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.
+
+=end comments
+
+class C99::CPP::Grammar::Actions;
+
+method TOP($/) {
+}
+
+
+
+# Local Variables:
+# mode: cperl
+# cperl-indent-level: 4
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4:
+
Added: c99/trunk/src/cpp/src/parser/grammar.pg
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/src/cpp/src/parser/grammar.pg Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1,431 @@
+# $Id: grammar.pg 36833 2009-02-17 20:09:26Z allison $
+# Copyright (C) 2008, Parrot Foundation.
+
+=begin overview
+
+This is the grammar for C99 written as a sequence of Perl 6 rules.
+
+
+taken from n869.pdf
+google for n869.pdf
+
+=end overview
+
+grammar C99::CPP::Grammar is PCT::Grammar;
+
+token ws {
+ | \h*
+ | <multilinecomment>
+}
+
+token TOP {
+ ^
+ <pre_processing_file>
+ [ $ || <.panic: Syntax error> ]
+ {*}
+}
+
+## A.1.5 Constants
+##
+token constant {
+ | <floating_constant> {*} #= floating_constant
+ | <integer_constant> {*} #= integer_constant
+ | <enumeration_constant> {*} #= enumeration_constant
+ | <character_constant> {*} #= character_constant
+}
+
+token integer_constant {
+ [ <decimal_constant>
+ | <octal_constant>
+ | <hexadecimal_constant>
+ ]
+ <integer_suffix>?
+ {*}
+}
+
+token decimal_constant {
+ <[1..9]> <digit>*
+}
+
+token octal_constant {
+ 0 <[0..7]>*
+}
+
+token hexadecimal_constant {
+ 0 <[xX]> <xdigit>+
+}
+
+token integer_suffix {
+ | <[uU]> [ll?|LL?]?
+ | [ll?|LL?] <[uU]>?
+}
+
+token floating_constant {
+ [
+ | <decimal_floating_constant>
+ | <hexadecimal_floating_constant>
+ ]
+ {*}
+}
+
+token decimal_floating_constant {
+ [
+ | <fractional_constant> <exponent_part>?
+ | <digit_sequence> <exponent_part>
+ ]
+ <floating_suffix>?
+}
+
+token hexadecimal_prefix {
+ 0 <[xX]>
+}
+
+token hexadecimal_floating_constant {
+ <hexadecimal_prefix>
+ [
+ | <hexadecimal_fractional_constant>
+ | <hexadecimal_digit_constant>
+ ]
+ <binary_exponent_part> <floating_suffix>?
+}
+
+token fractional_constant {
+ | <digit_sequence>? \. <digit_sequence>
+ | <digit_sequence> \.
+}
+
+token exponent_part {
+ <[eE]> ['+'|'-']? <digit_sequence>
+}
+
+token digit_sequence { <digit>+ }
+
+token hexadecimal_fractional_constant {
+ | <hexadecimal_digit_sequence>? \. <hexadecimal_digit_sequence>
+ | <hexadecimal_digit_sequence> \.
+}
+
+token binary_exponent_part {
+ <[pP]> ['+'|'-']? <digit_sequence>
+}
+
+token hexadecimal_digit_sequence { <xdigit>+ }
+
+token floating_suffix { <[fFlL]> }
+
+token enumeration_constant { <identifier> }
+
+token character_constant { [L]? \' <c_char>+ \' }
+
+token <c_char> { <-['\\\n]> | <escape_sequence> }
+
+token escape_sequence {
+ \\
+ [ <['"?\\abfnrtv]>
+ | <octal_digit>**{1..3}
+ | x <xdigit>+
+ | <universal_character_name>
+ ]
+}
+
+## A.1.6 String literals
+token c_string_literal {
+ [L]? <string_literal: '"'>
+ {*}
+}
+
+##\" <s_char>* \"
+
+token s_char { <-["\\\n]> | <escape_sequence> }
+
+
+## A.2 Phrase structure grammar
+##
+
+## A.2.1 Expressions
+##
+
+rule expression {
+ <constant_expression>
+ {*}
+}
+
+rule constant_expression {
+ <conditional_expression>
+ {*}
+}
+
+rule assign_op { '='|'*='|'/='|'%='|'+='|'-='|'<<='|'>>='|'&='|'^='|'|=' }
+
+rule conditional_expression {
+ <logical_expression> ['?' <conditional_expression> ':' <conditional_expression>]?
+ {*}
+}
+
+rule logical_expression is optable { ... }
+
+proto 'infix:||' is precedence('1') { ... }
+
+proto 'infix:&&' is tighter('infix:||') { ... }
+
+proto 'infix:|' is tighter('infix:&&') { ... }
+
+proto 'infix:^' is tighter('infix:|') { ... }
+
+proto 'infix:&' is tighter('infix:^') { ... }
+
+proto 'infix:==' is tighter('infix:&') { ... }
+proto 'infix:!=' is equal('infix:==') { ... }
+
+proto 'infix:<' is tighter('infix:==') { ... }
+proto 'infix:>' is equal('infix:<') { ... }
+proto 'infix:>=' is equal('infix:<') { ... }
+proto 'infix:<=' is equal('infix:<') { ... }
+
+proto 'infix:<<' is tighter('infix:==') { ... }
+proto 'infix:>>' is equal('infix:<<') { ... }
+
+proto 'infix:+' is tighter('infix:<<') is pirop('n_add') { ... }
+proto 'infix:-' is equal('infix:+') is pirop('n_sub') { ... }
+
+proto 'infix:*' is tighter('infix:+') is pirop('n_mul') { ... }
+proto 'infix:/' is equal('infix:*') is pirop('n_div') { ... }
+proto 'infix:%' is equal('infix:*') is pirop('n_mod') { ... }
+
+proto 'term:' is tighter('infix:*')
+ is parsed(&cast_expression) { ... }
+
+
+rule postfix_expression_prefix {
+ | <primary_expression> {*} #= primary_expression
+ | '(' <type_name> ')' '{' <initializer_list> [',']? '}' {*} #= type_name
+}
+
+rule postfix_expression {
+ <postfix_expression_prefix>
+ <postfix_expression_suffix>*
+ {*}
+}
+
+rule postfix_expression_suffix {
+ | <index> {*} #= index
+ | <arguments> {*} #= arguments
+ | <direct_field> {*} #= direct_field
+ | <indirect_field> {*} #= indirect_field
+ | <inc_or_dec> {*} #= inc_or_dec
+}
+
+rule inc_or_dec {
+ $<op>=['++'|'--']
+ {*}
+}
+
+rule index {
+ '[' <expression> ']'
+ {*}
+}
+
+rule direct_field {
+ '.' <identifier>
+ {*}
+}
+
+rule indirect_field {
+ '->' <identifier>
+ {*}
+}
+
+rule arguments {
+ '(' <argument_expression_list>? ')'
+ {*}
+}
+
+rule argument_expression_list {
+ <assignment_expression> [',' <assignment_expression>]*
+ {*}
+}
+
+rule unary_expression {
+ | <postfix_expression> {*} #= postfix_expression
+ | <prefix_expression> {*} #= prefix_expression
+ | <unary_operator> <cast_expression>
+ | 'sizeof' <unary_expression>
+ | 'sizeof' '(' <type_name> ')'
+}
+
+rule prefix_expression {
+ $<op>=['++'|'--'] <unary_expression>
+ {*}
+}
+
+rule unary_operator {
+ '&' | '*' | '+' | '-' | '~' | '!'
+}
+
+rule cast_expression {
+ ['(' <type_name> ')']* <unary_expression>
+ {*}
+}
+
+rule primary_expression {
+ | <identifier> {*} #= identifier
+ | <constant> {*} #= constant
+ | <c_string_literal> {*} #= c_string_literal
+ | '(' <expression> ')' {*} #= expression
+}
+
+token pound { '#' }
+token begincomment { '/*' }
+
+token multilinecomment { '/*' .*? '*/' }
+
+
+regex preprocessing_token {
+# | <multilinecomment>
+ | <header_name>
+ | <identifier>
+ | <pp_number>
+ | <character_constant>
+ | '"' <string_literal: '"'> '"'
+ | <!pound> <!begincomment> <punctuator>
+ | <universal_character_name>
+ | <!begincomment><-[# \t\r\n]>\S* ## <-[#]-\S>\S* ##non-whitespace
+}
+
+## A.1.2 Keywords
+##
+token keyword {
+ [ auto | enum | restrict | unsigned
+ | break | extern | return | void
+ | case | float | short | volatile
+ | char | for | signed | while
+ | const | goto | sizeof | _Bool
+ | continue | if | static | _Complex
+ | default | inline | struct | _Imaginary
+ | do | int | switch
+ | double | long | typedef
+ | else | register | union ]>>
+}
+
+token reserved_word {
+ <keyword>
+}
+
+token identifier {
+ <!reserved_word>
+ <identifier_nondigit> [ <identifier_nondigit> | <digit> ]*
+ {*}
+}
+
+token identifier_nondigit {
+ <alpha> | <[_]> | <universal_character_name>
+}
+
+token character_constant { [L]? \' <c_char>+ \' }
+
+token <c_char> { <-['\\\n]> | <escape_sequence> }
+
+## A.1.4 Universal character names
+##
+token universal_character_name {
+ | '\u' <xdigit>**{4}
+ | '\U' <xdigit>**{8}
+}
+
+
+## A.1.7 Punctuators
+##
+
+token punctuator {
+ | \[ | \] | <[(){}.]> | '->'
+ | '++' | '--' | <[&*+\-~!/%]>
+ | '<<' | '>>' | '<' | '>'
+ | '<=' | '>=' | '==' | '!='
+ | <[^|]> | '&&' | '||'
+ | <[?:;]> | '...'
+ | <[*/%+\-&^|]> | '<<' | '>>' | '='
+ | <[,#]> | '##'
+ | '<:' | ':>' | '<%' | '%>' | '%:' | '%:%:'
+}
+
+## A.3 Preprocessing directives
+##
+
+rule pre_processing_file {
+ <group>?
+}
+
+rule group {
+ <group_part>+
+}
+
+rule group_part {
+ | <pp_tokens>? <newline>
+ | <if_section>
+ | <control_line>
+}
+
+rule if_section {
+ <if_group> <elif_group>* <else_group>? <endif_line>
+}
+
+rule if_group {
+ | '#' 'if' <constant_expression> <newline> <group>?
+ | '#' 'ifdef' <identifier> <newline> <group>?
+ | '#' 'ifndef' <identifier> <newline> <group>?
+}
+
+rule elif_group {
+ '#' 'elif' <constant_expression> <newline> <group>?
+}
+
+rule else_group {
+ '#' 'else' <newline> <group>?
+}
+
+rule endif_line {
+ '#' 'endif' <newline>
+}
+
+rule control_line {
+ | '#' 'include' <pp_tokens> <newline>
+ | '#' 'define' <identifier> <replacement_list> <newline>
+ | '#' 'define' <identifier> <lparen> <identifier_list>? ')' <replacement_list> <newline>
+ | '#' 'define' <identifier> <lparen> '...' ')' <replacement_list> <newline>
+ | '#' 'define' <identifier> <lparen> <identifier_list> ',' '...' ')' <replacement_list> <newline>
+ | '#' 'undef' <identifier> <newline>
+ | '#' 'line' <pp_tokens> <newline>
+ | '#' 'error' <pp_tokens>? <newline>
+ | '#' 'pragma' <pp_tokens>? <newline>
+ | '#' <newline>
+}
+
+rule pp_tokens { [ <preprocessing_token> ]+ }
+
+token pp_number {
+ ['.']? <digit> <pp_number_suffix>*
+}
+
+token pp_number_suffix {
+ | '.'
+ | <identifier_nondigit>
+ | <digit>
+ | <[eEpP]> ['+'|'-']
+}
+
+rule replacement_list {
+ <pp_tokens>?
+}
+
+token lparen { '(' }
+
+token newline { \n }
+
+## A.1.8 Header names
+token header_name {
+ | \< <h_char>+ \>
+ | \" <q_char>+ \"
+}
+
+token h_char { <-[\n>]> }
+token q_char { <-[\n"]> }
Added: c99/trunk/src/cpp/t/comment_01.t
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/src/cpp/t/comment_01.t Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1 @@
+/*hello */
Added: c99/trunk/src/cpp/t/cpp_0.t
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/src/cpp/t/cpp_0.t Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1 @@
+#define L1 1
Added: c99/trunk/src/cpp/t/harness
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/src/cpp/t/harness Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1,7 @@
+#!/usr/bin/perl
+
+# $Id: harness 26906 2008-04-10 19:45:40Z bernhard $
+
+use FindBin;
+use lib qw( . lib ../lib ../../lib ../../lib ../../../../lib );
+use Parrot::Test::Harness language => 'c99', exec => [ '../../../../parrot', './', 'cpp.pbc' ] ;
Added: c99/trunk/src/cpp/t/spi.t
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/src/cpp/t/spi.t Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1,158 @@
+/*-------------------------------------------------------------------------
+ *
+ * spi.h
+ * Server Programming Interface public declarations
+ *
+ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $PostgreSQL$
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef SPI_H
+#define SPI_H
+
+/*
+ * This file may be used by client modules that haven't already
+ * included postgres.h
+ */
+#include "postgres.h"
+
+/*
+ * Most of these are not needed by this file, but may be used by
+ * user-written code that uses SPI
+ */
+#include "access/heapam.h"
+#include "access/xact.h"
+#include "catalog/pg_language.h"
+#include "catalog/pg_proc.h"
+#include "catalog/pg_type.h"
+#include "executor/execdefs.h"
+#include "executor/executor.h"
+#include "nodes/execnodes.h"
+#include "nodes/params.h"
+#include "nodes/parsenodes.h"
+#include "nodes/plannodes.h"
+#include "nodes/primnodes.h"
+#include "nodes/relation.h"
+#include "tcop/dest.h"
+#include "tcop/pquery.h"
+#include "tcop/tcopprot.h"
+#include "tcop/utility.h"
+#include "utils/builtins.h"
+#include "utils/datum.h"
+#include "utils/portal.h"
+#include "utils/syscache.h"
+
+
+typedef struct SPITupleTable
+{
+ MemoryContext tuptabcxt; /* memory context of result table */
+ uint32 alloced; /* # of alloced vals */
+ uint32 free; /* # of free vals */
+ TupleDesc tupdesc; /* tuple descriptor */
+ HeapTuple *vals; /* tuples */
+} SPITupleTable;
+
+/* Plans are opaque structs for standard users of SPI */
+typedef struct _SPI_plan *SPIPlanPtr;
+
+#define SPI_ERROR_CONNECT (-1)
+#define SPI_ERROR_COPY (-2)
+#define SPI_ERROR_OPUNKNOWN (-3)
+#define SPI_ERROR_UNCONNECTED (-4)
+#define SPI_ERROR_CURSOR (-5) /* not used anymore */
+#define SPI_ERROR_ARGUMENT (-6)
+#define SPI_ERROR_PARAM (-7)
+#define SPI_ERROR_TRANSACTION (-8)
+#define SPI_ERROR_NOATTRIBUTE (-9)
+#define SPI_ERROR_NOOUTFUNC (-10)
+#define SPI_ERROR_TYPUNKNOWN (-11)
+
+#define SPI_OK_CONNECT 1
+#define SPI_OK_FINISH 2
+#define SPI_OK_FETCH 3
+#define SPI_OK_UTILITY 4
+#define SPI_OK_SELECT 5
+#define SPI_OK_SELINTO 6
+#define SPI_OK_INSERT 7
+#define SPI_OK_DELETE 8
+#define SPI_OK_UPDATE 9
+#define SPI_OK_CURSOR 10
+#define SPI_OK_INSERT_RETURNING 11
+#define SPI_OK_DELETE_RETURNING 12
+#define SPI_OK_UPDATE_RETURNING 13
+
+extern PGDLLIMPORT uint32 SPI_processed;
+extern PGDLLIMPORT Oid SPI_lastoid;
+extern PGDLLIMPORT SPITupleTable *SPI_tuptable;
+extern PGDLLIMPORT int SPI_result;
+
+extern int SPI_connect(void);
+extern int SPI_finish(void);
+extern void SPI_push(void);
+extern void SPI_pop(void);
+extern void SPI_restore_connection(void);
+extern int SPI_execute(const char *src, bool read_only, long tcount);
+extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls,
+ bool read_only, long tcount);
+extern int SPI_exec(const char *src, long tcount);
+extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls,
+ long tcount);
+extern int SPI_execute_snapshot(SPIPlanPtr plan,
+ Datum *Values, const char *Nulls,
+ Snapshot snapshot,
+ Snapshot crosscheck_snapshot,
+ bool read_only, bool fire_triggers, long tcount);
+extern int SPI_execute_with_args(const char *src,
+ int nargs, Oid *argtypes,
+ Datum *Values, const char *Nulls,
+ bool read_only, long tcount);
+extern SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes);
+extern SPIPlanPtr SPI_prepare_cursor(const char *src, int nargs, Oid *argtypes,
+ int cursorOptions);
+extern SPIPlanPtr SPI_saveplan(SPIPlanPtr plan);
+extern int SPI_freeplan(SPIPlanPtr plan);
+
+extern Oid SPI_getargtypeid(SPIPlanPtr plan, int argIndex);
+extern int SPI_getargcount(SPIPlanPtr plan);
+extern bool SPI_is_cursor_plan(SPIPlanPtr plan);
+extern const char *SPI_result_code_string(int code);
+
+extern HeapTuple SPI_copytuple(HeapTuple tuple);
+extern HeapTupleHeader SPI_returntuple(HeapTuple tuple, TupleDesc tupdesc);
+extern HeapTuple SPI_modifytuple(Relation rel, HeapTuple tuple, int natts,
+ int *attnum, Datum *Values, const char *Nulls);
+extern int SPI_fnumber(TupleDesc tupdesc, const char *fname);
+extern char *SPI_fname(TupleDesc tupdesc, int fnumber);
+extern char *SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber);
+extern Datum SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull);
+extern char *SPI_gettype(TupleDesc tupdesc, int fnumber);
+extern Oid SPI_gettypeid(TupleDesc tupdesc, int fnumber);
+extern char *SPI_getrelname(Relation rel);
+extern char *SPI_getnspname(Relation rel);
+extern void *SPI_palloc(Size size);
+extern void *SPI_repalloc(void *pointer, Size size);
+extern void SPI_pfree(void *pointer);
+extern void SPI_freetuple(HeapTuple pointer);
+extern void SPI_freetuptable(SPITupleTable *tuptable);
+
+extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan,
+ Datum *Values, const char *Nulls, bool read_only);
+extern Portal SPI_cursor_open_with_args(const char *name,
+ const char *src,
+ int nargs, Oid *argtypes,
+ Datum *Values, const char *Nulls,
+ bool read_only, int cursorOptions);
+extern Portal SPI_cursor_find(const char *name);
+extern void SPI_cursor_fetch(Portal portal, bool forward, long count);
+extern void SPI_cursor_move(Portal portal, bool forward, long count);
+extern void SPI_scroll_cursor_fetch(Portal, FetchDirection direction, long count);
+extern void SPI_scroll_cursor_move(Portal, FetchDirection direction, long count);
+extern void SPI_cursor_close(Portal portal);
+
+extern void AtEOXact_SPI(bool isCommit);
+extern void AtEOSubXact_SPI(bool isCommit, SubTransactionId mySubid);
+
+#endif /* SPI_H */
Added: c99/trunk/src/parser/actions.pm
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/src/parser/actions.pm Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1,378 @@
+# $Id: actions.pm 36833 2009-02-17 20:09:26Z allison $
+# Copyright (C) 2008, Parrot Foundation.
+
+=begin comments
+
+C99::Grammar::Actions - ast transformations for C99
+
+This file contains the methods that are used by the parse grammar
+to build the PAST representation of an C 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.
+
+=end comments
+
+class C99::Grammar::Actions;
+
+method TOP($/) {
+ for $<external_declaration> {
+ my $fun := $( $_ );
+
+ ## Look for the "main" function, and set that as the result
+ ## object.
+ if $fun.name() eq 'main' {
+ make $fun;
+ }
+ }
+}
+
+method external_declaration($/, $key) {
+ make $( $/{$key} );
+}
+
+method declaration($/) {
+ my $past := PAST::Stmts.new( :node($/) );
+
+ for $<init_declarator> {
+ $past.push( $( $_ ) );
+ }
+ make $past;
+}
+
+method init_declarator($/) {
+ make $( $<declarator> );
+}
+
+method function_definition($/) {
+ my $past := PAST::Block.new( :blocktype('declaration'), :node($/) );
+ my $decl := $( $<declarator> );
+ $past.name( $decl.name() );
+
+ my $body := $( $<compound_statement> );
+ $past.push($body);
+ make $past;
+}
+
+method declaration($/) {
+
+}
+
+method declarator($/) {
+ make $( $<direct_declarator> );
+}
+
+method direct_declarator($/) {
+ my $past := $( $<declarator_prefix> );
+ #my $past := $( $<declarator_suffix>[0] );
+ #$past.name($pref.name());
+ make $past;
+}
+
+method declarator_prefix($/, $key) {
+ make $( $/{$key} );
+}
+
+method declarator_suffix($/, $key) {
+ make $( $/{$key} );
+}
+
+method parameter_type_list($/) {
+ my $past := $( $<parameter_list> );
+ if $<vararg> {
+ $past.push( PAST::Var.new( :name('@vararg'), :slurpy(1), :scope('parameter'), :node($/) ) );
+ }
+ make $past;
+}
+
+method parameter_list($/) {
+ ## create the function block here already; it's needed to store the parameters
+ my $past := PAST::Block.new( :blocktype('declaration'), :node($/) );
+ for $<parameter_declaration> {
+ $past.push( $( $_ ) );
+ }
+ make $past;
+}
+
+method parameter_declaration($/, $key) {
+ make $( $/{$key} );
+}
+
+method statement($/, $key) {
+ make $( $/{$key} );
+}
+
+method jump_statement($/, $key) {
+ if $key eq 'return' {
+ my $past := PAST::Op.new( :pirop('return'), :node($/) );
+ if $<expression> {
+ $past.push( $( $<expression>[0] ) );
+ }
+ make $past;
+ }
+ else {
+ $/.panic("$key is not implemented!");
+ }
+}
+
+method for1_statement($/) {
+ my $past := PAST::Stmts.new( :node($/) );
+ my $body := $( $<statement> );
+ my $cond;
+ if $<cond> {
+ $cond := $( $<cond>[0] );
+ }
+ else { # a missing condition is true
+ $cond := PAST::Val.new( :returns('Integer'), :value('1'), :node($/) );
+ }
+
+
+
+ if $<init> {
+ my $init := $( $<init>[0] );
+ $past.unshift($init);
+ }
+
+
+ if $<step> {
+ my $step := $( $<step>[0] );
+ $body := PAST::Stmts.new( $body, $step, :node($/) );
+ }
+ my $loop := PAST::Op.new( $cond, $body, :pasttype('while'), :node($/) );
+ $past.push($loop);
+
+ make $past;
+}
+
+method for2_statement($/) {
+ my $past := PAST::Block.new( :blocktype('immediate'), :node($/) );
+ my $loop := PAST::Op.new( :pasttype('while'), :node($/) );
+
+ $past.push( $( $<declaration> ) );
+ my $body := $( $<statement> );
+
+ if $<step> {
+ my $step := $( $<step>[0] );
+ }
+ my $cond;
+ if $<cond> {
+ $cond := $( $<cond>[0] );
+ }
+ else {
+ $cond := PAST::Val.new( :returns('Integer'), :value('1'), :node($/) );
+ }
+ $loop.push($cond);
+ $loop.push($body);
+
+ $past.push($loop);
+ make $past;
+}
+
+method expression($/) {
+ if +$<assignment_expression> != 1 {
+ my $past := PAST::Stmts.new( :node($/) );
+ for $<assignment_expression> {
+ $past.push( $( $_ ) );
+ }
+ make $past;
+ }
+ else {
+ make $( $<assignment_expression>[0] );
+ }
+}
+
+method expression_statement($/) {
+ if $<expression> {
+ make $( $<expression>[0] );
+ }
+ else {
+ make PAST::Op.new( :inline(' # empty statement'), :node($/) );
+ }
+}
+
+method compound_statement($/) {
+ my $past := PAST::Block.new( :blocktype('immediate'), :node($/) );
+ #my $past := PAST::Stmts.new( :node($/) );
+ for $<block_item> {
+ $past.push( $($_) );
+ }
+ make $past;
+}
+
+method if_statement($/) {
+ my $cond := $( $<expression> );
+ my $then := $( $<statement> );
+ my $past := PAST::Op.new( $cond, $then, :pasttype('if'), :node($/) );
+ if $<else> {
+ $past.push( $( $<else>[0] ) );
+ }
+ make $past;
+}
+
+method do_while_statement($/) {
+ my $cond := $( $<expression> );
+ my $body := $( $<statement> );
+ make PAST::Op.new( $cond, $body, :pasttype('repeat_while'), :node($/) );
+}
+
+method while_statement($/) {
+ my $cond := $( $<expression> );
+ my $body := $( $<statement> );
+ make PAST::Op.new( $cond, $body, :pasttype('while'), :node($/) );
+}
+
+method block_item($/, $key) {
+ make $( $/{$key} );
+}
+
+method constant($/, $key) {
+ make $( $/{$key} );
+}
+
+method constant_expression($/) {
+ make $( $<conditional_expression> );
+}
+
+method assignment_expression($/) {
+ make $( $<conditional_expression> );
+}
+
+method conditional_expression($/) {
+ my $cond := $( $<logical_expression> );
+ if $<expression> {
+ my $then := $( $<expression>[0] );
+ my $else := $( $<conditional_expression>[0] );
+ make PAST::Op.new( $cond, $then, $else, :pasttype('if'), :node($/) );
+ }
+ else {
+ make $cond;
+ }
+}
+
+method postfix_expression_prefix($/, $key) {
+ make $( $/{$key} );
+}
+
+method postfix_expression_suffix($/, $key) {
+ make $( $/{$key} );
+}
+
+method index($/) {
+ my $expr := $( $<expression> );
+ ## XXX
+ make PAST::Op.new( $expr, :name('xxx_index'), :pasttype('call'), :node($/) );
+}
+
+method direct_field($/) {
+ my $field := $( $<identifier> );
+ ## XXX
+ make PAST::Op.new( $field, :name('xxx_get_field'), :pasttype('call'), :node($/) );
+}
+
+method indirect_field($/) {
+ my $field := $( $<identifier> );
+ ## XXX
+ make PAST::Op.new( $field, :name('xxx_get_indirect'), :pasttype('call'), :node($/) );
+}
+
+method inc_or_dec($/) {
+ my $opname := 'postfix:' ~ ~$<op>;
+ my $past := PAST::Op.new( :name($opname), :pasttype('call'), :node($/) );
+ make $past;
+}
+
+method arguments($/) {
+ if $<argument_expression_list> {
+ make $( $<argument_expression_list>[0] );
+ }
+ else {
+ make PAST::Op.new( :pasttype('call'), :node($/) );
+ }
+}
+
+method argument_expression_list($/) {
+ my $past := PAST::Op.new( :pasttype('call'), :node($/) );
+ for $<assignment_expression> {
+ $past.push( $( $_ ) );
+ }
+ make $past;
+}
+
+method postfix_expression($/) {
+ my $past := $( $<postfix_expression_prefix> );
+ for $<postfix_expression_suffix> {
+ ## XXX
+ my $args := $( $_ );
+ $args.unshift($past);
+ $past := $args;
+ }
+ make $past;
+}
+
+method prefix_expression($/) {
+ my $opname := 'prefix:' ~ ~$<op>;
+ my $expr := $( $<unary_expression> );
+ make PAST::Op.new( $expr, :name($opname), :pasttype('call'), :node($/) );
+}
+
+method primary_expression($/, $key) {
+ make $( $/{$key} );
+}
+
+method unary_expression($/, $key) {
+ make $( $/{$key} );
+}
+
+method integer_constant($/) {
+ make PAST::Val.new( :value( ~$/ ), :returns('Integer'), :node($/) );
+}
+
+method floating_constant($/) {
+ make PAST::Val.new( :value( ~$/ ), :returns('Float'), :node($/) );
+}
+
+
+method c_string_literal($/) {
+ make PAST::Val.new( :value( ~$<string_literal> ), :node($/) );
+ #make PAST::Val.new( :value( ~$/ ), :node($/) );
+}
+
+method identifier($/) {
+ ## XXX fix scopes
+ ## XXX fix declarations so that :viviself can be removed
+ make PAST::Var.new( :name( ~$/ ), :scope('package'), :viviself('Integer'), :node($/) );
+}
+
+method cast_expression($/) {
+ make $( $<unary_expression> );
+}
+
+method logical_expression($/, $key) {
+ if ($key eq 'end') {
+ make $($<expr>);
+ }
+ else {
+ my $past := PAST::Op.new( :name($<type>),
+ :pasttype($<top><pasttype>),
+ :pirop($<top><pirop>),
+ :lvalue($<top><lvalue>),
+ :node($/)
+ );
+ for @($/) {
+ $past.push( $($_) );
+ }
+ make $past;
+ }
+
+}
+
+
+# Local Variables:
+# mode: cperl
+# cperl-indent-level: 4
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4:
+
Added: c99/trunk/src/parser/grammar.pg
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/src/parser/grammar.pg Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1,769 @@
+# $Id: grammar.pg 36833 2009-02-17 20:09:26Z allison $
+# Copyright (C) 2008, Parrot Foundation.
+
+=begin overview
+
+This is the grammar for C99 written as a sequence of Perl 6 rules.
+
+
+taken from n869.pdf
+google for n869.pdf
+
+=end overview
+
+grammar C99::Grammar is PCT::Grammar;
+
+## A.2.4 External definitions
+##
+
+token TOP {
+ ^
+ <external_declaration>+
+ [ $ || <.panic: Syntax error> ]
+ {*}
+}
+
+rule external_declaration {
+ | <declaration> {*} #= declaration
+ | <function_definition> {*} #= function_definition
+}
+
+rule function_definition {
+ <declaration_specifiers>
+ <declarator>
+ <declaration>*
+ <compound_statement>
+ {*}
+}
+
+
+## A.2.2
+##
+
+rule declaration {
+ <declaration_specifiers>
+ [ <init_declarator> [',' <init_declarator>]* ]?
+ ';'
+ {*}
+}
+
+rule declaration_specifiers {
+ [ <type_specifier>
+ | <storage_class_specifier>
+ | <type_qualifier>
+ | <function_specifier>
+ ]+
+}
+
+rule function_specifier {
+ 'inline'
+}
+
+rule init_declarator {
+ <declarator> ['=' <initializer>]?
+ {*}
+}
+
+rule storage_class_specifier {
+ | 'typedef'
+ | 'extern'
+ | 'static'
+ | 'auto'
+ | 'register'
+}
+
+rule type_specifier {
+ | <builtin_type>
+ | <struct_or_union_specifier>
+ | <enum_specifier>
+ | <typedef_name>
+}
+
+token builtin_type {
+ | 'void'
+ | 'char'
+ | 'short'
+ | 'int'
+ | 'long'
+ | 'float'
+ | 'double'
+ | 'signed'
+ | 'unsigned'
+ | '_Bool'
+ | '_Complex'
+ | '_Imaginary'
+}
+
+rule struct_or_union_specifier {
+ $<type>=['struct'|'union']
+ [
+ | <struct_or_union_definition>
+ | <pre_declaration>
+ ]
+}
+
+rule struct_or_union_definition {
+ <identifier>? '{' <struct_declaration>+ '}'
+}
+
+rule pre_declaration {
+ <identifier>
+}
+
+rule struct_declaration {
+ <specifier_qualifier_list> <struct_declarator_list>* ';'
+}
+
+rule specifier_qualifier_list {
+ [
+ | <type_specifier>
+ | <type_qualifier>
+ ]+
+}
+
+rule struct_declarator_list {
+ <struct_declarator> [',' <struct_declarator>]*
+}
+
+rule struct_declarator {
+ | <declarator>? ':' <constant_expression>
+ | <declarator>
+}
+
+rule enum_specifier {
+ | 'enum' <identifier>? '{' <enumerator_list> [',']? '}'
+ | 'enum' <identifier>
+}
+
+rule enumerator_list {
+ <enumerator> [',' <enumerator>]*
+}
+
+rule enumerator {
+ <enumeration_constant> ['=' <constant_expression>]?
+}
+
+rule type_qualifier {
+ $<qualifier>=['const'|'restrict'|'volatile']
+}
+
+rule declarator {
+ <pointer>?
+ <direct_declarator>
+ {*}
+}
+
+rule direct_declarator {
+ <declarator_prefix>
+ <declarator_suffix>*
+ {*}
+}
+
+rule declarator_prefix {
+ | '(' <declarator> ')' {*} #= declarator
+ | <identifier> {*} #= identifier
+}
+
+rule declarator_suffix {
+ | '(' <parameter_type_list> ')' {*} #= parameter_type_list
+ ## old-style C parameter declarations
+ | '(' <identifier_list>? ')' {*} #= identifier_list
+ | '[' <assignment_expression>? ']'
+ | '[' '*' ']'
+}
+
+rule pointer {
+ '*' <type_qualifier>* ['*']?
+}
+
+rule parameter_type_list {
+ <parameter_list> [$<vararg>=[',' '...']]?
+ {*}
+}
+
+rule parameter_list {
+ <parameter_declaration> [',' <parameter_declaration>]*
+ {*}
+}
+
+rule parameter_declaration {
+ <declaration_specifiers>
+ [
+ | <declarator> {*} #= declarator
+ | <abstract_declarator>? {*} #= abstract_declarator
+ ]
+}
+
+rule identifier_list {
+ <identifier> [',' <identifier>]*
+}
+
+rule type_name {
+ <specifier_qualifier_list> <abstract_declarator>?
+}
+
+rule abstract_declarator {
+ | '*'
+ | ['*']? <direct_abstract_declarator>
+}
+
+rule direct_abstract_declarator {
+ [
+ | '(' <abstract_declatator> ')'
+ | '[' <assignment_expression>? ']'
+ | '(' <parameter_type_list> ')'
+ ]
+ <direct_abstract_declarator_1>*
+}
+
+rule direct_abstract_declarator_1 {
+ | '[' <assignment_expression>? ']'
+ | '[' '*' ']'
+ | '(' <parameter_type_list> ')'
+}
+
+rule typedef_name {
+
+## a typedef name can be a return type specifier. This is ambiguous, because
+## the parser doesn't know if it's a return type thingie or the name of the
+## function. Therefore, typedef'd names must be stored in a %hash, so that
+## this rule is not calling <identifier>, but inspecting the registered
+## typedef'd names. For now, specify 'SOME_TYPEDEF_NAME' as the only typedef'd name.
+##
+ #<identifier>
+ 'SOME_TYPEDEF_NAME'
+}
+
+rule initializer {
+ | <assignment_expression>
+ | '{' <initializer_list> [',']? '}'
+}
+
+rule initializer_list {
+ <initializer_item> [',' <initializer_item>]*
+}
+
+rule initializer_item {
+ <designation>? <initializer>
+}
+
+rule designation {
+ <designator>+ '='
+}
+
+rule designator {
+ | '[' <constant_expression> ']'
+ | '.' <identifier>
+}
+
+
+## A.2.3 Statements
+##
+
+rule statement {
+ | <labeled_statement>
+ | <compound_statement> {*} #= compound_statement
+ | <expression_statement> {*} #= expression_statement
+ | <if_statement> {*} #= if_statement
+ | <switch_statement>
+ | <while_statement> {*} #= while_statement
+ | <do_while_statement> {*} #= do_while_statement
+ | <for1_statement> {*} #= for1_statement
+ | <for2_statement> {*} #= for2_statement
+ | <jump_statement> {*} #= jump_statement
+}
+
+rule labeled_statement {
+ | <identifier> ':' <statement>
+ | 'case' <constant_expression> ':' <statement>
+ | 'default' ':' <statement>
+}
+
+rule compound_statement {
+ '{' <block_item>* '}'
+ {*}
+}
+
+rule block_item {
+ | <declaration> {*} #= declaration
+ | <statement> {*} #= statement
+}
+
+rule expression_statement {
+ <expression>? ';'
+ {*}
+}
+
+rule if_statement {
+ 'if' '(' <expression> ')' <statement> ['else' $<else>=<statement>]?
+ {*}
+}
+
+rule switch_statement {
+ 'switch' '(' <expression> ')' <statement>
+}
+
+rule while_statement {
+ 'while' '(' <expression> ')' <statement>
+ {*}
+}
+
+rule do_while_statement {
+ 'do' <statement> 'while' '(' <expression> ')' ';'
+ {*}
+}
+
+rule for1_statement {
+ 'for' '(' [$<init>=<expression>]? ';' [$<cond>=<expression>]? ';' [$<step>=<expression>]? ')'
+ <statement>
+ {*}
+}
+
+rule for2_statement {
+ 'for' '(' <declaration> [$<cond>=<expression>]? ';' [$<step>=<expression>]? ')' <statement>
+ {*}
+}
+
+rule jump_statement {
+ | 'goto' <identifier> ';' {*} #= goto
+ | 'continue' ';' {*} #= continue
+ | 'break' ';' {*} #= break
+ | 'return' <expression>? ';' {*} #= return
+}
+
+
+## A.1.1 Lexical elements
+##
+##rule token {
+## | <keyword>
+## | <identifier>
+## | <constant>
+## | <c_string_literal>
+## | <punctuator>
+##}
+
+regex preprocessing_token {
+ | <header_name>
+ | <identifier>
+ | <pp_number>
+ | <character_constant>
+ | <string_literal>
+ | <!pound> <punctuator>
+ | <universal_character_name>
+ | <-[# \r\n\t]>\S* ## <-[#]-\S>\S* ##non-whitespace
+}
+
+## A.1.2 Keywords
+##
+token keyword {
+ [ auto | enum | restrict | unsigned
+ | break | extern | return | void
+ | case | float | short | volatile
+ | char | for | signed | while
+ | const | goto | sizeof | _Bool
+ | continue | if | static | _Complex
+ | default | inline | struct | _Imaginary
+ | do | int | switch
+ | double | long | typedef
+ | else | register | union ]>>
+
+}
+
+token reserved_word {
+ <keyword>
+}
+
+
+token identifier {
+ <!reserved_word>
+ <identifier_nondigit> [ <identifier_nondigit> | <digit> ]*
+ {*}
+}
+
+token identifier_nondigit {
+ <alpha> | <[_]> | <universal_character_name>
+}
+
+## A.1.4 Universal character names
+##
+token universal_character_name {
+ | '\u' <xdigit>**{4}
+ | '\U' <xdigit>**{8}
+}
+
+
+## A.1.5 Constants
+##
+token constant {
+ | <floating_constant> {*} #= floating_constant
+ | <integer_constant> {*} #= integer_constant
+ | <enumeration_constant> {*} #= enumeration_constant
+ | <character_constant> {*} #= character_constant
+}
+
+token integer_constant {
+ [ <decimal_constant>
+ | <octal_constant>
+ | <hexadecimal_constant>
+ ]
+ <integer_suffix>?
+ {*}
+}
+
+token decimal_constant {
+ <[1..9]> <digit>*
+}
+
+token octal_constant {
+ 0 <[0..7]>*
+}
+
+token hexadecimal_constant {
+ 0 <[xX]> <xdigit>+
+}
+
+token integer_suffix {
+ | <[uU]> [ll?|LL?]?
+ | [ll?|LL?] <[uU]>?
+}
+
+token floating_constant {
+ [
+ | <decimal_floating_constant>
+ | <hexadecimal_floating_constant>
+ ]
+ {*}
+}
+
+token decimal_floating_constant {
+ [
+ | <fractional_constant> <exponent_part>?
+ | <digit_sequence> <exponent_part>
+ ]
+ <floating_suffix>?
+}
+
+token hexadecimal_prefix {
+ 0 <[xX]>
+}
+
+token hexadecimal_floating_constant {
+ <hexadecimal_prefix>
+ [
+ | <hexadecimal_fractional_constant>
+ | <hexadecimal_digit_constant>
+ ]
+ <binary_exponent_part> <floating_suffix>?
+}
+
+token fractional_constant {
+ | <digit_sequence>? \. <digit_sequence>
+ | <digit_sequence> \.
+}
+
+token exponent_part {
+ <[eE]> ['+'|'-']? <digit_sequence>
+}
+
+token digit_sequence { <digit>+ }
+
+token hexadecimal_fractional_constant {
+ | <hexadecimal_digit_sequence>? \. <hexadecimal_digit_sequence>
+ | <hexadecimal_digit_sequence> \.
+}
+
+token binary_exponent_part {
+ <[pP]> ['+'|'-']? <digit_sequence>
+}
+
+token hexadecimal_digit_sequence { <xdigit>+ }
+
+token floating_suffix { <[fFlL]> }
+
+token enumeration_constant { <identifier> }
+
+token character_constant { [L]? \' <c_char>+ \' }
+
+token <c_char> { <-['\\\n]> | <escape_sequence> }
+
+token escape_sequence {
+ \\
+ [ <['"?\\abfnrtv]>
+ | <octal_digit>**{1..3}
+ | x <xdigit>+
+ | <universal_character_name>
+ ]
+}
+
+## A.1.6 String literals
+token c_string_literal {
+ [L]? <string_literal: '"'>
+ {*}
+}
+
+##\" <s_char>* \"
+
+token s_char { <-["\\\n]> | <escape_sequence> }
+
+
+## A.2 Phrase structure grammar
+##
+
+## A.2.1 Expressions
+##
+
+rule constant_expression {
+ <conditional_expression>
+ {*}
+}
+
+rule expression {
+ <assignment_expression> [',' <assignment_expression>]*
+ {*}
+}
+
+rule assignment_expression {
+ [<unary_expression> <assign_op>]* <conditional_expression>
+ {*}
+}
+
+rule assign_op { '='|'*='|'/='|'%='|'+='|'-='|'<<='|'>>='|'&='|'^='|'|=' }
+
+rule conditional_expression {
+ <logical_expression> ['?' <expression> ':' <conditional_expression>]?
+ {*}
+}
+
+rule logical_expression is optable { ... }
+
+proto 'infix:||' is precedence('1') { ... }
+
+proto 'infix:&&' is tighter('infix:||') { ... }
+
+proto 'infix:|' is tighter('infix:&&') { ... }
+
+proto 'infix:^' is tighter('infix:|') { ... }
+
+proto 'infix:&' is tighter('infix:^') { ... }
+
+proto 'infix:==' is tighter('infix:&') { ... }
+proto 'infix:!=' is equal('infix:==') { ... }
+
+proto 'infix:<' is tighter('infix:==') { ... }
+proto 'infix:>' is equal('infix:<') { ... }
+proto 'infix:>=' is equal('infix:<') { ... }
+proto 'infix:<=' is equal('infix:<') { ... }
+
+proto 'infix:<<' is tighter('infix:==') { ... }
+proto 'infix:>>' is equal('infix:<<') { ... }
+
+proto 'infix:+' is tighter('infix:<<') is pirop('n_add') { ... }
+proto 'infix:-' is equal('infix:+') is pirop('n_sub') { ... }
+
+proto 'infix:*' is tighter('infix:+') is pirop('n_mul') { ... }
+proto 'infix:/' is equal('infix:*') is pirop('n_div') { ... }
+proto 'infix:%' is equal('infix:*') is pirop('n_mod') { ... }
+
+proto 'term:' is tighter('infix:*')
+ is parsed(&cast_expression) { ... }
+
+
+rule postfix_expression_prefix {
+ | <primary_expression> {*} #= primary_expression
+ | '(' <type_name> ')' '{' <initializer_list> [',']? '}' {*} #= type_name
+}
+
+rule postfix_expression {
+ <postfix_expression_prefix>
+ <postfix_expression_suffix>*
+ {*}
+}
+
+rule postfix_expression_suffix {
+ | <index> {*} #= index
+ | <arguments> {*} #= arguments
+ | <direct_field> {*} #= direct_field
+ | <indirect_field> {*} #= indirect_field
+ | <inc_or_dec> {*} #= inc_or_dec
+}
+
+rule inc_or_dec {
+ $<op>=['++'|'--']
+ {*}
+}
+
+rule index {
+ '[' <expression> ']'
+ {*}
+}
+
+rule direct_field {
+ '.' <identifier>
+ {*}
+}
+
+rule indirect_field {
+ '->' <identifier>
+ {*}
+}
+
+rule arguments {
+ '(' <argument_expression_list>? ')'
+ {*}
+}
+
+rule argument_expression_list {
+ <assignment_expression> [',' <assignment_expression>]*
+ {*}
+}
+
+rule unary_expression {
+ | <postfix_expression> {*} #= postfix_expression
+ | <prefix_expression> {*} #= prefix_expression
+ | <unary_operator> <cast_expression>
+ | 'sizeof' <unary_expression>
+ | 'sizeof' '(' <type_name> ')'
+}
+
+rule prefix_expression {
+ $<op>=['++'|'--'] <unary_expression>
+ {*}
+}
+
+rule unary_operator {
+ '&' | '*' | '+' | '-' | '~' | '!'
+}
+
+rule cast_expression {
+ ['(' <type_name> ')']* <unary_expression>
+ {*}
+}
+
+rule primary_expression {
+ | <identifier> {*} #= identifier
+ | <constant> {*} #= constant
+ | <c_string_literal> {*} #= c_string_literal
+ | '(' <expression> ')' {*} #= expression
+}
+
+token ws {
+ [
+ | '//' \N* \n
+ | '/*' .*? '*/'
+ | \s+
+ | '#' \N* \n
+ ]*
+}
+
+## A.1.7 Punctuators
+##
+
+token punctuator {
+ | \[ | \] | <[(){}.]> | '->'
+ | '++' | '--' | <[&*+\-~!/%]>
+ | '<<' | '>>' | '<' | '>'
+ | '<=' | '>=' | '==' | '!='
+ | <[^|]> | '&&' | '||'
+ | <[?:;]> | '...'
+ | <[*/%+\-&^|]> | '<<' | '>>' | '='
+ | <[,#]> | '##'
+ | '<:' | ':>' | '<%' | '%>' | '%:' | '%:%:'
+}
+
+
+## A.3 Preprocessing directives
+##
+
+rule pre_processing_file {
+ <group>?
+}
+
+rule group {
+ <group_part>+
+}
+
+rule group_part {
+ | <pp_tokens>? <newline>
+ | <if_section>
+ | <control_line>
+}
+
+rule if_section {
+ <if_group> <elif_group>* <else_group>? <endif_line>
+}
+
+rule if_group {
+ | '#' 'if' <constant_expression> <newline> <group>?
+ | '#' 'ifdef' <identifier> <newline> <group>?
+ | '#' 'ifndef' <identifier> <newline> <group>?
+}
+
+rule elif_group {
+ '#' 'elif' <constant_expression> <newline> <group>?
+}
+
+rule else_group {
+ '#' 'else' <newline> <group>?
+}
+
+rule endif_line {
+ '#' 'endif' <newline>
+}
+
+rule control_line {
+ | '#' 'include' <pp_tokens> <newline>
+ | '#' 'define' <identifier> <replacement_list> <newline>
+ | '#' 'define' <identifier> <lparen> <identifier_list>? ')' <replacement_list> <newline>
+ | '#' 'define' <identifier> <lparen> '...' ')' <replacement_list> <newline>
+ | '#' 'define' <identifier> <lparen> <identifier_list> ',' '...' ')' <replacement_list> <newline>
+ | '#' 'undef' <identifier> <newline>
+ | '#' 'line' <pp_tokens> <newline>
+ | '#' 'error' <pp_tokens>? <newline>
+ | '#' 'pragma' <pp_tokens>? <newline>
+ | '#' <newline>
+}
+
+rule pp_tokens {
+ <preprocessing_token>+
+}
+
+rule preprocessing_token {
+ | <header_name>
+ | <identifier>
+ | <pp_number>
+ | <character_constant>
+ | <c_string_literal>
+ | <punctuator>
+}
+
+rule pp_number {
+ ['.']? <digit> <pp_number_suffix>*
+}
+
+rule pp_number_suffix {
+ | '.'
+ | <identifier_nondigit>
+ | <digit>
+ | <[eEpP]> ['+'|'-']
+}
+
+rule replacement_list {
+ <pp_tokens>?
+}
+
+token lparen {
+ '('
+}
+
+token newline {
+ \n
+}
+
+## A.1.8 Header names
+token header_name {
+ | \< <h_char>+ \>
+ | \" <q_char>+ \"
+}
+
+token h_char { <-[\n>]> }
+token q_char { <-[\n"]> }
Added: c99/trunk/src/preamble
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/src/preamble Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1,96 @@
+.macro kdump ( x )
+ .local pmc it
+ it = get_root_global ['parrot'], '_dumper'
+ it(.x)
+.endm
+
+.macro kdump2 ( x, d)
+ .local pmc it
+ it = get_root_global ['parrot'], '_dumper'
+ it(.x, .d)
+.endm
+
+.macro dump_root
+ .local string it
+ .local pmc ns
+ ns = get_root_namespace [ 'parrot'; 'Cardinal::Grammar' ]
+ .local pmc iter
+ iter = new 'Iterator', ns
+ set iter, 0
+ .label $iter_loop:
+ unless iter, .$iter_end
+ shift it, iter
+ print it
+ print "\n"
+ goto .$iter_loop
+ .label $iter_end:
+.endm
+
+.macro dump_hll
+ .local string it
+ .local pmc ns
+ ns = get_hll_namespace
+ .local pmc iter
+ iter = new 'Iterator', ns
+ set iter, 0
+ .label $iter_loop:
+ unless iter, .$iter_end
+ shift it, iter
+ print it
+ print "\n"
+ goto .$iter_loop
+ .label $iter_end:
+.endm
+
+.macro dump_hll2
+ .local string it
+ .local pmc ns
+ ns = get_hll_namespace
+ .local pmc iter
+ iter = new 'Iterator', ns
+ set iter, 0
+ .label $iter_loop:
+ unless iter, .$iter_end
+ shift it, iter
+ print it
+ print "\n"
+ goto .$iter_loop
+ .label $iter_end:
+.endm
+
+.macro dump_current
+ .local string it
+ .local pmc ns
+ ns = get_namespace
+ .local pmc iter
+ iter = new 'Iterator', ns
+ set iter, 0
+ .label $iter_loop:
+ unless iter, .$iter_end
+ shift it, iter
+ print it
+ print "\n"
+ goto .$iter_loop
+ .label $iter_end:
+.endm
+
+.macro gen_accessor(x)
+.sub .x :method
+ .param pmc value :optional
+ .param int has_value :opt_flag
+ .return self.'attr'(.x, value, has_value)
+.end
+.endm
+
+.macro gen_get_accessor(x)
+.sub .x :method
+ null $P0
+ .return self.'attr'(.x, $P0, 0)
+.end
+.endm
+
+.macro gen_dumplist(x)
+.sub '__dumplist' :method
+ .return (.x)
+.end
+.endm
Added: c99/trunk/t/harness
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/t/harness Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1,7 @@
+#!/usr/bin/perl
+
+# $Id: harness 25985 2008-02-22 12:22:13Z kjs $
+
+use FindBin;
+use lib qw( . lib ../lib ../../lib ../../lib );
+use Parrot::Test::Harness language => 'c99', compiler => 'c99.pbc';
Added: c99/trunk/t/spi.t
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ c99/trunk/t/spi.t Tue Mar 10 23:43:32 2009 (r20)
@@ -0,0 +1,33 @@
+
+
+
+void main() {
+ puts("1..6");
+ puts("ok 1");
+
+ if (0)
+ puts("nok 2");
+ else {
+ puts("ok 2");
+ }
+
+
+ if (1) {
+ puts("ok 3");
+ }
+ else
+ puts("nok 3");
+
+ do {
+ puts("ok 4");
+ }
+ while(0);
+
+ while(0) {
+ puts("nok 5");
+ }
+ puts("ok 5");
+
+ 1 ? puts("ok 6") : puts("nok 6");
+}
+
More information about the parrot-commits
mailing list