Changeset 5697
- Timestamp:
- 07/19/05 16:28:50 (3 years ago)
- svk:copy_cache_prev:
- 7696
- Files:
-
- 2 added
- 4 modified
-
perl5/PIL2JS/jspugs.pl (modified) (3 diffs)
-
perl5/PIL2JS/lib6/Prelude/JS.pm (modified) (1 diff)
-
perl5/PIL2JS/libjs (added)
-
perl5/PIL2JS/libjs/PIL2JS.js (added)
-
perl5/PIL2JS/pil2js.pl (modified) (4 diffs)
-
src/Pugs/Compile.hs (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
perl5/PIL2JS/jspugs.pl
r5667 r5697 98 98 my $pil = pugs("-I$cfg{lib6}", "-CPIL", "-MPrelude::JS", "-e", "''"); 99 99 print $OUT "Error: Couldn't compile Prelude::JS to PIL!\n" and return if not defined $pil; 100 pil2js($pil, $cfg{preludepc}, "-- no-jsprelude") or100 pil2js($pil, $cfg{preludepc}, "--jsprelude-mode=no", "--p6preludepc-mode=no") or 101 101 print $OUT "Error: Couldn't compile Prelude::JS to JavaScript!\n"; 102 102 command_conf("preludepc"); … … 134 134 my $pil = pugs("-I$cfg{lib6}", "-CPIL", @_); 135 135 print $OUT "Error: Couldn't compile to PIL!\n" and return if not defined $pil; 136 pil2js($pil, $cfg{output}, "--html", "--p reludepc", $cfg{preludepc}) or136 pil2js($pil, $cfg{output}, "--html", "--p6preludepc-path", $cfg{preludepc}) or 137 137 print $OUT "Error: Couldn't compile to JavaScript!\n" and return; 138 138 command_conf("output"); … … 142 142 my $pil = pugs("-I$cfg{lib6}", "-CPIL", "-e", $_[0]); 143 143 print $OUT "Error: Couldn't compile to PIL!\n" and return if not defined $pil; 144 pil2js($pil, undef, "-- no-jsprelude") or144 pil2js($pil, undef, "--jsprelude-mode=no", "--p6preludepc-mode=no") or 145 145 print $OUT "Error: Couldn't compile to JavaScript!\n" and return; 146 146 print $OUT "\n"; -
perl5/PIL2JS/lib6/Prelude/JS.pm
r5690 r5697 142 142 JS::inline(' 143 143 function (msg) { 144 // Convert "\n"s correctly (IE...)145 var LF = typeof document != "undefined" && typeof document.all != "undefined"146 ? "\r"147 : "\n";148 msg.replace(/\n/, LF);149 150 144 // Rest copied from 151 145 // http://openjsan.org/doc/t/th/theory/Test/Simple/0.11/lib/Test/Builder.html. -
perl5/PIL2JS/pil2js.pl
r5690 r5697 11 11 use PIL::Nodes; 12 12 13 local ($/, $_); 14 15 sub slurp($) { 16 open my $fh, "<", $_[0] or die "Couldn't open \"$_[0]\" for reading: $!\n"; 17 local $/; 18 return <$fh>; 19 } 20 21 sub guess_jsprelude_path { 22 my $pathsep = $^O eq "MSWin32" ? "\\" : "/"; 23 24 my $path = $INC{"PIL${pathsep}Nodes.pm"}; 25 $path =~ s[PIL${pathsep}Nodes\.pm][..${pathsep}libjs${pathsep}PIL2JS.js]; 26 27 return -f $path ? $path : undef; 28 } 29 30 my %jsprelude = (mode => "inline", path => guess_jsprelude_path()); 31 my %p6prelude = (mode => "link"); 32 13 33 GetOptions( 14 "verbose" => \my $verbose, 15 "html" => \my $html, 16 "no-jsprelude" => \my $no_jsprelude, 17 "preludepc=s" => \my $preludepc, 18 "yaml-dump" => \my $yaml_dump, 19 "help" => \&usage, 34 "verbose" => \my $verbose, 35 "html" => \my $html, 36 "jsprelude-mode=s" => \$jsprelude{mode}, 37 "p6preludepc-mode=s" => \$p6prelude{mode}, 38 "jsprelude-path=s" => \$jsprelude{path}, 39 "p6preludepc-path=s" => \$p6prelude{path}, 40 "yaml-dump" => \my $yaml_dump, 41 "help" => \&usage, 20 42 ) or usage(); 21 43 22 die "Option --preludepc needs --html.\n" 23 if $preludepc and not $html;24 die <<ERR if $yaml_dump and ($html or $no_jsprelude or $preludepc);25 Option --yaml-dump only dumps the PIL parse tree as YAML and then 26 exits; Terefore, it can't be used in conjunction with --html, 27 --no-jsprelude, or --preludepc. 44 usage() unless 45 $jsprelude{mode} =~ /^(?:no|inline|link)$/ and 46 $p6prelude{mode} =~ /^(?:no|inline|link)$/; 47 48 die <<ERR if not $html and ($jsprelude{mode} eq "link" or $p6prelude{mode} eq "link"); 49 *** Can't link to Prelude if --html option not given! 28 50 ERR 29 51 30 local $/; 52 die <<ERR if not $p6prelude{path} and ($p6prelude{inline} or $p6prelude{link}); 53 *** Can't inline or link to the precompiled Prelude, 54 as no path to the Prelude was given. 55 ERR 56 57 die <<ERR if not $jsprelude{path} and ($jsprelude{inline} or $jsprelude{link}); 58 *** Can't inline or link to the JavaScript Prelude (PIL2JS.js), 59 as no path to the Prelude was given. 60 ERR 61 62 warn "*** Reading PIL...\n" if $verbose; 63 31 64 my $pil = <>; 32 65 my $tree = PIL::Parser->parse($pil); … … 38 71 } 39 72 40 # This is the part of the JS Prelude which needs to be written in JS. 41 local $_; 42 my $prelude = <<'EOF'; 43 if(PIL2JS == undefined) var PIL2JS = {}; 44 45 // This is necessary to emulate pass by ref, needed for is rw and is ref. 46 PIL2JS.Box = function (value) { 47 this.GET = function () { return value }; 48 this.STORE = function (n) { value = n.GET(); return n }; 49 }; 50 51 PIL2JS.Box.prototype = { 52 clone: function () { 53 return new PIL2JS.Box(this.GET()); 54 }, 55 toNative: function () { 56 var unboxed = this.GET(); 57 if(unboxed instanceof Array) { 58 var arr = []; 59 for(var i = 0; i < unboxed.length; i++) { 60 arr.push(unboxed[i].toNative()); 61 } 62 return arr; 63 } else if(unboxed instanceof Function) { 64 return function () { 65 var args = arguments; 66 for(var i = 0; i < args.length; i++) 67 args[i] = new PIL2JS.Box.Constant(args[i]); 68 return unboxed(args).toNative(); 69 }; 70 } else { 71 return unboxed; 72 } 73 }, 74 perl_methods: {} 75 /* 76 toString: function () { 77 _26main_3a_3aprefix_3a_7e.GET()([this]); 78 }, 79 */ 80 }; 81 82 PIL2JS.Box.ReadOnly = function (box) { 83 this.GET = function () { return box.GET() }; 84 this.STORE = function (n) { PIL2JS.die("Can't modify constant item!\n"); return n }; 85 }; 86 PIL2JS.Box.Constant = function (value) { 87 this.GET = function () { return value }; 88 this.STORE = function (n) { PIL2JS.die("Can't modify constant item!\n"); return n }; 89 }; 90 PIL2JS.Box.Stub = function (value) { 91 this.GET = function () { PIL2JS.die(".GET() of a PIL2JS.Box.Stub called!\n") } 92 this.STORE = function (n) { PIL2JS.die(".STORE() of a PIL2JS.Box.Stub called!\n"); return n }; 93 }; 94 95 PIL2JS.Box.ReadOnly.prototype = PIL2JS.Box.prototype; 96 PIL2JS.Box.Constant.prototype = PIL2JS.Box.prototype; 97 PIL2JS.Box.Stub.prototype = PIL2JS.Box.prototype; 98 99 // Call (possibly native sub) sub with args 100 PIL2JS.call = function (inv, sub, args) { 101 if(sub == undefined) 102 PIL2JS.die("Use of uninitialized value in subroutine entry!\n"); 103 104 // It's a plain sub (i.e. not method) call. 105 if(inv == undefined) { 106 // It's a boxed (and therefore Perl 6) sub. 107 if(sub.GET) { 108 var ret = sub.GET()(args); 109 if(ret == undefined) 110 PIL2JS.die("Internal error: Boxed sub returned unboxed undefined!"); 111 return ret; 112 } else { 113 var code = "new PIL2JS.Box.Constant(sub("; 114 for(var i = 0; i < args.length; i++) { 115 code += "args[" + i + "].toNative(),"; 116 } 117 if(args.length > 0) code = code.slice(0, -1); 118 code += "))"; 119 return eval(code); 120 } 121 } else { 122 if(inv.GET) { 123 if(inv.perl_methods[sub]) { 124 return PIL2JS.call(undefined, inv.perl_methods[sub], [inv].concat(args)); 125 } else { 126 PIL2JS.die("No such method: \"" + sub + "\""); 127 } 128 } else { 129 PIL2JS.die("Internal error: PIL2JS.call not implemented for invocation of native methods\n"); 130 } 131 } 132 }; 133 134 PIL2JS.make_slurpy_array = function (inp_arr) { 135 var out_arr = []; 136 137 for(var i = 0; i < inp_arr.length; i++) { 138 if(inp_arr[i].GET() instanceof Array) { 139 out_arr = out_arr.concat(inp_arr[i].GET()); 140 } else { 141 out_arr.push(inp_arr[i]); 142 } 143 } 144 145 return out_arr; 146 }; 147 148 _24main_3a_3a_3fPOSITION = new PIL2JS.Box("<unknown>"); 149 150 PIL2JS.new_error = function (msg) { 151 return new Error(msg.substr(-1, 1) == "\n" 152 ? msg 153 : msg + " at " + _24main_3a_3a_3fPOSITION.toNative() 154 ); 155 }; 156 PIL2JS.warn = function (msg) { alert(PIL2JS.new_error(msg)) }; 157 PIL2JS.die = function (msg) { 158 var error = PIL2JS.new_error(msg); 73 warn "*** Compiling input PIL to JavaScript...\n" if $verbose; 74 my $load_check = <<EOF; 75 if(PIL2JS == undefined) { 76 var error = new Error("PIL2JS.js not loaded; aborting."); 159 77 alert(error); 160 78 throw(error); 161 }; 162 163 PIL2JS.Exception = {}; 164 PIL2JS.Exception.last = function () {}; 165 PIL2JS.Exception.next = function () {}; 166 PIL2JS.Exception.ret = function (level, retval) { 167 this.level = level; 168 this.return_value = retval; 169 this.toString = function () { 170 var msg = 171 "Can't return outside a " + level + "-routine. at " + 172 _24main_3a_3a_3fPOSITION.toNative(); 173 alert(msg); 174 return msg; 175 } 176 }; 177 178 _26PIL2JS_3a_3aInternals_3a_3ageneric_return = 179 new PIL2JS.Box.Constant(function (args) { 180 var level = args[0].toNative(); 181 return new PIL2JS.Box.Constant(function (args) { 182 args = PIL2JS.make_slurpy_array(args); 183 var ret = 184 args.length > 1 ? new PIL2JS.Box.Constant(args) : 185 args.length == 1 ? args[0] : 186 new PIL2J2.Box.Constant(undefined); 187 throw(new PIL2JS.Exception.ret(level, ret)); 188 }); 189 }); 190 191 PIL2JS.Pair = function (key, value) { 192 this.key = key; 193 this.value = value; 194 }; 195 196 PIL2JS.part_pairs = function (args) { 197 var normal_args = []; 198 var pairs = {}; 199 200 for(var i = 0; i < args.length; i++) { 201 if(args[i].GET() instanceof PIL2JS.Pair) { 202 pairs[args[i].GET().key.toNative()] = args[i].GET().value; 203 } else { 204 normal_args.push(args[i]); 205 } 206 } 207 208 return [normal_args, pairs]; 209 }; 79 } 210 80 EOF 211 81 212 my $js = join "\n", map { $_->as_js } @{ $tree->{"pilGlob"} }, $tree->{pilMain}; 82 my $program_js = join "\n", 83 $load_check, 84 map { $_->as_js } @{ $tree->{"pilGlob"} }, $tree->{pilMain}; 85 86 warn "*** Inlining the JavaScript Prelude (PIL2JS.pl)...\n" if $verbose; 87 my $jsprelude_js = $jsprelude{mode} eq "inline" ? slurp $jsprelude{path} : undef; 88 warn "*** Inlining the Perl 6 Prelude...\n" if $verbose; 89 my $p6prelude_js = $p6prelude{mode} eq "inline" ? slurp $p6prelude{path} : undef; 90 91 my $js; 92 $js .= $jsprelude_js if $jsprelude{mode} eq "inline" and not $html; 93 $js .= $p6prelude_js if $p6prelude{mode} eq "inline"; 94 $js .= $program_js; 213 95 214 96 unless($html) { 215 print $prelude . "\n" unless $no_jsprelude;216 97 print $js; 217 98 } else { 218 99 # Output a standard HTML skeleton. 219 100 my $indent = sub { join "\n", map { " " x 6 . $_ } split "\n", shift }; 220 printf <<EOF, $no_jsprelude ? "" : $indent->($prelude), $indent->($js); 101 my $link = sub { "<script type=\"text/javascript\" src=\"$_[0]\"></script>" }; 102 103 print <<EOF; 221 104 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 222 105 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> … … 229 112 <pre id="__pil2js_tty"></pre> 230 113 231 @{[ 232 $no_jsprelude 233 ? "" 234 : "<script type=\"text/javascript\">//<![CDATA[\n%s\n //]]</script>\n" 235 ]} 236 @{[ 237 $preludepc 238 ? "<script type=\"text/javascript\" src=\"$preludepc\"></script>\n" 239 : "" 240 ]} 114 EOF 115 116 print <<EOF if $jsprelude{mode} eq "inline"; 241 117 <script type="text/javascript">//<![CDATA[ 242 %s 118 @{[$indent->($jsprelude_js)]} 119 //]] 120 </script> 121 EOF 122 123 print <<EOF; 124 @{[ $jsprelude{mode} eq "link" ? $link->($jsprelude{path}) : "" ]} 125 @{[ $p6prelude{mode} eq "link" ? $link->($p6prelude{path}) : "" ]} 126 <script type="text/javascript">//<![CDATA[ 127 @{[$indent->($js)]} 243 128 //]] 244 129 </script> … … 253 138 254 139 Available options (options may be abbreviated to uniqueness): 255 --verbose Sets verboseness. 256 --html Outputs the JavaScript packed in an HTML page. 257 --no-jsprelude Omits the part of the Prelude written in JavaScript. 258 --preludepc=http://.../preludepc.js 259 Sets the path to a precompiled Prelude. 140 --verbose Be verbose. 141 --html Output the JavaScript packed in an HTML page. 142 143 --jsprelude-mode=no|inline|link 144 --p6preludepc-mode=no|inline|link 145 Don't include, inline, or link to the specified part 146 of the Prelude. 147 148 --jsprelude-path=... 149 --p6preludepc-path=... 150 Sets the path to the specified part of the Prelude. 151 152 --yaml-dump Only output the PIL as YAML; don't compile anything. 260 153 261 154 Recommended usage: 262 155 \$ cd perl5/PIL2JS 263 156 \$ pugs -CPIL -Ilib6 -MPrelude::JS -we 'say 2 + 3' | \ 264 ./pil2js.pl --html > test.js157 ./pil2js.pl --html --p6preludepc-mode=no > test.js 265 158 # or (*much* faster) 266 159 \$ pugs -CPIL -Ilib6 -MPrelude::JS -we '' | \ 267 ./pil2js.pl -- no-jsprelude> preludepc.js160 ./pil2js.pl --jsprelude-mode=no --p6preludepc-mode=no > preludepc.js 268 161 \$ pugs -CPIL -we 'say 2 + 3' | \ 269 ./pil2js.pl --html --p reludepc="http://.../preludepc.js" > test.js162 ./pil2js.pl --html --p6preludepc="http://.../preludepc.js" > test.js 270 163 271 164 USAGE -
src/Pugs/Compile.hs
r5667 r5697 89 89 show PNil = "PNil" 90 90 show PNoop = "PNoop" 91 -- We don't show the raw Exp here to ease writing parsers for PIL (Exp 92 -- contains things like MkEnv, etc.). 91 93 show (PPos x _ z) = "(PPos " ++ show x ++ " Noop " ++ show z ++ ")" 92 94 show (PApp x y i z) = "(PApp " ++ show x ++ " " ++ show y ++ " " ++ show i ++ " " ++ show z ++ ")"
