Changeset 5721
- Timestamp:
- 07/20/05 22:35:24 (3 years ago)
- svk:copy_cache_prev:
- 7696
- Files:
-
- 8 modified
-
lib/pugs/hack.pod (modified) (1 diff)
-
perl5/PIL2JS/README (modified) (8 diffs)
-
perl5/PIL2JS/lib/PIL/Nodes.pm (modified) (6 diffs)
-
perl5/PIL2JS/lib6/Prelude/JS.pm (modified) (9 diffs)
-
perl5/PIL2JS/libjs/PIL2JS.js (modified) (5 diffs)
-
perl5/Perl6-MetaModel/t/80_Code.t (modified) (2 props)
-
src/Pugs/Compile.hs (modified) (1 diff)
-
t/builtins/control_flow/try.t (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
lib/pugs/hack.pod
r5561 r5721 144 144 | |-- Code-Perl Helper module for Perl 5 code generation 145 145 | |-- PIL-Run PIL virtual machine in Perl 5 146 | |-- PIL2JS PIL to JavaScript compiler 146 147 | `-- Perl6-MetaModel Perl 5 Prototype of the Perl 6 Metaclass model 147 148 | -
perl5/PIL2JS/README
r5700 r5721 14 14 . 15 15 |-- pil2js.pl Frontend for the PIL:: modules 16 |-- runjs.pl Compiles Perl 6 to JavaScript and runs it 17 |-- jspugs.pl Interactive shell for PIL2JS development 16 18 |-- lib 17 19 | |-- PIL … … 19 21 | | `-- Nodes.pm Module which provides appropriate ->as_js methods 20 22 | | for the objects returned by PIL::Parser 23 |-- lib6 21 24 | |-- Prelude 22 | | `-- JS.pm JavaScript Prelude, written in Perl 6 25 | | `-- JS.pm Part of the JavaScript Prelude, 26 | | written in Perl 6 27 |-- libjs 28 | `-- PIL2JS.js Part of the JavaScript Prelude, 29 | written in JavaScript 23 30 24 31 =head1 WHAT'S WORKING ALREADY? … … 28 35 =item * 29 36 30 Variables (scalars and arrays)37 Variables (scalars, arrays, and hashes), assignment, binding 31 38 32 39 =item * … … 91 98 function, e.g. C<@array[$idx] := $foo>. 92 99 100 =head2 Identity comparision 101 102 The C<.uid> property which every C<PIL2JS.Box> object has got contains the 103 unique ID of the box (or C<undefined> if it's a C<PIL2JS.Box.Constant>, as we 104 can't map all real numbers and more to a finite C<.uid>). C<< &infix:<=:=> >> 105 can then compare C<this.uid> with C<other.uid>. 106 93 107 =head2 Calling conventions 94 108 … … 100 114 extracted (see C<PIL::Nodes>, package C<PIL::Params>). 101 115 116 Additionally to the arguments passed by the user, the first argument is always 117 a boxed C<PIL2JS.Context> object. Methods expect C<$?SELF> as their second 118 argument. 119 102 120 =head2 Escape continuations 103 121 … … 107 125 // normal body here... 108 126 } catch(err) { 109 if(err instanceof PIL2JS. Exception.ret && this_sublevel >= err.level) {127 if(err instanceof PIL2JS.ControlException.ret && this_sublevel >= err.level) { 110 128 // The return/leave/whatever concerns us, return! 111 129 return err.return_value; … … 119 137 C<&return> can then be simply implemented as: 120 138 121 throw new PIL2JS. Exception.ret(sublevel_to_break_out_of, retval);139 throw new PIL2JS.ControlException.ret(sublevel_to_break_out_of, retval); 122 140 123 C<&last> issimilar.141 C<&last> and C<&next> are similar. 124 142 125 143 =head1 TODO … … 129 147 =item * 130 148 131 Make C<use js:Foo> load C<Foo> from L<JSAN|http://www.openjsan.org/> ?149 Make C<use js:Foo> load C<Foo> from L<JSAN|http://www.openjsan.org/> 132 150 133 151 =item * 134 152 135 Primitives 136 137 =item * 138 139 Better error reporting (with line number etc., should be relatively simple to 140 implement because of C<PPos>) 141 142 =back 153 Primitives! 143 154 144 155 =head1 AUTHOR 145 156 146 Ingo Blechschmidt C<< iblech@web.de>>157 Ingo Blechschmidt C<< <iblech@web.de> >> 147 158 148 159 =head1 LICENSE -
perl5/PIL2JS/lib/PIL/Nodes.pm
r5717 r5721 32 32 } catch(err) { 33 33 PIL2JS.call_chain.pop(); 34 if(err instanceof PIL2JS. Exception.ret && $level >= err.level) {34 if(err instanceof PIL2JS.ControlException.ret && $level >= err.level) { 35 35 return err.return_value; 36 36 } else { … … 517 517 PIL::Nodes::name_mangle($self->[0]), 518 518 PIL::Nodes::doublequote($self->[0]); 519 $js .= sprintf 520 "%s.arity = %d;\n", 521 PIL::Nodes::name_mangle($self->[0]), 522 $self->[2]->arity; 519 523 520 524 # Special magic for methods. … … 554 558 555 559 # Sub declaration 556 return sprintf "new PIL2JS.Box.Constant(function (args) {\n%s\n})", 560 return sprintf "PIL2JS.Box.constant_func(%d, function (args) {\n%s\n})", 561 $self->[1]->arity, 557 562 PIL::Nodes::add_indent 1, PIL::Nodes::generic_catch($IN_SUBLIKE, $body); 558 563 } … … 570 575 571 576 local $_; 572 return sprintf " new PIL2JS.Box.Constant(function (args) { var cxt = args.shift(); return(%s); })",577 return sprintf "PIL2JS.Box.constant_func(0, function (args) { var cxt = args.shift(); return(%s); })", 573 578 $self->[0]->as_js; 574 579 } … … 590 595 my $js; 591 596 $js .= "var cxt = args.shift();\n"; 597 $js .= "args = PIL2JS.possibly_flatten(args);\n"; 592 598 $js .= "var pairs = PIL2JS.grep_for_pairs(args);\n"; 593 599 $js .= $_->as_js1() . "\n" for @$self; … … 607 613 return $js; 608 614 } 615 616 sub arity { 617 local $_; 618 my $arity = 0; 619 $_->is_required and $arity++ for @{ $_[0] }; 620 return $arity; 621 } 609 622 } 610 623 611 624 { 612 625 package PIL::MkTParam; 626 627 sub is_required { $_[0]->{tpParam}{isOptional}->isa("PIL::False") } 613 628 614 629 sub as_js1 { -
perl5/PIL2JS/lib6/Prelude/JS.pm
r5717 r5721 30 30 body(); 31 31 } catch(err) { 32 if(err instanceof PIL2JS. Exception.next) {32 if(err instanceof PIL2JS.ControlException.next) { 33 33 // Ok; 34 34 } else { … … 38 38 } 39 39 } catch(err) { 40 if(err instanceof PIL2JS. Exception.last) {40 if(err instanceof PIL2JS.ControlException.last) { 41 41 return undefined; 42 42 } else { … … 49 49 } 50 50 51 sub JS::Root::last() is primitive { JS::inline "throw(new PIL2JS. Exception.last())"; 1 }52 sub JS::Root::next() is primitive { JS::inline "throw(new PIL2JS. Exception.next())"; 1 }51 sub JS::Root::last() is primitive { JS::inline "throw(new PIL2JS.ControlException.last())"; 1 } 52 sub JS::Root::next() is primitive { JS::inline "throw(new PIL2JS.ControlException.next())"; 1 } 53 53 54 54 sub statement_control:<while>(Code $cond, Code $body) is primitive { … … 88 88 } 89 89 90 sub statement_control:<for>(@array is copy, Code $code) is primitive { 91 my $arity = $code.arity; 92 die "Can't use 0-ary subroutine as \"for\" body!" if $arity == 0; 93 94 while(+@array > 0) { 95 my @args = (); 96 my $i; loop $i = 0; $i < $arity; $i++ { 97 push @args: @array.shift; 98 } 99 $code(*@args); 100 } 101 undef; 102 } 103 90 104 sub JS::Root::defined($a) is primitive { 91 105 JS::inline(' … … 100 114 } 101 115 116 sub JS::Root::try(Code $code) is primitive { 117 JS::inline('new PIL2JS.Box.Constant(function (args) { 118 var cxt = args[0], code = args[1]; 119 var ret = new PIL2JS.Box.Constant(undefined); 120 try { ret = code.GET()([PIL2JS.Context.ItemAny]) } catch(err) { 121 if(err instanceof PIL2JS.ControlException.ret) { 122 throw err; 123 } else { 124 _24main_3a_3a_21.STORE(new PIL2JS.Box.Constant(err.toString())); 125 return new PIL2JS.Box.Constant(undefined); 126 } 127 } 128 return ret; 129 })')($code); 130 } 131 132 method JS::Root::shift(Array $self:) { 133 JS::inline('new PIL2JS.Box.Constant(function (args) { 134 var ret = args[1].GET().shift(); 135 return ret == undefined ? new PIL2JS.Box.Constant(undefined) : ret; 136 })')($self); 137 } 138 139 method JS::Root::push(Array $self: *@things) { 140 JS::inline('new PIL2JS.Box.Constant(function (args) { 141 var array = args[1].GET(), add = args[2].GET(); 142 for(var i = 0; i < add.length; i++) { 143 array.push(add[i]); 144 } 145 return new PIL2JS.Box.Constant(array.length); 146 })')($self, @things); 147 } 148 102 149 method JS::Root::join(Array $self: Str $sep) { 103 150 JS::inline(' … … 106 153 } 107 154 ')($self, $sep); 155 } 156 157 method JS::Root::arity(Code $self:) { 158 JS::inline('new PIL2JS.Box.Constant(function (args) { 159 return new PIL2JS.Box.Constant(args[1].GET().pil2js_arity); 160 })')($self); 108 161 } 109 162 … … 358 411 } 359 412 360 sub infix:<=:=>($a is rw, $b is rw) is primitive { JS::inline('new PIL2JS.Box.Constant(413 sub infix:<=:=>($a, $b) is primitive { JS::inline('new PIL2JS.Box.Constant( 361 414 function (args) { 362 415 var cxt = args.shift(); … … 401 454 402 455 sub JS::Root::warn(Str *@msg) is primitive { $JS::PIL2JS.warn(@msg.join("")) } 403 sub JS::Root::die(Str *@msg) is primitive { $JS::PIL2JS.die .(@msg.join(""))}456 sub JS::Root::die(Str *@msg) is primitive { $JS::PIL2JS.die(@msg.join("")) } 404 457 405 458 sub infix:«=>»($key, $value) is primitive { … … 411 464 })')($key, $value); 412 465 } 466 467 sub prefix:<*>(*@args) is primitive { 468 JS::inline('new PIL2JS.Box.Constant(function (args) { 469 var array = args[1]; 470 array.GET().flatten_me = true; 471 return array; 472 })')(@args); 473 } -
perl5/PIL2JS/libjs/PIL2JS.js
r5717 r5721 132 132 PIL2JS.Box.Stub.prototype = PIL2JS.Box.prototype; 133 133 134 PIL2JS.Box.constant_func = function (arity, f) { 135 f.pil2js_arity = arity; 136 return new PIL2JS.Box.Constant(f); 137 }; 138 134 139 // Call (possibly native sub) sub with args 135 140 PIL2JS.call = function (inv, sub, args) { … … 184 189 }; 185 190 186 // Magical variable : $?POSITION.191 // Magical variables: $?POSITION and $!. 187 192 var _24main_3a_3a_3fPOSITION = new PIL2JS.Box("<unknown>"); 193 var _24main_3a_3a_21 = new PIL2JS.Box(undefined); 188 194 189 195 // Prettyprint an error msg. … … 205 211 // &return, &leave, &last, &next are all implemented using faked escape 206 212 // continuations, i.e. exceptions. 207 PIL2JS. Exception= {};208 PIL2JS. Exception.last = function () {};209 PIL2JS. Exception.next = function () {};210 PIL2JS. Exception.ret = function (level, retval) {213 PIL2JS.ControlException = {}; 214 PIL2JS.ControlException.last = function () {}; 215 PIL2JS.ControlException.next = function () {}; 216 PIL2JS.ControlException.ret = function (level, retval) { 211 217 // The sublevel (SUBROUTINE, SUBBLOCK, etc.) the &return/&leave/whatever is 212 218 // destined to. … … 239 245 args.length == 1 ? args[0] : 240 246 new PIL2JS.Box.Constant(undefined); 241 throw(new PIL2JS. Exception.ret(level, ret));247 throw(new PIL2JS.ControlException.ret(level, ret)); 242 248 }); 243 249 }); … … 260 266 261 267 return pairs; 268 }; 269 270 // *@foo sets @foo's .flatten_me property to true. 271 // Here, we expand these flattened arrays. 272 PIL2JS.possibly_flatten = function (args) { 273 var ret = []; 274 275 for(var i = 0; i < args.length; i++) { 276 if(args[i].GET() instanceof Array && args[i].GET().flatten_me) { 277 ret = ret.concat(args[i].GET()); 278 } else { 279 ret.push(args[i]); 280 } 281 } 282 283 return ret; 262 284 }; 263 285 -
perl5/Perl6-MetaModel/t/80_Code.t
- Property svn:mime-type set to text/plain; charset=UTF-8
- Property svn:eol-style set to native
-
src/Pugs/Compile.hs
r5697 r5721 359 359 compile (Syn "\\{}" exps) = do 360 360 compile (App (Var "&circumfix:{}") Nothing exps) 361 compile (Syn "*" exps) = do 362 compile (App (Var "&prefix:*") Nothing exps) 361 363 compile (Syn "=" [lhs, rhs]) = do 362 364 lhsC <- enterLValue $ compile lhs -
t/builtins/control_flow/try.t
r4635 r5721 4 4 use Test; 5 5 6 plan 9;6 plan 11; 7 7 8 8 { … … 87 87 is(eval('ref($!)'), "Dandy", ".. of the right class", :todo); 88 88 }; 89 90 { 91 my $was_in_foo; 92 sub foo { 93 $was_in_foo++; 94 try { return 42 }; 95 $was_in_foo++; 96 return 23; 97 } 98 is foo(), 42, 'return() inside try{}-blocks works (1)', :todo<bug>; 99 is $was_in_foo, 1, 'return() inside try{}-blocks works (2)', :todo<bug>; 100 }
