develooper Front page | perl.cvs.parrot | Postings from January 2009

[svn:parrot] r35329 - in trunk/languages/ecmascript: . config/makefiles src/classes src/parser t/js_pt

From:
tewk
Date:
January 9, 2009 20:09
Subject:
[svn:parrot] r35329 - in trunk/languages/ecmascript: . config/makefiles src/classes src/parser t/js_pt
Message ID:
20090110040856.67F45CB9F9@x12.develooper.com
Author: tewk
Date: Fri Jan  9 20:08:55 2009
New Revision: 35329

Added:
   trunk/languages/ecmascript/src/classes/Array.pir
Modified:
   trunk/languages/ecmascript/config/makefiles/root.in
   trunk/languages/ecmascript/js.pir
   trunk/languages/ecmascript/src/classes/Object.pir
   trunk/languages/ecmascript/src/parser/actions.pm
   trunk/languages/ecmascript/src/parser/grammar.pg
   trunk/languages/ecmascript/t/js_pt/09-array_literals.t

Log:
[js] Objects and Arrays starting to construct

Modified: trunk/languages/ecmascript/config/makefiles/root.in
==============================================================================
--- trunk/languages/ecmascript/config/makefiles/root.in	(original)
+++ trunk/languages/ecmascript/config/makefiles/root.in	Fri Jan  9 20:08:55 2009
@@ -42,6 +42,7 @@
   src/gen_actions.pir \
   src/builtin/builtins.pir \
   src/classes/Object.pir \
+  src/classes/Array.pir \
   src/classes/Null.pir \
   src/classes/Boolean.pir \
   src/classes/Number.pir \

Modified: trunk/languages/ecmascript/js.pir
==============================================================================
--- trunk/languages/ecmascript/js.pir	(original)
+++ trunk/languages/ecmascript/js.pir	Fri Jan  9 20:08:55 2009
@@ -81,6 +81,7 @@
 
 .include 'src/builtin/builtins.pir'
 .include 'src/classes/Object.pir'
+.include 'src/classes/Array.pir'
 .include 'src/classes/Boolean.pir'
 .include 'src/classes/Null.pir'
 #.include 'src/classes/Number.pir'

Added: trunk/languages/ecmascript/src/classes/Array.pir
==============================================================================
--- (empty file)
+++ trunk/languages/ecmascript/src/classes/Array.pir	Fri Jan  9 20:08:55 2009
@@ -0,0 +1,346 @@
+## $Id$
+
+=head1 TITLE
+
+Object - JS Array class
+
+=head1 DESCRIPTION
+
+This file sets up the base classes and methods for JS's
+object system.  Differences (and conflicts) between Parrot's
+object model and the JS model means we have to do a little
+name and method trickery here and there, and this file takes
+care of much of that.
+
+=cut
+
+.namespace []
+.sub '' :anon :init :load
+    .local pmc jsmeta
+    load_bytecode 'PCT.pbc'
+    $P0 = get_root_global ['parrot'], 'P6metaclass'
+    $P0.'new_class'('JSArray', 'parent'=>'JSObject')
+    jsmeta = $P0.'HOW'()
+    set_hll_global ['JSArray'], '$!JSMETA', jsmeta
+.end
+
+=head2 Methods
+
+=over 4
+
+=item clone()
+
+Returns a copy of the object.
+
+NOTE: Don't copy what this method does; it's a tad inside-out. We should be
+overriding the clone vtable method to call .clone() really. But if we do that,
+we can't current get at the Object PMC's clone method, so for now we do it
+like this.
+
+=cut
+
+.namespace ['JSArray']
+.sub 'Set' :method
+    .param pmc key
+    .param pmc val
+    self[key] = val
+    .return(self)
+.end
+
+.namespace ['JSArray']
+.sub 'Get' :method
+    .param pmc key
+    .local pmc val
+    val = self[key]
+    .return(val)
+.end
+
+.namespace ['JSArray']
+.sub 'clone' :method
+    .param pmc new_attrs :slurpy :named
+
+    # Make a clone.
+    .local pmc result
+    $I0 = isa self, 'ObjectRef'
+    unless $I0 goto do_clone
+    self = deref self
+  do_clone:
+    result = clone self
+
+    # Set any new attributes.
+    .local pmc it
+    it = iter new_attrs
+  it_loop:
+    unless it goto it_loop_end
+    $S0 = shift it
+    $P0 = new_attrs[$S0]
+    $S0 = concat '!', $S0
+    $P1 = result.$S0()
+    'infix:='($P1, $P0)
+    goto it_loop
+  it_loop_end:
+
+    .return (result)
+.end
+
+
+=item defined()
+
+Return true if the object is defined.
+
+=cut
+
+.namespace ['JSArray']
+.sub 'defined' :method
+    $P0 = get_hll_global ['Bool'], 'True'
+    .return ($P0)
+.end
+
+
+=item hash
+
+Return invocant in hash context.
+
+=cut
+
+.namespace ['JSArray']
+.sub 'hash' :method
+    .tailcall self.'Hash'()
+.end
+
+.namespace []
+.sub 'hash'
+    .param pmc values :slurpy
+    .tailcall values.'Hash'()
+.end
+
+=item item
+
+Return invocant in item context.  Default is to return self.
+
+=cut
+
+.namespace ['JSArray']
+.sub 'item' :method
+    .return (self)
+.end
+
+.namespace []
+.sub 'item'
+    .param pmc x               :slurpy
+    $I0 = elements x
+    unless $I0 == 1 goto have_x
+    x = shift x
+  have_x:
+    $I0 = can x, 'item'
+    unless $I0 goto have_item
+    x = x.'item'()
+  have_item:
+    .return (x)
+.end
+
+
+=item list
+
+Return invocant in list context.  Default is to return a List containing self.
+
+=cut
+
+.namespace ['JSArray']
+.sub 'list' :method
+    $P0 = new 'List'
+    push $P0, self
+    .return ($P0)
+.end
+
+=item print()
+
+Print the object.
+
+=cut
+
+.namespace ['JSArray']
+.sub 'print' :method
+    $P0 = get_hll_global 'print'
+    .tailcall $P0(self)
+.end
+
+=item say()
+
+Print the object, followed by a newline.
+
+=cut
+
+.namespace ['JSArray']
+.sub 'say' :method
+    $P0 = get_hll_global 'say'
+    .tailcall $P0(self)
+.end
+
+=item true()
+
+Boolean value of object -- defaults to C<.defined> (S02).
+
+=cut
+
+.namespace ['JSArray']
+.sub 'true' :method
+    .tailcall self.'defined'()
+.end
+
+=back
+
+=head2 Coercion methods
+
+=over 4
+
+=item Array()
+
+=cut
+
+.namespace ['JSArray']
+.sub 'Array' :method
+    $P0 = new 'JSArray'
+    $P0.'!STORE'(self)
+    .return ($P0)
+.end
+
+=item Hash()
+
+=cut
+
+.namespace ['JSArray']
+.sub 'Hash' :method
+    $P0 = new 'JSHash'
+    $P0.'!STORE'(self)
+    .return ($P0)
+.end
+
+=item Iterator()
+
+=cut
+
+.sub 'Iterator' :method
+    $P0 = self.'list'()
+    .tailcall $P0.'Iterator'()
+.end
+
+=item Scalar()
+
+Default Scalar() gives reference type semantics, returning
+an object reference (unless the invocant already is one).
+
+=cut
+
+.namespace ['JSArray']
+.sub '' :method('Scalar') :anon
+    $I0 = isa self, 'ObjectRef'
+    unless $I0 goto not_ref
+    .return (self)
+  not_ref:
+    $P0 = new 'ObjectRef', self
+    .return ($P0)
+.end
+
+.namespace []
+.sub 'Scalar'
+    .param pmc source
+    $I0 = isa source, 'ObjectRef'
+    if $I0 goto done
+    $I0 = can source, 'Scalar'
+    if $I0 goto can_scalar
+    $I0 = does source, 'scalar'
+    source = new 'ObjectRef', source
+  done:
+    .return (source)
+  can_scalar:
+    .tailcall source.'Scalar'()
+.end
+
+=item Str()
+
+Return a string representation of the invocant.  Default is
+the object's type and address.
+
+=cut
+
+.namespace ['JSArray']
+.sub 'Str' :method
+    $P0 = new 'ResizableStringArray'
+    $P1 = self.'WHAT'()
+    push $P0, $P1
+    $I0 = get_addr self
+    push $P0, $I0
+    #$S0 = sprintf "[object Object %s 0x%x]", $P0
+    $S0 = sprintf "[object Object]", $P0
+    .return ($S0)
+.end
+
+=back
+
+=head2 Special methods
+
+=over 4
+
+=item new()
+
+Create a new object having the same class as the invocant.
+
+=cut
+
+.namespace ['JSArray']
+.sub 'new' :method
+    .param pmc init_parents :slurpy
+    .param pmc init_this    :named :slurpy
+
+    # Instantiate.
+    .local pmc jsmeta
+    jsmeta = get_hll_global ['JSArray'], '$!JSMETA'
+    $P0 = jsmeta.'get_parrotclass'(self)
+    $P1 = new $P0
+    .return ($P1)
+.end
+
+=back
+
+=head2 Vtable functions
+
+=cut
+
+.namespace ['JSArray']
+.sub '' :vtable('decrement') :method
+    $P0 = self.'pred'()
+    'infix:='(self, $P0)
+    .return(self)
+.end
+
+.sub '' :vtable('defined') :method
+    $I0 = self.'defined'()
+    .return ($I0)
+.end
+
+.sub '' :vtable('get_bool') :method
+    $I0 = self.'true'()
+    .return ($I0)
+.end
+
+.sub '' :vtable('get_iter') :method
+    .tailcall self.'Iterator'()
+.end
+
+.sub '' :vtable('get_string') :method
+    $S0 = self.'Str'()
+    .return ($S0)
+.end
+
+.sub '' :vtable('increment') :method
+    $P0 = self.'succ'()
+    'infix:='(self, $P0)
+    .return(self)
+.end
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: trunk/languages/ecmascript/src/classes/Object.pir
==============================================================================
--- trunk/languages/ecmascript/src/classes/Object.pir	(original)
+++ trunk/languages/ecmascript/src/classes/Object.pir	Fri Jan  9 20:08:55 2009
@@ -19,7 +19,7 @@
     .local pmc jsmeta
     load_bytecode 'PCT.pbc'
     $P0 = get_root_global ['parrot'], 'P6metaclass'
-    $P0.'new_class'('JSObject')
+    $P0.'new_class'('JSObject', 'parent'=>'Hash')
     jsmeta = $P0.'HOW'()
     set_hll_global ['JSObject'], '$!JSMETA', jsmeta
 .end
@@ -40,6 +40,22 @@
 =cut
 
 .namespace ['JSObject']
+.sub 'Set' :method
+    .param pmc key
+    .param pmc val
+    self[key] = val
+    .return(self)
+.end
+
+.namespace ['JSObject']
+.sub 'Get' :method
+    .param pmc key
+    .local pmc val
+    val = self[key]
+    .return(val)
+.end
+
+.namespace ['JSObject']
 .sub 'clone' :method
     .param pmc new_attrs :slurpy :named
 
@@ -255,7 +271,8 @@
     push $P0, $P1
     $I0 = get_addr self
     push $P0, $I0
-    $S0 = sprintf "%s<0x%x>", $P0
+    #$S0 = sprintf "[object Object %s 0x%x]", $P0
+    $S0 = sprintf "[object Object]", $P0
     .return ($S0)
 .end
 
@@ -281,6 +298,20 @@
     jsmeta = get_hll_global ['JSObject'], '$!JSMETA'
     $P0 = jsmeta.'get_parrotclass'(self)
     $P1 = new $P0
+    .return ($P1)
+.end
+
+.sub 'old_new' :method
+    .param pmc init_parents :slurpy
+    .param pmc init_this    :named :slurpy
+
+    # Instantiate.
+    .local pmc jsmeta
+    jsmeta = get_hll_global ['JSObject'], '$!JSMETA'
+    $P0 = jsmeta.'get_parrotclass'(self)
+    $P1 = new $P0
+    goto no_whence
+    #.return ($P1)
 
     # If this proto object has a WHENCE auto-vivification, we should use
     # put any values it contains but that init_this does not into init_this.
@@ -408,7 +439,7 @@
 
     # Is it a Hash? If so, initialize to JSHash.
     if sigil != '%' goto no_hash
-    $P3 = new 'JSHash'
+    $P3 = new 'Hash'
     $I0 = defined $P2
     if $I0 goto have_hash_value
     set $P2, $P3

Modified: trunk/languages/ecmascript/src/parser/actions.pm
==============================================================================
--- trunk/languages/ecmascript/src/parser/actions.pm	(original)
+++ trunk/languages/ecmascript/src/parser/actions.pm	Fri Jan  9 20:08:55 2009
@@ -682,32 +682,25 @@
     my $past := PAST::Stmts.new( :node($/) );
 
     my $type := PAST::Var.new( :name('JSObject'), :scope('package'), :node($/) );
-    my $obj := PAST::Op.new( :pasttype('callmethod'), :name("new"), :node($/), $type);
+    my $objvar := PAST::Var.new(:scope('register'), :name('obj'));
+    $past.push( 
+        PAST::Op.new(:pasttype('bind'), 
+          PAST::Var.new(:scope('register'), :name('obj'), :isdecl(1)),
+          PAST::Op.new( :pasttype('callmethod'), :name("new"), :node($/), $type),
+          :node($/)));
 
     for $<property> {
-        $($_).unshift($obj);
-        $past.push( $($_) );
+      $($_).unshift($objvar);
+      $past.push( $($_) );
     }
+    $past.push($objvar);
     make $past;
 }
 
 method property($/) {
-    ## TODO: a property is a key/value pair. The value must be passed as a parameter
-    ## and passed as a :named parameter using the key as a name.
-    ##
-    ## XXX figure out whether this is the way to go, or to use "setattribute", so use
-    ## parrot's actual object system instead of hashtables.
-    ##
-    ## How to solve this, as property_name can be a value and a variable (but I think this is
-    ## is supposed to be an auto-quoted identifier). Check manual.
-    ## For now: this is broken, but it's a start.
     my $key  := $( $<property_name> );
-
-    ## XXX my $key  := PAST::Val.new( $prop, :returns('String'), :node($/) );
     my $val  := $( $<assignment_expression> );
-
     my $past := PAST::Op.new( :pasttype('callmethod'), :name('Set'), $key, $val, :node($/) );
-
     make $past;
 }
 
@@ -722,20 +715,51 @@
 }
 
 method array_literal($/) {
-    ## XXX todo
-    my $past := PAST::Op.new( :pasttype('call'), :name('Array'), :node($/) );
+    my $past := PAST::Stmts.new( :node($/) );
 
+    my $type := PAST::Var.new( :name('JSArray'), :scope('package'), :node($/) );
+    my $objvar := PAST::Var.new(:scope('register'), :name('obj'));
+    $past.push( 
+        PAST::Op.new(:pasttype('bind'), 
+          PAST::Var.new(:scope('register'), :name('obj'), :isdecl(1)),
+          PAST::Op.new( :pasttype('callmethod'), :name("new"), :node($/), $type),
+          :node($/)));
+    my $i := 0;
+    for $<assignment_expression> {
+      $past.push( 
+          PAST::Op.new( :pasttype('callmethod'), :name('Set'), $objvar, $i, $($_), :node($/) ));
+      $i := $i + 1;
+    }
+    $past.push($objvar);
     make $past;
 }
 
 method element_list($/) {
-    ## XXX todo
+    print("el\n");
+    my $past := PAST::Stmts.new( :node($/) );
+    for $<assignment_expression> {
+      _dumper($_);
+    }
+    for $<elision> {
+      _dumper($_);
+    }
+    #for $/.list() {
+    #  _dumper($_);
+      #for $_.list() {
+      #  $past.push( $($_) );
+      #}
+    #}
+    make $past;
 }
 
 method elision($/) {
-    ## return number of commas.
-    my $value := +$<comma>;
-    make PAST::Val.new( :value($value), :returns('Integer'), :node($/) );
+    my $past := PAST::Stmts.new( :node($/) );
+    my $undef := PAST::Var.new( :name('undef'), :namespace('JSUndefined'), :scope('package'), :node($/) );
+    
+    for $<comma> {
+      $past.push(PAST::Op.new( :pasttype('callmethod'), :name('append'), $undef, :node($/) ));
+    }
+    make $past;
 }
 
 method str_literal($/) {

Modified: trunk/languages/ecmascript/src/parser/grammar.pg
==============================================================================
--- trunk/languages/ecmascript/src/parser/grammar.pg	(original)
+++ trunk/languages/ecmascript/src/parser/grammar.pg	Fri Jan  9 20:08:55 2009
@@ -304,7 +304,8 @@
 token this { 'this' {*} }
 
 rule array_literal {
-    '[' <elision>? <element_list>? [',' <elision>]?  ']'
+##    '[' <elision>? <element_list>? [',' <elision>]?  ']'
+    '[' <assignment_expression> [',' <assignment_expression>]* ']'
     {*}
 }
 

Modified: trunk/languages/ecmascript/t/js_pt/09-array_literals.t
==============================================================================
--- trunk/languages/ecmascript/t/js_pt/09-array_literals.t	(original)
+++ trunk/languages/ecmascript/t/js_pt/09-array_literals.t	Fri Jan  9 20:08:55 2009
@@ -7,7 +7,7 @@
 use FindBin;
 use lib "$FindBin::Bin/../../../../lib", "$FindBin::Bin/../../lib";
 
-use Parrot::Test tests => 1;
+use Parrot::Test tests => 2;
 
 language_output_is( 'JS', <<'CODE', <<'OUT', 'array literal of strings', todo => 'NOTIMPLEMENTED' );
 var digits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];
@@ -15,6 +15,11 @@
 CODE
 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
 OUT
+language_output_is( 'JS', <<'CODE', <<'OUT', 'array literal of strings', todo => 'elision' );
+var a = [,,,,1,2,,,,,,3,4,,,,,];
+CODE
+0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
+OUT
 
 # Local Variables:
 #   mode: cperl



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About