Permalink
Browse files

Perlito5 - js3 - add make build-5js3

  • Loading branch information...
1 parent ad58fdb commit bb527ad3a478038aaa9b910aac031c7b8e1a21d3 @fglock committed Sep 23, 2012
Showing with 18 additions and 3 deletions.
  1. +3 −0 Makefile
  2. +2 −2 perlito5.pl
  3. +1 −1 src5/lib/Perlito5/Javascript3/Emitter.pm
  4. +12 −0 src5/lib/Perlito5/Javascript3/Runtime.pm
View
3 Makefile
@@ -23,6 +23,9 @@ build-5js ::
build-5browser ::
perl perlito5.pl -I./src5/lib -Cjs src5/util/perlito5-browser.pl > html/perlito5.js
+build-5js3 ::
+ perl perlito5.pl -I./src5/lib -Cjs3 src5/util/perlito5.pl > perlito5.js
+
boot-5js ::
time node perlito5.js -Isrc5/lib -Cjs src5/util/perlito5.pl > perlito5-new.js && diff perlito5-new.js perlito5.js ; cp perlito5-new.js perlito5.js
View
4 perlito5.pl
@@ -9190,7 +9190,7 @@ package Perlito5::Javascript3;
push(@out, ($k . ' : ' . $v) )
};
if ($printable) {
- return (('new p5Hash({' . join(', ', @out) . '})'))
+ return (('{' . join(', ', @out) . '}'))
}
};
return (('p5a_to_h(' . to_list($items, $level, 'array') . ')'))
@@ -10421,7 +10421,7 @@ package main;
undef();
package Perlito5::Javascript3::Runtime;
sub Perlito5::Javascript3::Runtime::emit_javascript3 {
- return ((('//' . chr(10) . '// lib/Perlito5/Javascript3/Runtime.js' . chr(10) . '//' . chr(10) . '// Runtime for "Perlito" Perl5-in-Javascript3' . chr(10) . '//' . chr(10) . '// AUTHORS' . chr(10) . '//' . chr(10) . '// Flavio Soibelmann Glock fglock@gmail.com' . chr(10) . '//' . chr(10) . '// COPYRIGHT' . chr(10) . '//' . chr(10) . '// Copyright 2009, 2010, 2011, 2012 by Flavio Soibelmann Glock and others.' . chr(10) . '//' . chr(10) . '// This program is free software; you can redistribute it and/or modify it' . chr(10) . '// under the same terms as Perl itself.' . chr(10) . '//' . chr(10) . '// See http://www.perl.com/perl/misc/Artistic.html' . chr(10) . chr(10) . 'var isNode = typeof require != "undefined";' . chr(10) . chr(10) . 'if (typeof p5pkg !== "object") {' . chr(10) . ' p5pkg = {};' . chr(10) . ' p5LOCAL = [];' . chr(10) . chr(10) . ' var universal = function () {};' . chr(10) . ' p5pkg.UNIVERSAL = new universal();' . chr(10) . ' p5pkg.UNIVERSAL._ref_ = "UNIVERSAL";' . chr(10) . ' p5pkg.UNIVERSAL.isa = function (List__) {' . chr(10) . ' // TODO - use @ISA' . chr(10) . ' return List__[0]._class_._ref_ == List__[1]' . chr(10) . ' };' . chr(10) . ' p5pkg.UNIVERSAL.can = function (List__) {' . chr(10) . ' var o = List__[0];' . chr(10) . ' var s = List__[1];' . chr(10) . ' if ( s.indexOf("::") == -1 ) {' . chr(10) . ' return p5method_lookup(s, o._class_._ref__, {})' . chr(10) . ' }' . chr(10) . ' var c = s.split("::");' . chr(10) . ' s = c.pop(); ' . chr(10) . ' return p5method_lookup(s, c.join("::"), {});' . chr(10) . ' };' . chr(10) . ' p5pkg.UNIVERSAL.DOES = p5pkg.UNIVERSAL.can;' . chr(10) . chr(10) . ' var core = function () {};' . chr(10) . ' p5pkg["CORE"] = new core();' . chr(10) . ' p5pkg["CORE"]._ref_ = "CORE";' . chr(10) . chr(10) . ' var core_global = function () {};' . chr(10) . ' core_global.prototype = p5pkg.CORE;' . chr(10) . ' p5pkg["CORE::GLOBAL"] = new core_global();' . chr(10) . ' p5pkg["CORE::GLOBAL"]._ref_ = "CORE::GLOBAL";' . chr(10) . chr(10) . ' p5_error = function (type, v) {' . chr(10) . ' this.type = type;' . chr(10) . ' this.v = v;' . chr(10) . ' this.toString = function(){' . chr(10) . ' if (this.type == ' . chr(39) . 'break' . chr(39) . ') {' . chr(10) . ' return ' . chr(39) . 'Can' . chr(92) . chr(39) . 't "break" outside a given block' . chr(39) . chr(10) . ' }' . chr(10) . ' if (this.type == ' . chr(39) . 'next' . chr(39) . ' || this.type == ' . chr(39) . 'last' . chr(39) . ' || this.type == ' . chr(39) . 'redo' . chr(39) . ') {' . chr(10) . ' if (this.v == "") { return ' . chr(39) . 'Can' . chr(92) . chr(39) . 't "' . chr(39) . ' + this.type + ' . chr(39) . '" outside a loop block' . chr(39) . ' }' . chr(10) . ' return ' . chr(39) . 'Label not found for "' . chr(39) . ' + this.type + ' . chr(39) . ' ' . chr(39) . ' + this.v + ' . chr(39) . '"' . chr(39) . ';' . chr(10) . ' }' . chr(10) . ' return this.v;' . chr(10) . ' };' . chr(10) . ' };' . chr(10) . ' p5_error.prototype = Error.prototype;' . chr(10) . '}' . chr(10) . chr(10) . 'function p5make_package(pkg_name) {' . chr(10) . ' if (!p5pkg.hasOwnProperty(pkg_name)) {' . chr(10) . ' var tmp = function () {};' . chr(10) . ' tmp.prototype = p5pkg["CORE::GLOBAL"];' . chr(10) . ' p5pkg[pkg_name] = new tmp();' . chr(10) . ' p5pkg[pkg_name]._ref_ = pkg_name;' . chr(10) . ' p5pkg[pkg_name]._class_ = p5pkg[pkg_name]; // XXX memory leak' . chr(10) . chr(10) . ' // TODO - add the other package global variables' . chr(10) . ' p5pkg[pkg_name]["List_ISA"] = new p5Array([]);' . chr(10) . ' p5pkg[pkg_name]["v_a"] = new p5Scalar(null);' . chr(10) . ' p5pkg[pkg_name]["v_b"] = new p5Scalar(null);' . chr(10) . ' p5pkg[pkg_name]["v__"] = new p5Scalar(null);' . chr(10) . ' p5pkg[pkg_name]["v_AUTOLOAD"] = new p5Scalar(null);' . chr(10) . ' }' . chr(10) . ' return p5pkg[pkg_name];' . chr(10) . '}' . chr(10) . chr(10) . 'function p5code_lookup_by_name(package_name, sub_name) {' . chr(10) . ' // sub_name can have an optional namespace' . chr(10) . ' var parts = sub_name.split(/::/);' . chr(10) . ' if (parts.length > 1) {' . chr(10) . ' sub_name = parts.pop();' . chr(10) . ' package_name = parts.join("::");' . chr(10) . ' }' . chr(10) . ' if (p5pkg.hasOwnProperty(package_name)) {' . chr(10) . ' var c = p5pkg[package_name];' . chr(10) . ' if ( c.hasOwnProperty(sub_name) ) {' . chr(10) . ' return c[sub_name]' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' return null;' . chr(10) . '}' . chr(10) . chr(10) . 'function p5get_class_for_method(method, class_name, seen) {' . chr(10) . ' // default mro' . chr(10) . ' // TODO - cache the methods that were already looked up' . chr(10) . ' if ( p5pkg[class_name].hasOwnProperty(method) ) {' . chr(10) . ' return class_name' . chr(10) . ' }' . chr(10) . ' var isa = p5pkg[class_name].List_ISA;' . chr(10) . ' for (var i = 0; i < isa.length; i++) {' . chr(10) . ' if (!seen[isa[i]]) {' . chr(10) . ' var m = p5get_class_for_method(method, isa[i]);' . chr(10) . ' if (m) {' . chr(10) . ' return m ' . chr(10) . ' }' . chr(10) . ' seen[isa[i]]++;' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . '}' . chr(10) . chr(10) . 'function p5method_lookup(method, class_name, seen) {' . chr(10) . ' var c = p5get_class_for_method(method, class_name, seen);' . chr(10) . ' if (c) {' . chr(10) . ' return p5pkg[c][method]' . chr(10) . ' }' . chr(10) . ' if ( p5pkg.UNIVERSAL.hasOwnProperty(method) ) {' . chr(10) . ' return p5pkg.UNIVERSAL[method]' . chr(10) . ' }' . chr(10) . '}' . chr(10) . chr(10) . 'function p5call(invocant, method, list) {' . chr(10) . ' list.unshift(invocant);' . chr(10) . chr(10) . ' if (invocant instanceof p5Scalar) {' . chr(10) . ' // TODO - move p5call() to p5Scalar method' . chr(10) . ' invocant = invocant._v_;' . chr(10) . ' }' . chr(10) . chr(10) . ' if ( invocant.hasOwnProperty("_class_") ) {' . chr(10) . chr(10) . ' if ( invocant._class_.hasOwnProperty(method) ) {' . chr(10) . ' return invocant._class_[method](list)' . chr(10) . ' }' . chr(10) . ' var m = p5method_lookup(method, invocant._class_._ref_, {});' . chr(10) . ' if (m) {' . chr(10) . ' return m(list)' . chr(10) . ' }' . chr(10) . chr(10) . ' // method can have an optional namespace' . chr(10) . ' var pkg_name = method.split(/::/);' . chr(10) . ' if (pkg_name.length > 1) {' . chr(10) . ' var name = pkg_name.pop();' . chr(10) . ' pkg_name = pkg_name.join("::");' . chr(10) . ' m = p5method_lookup(name, pkg_name, {});' . chr(10) . ' if (m) {' . chr(10) . ' return m(list)' . chr(10) . ' }' . chr(10) . ' p5pkg.CORE.die(["method not found: ", name, " in class ", pkg_name]);' . chr(10) . ' }' . chr(10) . chr(10) . ' pkg_name = p5get_class_for_method(' . chr(39) . 'AUTOLOAD' . chr(39) . ', invocant._class_._ref_, {}) || p5get_class_for_method(' . chr(39) . 'AUTOLOAD' . chr(39) . ', "UNIVERSAL", {});' . chr(10) . ' if (pkg_name) {' . chr(10) . ' p5pkg[pkg_name]["v_AUTOLOAD"] = invocant._class_._ref_ + "::" + method;' . chr(10) . ' return p5pkg[pkg_name]["AUTOLOAD"](list);' . chr(10) . ' }' . chr(10) . chr(10) . ' p5pkg.CORE.die(["method not found: ", method, " in class ", invocant._class_._ref_]);' . chr(10) . chr(10) . ' }' . chr(10) . chr(10) . ' // the invocant doesn' . chr(39) . 't have a class' . chr(10) . chr(10) . ' if (typeof invocant === "string") {' . chr(10) . ' var aclass = p5make_package(invocant);' . chr(10) . ' return p5call(aclass, method, list);' . chr(10) . ' }' . chr(10) . chr(10) . ' p5pkg.CORE.die(["Can' . chr(39) . 't call method ", method, " on unblessed reference"]);' . chr(10) . chr(10) . '}' . chr(10) . chr(10) . 'p5make_package("main");' . chr(10) . 'p5pkg["main"]["v_@"] = ""; // $@' . chr(10) . 'p5pkg["main"]["v_|"] = 0; // $|' . chr(10) . 'p5pkg["main"]["List_#"] = new p5Array([]); // @#' . chr(10) . 'p5pkg["main"]["v_^O"] = isNode ? "node.js" : "javascript3";' . chr(10) . 'p5pkg["main"]["List_INC"] = new p5Array([]);' . chr(10) . 'p5pkg["main"]["Hash_INC"] = {};' . chr(10) . 'p5pkg["main"]["List_ARGV"] = new p5Array([]);' . chr(10) . 'p5pkg["main"]["Hash_ENV"] = {};' . chr(10) . 'if (isNode) {' . chr(10) . ' p5pkg["main"]["List_ARGV"] = new p5Array(process.argv.splice(2));' . chr(10) . ' p5pkg["main"]["Hash_ENV"] = process.env;' . chr(10) . ' p5pkg["main"]["v_$"] = process.pid;' . chr(10) . '} else if (typeof arguments === "object") {' . chr(10) . ' p5pkg["main"]["List_ARGV"] = new p5Array(arguments);' . chr(10) . '}' . chr(10) . chr(10) . 'p5make_package("Perlito5");' . chr(10) . 'p5make_package("Perlito5::IO");' . chr(10) . 'p5make_package("Perlito5::Runtime");' . chr(10) . 'p5make_package("Perlito5::Grammar");' . chr(10) . chr(10) . 'function p5make_sub(pkg_name, sub_name, func) {' . chr(10) . ' p5pkg[pkg_name][sub_name] = func;' . chr(10) . '}' . chr(10) . chr(10) . 'function p5set_glob(name, data) {' . chr(10) . ' if ( name.indexOf("::") == -1 ) {' . chr(10) . ' p5pkg[p5pkg["Perlito5"].v_PKG_NAME][name] = data;' . chr(10) . ' return data;' . chr(10) . ' }' . chr(10) . ' var c = name.split("::");' . chr(10) . ' s = c.pop(); ' . chr(10) . ' var pkg = c.join("::");' . chr(10) . ' p5make_package(pkg);' . chr(10) . ' p5pkg[pkg][s] = data;' . chr(10) . ' return data;' . chr(10) . '}' . chr(10) . chr(10) . 'function p5set_local(namespace, name, sigil) {' . chr(10) . ' var v = name;' . chr(10) . ' if (sigil == "$") {' . chr(10) . ' v = "v_"+name;' . chr(10) . ' }' . chr(10) . ' p5LOCAL.push([namespace, v, namespace[v]]);' . chr(10) . '}' . chr(10) . chr(10) . 'function p5cleanup_local(idx, value) {' . chr(10) . ' while (p5LOCAL.length > idx) {' . chr(10) . ' l = p5LOCAL.pop();' . chr(10) . ' l[0][l[1]] = l[2];' . chr(10) . ' }' . chr(10) . ' return value;' . chr(10) . '}' . chr(10) . chr(10) . 'var sigils = { ' . chr(39) . '@' . chr(39) . ' : ' . chr(39) . 'List_' . chr(39) . ', ' . chr(39) . '%' . chr(39) . ' : ' . chr(39) . 'Hash_' . chr(39) . ', ' . chr(39) . '$' . chr(39) . ' : ' . chr(39) . 'v_' . chr(39) . ' };' . chr(10) . 'function p5global(sigil, namespace, name) {' . chr(10) . ' // TODO - autovivify namespace' . chr(10) . ' v = p5pkg[namespace][sigils[sigil] + name ];' . chr(10) . ' if (v != null) {' . chr(10) . ' return v;' . chr(10) . ' }' . chr(10) . ' if (sigil == ' . chr(39) . '$' . chr(39) . ') {' . chr(10) . ' p5pkg[namespace][sigils[sigil] + name ] = new p5Scalar(null);' . chr(10) . ' }' . chr(10) . ' else if (sigil == ' . chr(39) . '@' . chr(39) . ') {' . chr(10) . ' p5pkg[namespace][sigils[sigil] + name ] = new p5Array([]);' . chr(10) . ' }' . chr(10) . ' else if (sigil == ' . chr(39) . '%' . chr(39) . ') {' . chr(10) . ' p5pkg[namespace][sigils[sigil] + name ] = new p5Hash({});' . chr(10) . ' }' . chr(10) . ' return p5pkg[namespace][sigils[sigil] + name ];' . chr(10) . '}' . chr(10) . chr(10) . 'function p5HashRef(o) {' . chr(10) . ' this._href_ = o;' . chr(10) . ' this._ref_ = "HASH";' . chr(10) . ' this.p5bool = function() { return 1 };' . chr(10) . ' this.hderef = function() {' . chr(10) . ' return this._href_;' . chr(10) . ' };' . chr(10) . ' this.hset = function(i, v) {' . chr(10) . ' this._href_._hash_[i] = v;' . chr(10) . ' return v;' . chr(10) . ' };' . chr(10) . ' this.hget = function(i, autoviv) {' . chr(10) . ' return this._href_.hget(i, autoviv);' . chr(10) . ' }' . chr(10) . '}' . chr(10) . chr(10) . 'function p5ArrayRef(o) {' . chr(10) . ' this._aref_ = o;' . chr(10) . ' this._ref_ = "ARRAY";' . chr(10) . ' this.p5bool = function() { return 1 };' . chr(10) . ' this.aderef = function() {' . chr(10) . ' return this._aref_;' . chr(10) . ' };' . chr(10) . ' this.aset = function(i, v) {' . chr(10) . ' this._aref_._array_[i >= 0 ? i : this._aref_._array_.length + i] = v;' . chr(10) . ' return v;' . chr(10) . ' }' . chr(10) . ' this.aget = function(i, autoviv) {' . chr(10) . ' return this._aref_.aget(i, autoviv);' . chr(10) . ' }' . chr(10) . '}' . chr(10) . chr(10) . 'function p5ScalarRef(o) {' . chr(10) . ' this._scalar_ = o;' . chr(10) . ' this._ref_ = "SCALAR";' . chr(10) . ' this.p5bool = function() { return 1 };' . chr(10) . ' this.sderef = function(i) {' . chr(10) . ' return this._scalar_;' . chr(10) . ' };' . chr(10) . '}' . chr(10) . chr(10) . 'function p5GlobRef(o) {' . chr(10) . ' this._scalar_ = o;' . chr(10) . ' this._ref_ = "GLOB";' . chr(10) . ' this.p5bool = function() { return 1 };' . chr(10) . '}' . chr(10) . chr(10) . 'function p5Array(o) {' . chr(10) . ' // TODO - array slice' . chr(10) . ' this._array_ = o;' . chr(10) . ' this._ref_ = "";' . chr(10) . ' this.p5bool = function() {' . chr(10) . ' return this._array_.length != 0' . chr(10) . ' };' . chr(10) . ' this.aset = function(i, v) {' . chr(10) . ' this._array_[i >= 0 ? i : this._array_.length + i] = v;' . chr(10) . ' return v;' . chr(10) . ' };' . chr(10) . ' this.aget = function(i, autoviv) {' . chr(10) . ' if (i < 0) {' . chr(10) . ' i = this._array_.length + i;' . chr(10) . ' }' . chr(10) . ' var v = this._array_[i];' . chr(10) . ' if (v != null) {' . chr(10) . ' return v;' . chr(10) . ' }' . chr(10) . ' if (autoviv == ' . chr(39) . 'array' . chr(39) . ') {' . chr(10) . ' this._array_[i] = new p5ArrayRef(new p5Array([]));' . chr(10) . ' }' . chr(10) . ' else if (autoviv == ' . chr(39) . 'hash' . chr(39) . ') {' . chr(10) . ' this._array_[i] = new p5HashRef(new p5Hash({}));' . chr(10) . ' }' . chr(10) . ' return this._array_[i];' . chr(10) . ' };' . chr(10) . ' this.assign = function(a) {' . chr(10) . ' if (a instanceof Array) {' . chr(10) . ' // TODO - cleanup, this shouldn' . chr(39) . 't happen' . chr(10) . ' this._array_ = a;' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' this._array_ = a._array_;' . chr(10) . ' }' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . '}' . chr(10) . chr(10) . 'function p5Hash(o) {' . chr(10) . ' // TODO - hash slice' . chr(10) . ' this._hash_ = o;' . chr(10) . ' this._ref_ = "";' . chr(10) . ' this.p5bool = function() {' . chr(10) . ' o = this._hash_;' . chr(10) . ' for (var i in o) {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' return false;' . chr(10) . ' };' . chr(10) . ' this.hset = function(i, v) {' . chr(10) . ' this._hash_[i] = v;' . chr(10) . ' return v;' . chr(10) . ' };' . chr(10) . ' this.hget = function(i, autoviv) {' . chr(10) . ' var v = this._hash_[i];' . chr(10) . ' if (v != null) {' . chr(10) . ' return v;' . chr(10) . ' }' . chr(10) . ' if (autoviv == ' . chr(39) . 'array' . chr(39) . ') {' . chr(10) . ' this._hash_[i] = new p5ArrayRef(new p5Array([]));' . chr(10) . ' }' . chr(10) . ' else if (autoviv == ' . chr(39) . 'hash' . chr(39) . ') {' . chr(10) . ' this._hash_[i] = new p5HashRef(new p5Hash({}));' . chr(10) . ' }' . chr(10) . ' return this._hash_[i];' . chr(10) . ' };' . chr(10) . ' this.assign = function(h) {' . chr(10) . ' if (h instanceof p5Hash) {' . chr(10) . ' this._hash_ = h._hash_;' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' // TODO - cleanup, this shouldn' . chr(39) . 't happen' . chr(10) . ' this._hash_ = h;' . chr(10) . ' }' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . '}' . chr(10) . chr(10) . 'function p5Scalar(o) {' . chr(10) . ' this._v_ = o;' . chr(10) . ' this._ref_ = "";' . chr(10) . chr(10) . ' // be a value' . chr(10) . ' this.p5bool = function() {' . chr(10) . ' return p5bool(this._v_);' . chr(10) . ' };' . chr(10) . ' this.p5string = function() {' . chr(10) . ' return p5str(this._v_);' . chr(10) . ' };' . chr(10) . ' this.p5num = function() {' . chr(10) . ' return p5num(this._v_);' . chr(10) . ' };' . chr(10) . ' this.p5code = function() {' . chr(10) . ' return p5code(this._v_);' . chr(10) . ' };' . chr(10) . chr(10) . ' // be a scalar ref' . chr(10) . ' this.sderef = function(i) {' . chr(10) . ' return this._v_.sderef;' . chr(10) . ' };' . chr(10) . chr(10) . ' // be an array ref' . chr(10) . ' this.aderef = function() {' . chr(10) . ' // TODO - autovivify array (with proxy object?)' . chr(10) . ' return this._v_.aderef();' . chr(10) . ' };' . chr(10) . ' this.aget = function(i, autoviv) {' . chr(10) . ' // TODO - autovivify array (with proxy object?)' . chr(10) . ' if (this._v_ == null) {' . chr(10) . ' this._v_ = new p5ArrayRef(new p5Array([]));' . chr(10) . ' }' . chr(10) . ' return this._v_.aget(i, autoviv);' . chr(10) . ' };' . chr(10) . ' this.aset = function(i, v) {' . chr(10) . ' if (this._v_ == null) {' . chr(10) . ' this._v_ = new p5ArrayRef(new p5Array([]));' . chr(10) . ' }' . chr(10) . ' return this._v_.aset(i, v);' . chr(10) . ' };' . chr(10) . chr(10) . ' // be a hash ref' . chr(10) . ' this.hderef = function() {' . chr(10) . ' // TODO - autovivify hash (with proxy object?)' . chr(10) . ' if (this._v_ == null) {' . chr(10) . ' this._v_ = new p5HashRef(new p5Hash([]));' . chr(10) . ' }' . chr(10) . ' return this._v_.hderef();' . chr(10) . ' };' . chr(10) . ' this.hget = function(i, autoviv) {' . chr(10) . ' // TODO - autovivify hash (with proxy object?)' . chr(10) . ' if (this._v_ == null) {' . chr(10) . ' this._v_ = new p5HashRef(new p5Hash([]));' . chr(10) . ' }' . chr(10) . ' return this._v_.hget(i, autoviv);' . chr(10) . ' }' . chr(10) . ' this.hset = function(i, v) {' . chr(10) . ' if (this._v_ == null) {' . chr(10) . ' this._v_ = new p5HashRef(new p5Hash([]));' . chr(10) . ' }' . chr(10) . ' return this._v_.hset(i, v);' . chr(10) . ' }' . chr(10) . chr(10) . ' // be a container' . chr(10) . ' this.vset = function(v) {' . chr(10) . ' this._v_ = v;' . chr(10) . ' return v;' . chr(10) . ' };' . chr(10) . ' this.vget = function() {' . chr(10) . ' return this._v_;' . chr(10) . ' };' . chr(10) . ' this.assign = function(v) {' . chr(10) . ' if (v instanceof p5Scalar) {' . chr(10) . ' this._v_ = v._v_;' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' // TODO - cleanup, this shouldn' . chr(39) . 't happen' . chr(10) . ' this._v_ = v;' . chr(10) . ' }' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . '}' . chr(10) . chr(10) . 'p5list_to_a = function() {' . chr(10) . ' var res = [];' . chr(10) . ' for (i = 0; i < arguments.length; i++) {' . chr(10) . ' var o = arguments[i];' . chr(10) . ' if ( o == null' . chr(10) . ' || o._class_ // perl5 blessed reference' . chr(10) . ' || o._ref_ // perl5 un-blessed reference' . chr(10) . ' )' . chr(10) . ' {' . chr(10) . ' res.push(o);' . chr(10) . ' }' . chr(10) . ' else if (o instanceof p5Array) {' . chr(10) . ' // perl5 array' . chr(10) . ' for (j = 0; j < o._array_.length; j++) {' . chr(10) . ' res.push(o._array_[j]);' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' else if (o instanceof Array) {' . chr(10) . ' // js array' . chr(10) . ' for (j = 0; j < o.length; j++) {' . chr(10) . ' res.push(o[j]);' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' else if (o instanceof p5Hash) {' . chr(10) . ' // perl5 hash' . chr(10) . ' for(var j in o._hash_) {' . chr(10) . ' if (o._hash_.hasOwnProperty(j)) {' . chr(10) . ' res.push(j);' . chr(10) . ' res.push(o._hash_[j]);' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' else if (typeof o === "object") {' . chr(10) . ' // perl5 hash' . chr(10) . ' for(var j in o) {' . chr(10) . ' if (o.hasOwnProperty(j)) {' . chr(10) . ' res.push(j);' . chr(10) . ' res.push(o[j]);' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' // non-ref' . chr(10) . ' res.push(o);' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' return res;' . chr(10) . '};' . chr(10) . chr(10) . 'p5a_to_h = function(a) {' . chr(10) . ' var res = {};' . chr(10) . ' for (i = 0; i < a.length; i+=2) {' . chr(10) . ' res[p5str(a[i])] = a[i+1];' . chr(10) . ' }' . chr(10) . ' return res;' . chr(10) . '};' . chr(10) . chr(10) . 'if (isNode) {' . chr(10) . ' var fs = require("fs");' . chr(10) . ' p5make_sub("Perlito5::IO", "slurp", function(List__) {' . chr(10) . ' return fs.readFileSync(List__[0],"utf8");' . chr(10) . ' });' . chr(10) . '} else {' . chr(10) . ' p5make_sub("Perlito5::IO", "slurp", function(List__) {' . chr(10) . ' var filename = List__[0];' . chr(10) . ' if (typeof readFile == "function") {' . chr(10) . ' return readFile(filename);' . chr(10) . ' }' . chr(10) . ' if (typeof read == "function") {' . chr(10) . ' // v8' . chr(10) . ' return read(filename);' . chr(10) . ' }' . chr(10) . ' p5pkg.CORE.die(["Perlito5::IO::slurp() not implemented"]);' . chr(10) . ' });' . chr(10) . '}' . chr(10) . chr(10) . 'p5context = function(List__, p5want) {' . chr(10) . ' if (p5want) {' . chr(10) . ' return p5list_to_a.apply(null, List__);' . chr(10) . ' }' . chr(10) . ' // scalar: return the last value' . chr(10) . ' var o = List__;' . chr(10) . ' while (o instanceof Array) {' . chr(10) . ' o = o.length' . chr(10) . ' ? o[o.length-1]' . chr(10) . ' : null;' . chr(10) . ' }' . chr(10) . ' return o;' . chr(10) . '}' . chr(10) . chr(10) . 'p5code = function(o) {' . chr(10) . ' if (typeof o === "function") {' . chr(10) . ' return o;' . chr(10) . ' }' . chr(10) . ' return o.p5code();' . chr(10) . '};' . chr(10) . chr(10) . 'p5str = function(o) {' . chr(10) . ' if (o == null) {' . chr(10) . ' return "";' . chr(10) . ' }' . chr(10) . ' if (typeof o === "object" && (o instanceof Array)) {' . chr(10) . ' return CORE.join(["", o]);' . chr(10) . ' }' . chr(10) . ' if (typeof o.p5string === "function") {' . chr(10) . ' return o.p5string();' . chr(10) . ' }' . chr(10) . ' if (typeof o == "number" && Math.abs(o) < 0.0001 && o != 0) {' . chr(10) . ' return o.toExponential().replace(/e-(' . chr(92) . 'd)$/,"e-0$1");' . chr(10) . ' }' . chr(10) . ' if (typeof o === "boolean") {' . chr(10) . ' return o ? "1" : "";' . chr(10) . ' }' . chr(10) . ' if (typeof o !== "string") {' . chr(10) . ' return "" + o;' . chr(10) . ' }' . chr(10) . ' return o;' . chr(10) . '};' . chr(10) . chr(10) . 'p5num = function(o) {' . chr(10) . ' if (o == null) {' . chr(10) . ' return 0;' . chr(10) . ' }' . chr(10) . ' if (typeof o === "object" && (o instanceof Array)) {' . chr(10) . ' return o.length;' . chr(10) . ' }' . chr(10) . ' if (typeof o.p5num === "function") {' . chr(10) . ' return o.p5num();' . chr(10) . ' }' . chr(10) . ' if (typeof o !== "number") {' . chr(10) . ' return parseFloat(p5str(o));' . chr(10) . ' }' . chr(10) . ' return o;' . chr(10) . '};' . chr(10) . chr(10) . 'p5bool = function(o) {' . chr(10) . ' if (o) {' . chr(10) . ' if (typeof o === "boolean") {' . chr(10) . ' return o;' . chr(10) . ' }' . chr(10) . ' if (typeof o === "number") {' . chr(10) . ' return o;' . chr(10) . ' }' . chr(10) . ' if (typeof o === "string") {' . chr(10) . ' return o != "" && o != "0";' . chr(10) . ' }' . chr(10) . ' if (typeof o.p5bool === "function") {' . chr(10) . ' return o.p5bool();' . chr(10) . ' }' . chr(10) . ' if (typeof o.length === "number") {' . chr(10) . ' return o.length;' . chr(10) . ' }' . chr(10) . ' if (o instanceof Error) {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' for (var i in o) {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' return false;' . chr(10) . '};' . chr(10) . chr(10) . 'p5and = function(a, fb) {' . chr(10) . ' if (p5bool(a)) {' . chr(10) . ' return fb();' . chr(10) . ' }' . chr(10) . ' return a;' . chr(10) . '};' . chr(10) . chr(10) . 'p5or = function(a, fb) {' . chr(10) . ' if (p5bool(a)) {' . chr(10) . ' return a;' . chr(10) . ' }' . chr(10) . ' return fb();' . chr(10) . '};' . chr(10) . chr(10) . 'p5defined_or = function(a, fb) {' . chr(10) . ' if (a == null) {' . chr(10) . ' return fb();' . chr(10) . ' }' . chr(10) . ' return a;' . chr(10) . '};' . chr(10) . chr(10) . 'p5cmp = function(a, b) {' . chr(10) . ' return a > b ? 1 : a < b ? -1 : 0 ' . chr(10) . '};' . chr(10) . chr(10) . 'p5complement = function(a) {' . chr(10) . ' return a < 0 ? ~a : 4294967295 - a' . chr(10) . ' // return a < 0 ? ~a : 18446744073709551615 - a' . chr(10) . '};' . chr(10) . chr(10) . 'p5str_replicate = function(o, n) {' . chr(10) . ' n = p5num(n);' . chr(10) . ' return n ? Array(n + 1).join(o) : "";' . chr(10) . '};' . chr(10) . chr(10) . 'p5str_inc = function(s) {' . chr(10) . ' s = p5str(s);' . chr(10) . ' if (s.length < 2) {' . chr(10) . ' if (s.match(/[012345678ABCDEFGHIJKLMNOPQRSTUVWXYabcdefghijklmnopqrstuvwxy]/)) {' . chr(10) . ' return String.fromCharCode(s.charCodeAt(0) + 1);' . chr(10) . ' }' . chr(10) . ' if (s == "9") {' . chr(10) . ' return "10";' . chr(10) . ' }' . chr(10) . ' if (s == "Z") {' . chr(10) . ' return "AA";' . chr(10) . ' }' . chr(10) . ' if (s == "z") {' . chr(10) . ' return "aa";' . chr(10) . ' }' . chr(10) . ' return "1";' . chr(10) . ' }' . chr(10) . ' var c = p5str_inc(s.substr(s.length-1, 1));' . chr(10) . ' if (c.length == 1) {' . chr(10) . ' return s.substr(0, s.length-1) + c;' . chr(10) . ' }' . chr(10) . ' return p5str_inc(s.substr(0, s.length-1)) + c.substr(c.length-1, 1);' . chr(10) . '};' . chr(10) . chr(10) . 'p5for = function(namespace, func, args, cont, label) {' . chr(10) . ' var _redo = false;' . chr(10) . ' var v_old = namespace["v__"];' . chr(10) . ' for(var i = 0; i < args.length; i++) {' . chr(10) . ' namespace["v__"] = args[i];' . chr(10) . ' try {' . chr(10) . ' func()' . chr(10) . ' }' . chr(10) . ' catch(err) {' . chr(10) . ' if (err instanceof p5_error && err.v == label) {' . chr(10) . ' if (err.type == ' . chr(39) . 'last' . chr(39) . ') { return }' . chr(10) . ' else if (err.type == ' . chr(39) . 'redo' . chr(39) . ') { i--; _redo = true }' . chr(10) . ' else if (err.type != ' . chr(39) . 'next' . chr(39) . ') { throw(err) }' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' throw(err)' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' if (cont) {' . chr(10) . ' try {' . chr(10) . ' if (!_redo) { cont() }' . chr(10) . ' }' . chr(10) . ' catch(err) {' . chr(10) . ' if (err instanceof p5_error && err.v == label) {' . chr(10) . ' if (err.type == ' . chr(39) . 'last' . chr(39) . ') { return }' . chr(10) . ' else if (err.type == ' . chr(39) . 'redo' . chr(39) . ') { _redo = true }' . chr(10) . ' else if (err.type != ' . chr(39) . 'next' . chr(39) . ') { throw(err) }' . chr(10) . ' } ' . chr(10) . ' else {' . chr(10) . ' throw(err)' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' namespace["v__"] = v_old;' . chr(10) . '};' . chr(10) . chr(10) . 'p5for_lex = function(func, args, cont, label) {' . chr(10) . ' var _redo = false;' . chr(10) . ' for(var i = 0; i < args.length; i++) {' . chr(10) . ' try {' . chr(10) . ' func(args[i])' . chr(10) . ' }' . chr(10) . ' catch(err) {' . chr(10) . ' if (err instanceof p5_error && err.v == label) {' . chr(10) . ' if (err.type == ' . chr(39) . 'last' . chr(39) . ') { return }' . chr(10) . ' else if (err.type == ' . chr(39) . 'redo' . chr(39) . ') { i--; _redo = true }' . chr(10) . ' else if (err.type != ' . chr(39) . 'next' . chr(39) . ') { throw(err) }' . chr(10) . ' } ' . chr(10) . ' else {' . chr(10) . ' throw(err)' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' if (cont) {' . chr(10) . ' try {' . chr(10) . ' if (!_redo) { cont() }' . chr(10) . ' }' . chr(10) . ' catch(err) {' . chr(10) . ' if (err instanceof p5_error && err.v == label) {' . chr(10) . ' if (err.type == ' . chr(39) . 'last' . chr(39) . ') { return }' . chr(10) . ' else if (err.type == ' . chr(39) . 'redo' . chr(39) . ') { _redo = true }' . chr(10) . ' else if (err.type != ' . chr(39) . 'next' . chr(39) . ') { throw(err) }' . chr(10) . ' } ' . chr(10) . ' else {' . chr(10) . ' throw(err)' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . '};' . chr(10) . chr(10) . 'p5while = function(func, cond, cont, label) {' . chr(10) . ' var _redo = false;' . chr(10) . ' while (_redo || p5bool(cond())) {' . chr(10) . ' _redo = false;' . chr(10) . ' try {' . chr(10) . ' func()' . chr(10) . ' }' . chr(10) . ' catch(err) {' . chr(10) . ' if (err instanceof p5_error && err.v == label) {' . chr(10) . ' if (err.type == ' . chr(39) . 'last' . chr(39) . ') { return }' . chr(10) . ' else if (err.type == ' . chr(39) . 'redo' . chr(39) . ') { _redo = true }' . chr(10) . ' else if (err.type != ' . chr(39) . 'next' . chr(39) . ') { throw(err) }' . chr(10) . ' } ' . chr(10) . ' else {' . chr(10) . ' throw(err)' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' if (cont) {' . chr(10) . ' try {' . chr(10) . ' if (!_redo) { cont() }' . chr(10) . ' }' . chr(10) . ' catch(err) {' . chr(10) . ' if (err instanceof p5_error && err.v == label) {' . chr(10) . ' if (err.type == ' . chr(39) . 'last' . chr(39) . ') { return }' . chr(10) . ' else if (err.type == ' . chr(39) . 'redo' . chr(39) . ') { _redo = true }' . chr(10) . ' else if (err.type != ' . chr(39) . 'next' . chr(39) . ') { throw(err) }' . chr(10) . ' } ' . chr(10) . ' else {' . chr(10) . ' throw(err)' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . '};' . chr(10) . chr(10) . 'p5map = function(namespace, func, args) {' . chr(10) . ' var v_old = namespace["v__"];' . chr(10) . ' var out = [];' . chr(10) . ' for(var i = 0; i < args.length; i++) {' . chr(10) . ' namespace["v__"] = args[i];' . chr(10) . ' var o = p5list_to_a(func(1));' . chr(10) . ' for(var j = 0; j < o.length; j++) {' . chr(10) . ' out.push(o[j]);' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' namespace["v__"] = v_old;' . chr(10) . ' return out;' . chr(10) . '};' . chr(10) . chr(10) . 'p5grep = function(namespace, func, args) {' . chr(10) . ' var v_old = namespace["v__"];' . chr(10) . ' var out = [];' . chr(10) . ' for(var i = 0; i < args.length; i++) {' . chr(10) . ' namespace["v__"] = args[i];' . chr(10) . ' if (p5bool(func(0))) {' . chr(10) . ' out.push(args[i])' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' namespace["v__"] = v_old;' . chr(10) . ' return out;' . chr(10) . '};' . chr(10) . chr(10) . 'p5sort = function(namespace, func, args) {' . chr(10) . ' var a_old = namespace["v_a"];' . chr(10) . ' var b_old = namespace["v_b"];' . chr(10) . ' var out = ' . chr(10) . ' func == null' . chr(10) . ' ? args.sort()' . chr(10) . ' : args.sort(' . chr(10) . ' function(a, b) {' . chr(10) . ' namespace["v_a"] = a;' . chr(10) . ' namespace["v_b"] = b;' . chr(10) . ' return func(0);' . chr(10) . ' }' . chr(10) . ' );' . chr(10) . ' namespace["v_a"] = a_old;' . chr(10) . ' namespace["v_b"] = b_old;' . chr(10) . ' return out;' . chr(10) . '};' . chr(10) . chr(10) . 'perl5_to_js = function( source, namespace, var_env_js, p5want ) {' . chr(10) . ' // CORE.say(["source: [" + source + "]"]);' . chr(10) . chr(10) . ' var strict_old = p5pkg["Perlito5"].v_STRICT;' . chr(10) . ' var var_env_js_old = p5pkg["Perlito5"].v_VAR;' . chr(10) . ' p5pkg["Perlito5"].v_VAR = var_env_js;' . chr(10) . chr(10) . ' var namespace_old = p5pkg["Perlito5"].v_PKG_NAME;' . chr(10) . ' p5pkg["Perlito5"].v_PKG_NAME = namespace;' . chr(10) . chr(10) . ' match = p5call(p5pkg["Perlito5::Grammar"], "exp_stmts", [source, 0]);' . chr(10) . chr(10) . ' if ( !match || match._hash_.to != source.length ) {' . chr(10) . ' CORE.die(["Syntax error in eval near pos ", match._hash_.to]);' . chr(10) . ' }' . chr(10) . chr(10) . ' ast = p5pkg.CORE.bless([' . chr(10) . ' new p5HashRef({' . chr(10) . ' block: p5pkg.CORE.bless([' . chr(10) . ' new p5HashRef({' . chr(10) . ' stmts: p5pkg["Perlito5::Match"].flat([match])' . chr(10) . ' }),' . chr(10) . ' p5pkg["Perlito5::AST::Lit::Block"]' . chr(10) . ' ])' . chr(10) . ' }),' . chr(10) . ' p5pkg["Perlito5::AST::Do"]' . chr(10) . ' ]);' . chr(10) . chr(10) . ' // CORE.say(["ast: [" + ast + "]"]);' . chr(10) . ' js_code = p5call(ast, "emit_javascript3", [0, p5want]);' . chr(10) . ' // CORE.say(["js-source: [" + js_code + "]"]);' . chr(10) . chr(10) . ' p5pkg["Perlito5"].v_PKG_NAME = namespace_old;' . chr(10) . ' p5pkg["Perlito5"].v_VAR = var_env_js_old;' . chr(10) . ' p5pkg["Perlito5"].v_STRICT = strict_old;' . chr(10) . ' return js_code;' . chr(10) . '}' . chr(10) . chr(10))))
+ return ((('//' . chr(10) . '// lib/Perlito5/Javascript3/Runtime.js' . chr(10) . '//' . chr(10) . '// Runtime for "Perlito" Perl5-in-Javascript3' . chr(10) . '//' . chr(10) . '// AUTHORS' . chr(10) . '//' . chr(10) . '// Flavio Soibelmann Glock fglock@gmail.com' . chr(10) . '//' . chr(10) . '// COPYRIGHT' . chr(10) . '//' . chr(10) . '// Copyright 2009, 2010, 2011, 2012 by Flavio Soibelmann Glock and others.' . chr(10) . '//' . chr(10) . '// This program is free software; you can redistribute it and/or modify it' . chr(10) . '// under the same terms as Perl itself.' . chr(10) . '//' . chr(10) . '// See http://www.perl.com/perl/misc/Artistic.html' . chr(10) . chr(10) . 'var isNode = typeof require != "undefined";' . chr(10) . chr(10) . 'if (typeof p5pkg !== "object") {' . chr(10) . ' p5pkg = {};' . chr(10) . ' p5LOCAL = [];' . chr(10) . chr(10) . ' var universal = function () {};' . chr(10) . ' p5pkg.UNIVERSAL = new universal();' . chr(10) . ' p5pkg.UNIVERSAL._ref_ = "UNIVERSAL";' . chr(10) . ' p5pkg.UNIVERSAL.isa = function (List__) {' . chr(10) . ' // TODO - use @ISA' . chr(10) . ' return List__[0]._class_._ref_ == List__[1]' . chr(10) . ' };' . chr(10) . ' p5pkg.UNIVERSAL.can = function (List__) {' . chr(10) . ' var o = List__[0];' . chr(10) . ' var s = List__[1];' . chr(10) . ' if ( s.indexOf("::") == -1 ) {' . chr(10) . ' return p5method_lookup(s, o._class_._ref__, {})' . chr(10) . ' }' . chr(10) . ' var c = s.split("::");' . chr(10) . ' s = c.pop(); ' . chr(10) . ' return p5method_lookup(s, c.join("::"), {});' . chr(10) . ' };' . chr(10) . ' p5pkg.UNIVERSAL.DOES = p5pkg.UNIVERSAL.can;' . chr(10) . chr(10) . ' var core = function () {};' . chr(10) . ' p5pkg["CORE"] = new core();' . chr(10) . ' p5pkg["CORE"]._ref_ = "CORE";' . chr(10) . chr(10) . ' var core_global = function () {};' . chr(10) . ' core_global.prototype = p5pkg.CORE;' . chr(10) . ' p5pkg["CORE::GLOBAL"] = new core_global();' . chr(10) . ' p5pkg["CORE::GLOBAL"]._ref_ = "CORE::GLOBAL";' . chr(10) . chr(10) . ' p5_error = function (type, v) {' . chr(10) . ' this.type = type;' . chr(10) . ' this.v = v;' . chr(10) . ' this.toString = function(){' . chr(10) . ' if (this.type == ' . chr(39) . 'break' . chr(39) . ') {' . chr(10) . ' return ' . chr(39) . 'Can' . chr(92) . chr(39) . 't "break" outside a given block' . chr(39) . chr(10) . ' }' . chr(10) . ' if (this.type == ' . chr(39) . 'next' . chr(39) . ' || this.type == ' . chr(39) . 'last' . chr(39) . ' || this.type == ' . chr(39) . 'redo' . chr(39) . ') {' . chr(10) . ' if (this.v == "") { return ' . chr(39) . 'Can' . chr(92) . chr(39) . 't "' . chr(39) . ' + this.type + ' . chr(39) . '" outside a loop block' . chr(39) . ' }' . chr(10) . ' return ' . chr(39) . 'Label not found for "' . chr(39) . ' + this.type + ' . chr(39) . ' ' . chr(39) . ' + this.v + ' . chr(39) . '"' . chr(39) . ';' . chr(10) . ' }' . chr(10) . ' return this.v;' . chr(10) . ' };' . chr(10) . ' };' . chr(10) . ' p5_error.prototype = Error.prototype;' . chr(10) . '}' . chr(10) . chr(10) . 'function p5make_package(pkg_name) {' . chr(10) . ' if (!p5pkg.hasOwnProperty(pkg_name)) {' . chr(10) . ' var tmp = function () {};' . chr(10) . ' tmp.prototype = p5pkg["CORE::GLOBAL"];' . chr(10) . ' p5pkg[pkg_name] = new tmp();' . chr(10) . ' p5pkg[pkg_name]._ref_ = pkg_name;' . chr(10) . ' p5pkg[pkg_name]._class_ = p5pkg[pkg_name]; // XXX memory leak' . chr(10) . chr(10) . ' // TODO - add the other package global variables' . chr(10) . ' p5pkg[pkg_name]["List_ISA"] = new p5Array([]);' . chr(10) . ' p5pkg[pkg_name]["v_a"] = new p5Scalar(null);' . chr(10) . ' p5pkg[pkg_name]["v_b"] = new p5Scalar(null);' . chr(10) . ' p5pkg[pkg_name]["v__"] = new p5Scalar(null);' . chr(10) . ' p5pkg[pkg_name]["v_AUTOLOAD"] = new p5Scalar(null);' . chr(10) . ' }' . chr(10) . ' return p5pkg[pkg_name];' . chr(10) . '}' . chr(10) . chr(10) . 'function p5code_lookup_by_name(package_name, sub_name) {' . chr(10) . ' // sub_name can have an optional namespace' . chr(10) . ' var parts = sub_name.split(/::/);' . chr(10) . ' if (parts.length > 1) {' . chr(10) . ' sub_name = parts.pop();' . chr(10) . ' package_name = parts.join("::");' . chr(10) . ' }' . chr(10) . ' if (p5pkg.hasOwnProperty(package_name)) {' . chr(10) . ' var c = p5pkg[package_name];' . chr(10) . ' if ( c.hasOwnProperty(sub_name) ) {' . chr(10) . ' return c[sub_name]' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' return null;' . chr(10) . '}' . chr(10) . chr(10) . 'function p5get_class_for_method(method, class_name, seen) {' . chr(10) . ' // default mro' . chr(10) . ' // TODO - cache the methods that were already looked up' . chr(10) . ' if ( p5pkg[class_name].hasOwnProperty(method) ) {' . chr(10) . ' return class_name' . chr(10) . ' }' . chr(10) . ' var isa = p5pkg[class_name].List_ISA;' . chr(10) . ' for (var i = 0; i < isa.length; i++) {' . chr(10) . ' if (!seen[isa[i]]) {' . chr(10) . ' var m = p5get_class_for_method(method, isa[i]);' . chr(10) . ' if (m) {' . chr(10) . ' return m ' . chr(10) . ' }' . chr(10) . ' seen[isa[i]]++;' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . '}' . chr(10) . chr(10) . 'function p5method_lookup(method, class_name, seen) {' . chr(10) . ' var c = p5get_class_for_method(method, class_name, seen);' . chr(10) . ' if (c) {' . chr(10) . ' return p5pkg[c][method]' . chr(10) . ' }' . chr(10) . ' if ( p5pkg.UNIVERSAL.hasOwnProperty(method) ) {' . chr(10) . ' return p5pkg.UNIVERSAL[method]' . chr(10) . ' }' . chr(10) . '}' . chr(10) . chr(10) . 'function p5call(invocant, method, list) {' . chr(10) . ' list.unshift(invocant);' . chr(10) . chr(10) . ' if (invocant instanceof p5Scalar) {' . chr(10) . ' // TODO - move p5call() to p5Scalar method' . chr(10) . ' invocant = invocant._v_;' . chr(10) . ' }' . chr(10) . chr(10) . ' if ( invocant.hasOwnProperty("_class_") ) {' . chr(10) . chr(10) . ' if ( invocant._class_.hasOwnProperty(method) ) {' . chr(10) . ' return invocant._class_[method](list)' . chr(10) . ' }' . chr(10) . ' var m = p5method_lookup(method, invocant._class_._ref_, {});' . chr(10) . ' if (m) {' . chr(10) . ' return m(list)' . chr(10) . ' }' . chr(10) . chr(10) . ' // method can have an optional namespace' . chr(10) . ' var pkg_name = method.split(/::/);' . chr(10) . ' if (pkg_name.length > 1) {' . chr(10) . ' var name = pkg_name.pop();' . chr(10) . ' pkg_name = pkg_name.join("::");' . chr(10) . ' m = p5method_lookup(name, pkg_name, {});' . chr(10) . ' if (m) {' . chr(10) . ' return m(list)' . chr(10) . ' }' . chr(10) . ' p5pkg.CORE.die(["method not found: ", name, " in class ", pkg_name]);' . chr(10) . ' }' . chr(10) . chr(10) . ' pkg_name = p5get_class_for_method(' . chr(39) . 'AUTOLOAD' . chr(39) . ', invocant._class_._ref_, {}) || p5get_class_for_method(' . chr(39) . 'AUTOLOAD' . chr(39) . ', "UNIVERSAL", {});' . chr(10) . ' if (pkg_name) {' . chr(10) . ' p5pkg[pkg_name]["v_AUTOLOAD"] = invocant._class_._ref_ + "::" + method;' . chr(10) . ' return p5pkg[pkg_name]["AUTOLOAD"](list);' . chr(10) . ' }' . chr(10) . chr(10) . ' p5pkg.CORE.die(["method not found: ", method, " in class ", invocant._class_._ref_]);' . chr(10) . chr(10) . ' }' . chr(10) . chr(10) . ' // the invocant doesn' . chr(39) . 't have a class' . chr(10) . chr(10) . ' if (typeof invocant === "string") {' . chr(10) . ' var aclass = p5make_package(invocant);' . chr(10) . ' return p5call(aclass, method, list);' . chr(10) . ' }' . chr(10) . chr(10) . ' p5pkg.CORE.die(["Can' . chr(39) . 't call method ", method, " on unblessed reference"]);' . chr(10) . chr(10) . '}' . chr(10) . chr(10) . 'p5make_package("main");' . chr(10) . 'p5pkg["main"]["v_@"] = ""; // $@' . chr(10) . 'p5pkg["main"]["v_|"] = 0; // $|' . chr(10) . 'p5pkg["main"]["List_#"] = new p5Array([]); // @#' . chr(10) . 'p5pkg["main"]["v_^O"] = isNode ? "node.js" : "javascript3";' . chr(10) . 'p5pkg["main"]["List_INC"] = new p5Array([]);' . chr(10) . 'p5pkg["main"]["Hash_INC"] = {};' . chr(10) . 'p5pkg["main"]["List_ARGV"] = new p5Array([]);' . chr(10) . 'p5pkg["main"]["Hash_ENV"] = {};' . chr(10) . 'if (isNode) {' . chr(10) . ' p5pkg["main"]["List_ARGV"] = new p5Array(process.argv.splice(2));' . chr(10) . ' p5pkg["main"]["Hash_ENV"] = process.env;' . chr(10) . ' p5pkg["main"]["v_$"] = process.pid;' . chr(10) . '} else if (typeof arguments === "object") {' . chr(10) . ' p5pkg["main"]["List_ARGV"] = new p5Array(arguments);' . chr(10) . '}' . chr(10) . chr(10) . 'p5make_package("Perlito5");' . chr(10) . 'p5make_package("Perlito5::IO");' . chr(10) . 'p5make_package("Perlito5::Runtime");' . chr(10) . 'p5make_package("Perlito5::Grammar");' . chr(10) . chr(10) . 'function p5make_sub(pkg_name, sub_name, func) {' . chr(10) . ' p5pkg[pkg_name][sub_name] = func;' . chr(10) . '}' . chr(10) . chr(10) . 'function p5set_glob(name, data) {' . chr(10) . ' if ( name.indexOf("::") == -1 ) {' . chr(10) . ' p5pkg[p5pkg["Perlito5"].v_PKG_NAME][name] = data;' . chr(10) . ' return data;' . chr(10) . ' }' . chr(10) . ' var c = name.split("::");' . chr(10) . ' s = c.pop(); ' . chr(10) . ' var pkg = c.join("::");' . chr(10) . ' p5make_package(pkg);' . chr(10) . ' p5pkg[pkg][s] = data;' . chr(10) . ' return data;' . chr(10) . '}' . chr(10) . chr(10) . 'function p5set_local(namespace, name, sigil) {' . chr(10) . ' var v = name;' . chr(10) . ' if (sigil == "$") {' . chr(10) . ' v = "v_"+name;' . chr(10) . ' }' . chr(10) . ' p5LOCAL.push([namespace, v, namespace[v]]);' . chr(10) . '}' . chr(10) . chr(10) . 'function p5cleanup_local(idx, value) {' . chr(10) . ' while (p5LOCAL.length > idx) {' . chr(10) . ' l = p5LOCAL.pop();' . chr(10) . ' l[0][l[1]] = l[2];' . chr(10) . ' }' . chr(10) . ' return value;' . chr(10) . '}' . chr(10) . chr(10) . 'var sigils = { ' . chr(39) . '@' . chr(39) . ' : ' . chr(39) . 'List_' . chr(39) . ', ' . chr(39) . '%' . chr(39) . ' : ' . chr(39) . 'Hash_' . chr(39) . ', ' . chr(39) . '$' . chr(39) . ' : ' . chr(39) . 'v_' . chr(39) . ' };' . chr(10) . 'function p5global(sigil, namespace, name) {' . chr(10) . ' // TODO - autovivify namespace' . chr(10) . ' v = p5pkg[namespace][sigils[sigil] + name ];' . chr(10) . ' if (v != null) {' . chr(10) . ' return v;' . chr(10) . ' }' . chr(10) . ' if (sigil == ' . chr(39) . '$' . chr(39) . ') {' . chr(10) . ' p5pkg[namespace][sigils[sigil] + name ] = new p5Scalar(null);' . chr(10) . ' }' . chr(10) . ' else if (sigil == ' . chr(39) . '@' . chr(39) . ') {' . chr(10) . ' p5pkg[namespace][sigils[sigil] + name ] = new p5Array([]);' . chr(10) . ' }' . chr(10) . ' else if (sigil == ' . chr(39) . '%' . chr(39) . ') {' . chr(10) . ' p5pkg[namespace][sigils[sigil] + name ] = new p5Hash({});' . chr(10) . ' }' . chr(10) . ' return p5pkg[namespace][sigils[sigil] + name ];' . chr(10) . '}' . chr(10) . chr(10) . 'function p5HashRef(o) {' . chr(10) . ' this._href_ = o;' . chr(10) . ' this._ref_ = "HASH";' . chr(10) . ' this.p5bool = function() { return 1 };' . chr(10) . ' this.p5string = function() {' . chr(10) . ' return "HASH(0x0000)"; // TODO' . chr(10) . ' };' . chr(10) . ' this.hderef = function() {' . chr(10) . ' return this._href_;' . chr(10) . ' };' . chr(10) . ' this.hset = function(i, v) {' . chr(10) . ' this._href_._hash_[i] = v;' . chr(10) . ' return v;' . chr(10) . ' };' . chr(10) . ' this.hget = function(i, autoviv) {' . chr(10) . ' return this._href_.hget(i, autoviv);' . chr(10) . ' }' . chr(10) . '}' . chr(10) . chr(10) . 'function p5ArrayRef(o) {' . chr(10) . ' this._aref_ = o;' . chr(10) . ' this._ref_ = "ARRAY";' . chr(10) . ' this.p5bool = function() { return 1 };' . chr(10) . ' this.p5string = function() {' . chr(10) . ' return "ARRAY(0x0000)"; // TODO' . chr(10) . ' };' . chr(10) . ' this.aderef = function() {' . chr(10) . ' return this._aref_;' . chr(10) . ' };' . chr(10) . ' this.aset = function(i, v) {' . chr(10) . ' this._aref_._array_[i >= 0 ? i : this._aref_._array_.length + i] = v;' . chr(10) . ' return v;' . chr(10) . ' }' . chr(10) . ' this.aget = function(i, autoviv) {' . chr(10) . ' return this._aref_.aget(i, autoviv);' . chr(10) . ' }' . chr(10) . '}' . chr(10) . chr(10) . 'function p5ScalarRef(o) {' . chr(10) . ' this._scalar_ = o;' . chr(10) . ' this._ref_ = "SCALAR";' . chr(10) . ' this.p5bool = function() { return 1 };' . chr(10) . ' this.p5string = function() {' . chr(10) . ' return "SCALAR(0x0000)"; // TODO' . chr(10) . ' };' . chr(10) . ' this.sderef = function(i) {' . chr(10) . ' return this._scalar_;' . chr(10) . ' };' . chr(10) . '}' . chr(10) . chr(10) . 'function p5GlobRef(o) {' . chr(10) . ' this._scalar_ = o;' . chr(10) . ' this._ref_ = "GLOB";' . chr(10) . ' this.p5bool = function() { return 1 };' . chr(10) . ' this.p5string = function() {' . chr(10) . ' return "GLOB(0x0000)"; // TODO' . chr(10) . ' };' . chr(10) . '}' . chr(10) . chr(10) . 'function p5Array(o) {' . chr(10) . ' // TODO - array slice' . chr(10) . ' this._array_ = o;' . chr(10) . ' this._ref_ = "";' . chr(10) . ' this.p5bool = function() {' . chr(10) . ' return this._array_.length != 0' . chr(10) . ' };' . chr(10) . ' this.aset = function(i, v) {' . chr(10) . ' this._array_[i >= 0 ? i : this._array_.length + i] = v;' . chr(10) . ' return v;' . chr(10) . ' };' . chr(10) . ' this.aget = function(i, autoviv) {' . chr(10) . ' if (i < 0) {' . chr(10) . ' i = this._array_.length + i;' . chr(10) . ' }' . chr(10) . ' var v = this._array_[i];' . chr(10) . ' if (v != null) {' . chr(10) . ' return v;' . chr(10) . ' }' . chr(10) . ' if (autoviv == ' . chr(39) . 'array' . chr(39) . ') {' . chr(10) . ' this._array_[i] = new p5ArrayRef(new p5Array([]));' . chr(10) . ' }' . chr(10) . ' else if (autoviv == ' . chr(39) . 'hash' . chr(39) . ') {' . chr(10) . ' this._array_[i] = new p5HashRef(new p5Hash({}));' . chr(10) . ' }' . chr(10) . ' return this._array_[i];' . chr(10) . ' };' . chr(10) . ' this.assign = function(a) {' . chr(10) . ' if (a instanceof Array) {' . chr(10) . ' // TODO - cleanup, this shouldn' . chr(39) . 't happen' . chr(10) . ' this._array_ = a;' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' this._array_ = a._array_;' . chr(10) . ' }' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . '}' . chr(10) . chr(10) . 'function p5Hash(o) {' . chr(10) . ' // TODO - hash slice' . chr(10) . ' this._hash_ = o;' . chr(10) . ' this._ref_ = "";' . chr(10) . ' this.p5bool = function() {' . chr(10) . ' o = this._hash_;' . chr(10) . ' for (var i in o) {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' return false;' . chr(10) . ' };' . chr(10) . ' this.hset = function(i, v) {' . chr(10) . ' this._hash_[i] = v;' . chr(10) . ' return v;' . chr(10) . ' };' . chr(10) . ' this.hget = function(i, autoviv) {' . chr(10) . ' var v = this._hash_[i];' . chr(10) . ' if (v != null) {' . chr(10) . ' return v;' . chr(10) . ' }' . chr(10) . ' if (autoviv == ' . chr(39) . 'array' . chr(39) . ') {' . chr(10) . ' this._hash_[i] = new p5ArrayRef(new p5Array([]));' . chr(10) . ' }' . chr(10) . ' else if (autoviv == ' . chr(39) . 'hash' . chr(39) . ') {' . chr(10) . ' this._hash_[i] = new p5HashRef(new p5Hash({}));' . chr(10) . ' }' . chr(10) . ' return this._hash_[i];' . chr(10) . ' };' . chr(10) . ' this.assign = function(h) {' . chr(10) . ' if (h instanceof p5Hash) {' . chr(10) . ' this._hash_ = h._hash_;' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' // TODO - cleanup, this shouldn' . chr(39) . 't happen' . chr(10) . ' this._hash_ = h;' . chr(10) . ' }' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . '}' . chr(10) . chr(10) . 'function p5Scalar(o) {' . chr(10) . ' this._v_ = o;' . chr(10) . ' this._ref_ = "";' . chr(10) . chr(10) . ' // be a value' . chr(10) . ' this.p5bool = function() {' . chr(10) . ' return p5bool(this._v_);' . chr(10) . ' };' . chr(10) . ' this.p5string = function() {' . chr(10) . ' return p5str(this._v_);' . chr(10) . ' };' . chr(10) . ' this.p5num = function() {' . chr(10) . ' return p5num(this._v_);' . chr(10) . ' };' . chr(10) . ' this.p5code = function() {' . chr(10) . ' return p5code(this._v_);' . chr(10) . ' };' . chr(10) . chr(10) . ' // be a scalar ref' . chr(10) . ' this.sderef = function(i) {' . chr(10) . ' return this._v_.sderef;' . chr(10) . ' };' . chr(10) . chr(10) . ' // be an array ref' . chr(10) . ' this.aderef = function() {' . chr(10) . ' // TODO - autovivify array (with proxy object?)' . chr(10) . ' return this._v_.aderef();' . chr(10) . ' };' . chr(10) . ' this.aget = function(i, autoviv) {' . chr(10) . ' // TODO - autovivify array (with proxy object?)' . chr(10) . ' if (this._v_ == null) {' . chr(10) . ' this._v_ = new p5ArrayRef(new p5Array([]));' . chr(10) . ' }' . chr(10) . ' return this._v_.aget(i, autoviv);' . chr(10) . ' };' . chr(10) . ' this.aset = function(i, v) {' . chr(10) . ' if (this._v_ == null) {' . chr(10) . ' this._v_ = new p5ArrayRef(new p5Array([]));' . chr(10) . ' }' . chr(10) . ' return this._v_.aset(i, v);' . chr(10) . ' };' . chr(10) . chr(10) . ' // be a hash ref' . chr(10) . ' this.hderef = function() {' . chr(10) . ' // TODO - autovivify hash (with proxy object?)' . chr(10) . ' if (this._v_ == null) {' . chr(10) . ' this._v_ = new p5HashRef(new p5Hash([]));' . chr(10) . ' }' . chr(10) . ' return this._v_.hderef();' . chr(10) . ' };' . chr(10) . ' this.hget = function(i, autoviv) {' . chr(10) . ' // TODO - autovivify hash (with proxy object?)' . chr(10) . ' if (this._v_ == null) {' . chr(10) . ' this._v_ = new p5HashRef(new p5Hash([]));' . chr(10) . ' }' . chr(10) . ' return this._v_.hget(i, autoviv);' . chr(10) . ' }' . chr(10) . ' this.hset = function(i, v) {' . chr(10) . ' if (this._v_ == null) {' . chr(10) . ' this._v_ = new p5HashRef(new p5Hash([]));' . chr(10) . ' }' . chr(10) . ' return this._v_.hset(i, v);' . chr(10) . ' }' . chr(10) . chr(10) . ' // be a container' . chr(10) . ' this.vset = function(v) {' . chr(10) . ' this._v_ = v;' . chr(10) . ' return v;' . chr(10) . ' };' . chr(10) . ' this.vget = function() {' . chr(10) . ' return this._v_;' . chr(10) . ' };' . chr(10) . ' this.assign = function(v) {' . chr(10) . ' if (v instanceof p5Scalar) {' . chr(10) . ' this._v_ = v._v_;' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' // TODO - cleanup, this shouldn' . chr(39) . 't happen' . chr(10) . ' this._v_ = v;' . chr(10) . ' }' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . '}' . chr(10) . chr(10) . 'p5list_to_a = function() {' . chr(10) . ' var res = [];' . chr(10) . ' for (i = 0; i < arguments.length; i++) {' . chr(10) . ' var o = arguments[i];' . chr(10) . ' if ( o == null' . chr(10) . ' || o._class_ // perl5 blessed reference' . chr(10) . ' || o._ref_ // perl5 un-blessed reference' . chr(10) . ' )' . chr(10) . ' {' . chr(10) . ' res.push(o);' . chr(10) . ' }' . chr(10) . ' else if (o instanceof p5Array) {' . chr(10) . ' // perl5 array' . chr(10) . ' for (j = 0; j < o._array_.length; j++) {' . chr(10) . ' res.push(o._array_[j]);' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' else if (o instanceof Array) {' . chr(10) . ' // js array' . chr(10) . ' for (j = 0; j < o.length; j++) {' . chr(10) . ' res.push(o[j]);' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' else if (o instanceof p5Hash) {' . chr(10) . ' // perl5 hash' . chr(10) . ' for(var j in o._hash_) {' . chr(10) . ' if (o._hash_.hasOwnProperty(j)) {' . chr(10) . ' res.push(j);' . chr(10) . ' res.push(o._hash_[j]);' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' else if (typeof o === "object") {' . chr(10) . ' // perl5 hash' . chr(10) . ' for(var j in o) {' . chr(10) . ' if (o.hasOwnProperty(j)) {' . chr(10) . ' res.push(j);' . chr(10) . ' res.push(o[j]);' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' // non-ref' . chr(10) . ' res.push(o);' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' return res;' . chr(10) . '};' . chr(10) . chr(10) . 'p5a_to_h = function(a) {' . chr(10) . ' var res = {};' . chr(10) . ' for (i = 0; i < a.length; i+=2) {' . chr(10) . ' res[p5str(a[i])] = a[i+1];' . chr(10) . ' }' . chr(10) . ' return res;' . chr(10) . '};' . chr(10) . chr(10) . 'if (isNode) {' . chr(10) . ' var fs = require("fs");' . chr(10) . ' p5make_sub("Perlito5::IO", "slurp", function(List__) {' . chr(10) . ' return fs.readFileSync(List__[0],"utf8");' . chr(10) . ' });' . chr(10) . '} else {' . chr(10) . ' p5make_sub("Perlito5::IO", "slurp", function(List__) {' . chr(10) . ' var filename = List__[0];' . chr(10) . ' if (typeof readFile == "function") {' . chr(10) . ' return readFile(filename);' . chr(10) . ' }' . chr(10) . ' if (typeof read == "function") {' . chr(10) . ' // v8' . chr(10) . ' return read(filename);' . chr(10) . ' }' . chr(10) . ' p5pkg.CORE.die(["Perlito5::IO::slurp() not implemented"]);' . chr(10) . ' });' . chr(10) . '}' . chr(10) . chr(10) . 'p5context = function(List__, p5want) {' . chr(10) . ' if (p5want) {' . chr(10) . ' return p5list_to_a.apply(null, List__);' . chr(10) . ' }' . chr(10) . ' // scalar: return the last value' . chr(10) . ' var o = List__;' . chr(10) . ' while (o instanceof Array) {' . chr(10) . ' o = o.length' . chr(10) . ' ? o[o.length-1]' . chr(10) . ' : null;' . chr(10) . ' }' . chr(10) . ' return o;' . chr(10) . '}' . chr(10) . chr(10) . 'p5code = function(o) {' . chr(10) . ' if (typeof o === "function") {' . chr(10) . ' return o;' . chr(10) . ' }' . chr(10) . ' return o.p5code();' . chr(10) . '};' . chr(10) . chr(10) . 'p5str = function(o) {' . chr(10) . ' if (o == null) {' . chr(10) . ' return "";' . chr(10) . ' }' . chr(10) . ' if (typeof o === "object" && (o instanceof Array)) {' . chr(10) . ' return CORE.join(["", o]);' . chr(10) . ' }' . chr(10) . ' if (typeof o.p5string === "function") {' . chr(10) . ' return o.p5string();' . chr(10) . ' }' . chr(10) . ' if (typeof o == "number" && Math.abs(o) < 0.0001 && o != 0) {' . chr(10) . ' return o.toExponential().replace(/e-(' . chr(92) . 'd)$/,"e-0$1");' . chr(10) . ' }' . chr(10) . ' if (typeof o === "boolean") {' . chr(10) . ' return o ? "1" : "";' . chr(10) . ' }' . chr(10) . ' if (typeof o !== "string") {' . chr(10) . ' return "" + o;' . chr(10) . ' }' . chr(10) . ' return o;' . chr(10) . '};' . chr(10) . chr(10) . 'p5num = function(o) {' . chr(10) . ' if (o == null) {' . chr(10) . ' return 0;' . chr(10) . ' }' . chr(10) . ' if (typeof o === "object" && (o instanceof Array)) {' . chr(10) . ' return o.length;' . chr(10) . ' }' . chr(10) . ' if (typeof o.p5num === "function") {' . chr(10) . ' return o.p5num();' . chr(10) . ' }' . chr(10) . ' if (typeof o !== "number") {' . chr(10) . ' return parseFloat(p5str(o));' . chr(10) . ' }' . chr(10) . ' return o;' . chr(10) . '};' . chr(10) . chr(10) . 'p5bool = function(o) {' . chr(10) . ' if (o) {' . chr(10) . ' if (typeof o === "boolean") {' . chr(10) . ' return o;' . chr(10) . ' }' . chr(10) . ' if (typeof o === "number") {' . chr(10) . ' return o;' . chr(10) . ' }' . chr(10) . ' if (typeof o === "string") {' . chr(10) . ' return o != "" && o != "0";' . chr(10) . ' }' . chr(10) . ' if (typeof o.p5bool === "function") {' . chr(10) . ' return o.p5bool();' . chr(10) . ' }' . chr(10) . ' if (typeof o.length === "number") {' . chr(10) . ' return o.length;' . chr(10) . ' }' . chr(10) . ' if (o instanceof Error) {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' for (var i in o) {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' return false;' . chr(10) . '};' . chr(10) . chr(10) . 'p5and = function(a, fb) {' . chr(10) . ' if (p5bool(a)) {' . chr(10) . ' return fb();' . chr(10) . ' }' . chr(10) . ' return a;' . chr(10) . '};' . chr(10) . chr(10) . 'p5or = function(a, fb) {' . chr(10) . ' if (p5bool(a)) {' . chr(10) . ' return a;' . chr(10) . ' }' . chr(10) . ' return fb();' . chr(10) . '};' . chr(10) . chr(10) . 'p5defined_or = function(a, fb) {' . chr(10) . ' if (a == null) {' . chr(10) . ' return fb();' . chr(10) . ' }' . chr(10) . ' return a;' . chr(10) . '};' . chr(10) . chr(10) . 'p5cmp = function(a, b) {' . chr(10) . ' return a > b ? 1 : a < b ? -1 : 0 ' . chr(10) . '};' . chr(10) . chr(10) . 'p5complement = function(a) {' . chr(10) . ' return a < 0 ? ~a : 4294967295 - a' . chr(10) . ' // return a < 0 ? ~a : 18446744073709551615 - a' . chr(10) . '};' . chr(10) . chr(10) . 'p5str_replicate = function(o, n) {' . chr(10) . ' n = p5num(n);' . chr(10) . ' return n ? Array(n + 1).join(o) : "";' . chr(10) . '};' . chr(10) . chr(10) . 'p5str_inc = function(s) {' . chr(10) . ' s = p5str(s);' . chr(10) . ' if (s.length < 2) {' . chr(10) . ' if (s.match(/[012345678ABCDEFGHIJKLMNOPQRSTUVWXYabcdefghijklmnopqrstuvwxy]/)) {' . chr(10) . ' return String.fromCharCode(s.charCodeAt(0) + 1);' . chr(10) . ' }' . chr(10) . ' if (s == "9") {' . chr(10) . ' return "10";' . chr(10) . ' }' . chr(10) . ' if (s == "Z") {' . chr(10) . ' return "AA";' . chr(10) . ' }' . chr(10) . ' if (s == "z") {' . chr(10) . ' return "aa";' . chr(10) . ' }' . chr(10) . ' return "1";' . chr(10) . ' }' . chr(10) . ' var c = p5str_inc(s.substr(s.length-1, 1));' . chr(10) . ' if (c.length == 1) {' . chr(10) . ' return s.substr(0, s.length-1) + c;' . chr(10) . ' }' . chr(10) . ' return p5str_inc(s.substr(0, s.length-1)) + c.substr(c.length-1, 1);' . chr(10) . '};' . chr(10) . chr(10) . 'p5for = function(namespace, func, args, cont, label) {' . chr(10) . ' var _redo = false;' . chr(10) . ' var v_old = namespace["v__"];' . chr(10) . ' for(var i = 0; i < args.length; i++) {' . chr(10) . ' namespace["v__"] = args[i];' . chr(10) . ' try {' . chr(10) . ' func()' . chr(10) . ' }' . chr(10) . ' catch(err) {' . chr(10) . ' if (err instanceof p5_error && err.v == label) {' . chr(10) . ' if (err.type == ' . chr(39) . 'last' . chr(39) . ') { return }' . chr(10) . ' else if (err.type == ' . chr(39) . 'redo' . chr(39) . ') { i--; _redo = true }' . chr(10) . ' else if (err.type != ' . chr(39) . 'next' . chr(39) . ') { throw(err) }' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' throw(err)' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' if (cont) {' . chr(10) . ' try {' . chr(10) . ' if (!_redo) { cont() }' . chr(10) . ' }' . chr(10) . ' catch(err) {' . chr(10) . ' if (err instanceof p5_error && err.v == label) {' . chr(10) . ' if (err.type == ' . chr(39) . 'last' . chr(39) . ') { return }' . chr(10) . ' else if (err.type == ' . chr(39) . 'redo' . chr(39) . ') { _redo = true }' . chr(10) . ' else if (err.type != ' . chr(39) . 'next' . chr(39) . ') { throw(err) }' . chr(10) . ' } ' . chr(10) . ' else {' . chr(10) . ' throw(err)' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' namespace["v__"] = v_old;' . chr(10) . '};' . chr(10) . chr(10) . 'p5for_lex = function(func, args, cont, label) {' . chr(10) . ' var _redo = false;' . chr(10) . ' for(var i = 0; i < args.length; i++) {' . chr(10) . ' try {' . chr(10) . ' func(args[i])' . chr(10) . ' }' . chr(10) . ' catch(err) {' . chr(10) . ' if (err instanceof p5_error && err.v == label) {' . chr(10) . ' if (err.type == ' . chr(39) . 'last' . chr(39) . ') { return }' . chr(10) . ' else if (err.type == ' . chr(39) . 'redo' . chr(39) . ') { i--; _redo = true }' . chr(10) . ' else if (err.type != ' . chr(39) . 'next' . chr(39) . ') { throw(err) }' . chr(10) . ' } ' . chr(10) . ' else {' . chr(10) . ' throw(err)' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' if (cont) {' . chr(10) . ' try {' . chr(10) . ' if (!_redo) { cont() }' . chr(10) . ' }' . chr(10) . ' catch(err) {' . chr(10) . ' if (err instanceof p5_error && err.v == label) {' . chr(10) . ' if (err.type == ' . chr(39) . 'last' . chr(39) . ') { return }' . chr(10) . ' else if (err.type == ' . chr(39) . 'redo' . chr(39) . ') { _redo = true }' . chr(10) . ' else if (err.type != ' . chr(39) . 'next' . chr(39) . ') { throw(err) }' . chr(10) . ' } ' . chr(10) . ' else {' . chr(10) . ' throw(err)' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . '};' . chr(10) . chr(10) . 'p5while = function(func, cond, cont, label) {' . chr(10) . ' var _redo = false;' . chr(10) . ' while (_redo || p5bool(cond())) {' . chr(10) . ' _redo = false;' . chr(10) . ' try {' . chr(10) . ' func()' . chr(10) . ' }' . chr(10) . ' catch(err) {' . chr(10) . ' if (err instanceof p5_error && err.v == label) {' . chr(10) . ' if (err.type == ' . chr(39) . 'last' . chr(39) . ') { return }' . chr(10) . ' else if (err.type == ' . chr(39) . 'redo' . chr(39) . ') { _redo = true }' . chr(10) . ' else if (err.type != ' . chr(39) . 'next' . chr(39) . ') { throw(err) }' . chr(10) . ' } ' . chr(10) . ' else {' . chr(10) . ' throw(err)' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' if (cont) {' . chr(10) . ' try {' . chr(10) . ' if (!_redo) { cont() }' . chr(10) . ' }' . chr(10) . ' catch(err) {' . chr(10) . ' if (err instanceof p5_error && err.v == label) {' . chr(10) . ' if (err.type == ' . chr(39) . 'last' . chr(39) . ') { return }' . chr(10) . ' else if (err.type == ' . chr(39) . 'redo' . chr(39) . ') { _redo = true }' . chr(10) . ' else if (err.type != ' . chr(39) . 'next' . chr(39) . ') { throw(err) }' . chr(10) . ' } ' . chr(10) . ' else {' . chr(10) . ' throw(err)' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . '};' . chr(10) . chr(10) . 'p5map = function(namespace, func, args) {' . chr(10) . ' var v_old = namespace["v__"];' . chr(10) . ' var out = [];' . chr(10) . ' for(var i = 0; i < args.length; i++) {' . chr(10) . ' namespace["v__"] = args[i];' . chr(10) . ' var o = p5list_to_a(func(1));' . chr(10) . ' for(var j = 0; j < o.length; j++) {' . chr(10) . ' out.push(o[j]);' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' namespace["v__"] = v_old;' . chr(10) . ' return out;' . chr(10) . '};' . chr(10) . chr(10) . 'p5grep = function(namespace, func, args) {' . chr(10) . ' var v_old = namespace["v__"];' . chr(10) . ' var out = [];' . chr(10) . ' for(var i = 0; i < args.length; i++) {' . chr(10) . ' namespace["v__"] = args[i];' . chr(10) . ' if (p5bool(func(0))) {' . chr(10) . ' out.push(args[i])' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' namespace["v__"] = v_old;' . chr(10) . ' return out;' . chr(10) . '};' . chr(10) . chr(10) . 'p5sort = function(namespace, func, args) {' . chr(10) . ' var a_old = namespace["v_a"];' . chr(10) . ' var b_old = namespace["v_b"];' . chr(10) . ' var out = ' . chr(10) . ' func == null' . chr(10) . ' ? args.sort()' . chr(10) . ' : args.sort(' . chr(10) . ' function(a, b) {' . chr(10) . ' namespace["v_a"] = a;' . chr(10) . ' namespace["v_b"] = b;' . chr(10) . ' return func(0);' . chr(10) . ' }' . chr(10) . ' );' . chr(10) . ' namespace["v_a"] = a_old;' . chr(10) . ' namespace["v_b"] = b_old;' . chr(10) . ' return out;' . chr(10) . '};' . chr(10) . chr(10) . 'perl5_to_js = function( source, namespace, var_env_js, p5want ) {' . chr(10) . ' // CORE.say(["source: [" + source + "]"]);' . chr(10) . chr(10) . ' var strict_old = p5pkg["Perlito5"].v_STRICT;' . chr(10) . ' var var_env_js_old = p5pkg["Perlito5"].v_VAR;' . chr(10) . ' p5pkg["Perlito5"].v_VAR = var_env_js;' . chr(10) . chr(10) . ' var namespace_old = p5pkg["Perlito5"].v_PKG_NAME;' . chr(10) . ' p5pkg["Perlito5"].v_PKG_NAME = namespace;' . chr(10) . chr(10) . ' match = p5call(p5pkg["Perlito5::Grammar"], "exp_stmts", [source, 0]);' . chr(10) . chr(10) . ' if ( !match || match._hash_.to != source.length ) {' . chr(10) . ' CORE.die(["Syntax error in eval near pos ", match._hash_.to]);' . chr(10) . ' }' . chr(10) . chr(10) . ' ast = p5pkg.CORE.bless([' . chr(10) . ' new p5HashRef({' . chr(10) . ' block: p5pkg.CORE.bless([' . chr(10) . ' new p5HashRef({' . chr(10) . ' stmts: p5pkg["Perlito5::Match"].flat([match])' . chr(10) . ' }),' . chr(10) . ' p5pkg["Perlito5::AST::Lit::Block"]' . chr(10) . ' ])' . chr(10) . ' }),' . chr(10) . ' p5pkg["Perlito5::AST::Do"]' . chr(10) . ' ]);' . chr(10) . chr(10) . ' // CORE.say(["ast: [" + ast + "]"]);' . chr(10) . ' js_code = p5call(ast, "emit_javascript3", [0, p5want]);' . chr(10) . ' // CORE.say(["js-source: [" + js_code + "]"]);' . chr(10) . chr(10) . ' p5pkg["Perlito5"].v_PKG_NAME = namespace_old;' . chr(10) . ' p5pkg["Perlito5"].v_VAR = var_env_js_old;' . chr(10) . ' p5pkg["Perlito5"].v_STRICT = strict_old;' . chr(10) . ' return js_code;' . chr(10) . '}' . chr(10) . chr(10))))
};
1;
View
2 src5/lib/Perlito5/Javascript3/Emitter.pm
@@ -288,7 +288,7 @@ package Perlito5::Javascript3;
push @out, "$k : $v";
}
- return 'new p5Hash({' . join(', ', @out) . '})'
+ return '{' . join(', ', @out) . '}'
if $printable;
}
View
12 src5/lib/Perlito5/Javascript3/Runtime.pm
@@ -265,6 +265,9 @@ function p5HashRef(o) {
this._href_ = o;
this._ref_ = "HASH";
this.p5bool = function() { return 1 };
+ this.p5string = function() {
+ return "HASH(0x0000)"; // TODO
+ };
this.hderef = function() {
return this._href_;
};
@@ -281,6 +284,9 @@ function p5ArrayRef(o) {
this._aref_ = o;
this._ref_ = "ARRAY";
this.p5bool = function() { return 1 };
+ this.p5string = function() {
+ return "ARRAY(0x0000)"; // TODO
+ };
this.aderef = function() {
return this._aref_;
};
@@ -297,6 +303,9 @@ function p5ScalarRef(o) {
this._scalar_ = o;
this._ref_ = "SCALAR";
this.p5bool = function() { return 1 };
+ this.p5string = function() {
+ return "SCALAR(0x0000)"; // TODO
+ };
this.sderef = function(i) {
return this._scalar_;
};
@@ -306,6 +315,9 @@ function p5GlobRef(o) {
this._scalar_ = o;
this._ref_ = "GLOB";
this.p5bool = function() { return 1 };
+ this.p5string = function() {
+ return "GLOB(0x0000)"; // TODO
+ };
}
function p5Array(o) {

0 comments on commit bb527ad

Please sign in to comment.