[svn:parrot] r41128 - in trunk/compilers/data_json: . data_json
japhb at svn.parrot.org
japhb at svn.parrot.org
Mon Sep 7 18:55:19 UTC 2009
Author: japhb
Date: Mon Sep 7 18:55:17 2009
New Revision: 41128
URL: https://trac.parrot.org/parrot/changeset/41128
Log:
[compilers/data_json] Straight copy of compilers/JSON; probably broken right now
Added:
trunk/compilers/data_json/
trunk/compilers/data_json/data_json/
trunk/compilers/data_json/data_json.pir
- copied unchanged from r41126, trunk/compilers/json/JSON.pir
trunk/compilers/data_json/data_json/grammar.pg
- copied unchanged from r41126, trunk/compilers/json/JSON/grammar.pg
trunk/compilers/data_json/data_json/pge2pir.tg
- copied unchanged from r41126, trunk/compilers/json/JSON/pge2pir.tg
Copied: trunk/compilers/data_json/data_json.pir (from r41126, trunk/compilers/json/JSON.pir)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/compilers/data_json/data_json.pir Mon Sep 7 18:55:17 2009 (r41128, copy of r41126, trunk/compilers/json/JSON.pir)
@@ -0,0 +1,83 @@
+# Copyright (C) 2005-2008, Parrot Foundation.
+# $Id$
+
+=head1 NAME
+
+JSON (JavaScript Object Notation) is a lightweight data-interchange format.
+
+=head1 SYNOPSIS
+
+Given a valid JSON string, the compiler will return a PMC containing the
+appropriate values. For example:
+
+ .local pmc JSON
+ JSON = compreg 'JSON'
+ $P0 = JSON('[1,2,3]')
+
+Will create a pmc that C<does> array, contains the values 1, 2, and 3, and
+store it in register C<$P0>.
+
+For more information about the structure of the JSON representation, see the
+documentation at L<http://www.json.org/>.
+
+=cut
+
+.namespace [ 'JSON' ]
+
+.sub '__onload' :load
+ load_bytecode 'PGE.pbc'
+ load_bytecode 'PGE/Util.pbc'
+ load_bytecode 'TGE.pbc'
+
+ load_bytecode 'compilers/json/JSON/grammar.pbc'
+ load_bytecode 'compilers/json/JSON/pge2pir.pbc'
+
+ $P1 = get_global '__compiler'
+ compreg "JSON", $P1
+
+ $P1 = new 'Hash'
+ $P1['\"'] = '"'
+ $P1['\\'] = "\\"
+ $P1['\/'] = '/'
+ $P1['\b'] = "\b"
+ $P1['\f'] = "\f"
+ $P1['\n'] = "\n"
+ $P1['\r'] = "\r"
+ $P1['\t'] = "\t"
+
+ set_root_global [ 'JSON' ], '$escapes', $P1
+.end
+
+.sub '__compiler'
+ .param string json_string
+
+ .local pmc parse, match
+ parse = get_root_global ['parrot'; 'JSON'], 'value'
+
+ $P0 = get_root_global ['parrot'; 'PGE'], 'Match'
+ match = $P0.'new'(json_string)
+ match.'to'(0)
+ match = parse(match)
+ unless match goto failed
+
+ .local pmc pirgrammar, pirbuilder, pir
+ pirgrammar = new ['JSON'; 'PIR']
+ pirbuilder = pirgrammar.'apply'(match)
+ pir = pirbuilder.'get'('result')
+
+ .local pmc pirc, result
+ pirc = compreg "PIR"
+ result = pirc(pir)
+ .tailcall result()
+
+ failed:
+ $P0 = new 'Exception'
+ $P0[0] = "invalid JSON value"
+ throw $P0
+.end
+
+# Local Variables:
+# mode: pir
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:
Copied: trunk/compilers/data_json/data_json/grammar.pg (from r41126, trunk/compilers/json/JSON/grammar.pg)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/compilers/data_json/data_json/grammar.pg Mon Sep 7 18:55:17 2009 (r41128, copy of r41126, trunk/compilers/json/JSON/grammar.pg)
@@ -0,0 +1,38 @@
+# From http://www.json.org/
+
+grammar JSON;
+
+rule object { '{' <members>? '}' }
+rule array { '[' ']' | '[' <elements> ']' }
+rule string { \"<char>*\" }
+
+rule members { <string> ':' <value> [',' <string> ':' <value> ]* }
+
+rule elements { <value> [',' <value> ]* }
+
+token value {
+ | <object>
+ | <array>
+ | <string>
+ | <number>
+ | true
+ | false
+ | null
+ | <?PGE::Util::die 'not a valid JSON value'>
+}
+
+# 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>
+}
Copied: trunk/compilers/data_json/data_json/pge2pir.tg (from r41126, trunk/compilers/json/JSON/pge2pir.tg)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/compilers/data_json/data_json/pge2pir.tg Mon Sep 7 18:55:17 2009 (r41128, copy of r41126, trunk/compilers/json/JSON/pge2pir.tg)
@@ -0,0 +1,210 @@
+grammar JSON::PIR is TGE::Grammar;
+
+transform result (ROOT) {
+ .local pmc pir
+ .local string result
+
+ $S0 = tree.'get'('pir', node, 'value')
+
+ pir = new 'CodeString'
+ pir.'emit'('.sub anon :anon')
+ pir.'emit'($S0)
+ result = node['ret']
+ pir.'emit'(' .return (%0)',result)
+ pir.'emit'('.end')
+
+ .return(pir)
+}
+
+transform pir (value) {
+
+ .local pmc sub_node, transform_result
+ .local pmc pir, result
+ .local string value, type
+
+ type = 'string'
+ sub_node = node[type]
+ unless null sub_node goto got_type
+
+ type = 'number'
+ sub_node = node[type]
+ unless null sub_node goto got_type
+
+ type = 'object'
+ sub_node = node[type]
+ unless null sub_node goto got_type
+
+ type = 'array'
+ sub_node = node[type]
+ unless null sub_node goto got_type
+
+ value = node
+ if value == 'true' goto got_true
+ if value == 'false' goto got_false
+ if value == 'null' goto got_null
+
+ .return ('') # should never reach this.
+
+ got_type:
+ pir = tree.'get'('pir', sub_node, type)
+ $S0 = sub_node['ret']
+ node['ret'] = $S0
+ .return (pir)
+
+ got_true:
+ pir = new 'CodeString'
+ result = pir.'unique'('$P')
+ $S0 = node
+ pir.'emit'(" %0 = new 'Boolean'", result)
+ pir.'emit'(' %0 = 1', result, $S0)
+ node['ret'] = result
+ .return(pir)
+
+ got_false:
+ pir = new 'CodeString'
+ result = pir.'unique'('$P')
+ $S0 = node
+ pir.'emit'(" %0 = new 'Boolean'", result)
+ pir.'emit'(' %0 = 0', result, $S0)
+ node['ret'] = result
+ .return(pir)
+
+ got_null:
+ pir = new 'CodeString'
+ result = pir.'unique'('$P')
+ $S0 = node
+ pir.'emit'(' null %0', result)
+ node['ret'] = result
+ .return(pir)
+}
+
+transform pir (object) {
+ .local pmc pir
+ pir = new 'CodeString'
+ .local string result, child_result, key_result
+ result = pir.'unique'('$P')
+ pir.'emit'(" %0 = new 'Hash'", result)
+
+ .local pmc items
+
+ items = node['members']
+ if null items goto end
+
+ items = items[0]
+
+ .local pmc keys
+ keys = items['string']
+ items = items['value']
+
+ .local pmc it, key_iter, child, key
+ key_iter = iter keys
+ it = iter items
+
+ # the two iters should be in lockstep as a result of the PGE grammar
+loop:
+ unless it goto end
+ child = shift it
+ $P0 = tree.'get'('pir', child, 'value')
+ $S0 = $P0
+ pir .= $S0
+ child_result = child['ret']
+
+ key = shift key_iter
+ $P0 = tree.'get'('pir', key, 'string')
+ $S0 = $P0
+ pir .= $S0
+ key_result = key['ret']
+
+ pir.'emit'(' %0[%1] = %2', result, key_result, child_result)
+
+
+ goto loop
+end:
+ node['ret'] = result
+
+ .return (pir)
+}
+
+transform pir (array) {
+ .local pmc pir
+ pir = new 'CodeString'
+ .local string result, child_result
+ result = pir.'unique'('$P')
+ pir.'emit'(" %0 = new 'ResizablePMCArray'", result)
+
+ .local pmc items
+
+
+ items = node['elements']
+ if null items goto end
+
+ items = items['value']
+
+ .local pmc it, child
+ it = iter items
+loop:
+ unless it goto end
+ child = shift it
+ $P0 = tree.'get'('pir', child, 'value')
+ $S0 = $P0
+ pir .= $S0
+
+ child_result = child['ret']
+ pir.'emit'(' push %0, %1', result, child_result)
+ goto loop
+end:
+ node['ret'] = result
+
+ .return (pir)
+}
+
+transform pir (string) {
+ .local pmc pir, result, children, it, child
+ .local string tmp
+ tmp = ''
+ pir = new 'CodeString'
+ children = node['char']
+ if null children goto loop_end
+ it = iter children
+ loop:
+ push_eh loop_end
+ child = shift it
+ pop_eh
+ unless child goto loop_end
+ $S0 = child
+ $I0 = length $S0
+ if $I0 == 1 goto char
+ if $I0 == 2 goto escape
+ unicode:
+ $P1 = new 'String'
+ $S1 = substr $S0, 2, 4
+ $P1 = $S1
+ $I0 = $P1.'to_int'(16)
+ $S0 = chr $I0
+ goto char
+ escape:
+ $P0 = get_root_global [ 'JSON' ], '$escapes'
+ $S0 = $P0[$S0]
+ char:
+ tmp .= $S0
+ goto loop
+ loop_end:
+
+ result = pir.'unique'('$P')
+ $S1 = pir.'escape'(tmp)
+ pir.'emit'(" %0 = new 'String'", result)
+ pir.'emit'(' %0 = %1', result, $S1)
+ node['ret'] = result
+ .return(pir)
+}
+
+transform pir (number) {
+ .local pmc pir, result
+ pir = new 'CodeString'
+ result = pir.'unique'('$P')
+ $S0 = node
+ pir.'emit'(" %0 = new 'Integer'", result)
+ pir.'emit'(' %0 = %1', result, $S0)
+ node['ret'] = result
+ .return(pir)
+}
More information about the parrot-commits
mailing list