Index: languages/json/json.pir
===================================================================
--- languages/json/json.pir	(revision 0)
+++ languages/json/json.pir	(revision 0)
@@ -0,0 +1,68 @@
+=head1 TITLE
+
+json.pir - A json compiler.
+
+=head2 Description
+
+This is the base file for the json 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 'json'.
+
+=head2 Functions
+
+=over 4
+
+=item onload()
+
+Creates the json compiler using a C<PCT::HLLCompiler>
+object.
+
+=cut
+
+.namespace [ 'json::Compiler' ]
+
+.loadlib 'json_group'
+
+.sub 'onload' :anon :load :init
+    load_bytecode 'PCT.pbc'
+
+    $P0 = get_hll_global ['PCT'], 'HLLCompiler'
+    $P1 = $P0.'new'()
+    $P1.'language'('json')
+    $P1.'parsegrammar'('json::Grammar')
+    $P1.'parseactions'('json::Grammar::Actions')
+.end
+
+=item main(args :slurpy)  :main
+
+Start compilation by passing any command line C<args>
+to the json compiler.
+
+=cut
+
+.sub 'main' :main
+    .param pmc args
+
+    load_bytecode 'dumper.pbc'
+
+    $P0 = compreg 'json'
+    $P1 = $P0.'command_line'(args)
+.end
+
+
+.include 'src/gen_builtins.pir'
+.include 'src/gen_grammar.pir'
+.include 'src/gen_actions.pir'
+
+=back
+
+=cut
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:
+
Index: languages/json/config/makefiles/root.in
===================================================================
--- languages/json/config/makefiles/root.in	(revision 0)
+++ languages/json/config/makefiles/root.in	(revision 0)
@@ -0,0 +1,127 @@
+## $Id$
+
+## arguments we want to run parrot with
+PARROT_ARGS =
+
+## configuration settings
+BUILD_DIR     = @build_dir@
+LOAD_EXT      = @load_ext@
+O             = @o@
+
+## Setup some commands
+LN_S          = @lns@
+PERL          = @perl@
+RM_RF         = @rm_rf@
+CP            = @cp@
+PARROT        = ../../parrot@exe@
+CAT           = $(PERL) -MExtUtils::Command -e cat
+BUILD_DYNPMC  = $(PERL) $(BUILD_DIR)/tools/build/dynpmc.pl
+RECONFIGURE   = $(PERL) $(BUILD_DIR)/tools/dev/reconfigure.pl
+#CONDITIONED_LINE(darwin):
+#CONDITIONED_LINE(darwin):# MACOSX_DEPLOYMENT_TARGET must be defined for OS X compilation/linking
+#CONDITIONED_LINE(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: json.pbc
+
+JSON_GROUP = $(PMC_DIR)/json_group$(LOAD_EXT)
+
+SOURCES = json.pir \
+  src/gen_grammar.pir \
+  src/gen_actions.pir \
+  src/gen_builtins.pir \
+#  $(JSON_GROUP)
+
+BUILTINS_PIR = \
+  src/builtins/say.pir \
+
+# PMCS = json
+# PMC_SOURCES = $(PMC_DIR)/json.pmc
+
+# the default target
+json.pbc: $(PARROT) $(SOURCES)
+	$(PARROT) $(PARROT_ARGS) -o json.pbc json.pir
+
+src/gen_grammar.pir: $(PERL6GRAMMAR) src/parser/grammar.pg src/parser/grammar-oper.pg
+	$(PARROT) $(PARROT_ARGS) $(PERL6GRAMMAR) \
+	    --output=src/gen_grammar.pir \
+	    src/parser/grammar.pg \
+	    src/parser/grammar-oper.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
+
+$(JSON_GROUP): $(PARROT) $(PMC_SOURCES)
+	cd $(PMC_DIR) && $(BUILD_DYNPMC) generate $(PMCS)
+	cd $(PMC_DIR) && $(BUILD_DYNPMC) compile $(PMCS)
+	cd $(PMC_DIR) && $(BUILD_DYNPMC) linklibs $(PMCS)
+	cd $(PMC_DIR) && $(BUILD_DYNPMC) copy --destination=$(PARROT_DYNEXT) $(PMCS)
+
+# regenerate the Makefile
+Makefile: config/makefiles/root.in
+	cd $(BUILD_DIR) && $(RECONFIGURE) --step=gen::languages --languages=json
+
+# 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:               json.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 = \
+  json.pbc \
+  src/gen_grammar.pir \
+  src/gen_actions.pir \
+  src/gen_builtins.pir \
+  $(PMC_DIR)/*.h \
+  $(PMC_DIR)/*.c \
+  $(PMC_DIR)/*.dump \
+  $(PMC_DIR)/*$(O) \
+  $(PMC_DIR)/*$(LOAD_EXT) \
+  $(PMC_DIR)/*.exp \
+  $(PMC_DIR)/*.ilk \
+  $(PMC_DIR)/*.manifest \
+  $(PMC_DIR)/*.pdb \
+  $(PMC_DIR)/*.lib \
+
+
+clean: testclean
+	$(RM_RF) $(CLEANUPS)
+
+realclean: clean
+	$(RM_RF) Makefile
+
+distclean: realclean
+
+
Index: languages/json/config/makefiles/root.in
===================================================================
--- languages/json/config/makefiles/root.in	(revision 0)
+++ languages/json/config/makefiles/root.in	(revision 0)
@@ -0,0 +1,127 @@
+## $Id$
+
+## arguments we want to run parrot with
+PARROT_ARGS =
+
+## configuration settings
+BUILD_DIR     = @build_dir@
+LOAD_EXT      = @load_ext@
+O             = @o@
+
+## Setup some commands
+LN_S          = @lns@
+PERL          = @perl@
+RM_RF         = @rm_rf@
+CP            = @cp@
+PARROT        = ../../parrot@exe@
+CAT           = $(PERL) -MExtUtils::Command -e cat
+BUILD_DYNPMC  = $(PERL) $(BUILD_DIR)/tools/build/dynpmc.pl
+RECONFIGURE   = $(PERL) $(BUILD_DIR)/tools/dev/reconfigure.pl
+#CONDITIONED_LINE(darwin):
+#CONDITIONED_LINE(darwin):# MACOSX_DEPLOYMENT_TARGET must be defined for OS X compilation/linking
+#CONDITIONED_LINE(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: json.pbc
+
+JSON_GROUP = $(PMC_DIR)/json_group$(LOAD_EXT)
+
+SOURCES = json.pir \
+  src/gen_grammar.pir \
+  src/gen_actions.pir \
+  src/gen_builtins.pir \
+#  $(JSON_GROUP)
+
+BUILTINS_PIR = \
+  src/builtins/say.pir \
+
+# PMCS = json
+# PMC_SOURCES = $(PMC_DIR)/json.pmc
+
+# the default target
+json.pbc: $(PARROT) $(SOURCES)
+	$(PARROT) $(PARROT_ARGS) -o json.pbc json.pir
+
+src/gen_grammar.pir: $(PERL6GRAMMAR) src/parser/grammar.pg src/parser/grammar-oper.pg
+	$(PARROT) $(PARROT_ARGS) $(PERL6GRAMMAR) \
+	    --output=src/gen_grammar.pir \
+	    src/parser/grammar.pg \
+	    src/parser/grammar-oper.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
+
+$(JSON_GROUP): $(PARROT) $(PMC_SOURCES)
+	cd $(PMC_DIR) && $(BUILD_DYNPMC) generate $(PMCS)
+	cd $(PMC_DIR) && $(BUILD_DYNPMC) compile $(PMCS)
+	cd $(PMC_DIR) && $(BUILD_DYNPMC) linklibs $(PMCS)
+	cd $(PMC_DIR) && $(BUILD_DYNPMC) copy --destination=$(PARROT_DYNEXT) $(PMCS)
+
+# regenerate the Makefile
+Makefile: config/makefiles/root.in
+	cd $(BUILD_DIR) && $(RECONFIGURE) --step=gen::languages --languages=json
+
+# 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:               json.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 = \
+  json.pbc \
+  src/gen_grammar.pir \
+  src/gen_actions.pir \
+  src/gen_builtins.pir \
+  $(PMC_DIR)/*.h \
+  $(PMC_DIR)/*.c \
+  $(PMC_DIR)/*.dump \
+  $(PMC_DIR)/*$(O) \
+  $(PMC_DIR)/*$(LOAD_EXT) \
+  $(PMC_DIR)/*.exp \
+  $(PMC_DIR)/*.ilk \
+  $(PMC_DIR)/*.manifest \
+  $(PMC_DIR)/*.pdb \
+  $(PMC_DIR)/*.lib \
+
+
+clean: testclean
+	$(RM_RF) $(CLEANUPS)
+
+realclean: clean
+	$(RM_RF) Makefile
+
+distclean: realclean
+
+
Index: languages/json/json.pir
===================================================================
--- languages/json/json.pir	(revision 0)
+++ languages/json/json.pir	(revision 0)
@@ -0,0 +1,68 @@
+=head1 TITLE
+
+json.pir - A json compiler.
+
+=head2 Description
+
+This is the base file for the json 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 'json'.
+
+=head2 Functions
+
+=over 4
+
+=item onload()
+
+Creates the json compiler using a C<PCT::HLLCompiler>
+object.
+
+=cut
+
+.namespace [ 'json::Compiler' ]
+
+.loadlib 'json_group'
+
+.sub 'onload' :anon :load :init
+    load_bytecode 'PCT.pbc'
+
+    $P0 = get_hll_global ['PCT'], 'HLLCompiler'
+    $P1 = $P0.'new'()
+    $P1.'language'('json')
+    $P1.'parsegrammar'('json::Grammar')
+    $P1.'parseactions'('json::Grammar::Actions')
+.end
+
+=item main(args :slurpy)  :main
+
+Start compilation by passing any command line C<args>
+to the json compiler.
+
+=cut
+
+.sub 'main' :main
+    .param pmc args
+
+    load_bytecode 'dumper.pbc'
+
+    $P0 = compreg 'json'
+    $P1 = $P0.'command_line'(args)
+.end
+
+
+.include 'src/gen_builtins.pir'
+.include 'src/gen_grammar.pir'
+.include 'src/gen_actions.pir'
+
+=back
+
+=cut
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:
+
Index: languages/json/src/builtins/say.pir
===================================================================
--- languages/json/src/builtins/say.pir	(revision 0)
+++ languages/json/src/builtins/say.pir	(revision 0)
@@ -0,0 +1,29 @@
+# $Id$
+
+=head1
+
+say.pir -- simple implementation of a say function
+
+=cut
+
+.namespace []
+
+.sub '!array'
+    .param pmc args            :slurpy
+    .return (args)
+.end
+
+.sub '!hash'
+    .param pmc args            :slurpy :named
+    .return (args)
+.end
+
+
+
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:
+
Index: languages/json/src/builtins/say.pir
===================================================================
--- languages/json/src/builtins/say.pir	(revision 0)
+++ languages/json/src/builtins/say.pir	(revision 0)
@@ -0,0 +1,29 @@
+# $Id$
+
+=head1
+
+say.pir -- simple implementation of a say function
+
+=cut
+
+.namespace []
+
+.sub '!array'
+    .param pmc args            :slurpy
+    .return (args)
+.end
+
+.sub '!hash'
+    .param pmc args            :slurpy :named
+    .return (args)
+.end
+
+
+
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:
+
Index: languages/json/src/parser/actions.pm
===================================================================
--- languages/json/src/parser/actions.pm	(revision 0)
+++ languages/json/src/parser/actions.pm	(revision 0)
@@ -0,0 +1,110 @@
+# $Id$
+
+=begin comments
+
+json::Grammar::Actions - ast transformations for json
+
+This file contains the methods that are used by the parse grammar
+to build the PAST representation of an json 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 json::Grammar::Actions;
+
+method TOP($/) {
+    my $past := PAST::Block.new( :blocktype('declaration'), :node( $/ ) );
+    for $<value> {
+        ## call _dumper for each value, and the string "JSON" as 2nd argument.
+        my $dumpcall := PAST::Op.new( :pasttype('call'), :name('_dumper'), :node($/));
+        $dumpcall.push( $( $_ ) );
+        $dumpcall.push( PAST::Val.new( :value("JSON")) );
+
+        $past.push( $dumpcall );
+    }
+    make $past;
+}
+
+method object($/) {
+    if $<members> {
+        make $( $<members>[0] );
+    }
+    else {
+        make PAST::Op.new( :name('!hash'), :pasttype('call'), :node($/) );
+    }
+}
+
+method array($/) {
+    if $<elements> {
+        make $( $<elements>[0] );
+    }
+    else {
+        make PAST::Op.new( :name('!array'), :pasttype('call'), :node($/) );
+    }
+}
+
+method elements($/) {
+    ## make use of the Parrot Calling Conventions, using a PIR sub that
+    ## takes a :slurpy parameter, which is in fact a (ResizablePMC)Array object.
+    ## This array constructor is called '!array'.
+    my $past := PAST::Op.new( :name('!array'), :pasttype('call'), :node($/) );
+    for $<value> {
+        $past.push( $( $_ ) );
+    }
+    make $past;
+}
+
+method members($/) {
+    ## make use of the Parrot Calling Conventions, using a PIR sub that
+    ## takes a :slurpy :named parameter, which is in fact a Hash object.
+    ## This hash constructor is called '!hash'.
+    my $past := PAST::Op.new( :name('!hash'), :pasttype('call'), :node($/) );
+    for $<string> {
+        my $key := $( $_ );
+        ## get the value node for the current string:
+        my $val := $( $<value>.shift() );
+        ## set the key as the name for the $val argument to the hash constructor.
+        $val.named($key);
+        $past.push($val);
+    }
+    make $past;
+}
+
+method value($/, $key) {
+    make $( $/{$key} );
+}
+
+method constant($/, $key) {
+    my $past;
+    if $key eq 'null' {
+        $past := PAST::Op.new( :inline('    %r = null') );
+    }
+    elsif $key eq 'false' {
+        $past := PAST::Val.new( :value(0), :returns('Boolean') );
+    }
+    elsif $key eq 'true' {
+        $past := PAST::Val.new( :value(1), :returns('Boolean') );
+    }
+    make $past;
+}
+
+method number($/) {
+    make PAST::Val.new( :value( ~$/ ), :node($/) );
+}
+
+method string($/) {
+    make PAST::Val.new( :value( ~$<characters> ), :node($/) );
+}
+
+
+# Local Variables:
+#   mode: cperl
+#   cperl-indent-level: 4
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4:
+
Index: languages/json/src/parser/grammar.pg
===================================================================
--- languages/json/src/parser/grammar.pg	(revision 0)
+++ languages/json/src/parser/grammar.pg	(revision 0)
@@ -0,0 +1,77 @@
+# $Id$
+
+=begin overview
+
+This is the grammar for json written as a sequence of Perl 6 rules.
+
+From http://www.json.org/
+
+=end overview
+
+grammar json::Grammar is PCT::Grammar;
+
+rule TOP {
+    <value>*
+    [ $ || <.panic: 'end of file expected'> ]
+    {*}
+}
+
+rule object {
+    '{' <members>?  '}'
+    {*}
+}
+
+rule array  {
+    '[' <elements>? ']'
+    {*}
+}
+
+rule string {
+    \"<characters>\"
+    {*}
+}
+
+token characters {
+    <char>*
+}
+
+rule members {
+    <string> ':' <value> [',' <string> ':' <value> ]*
+    {*}
+}
+
+rule elements {
+    <value> [',' <value> ]*
+    {*}
+}
+
+token value {
+    | <object> {*}                  #= object
+    | <array> {*}                   #= array
+    | <string> {*}                  #= string
+    | <number> {*}                  #= number
+    | <constant> {*}                #= constant
+}
+
+token constant {
+    | 'true' {*}      #= true
+    | 'false' {*}     #= false
+    | 'null' {*}      #= null
+}
+
+# XXX need to add "except control char" to the final charclass here.
+token char {
+    | \\<["\\/bfnrt]>
+    | \\u<xdigit>**{4}
+    | <-[\\"]>
+}
+
+token number {
+    <.ws>
+    '-'?
+    [ <[1..9]> <[0..9]>+ | <[0..9]> ]
+    [ '.' <[0..9]>+ ]?
+    [ <[Ee]> <[+\-]>? <[0..9]>+ ]?
+    <.ws>
+    {*}
+}
Index: languages/json/src/parser/grammar-oper.pg
===================================================================
--- languages/json/src/parser/grammar-oper.pg	(revision 0)
+++ languages/json/src/parser/grammar-oper.pg	(revision 0)
@@ -0,0 +1,13 @@
+# $Id$
+
+##  expressions and operators
+proto 'term:'     is precedence('=')     is parsed(&term)      { ... }
+
+## multiplicative operators
+proto infix:<*>   is looser(term:)       is pirop('n_mul')     { ... }
+proto infix:</>   is equiv(infix:<*>)    is pirop('n_div')     { ... }
+
+## additive operators
+proto infix:<+>   is looser(infix:<*>)   is pirop('n_add')     { ... }
+proto infix:<->   is equiv(infix:<+>)    is pirop('n_sub')     { ... }
+
Index: languages/json/src/parser/actions.pm
===================================================================
--- languages/json/src/parser/actions.pm	(revision 0)
+++ languages/json/src/parser/actions.pm	(revision 0)
@@ -0,0 +1,110 @@
+# $Id$
+
+=begin comments
+
+json::Grammar::Actions - ast transformations for json
+
+This file contains the methods that are used by the parse grammar
+to build the PAST representation of an json 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 json::Grammar::Actions;
+
+method TOP($/) {
+    my $past := PAST::Block.new( :blocktype('declaration'), :node( $/ ) );
+    for $<value> {
+        ## call _dumper for each value, and the string "JSON" as 2nd argument.
+        my $dumpcall := PAST::Op.new( :pasttype('call'), :name('_dumper'), :node($/));
+        $dumpcall.push( $( $_ ) );
+        $dumpcall.push( PAST::Val.new( :value("JSON")) );
+
+        $past.push( $dumpcall );
+    }
+    make $past;
+}
+
+method object($/) {
+    if $<members> {
+        make $( $<members>[0] );
+    }
+    else {
+        make PAST::Op.new( :name('!hash'), :pasttype('call'), :node($/) );
+    }
+}
+
+method array($/) {
+    if $<elements> {
+        make $( $<elements>[0] );
+    }
+    else {
+        make PAST::Op.new( :name('!array'), :pasttype('call'), :node($/) );
+    }
+}
+
+method elements($/) {
+    ## make use of the Parrot Calling Conventions, using a PIR sub that
+    ## takes a :slurpy parameter, which is in fact a (ResizablePMC)Array object.
+    ## This array constructor is called '!array'.
+    my $past := PAST::Op.new( :name('!array'), :pasttype('call'), :node($/) );
+    for $<value> {
+        $past.push( $( $_ ) );
+    }
+    make $past;
+}
+
+method members($/) {
+    ## make use of the Parrot Calling Conventions, using a PIR sub that
+    ## takes a :slurpy :named parameter, which is in fact a Hash object.
+    ## This hash constructor is called '!hash'.
+    my $past := PAST::Op.new( :name('!hash'), :pasttype('call'), :node($/) );
+    for $<string> {
+        my $key := $( $_ );
+        ## get the value node for the current string:
+        my $val := $( $<value>.shift() );
+        ## set the key as the name for the $val argument to the hash constructor.
+        $val.named($key);
+        $past.push($val);
+    }
+    make $past;
+}
+
+method value($/, $key) {
+    make $( $/{$key} );
+}
+
+method constant($/, $key) {
+    my $past;
+    if $key eq 'null' {
+        $past := PAST::Op.new( :inline('    %r = null') );
+    }
+    elsif $key eq 'false' {
+        $past := PAST::Val.new( :value(0), :returns('Boolean') );
+    }
+    elsif $key eq 'true' {
+        $past := PAST::Val.new( :value(1), :returns('Boolean') );
+    }
+    make $past;
+}
+
+method number($/) {
+    make PAST::Val.new( :value( ~$/ ), :node($/) );
+}
+
+method string($/) {
+    make PAST::Val.new( :value( ~$<characters> ), :node($/) );
+}
+
+
+# Local Variables:
+#   mode: cperl
+#   cperl-indent-level: 4
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4:
+
Index: languages/json/src/parser/grammar-oper.pg
===================================================================
--- languages/json/src/parser/grammar-oper.pg	(revision 0)
+++ languages/json/src/parser/grammar-oper.pg	(revision 0)
@@ -0,0 +1,13 @@
+# $Id$
+
+##  expressions and operators
+proto 'term:'     is precedence('=')     is parsed(&term)      { ... }
+
+## multiplicative operators
+proto infix:<*>   is looser(term:)       is pirop('n_mul')     { ... }
+proto infix:</>   is equiv(infix:<*>)    is pirop('n_div')     { ... }
+
+## additive operators
+proto infix:<+>   is looser(infix:<*>)   is pirop('n_add')     { ... }
+proto infix:<->   is equiv(infix:<+>)    is pirop('n_sub')     { ... }
+
Index: languages/json/src/parser/grammar.pg
===================================================================
--- languages/json/src/parser/grammar.pg	(revision 0)
+++ languages/json/src/parser/grammar.pg	(revision 0)
@@ -0,0 +1,77 @@
+# $Id$
+
+=begin overview
+
+This is the grammar for json written as a sequence of Perl 6 rules.
+
+From http://www.json.org/
+
+=end overview
+
+grammar json::Grammar is PCT::Grammar;
+
+rule TOP {
+    <value>*
+    [ $ || <.panic: 'end of file expected'> ]
+    {*}
+}
+
+rule object {
+    '{' <members>?  '}'
+    {*}
+}
+
+rule array  {
+    '[' <elements>? ']'
+    {*}
+}
+
+rule string {
+    \"<characters>\"
+    {*}
+}
+
+token characters {
+    <char>*
+}
+
+rule members {
+    <string> ':' <value> [',' <string> ':' <value> ]*
+    {*}
+}
+
+rule elements {
+    <value> [',' <value> ]*
+    {*}
+}
+
+token value {
+    | <object> {*}                  #= object
+    | <array> {*}                   #= array
+    | <string> {*}                  #= string
+    | <number> {*}                  #= number
+    | <constant> {*}                #= constant
+}
+
+token constant {
+    | 'true' {*}      #= true
+    | 'false' {*}     #= false
+    | 'null' {*}      #= null
+}
+
+# XXX need to add "except control char" to the final charclass here.
+token char {
+    | \\<["\\/bfnrt]>
+    | \\u<xdigit>**{4}
+    | <-[\\"]>
+}
+
+token number {
+    <.ws>
+    '-'?
+    [ <[1..9]> <[0..9]>+ | <[0..9]> ]
+    [ '.' <[0..9]>+ ]?
+    [ <[Ee]> <[+\-]>? <[0..9]>+ ]?
+    <.ws>
+    {*}
+}
Index: languages/json/t/harness
===================================================================
--- languages/json/t/harness	(revision 0)
+++ languages/json/t/harness	(revision 0)
@@ -0,0 +1,13 @@
+#! perl
+
+# $Id$
+
+# pragmata
+use strict;
+use warnings;
+use 5.008;
+
+use lib qw( . lib ../lib ../../lib ../../lib );
+use Parrot::Test::Harness language => 'json',
+                          compiler => 'json.pbc';
+
Index: languages/json/t/00-sanity.t
===================================================================
--- languages/json/t/00-sanity.t	(revision 0)
+++ languages/json/t/00-sanity.t	(revision 0)
@@ -0,0 +1,6 @@
+# This just checks that the basic parsing and call to builtin say() works.
+say '1..3';
+say 'ok 1';
+say 'ok ', 2;
+say 'ok ', 2 + 1;
+
Index: languages/json/t/00-sanity.t
===================================================================
--- languages/json/t/00-sanity.t	(revision 0)
+++ languages/json/t/00-sanity.t	(revision 0)
@@ -0,0 +1,6 @@
+# This just checks that the basic parsing and call to builtin say() works.
+say '1..3';
+say 'ok 1';
+say 'ok ', 2;
+say 'ok ', 2 + 1;
+
Index: languages/json/t/harness
===================================================================
--- languages/json/t/harness	(revision 0)
+++ languages/json/t/harness	(revision 0)
@@ -0,0 +1,13 @@
+#! perl
+
+# $Id$
+
+# pragmata
+use strict;
+use warnings;
+use 5.008;
+
+use lib qw( . lib ../lib ../../lib ../../lib );
+use Parrot::Test::Harness language => 'json',
+                          compiler => 'json.pbc';
+
