[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